Blob Blame History Raw
From: Collin Walling <walling@linux.ibm.com>
Date: Thu, 6 Dec 2018 17:30:04 -0500
Subject: s390/setup: set control program code via diag 318
Git-commit: 4ad78b8651aacf26b3ab6d1e784952eb70469c43
Patch-mainline: v5.0 or v5.0-rc3 (next release)
References: FATE#326363, LTC#169183, bsc#1126993

Summary:     kernel: Add diag318 instruction call
Description: The DIAGNOSE 0x318 instruction call is introduced with the z14 
             GA2 hardware. This allows us to set a "Control Program Code" 
             composite value that contains a "Control Program Name Code," 
             which denotes what environment the OS is running in (this patch 
             explicitly sets a value corresponding to Linux/KVM), and a 
             "Control Program Version Code," which will denote a value that 
             will provide more info on the OS.

             Note that the Version Code is set to define the Linux kernel 
             version and a distribution identifier, but both values are set 
             to 0. A future patch will implement these values once an 
             agreement is reached.

Upstream-Description:

             s390/setup: set control program code via diag 318

             The s390x diagnose 318 instruction sets the control program name code (CPNC)
             and control program version code (CPVC) to provide useful information
             regarding the OS during debugging. The CPNC is explicitly set to 4 to
             indicate a Linux/KVM environment.

             The CPVC is a 7-byte value containing:

              - 3-byte Linux version code, currently set to 0
              - 3-byte unique value, currently set to 0
              - 1-byte trailing null

             Signed-off-by: Collin Walling <walling@linux.ibm.com>
             Acked-by: Janosch Frank <frankja@linux.ibm.com>
             Acked-by: Heiko Carstens <heiko.carstens@de.ibm.com>
             Reviewed-by: David Hildenbrand <david@redhat.com>
             Reviewed-by: Cornelia Huck <cohuck@redhat.com>
             Message-Id: <1544135405-22385-2-git-send-email-walling@linux.ibm.com>
             [set version code to 0 until the structure is fully defined]
             Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
             Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

Signed-off-by: Collin Walling <walling@linux.ibm.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 arch/s390/include/asm/diag.h   |   12 ++++++++++++
 arch/s390/include/asm/sclp.h   |    1 +
 arch/s390/kernel/diag.c        |    1 +
 arch/s390/kernel/setup.c       |   20 ++++++++++++++++++++
 drivers/s390/char/sclp_early.c |    6 +++++-
 5 files changed, 39 insertions(+), 1 deletion(-)

--- a/arch/s390/include/asm/diag.h
+++ b/arch/s390/include/asm/diag.h
@@ -31,6 +31,7 @@ enum diag_stat_enum {
 	DIAG_STAT_X2FC,
 	DIAG_STAT_X304,
 	DIAG_STAT_X308,
+	DIAG_STAT_X318,
 	DIAG_STAT_X500,
 	NR_DIAG_STAT
 };
@@ -292,6 +293,17 @@ struct diag26c_mac_resp {
 	u8	res[2];
 } __aligned(8);
 
+#define CPNC_LINUX		0x4
+union diag318_info {
+	unsigned long val;
+	struct {
+		unsigned int cpnc : 8;
+		unsigned int cpvc_linux : 24;
+		unsigned char cpvc_distro[3];
+		unsigned char zero;
+	};
+};
+
 int diag204(unsigned long subcode, unsigned long size, void *addr);
 int diag224(void *ptr);
 int diag26c(void *req, void *resp, enum diag26c_sc subcode);
--- a/arch/s390/include/asm/sclp.h
+++ b/arch/s390/include/asm/sclp.h
@@ -77,6 +77,7 @@ struct sclp_info {
 	unsigned char has_skey : 1;
 	unsigned char has_kss : 1;
 	unsigned char has_gisaf : 1;
+	unsigned char has_diag318 : 1;
 	unsigned int ibc;
 	unsigned int mtid;
 	unsigned int mtid_cp;
--- a/arch/s390/kernel/diag.c
+++ b/arch/s390/kernel/diag.c
@@ -44,6 +44,7 @@ static const struct diag_desc diag_map[N
 	[DIAG_STAT_X2FC] = { .code = 0x2fc, .name = "Guest Performance Data" },
 	[DIAG_STAT_X304] = { .code = 0x304, .name = "Partition-Resource Service" },
 	[DIAG_STAT_X308] = { .code = 0x308, .name = "List-Directed IPL" },
+	[DIAG_STAT_X318] = { .code = 0x318, .name = "CP Name and Version Codes" },
 	[DIAG_STAT_X500] = { .code = 0x500, .name = "Virtio Service" },
 };
 
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -871,6 +871,25 @@ static void __init setup_task_size(void)
 }
 
 /*
+ * Issue diagnose 318 to set the control program name and
+ * version codes.
+ */
+static void __init setup_control_program_code(void)
+{
+	union diag318_info diag318_info = {
+		.cpnc = CPNC_LINUX,
+		.cpvc_linux = 0,
+		.cpvc_distro = {0},
+	};
+
+	if (!sclp.has_diag318)
+		return;
+
+	diag_stat_inc(DIAG_STAT_X318);
+	asm volatile("diag %0,0,0x318\n" : : "d" (diag318_info.val));
+}
+
+/*
  * Setup function called from init/main.c just after the banner
  * was printed.
  */
@@ -914,6 +933,7 @@ void __init setup_arch(char **cmdline_p)
 	os_info_init();
 	setup_ipl();
 	setup_task_size();
+	setup_control_program_code();
 
 	/* Do some memory reservations *before* memory is added to memblock */
 	reserve_memory_end();
--- a/drivers/s390/char/sclp_early.c
+++ b/drivers/s390/char/sclp_early.c
@@ -53,7 +53,9 @@ struct read_info_sccb {
 	u16	hcpua;			/* 120-121 */
 	u8	_pad_122[124 - 122];	/* 122-123 */
 	u32	hmfai;			/* 124-127 */
-	u8	_pad_128[4096 - 128];	/* 128-4095 */
+	u8	_pad_128[134 - 128];	/* 128-133 */
+	u8	byte_134;			/* 134 */
+	u8	_pad_135[4096 - 135];	/* 135-4095 */
 } __packed __aligned(PAGE_SIZE);
 
 static struct sclp_ipl_info sclp_ipl_info;
@@ -106,6 +108,8 @@ static void __init sclp_early_facilities
 		S390_lowcore.machine_flags |= MACHINE_FLAG_ESOP;
 	if (sccb->fac91 & 0x40)
 		S390_lowcore.machine_flags |= MACHINE_FLAG_TLB_GUEST;
+	if (sccb->cpuoff > 134)
+		sclp.has_diag318 = !!(sccb->byte_134 & 0x80);
 	sclp.rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2;
 	sclp.rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2;
 	sclp.rzm <<= 20;