diff --git a/Makefile b/Makefile
index 83623a1..7ac2eaa 100644
--- a/Makefile
+++ b/Makefile
@@ -18,6 +18,7 @@ build_test:  ## test only buildable
 	GOOS=linux GOARCH=arm go test ./... | $(BUILD_FAIL_PATTERN)
 	GOOS=linux GOARCH=arm64 go test ./... | $(BUILD_FAIL_PATTERN)
 	GOOS=linux GOARCH=riscv64 go test ./... | $(BUILD_FAIL_PATTERN)
+	GOOS=linux GOARCH=s390x go test ./... | $(BUILD_FAIL_PATTERN)
 	GOOS=freebsd GOARCH=amd64 go test ./... | $(BUILD_FAIL_PATTERN)
 	GOOS=freebsd GOARCH=386 go test ./... | $(BUILD_FAIL_PATTERN)
 	GOOS=freebsd GOARCH=arm go test ./... | $(BUILD_FAIL_PATTERN)
diff --git a/cpu/cpu_linux.go b/cpu/cpu_linux.go
index a60e462..f2feb07 100644
--- a/cpu/cpu_linux.go
+++ b/cpu/cpu_linux.go
@@ -190,7 +190,7 @@ func InfoWithContext(ctx context.Context) ([]InfoStat, error) {
 		switch key {
 		case "Processor":
 			processorName = value
-		case "processor":
+		case "processor", "cpu number":
 			if c.CPU >= 0 {
 				finishCPUInfo(&c)
 				ret = append(ret, c)
@@ -203,6 +203,9 @@ func InfoWithContext(ctx context.Context) ([]InfoStat, error) {
 			c.CPU = int32(t)
 		case "vendorId", "vendor_id":
 			c.VendorID = value
+			if strings.Contains(value, "S390") {
+				processorName = "S390"
+			}
 		case "CPU implementer":
 			if v, err := strconv.ParseUint(value, 0, 8); err == nil {
 				switch v {
@@ -273,7 +276,7 @@ func InfoWithContext(ctx context.Context) ([]InfoStat, error) {
 				return ret, err
 			}
 			c.Stepping = int32(t)
-		case "cpu MHz", "clock":
+		case "cpu MHz", "clock", "cpu MHz dynamic":
 			// treat this as the fallback value, thus we ignore error
 			if t, err := strconv.ParseFloat(strings.Replace(value, "MHz", "", 1), 64); err == nil {
 				c.Mhz = t
diff --git a/cpu/cpu_linux_test.go b/cpu/cpu_linux_test.go
index ec3330f..e06f305 100644
--- a/cpu/cpu_linux_test.go
+++ b/cpu/cpu_linux_test.go
@@ -48,7 +48,9 @@ func TestCPUCountsAgainstLscpu(t *testing.T) {
 		}
 		t.Errorf("error executing lscpu: %v", err)
 	}
-	var threadsPerCore, coresPerSocket, sockets int
+	var threadsPerCore, coresPerSocket, sockets, books, drawers int
+	books = 1
+	drawers = 1
 	lines := strings.Split(string(out), "\n")
 	for _, line := range lines {
 		fields := strings.Split(line, ":")
@@ -60,14 +62,18 @@ func TestCPUCountsAgainstLscpu(t *testing.T) {
 			threadsPerCore, _ = strconv.Atoi(strings.TrimSpace(fields[1]))
 		case "Core(s) per socket":
 			coresPerSocket, _ = strconv.Atoi(strings.TrimSpace(fields[1]))
-		case "Socket(s)":
+		case "Socket(s)", "Socket(s) per book":
 			sockets, _ = strconv.Atoi(strings.TrimSpace(fields[1]))
+		case "Book(s) per drawer":
+			books, _ = strconv.Atoi(strings.TrimSpace(fields[1]))
+		case "Drawer(s)":
+			drawers, _ = strconv.Atoi(strings.TrimSpace(fields[1]))
 		}
 	}
 	if threadsPerCore == 0 || coresPerSocket == 0 || sockets == 0 {
 		t.Errorf("missing info from lscpu: threadsPerCore=%d coresPerSocket=%d sockets=%d", threadsPerCore, coresPerSocket, sockets)
 	}
-	expectedPhysical := coresPerSocket * sockets
+	expectedPhysical := coresPerSocket * sockets * books * drawers
 	expectedLogical := expectedPhysical * threadsPerCore
 	physical, err := Counts(false)
 	skipIfNotImplementedErr(t, err)