Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 3148

kernel-2.6.18-194.11.1.el5.src.rpm

From: Hans-Joachim Picht <hpicht@redhat.com>
Date: Thu, 12 Mar 2009 15:24:16 +0100
Subject: [s390] kernel: extra kernel parameters via VMPARM
Message-id: 20090312142416.GI5103@redhat.com
O-Subject: [RHEL5 U4 PATCH 8/20] FEAT: s390 - kernel: Extra kernel parameters via VMPARM
Bugzilla: 475530

Description
============

This feature allows the user to append or replace kernel
parameters using PARM option of the IPL command.
Parameters can be set with the IPL command on the CP/CMS
commandline or via the new "parm" sysfs attribute
for the ccw and nss reipl types.

Bugzilla
=========

BZ 475530
https://bugzilla.redhat.com/show_bug.cgi?id=475530

Upstream status of the patch:
=============================

The patch is upstream as of git commit
a0443fbb467af5e5930b9b059b52190605f70059

Test status:
============

The patch has been tested by the IBM test department.

Please ACK.

With best regards,

	--Hans

diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 9278e87..c6dfba1 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -15,6 +15,7 @@
 #include <linux/reboot.h>
 #include <linux/ctype.h>
 #include <linux/fs.h>
+#include <linux/stringify.h>
 #include <asm/ipl.h>
 #include <asm/smp.h>
 #include <asm/setup.h>
@@ -22,6 +23,7 @@
 #include <asm/cio.h>
 #include <asm/ebcdic.h>
 #include <asm/setup.h>
+#include <asm/lowcore.h>
 
 #define IPL_PARM_BLOCK_VERSION 0
 
@@ -158,6 +160,43 @@ static enum dump_method dump_method = DUMP_METHOD_NONE;
 static struct ipl_parameter_block *dump_block_fcp;
 static struct ipl_parameter_block *dump_block_ccw;
 
+/*
+ * diag308_early() - Set program new psw and call DIAG308
+ *
+ * This function provides calls diag308 using its own exception handling.
+ * Use this function if the lowcore has not yet been initialized.
+ * NOTE: The first parameter must be the address, the second the subcode.
+ */
+int __init diag308_early(void *addr, unsigned long subcode);
+asm(
+	"	.section .init.text,\"ax\",@progbits\n"
+	"	.align	4\n"
+	"	.type	diag308_early, @function\n"
+	"diag308_early:\n"
+	"	basr	%r5,0\n"
+	"0:\n"
+	"	la	%r1,1f-0b(%r5)\n"
+#ifdef CONFIG_64BIT
+	"	mvc	" __stringify(__LC_PGM_NEW_PSW) "(8),.Lpcmsk-0b(%r5)\n"
+	"	stg	%r1," __stringify(__LC_PGM_NEW_PSW) "+8\n"
+#else
+	"	mvc	" __stringify(__LC_PGM_NEW_PSW) "(4),.Lpcmsk-0b(%r5)\n"
+	"	st	%r1," __stringify(__LC_PGM_NEW_PSW) "+4\n"
+#endif
+	"	diag	%r2,%r3,0x308\n"
+	"	la	%r2,0(%r3)\n"	/* store diag rc (%r3) in %r2 */
+	"	br	%r14\n"
+	"1:	la	%r2,0\n"
+	"	br	%r14\n"
+	".Lpcmsk:\n"
+#ifdef CONFIG_64BIT
+	"	.quad	0x0000000180000000\n"
+#else
+	"	.long	0x00080000\n"
+#endif
+	"	.size	diag308_early, .-diag308_early\n"
+	"	.previous\n");
+
 int diag308(unsigned long subcode, void *addr)
 {
 	register unsigned long _addr asm("0") = (unsigned long) addr;
@@ -1692,7 +1731,7 @@ void __init ipl_update_parameters(void)
 {
 	int rc;
 
-	rc = diag308(DIAG308_STORE, &ipl_block);
+	rc = diag308_early(&ipl_block, DIAG308_STORE);
 	if ((rc == DIAG308_RC_OK) || (rc == DIAG308_RC_NOCONFIG))
 		diag308_set_works = 1;
 }
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 36ff345..febfa6f 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -275,21 +275,40 @@ static void __init conmode_default(void)
 	}
 }
 
+/* Set up boot command line */
+static char __initdata s390_command_line[COMMAND_LINE_SIZE];
+
+static void __init setup_boot_command_line(void)
+{
+	char *parm = NULL;
+
+	/* copy arch command line */
+	strlcpy(s390_command_line, COMMAND_LINE, ARCH_COMMAND_LINE_SIZE);
+
+	/* append IPL PARM data to the boot command line */
+	if (MACHINE_IS_VM) {
+		parm = s390_command_line + strlen(s390_command_line);
+		*parm++ = ' ';
+		get_ipl_vmparm(parm);
+		if (parm[0] == '=')
+			memmove(s390_command_line, parm + 1, strlen(parm));
+	}
+}
+
 #if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE)
 static void __init setup_zfcpdump(unsigned int console_devno)
 {
-	static char str[64];
+	static char str[41];
 
 	if (ipl_info.type != IPL_TYPE_FCP_DUMP)
 		return;
 	if (console_devno != -1)
-		sprintf(str, "cio_ignore=all,!0.0.%04x,!0.0.%04x",
+		sprintf(str, " cio_ignore=all,!0.0.%04x,!0.0.%04x",
 			ipl_info.data.fcp.dev_id.devno, console_devno);
 	else
-		sprintf(str, "cio_ignore=all,!0.0.%04x",
+		sprintf(str, " cio_ignore=all,!0.0.%04x",
 			ipl_info.data.fcp.dev_id.devno);
-	strcat(COMMAND_LINE, " ");
-	strcat(COMMAND_LINE, str);
+	strcat(s390_command_line, str);
 	console_loglevel = 2;
 }
 #else
@@ -429,6 +448,8 @@ void __init startup_init(void)
 	clear_bss_section();
 	init_kernel_storage_key();
 	detect_machine_type();
+	ipl_update_parameters();
+	setup_boot_command_line();
 	create_kernel_nss();
 }
 
@@ -852,11 +873,9 @@ setup_arch(char **cmdline_p)
 	       "We are running native (64 bit mode)\n");
 #endif /* CONFIG_64BIT */
 
-	/* Save unparsed command line copy for /proc/cmdline */
-	strlcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
-
-	*cmdline_p = COMMAND_LINE;
-	*(*cmdline_p + COMMAND_LINE_SIZE - 1) = '\0';
+	/* save unparsed s390_command_line for /proc/cmdline */
+	memcpy(saved_command_line, s390_command_line, COMMAND_LINE_SIZE);
+	*cmdline_p = s390_command_line;
 
         ROOT_DEV = Root_RAM0;
 
diff --git a/include/asm-s390/setup.h b/include/asm-s390/setup.h
index e061bb0..7449513 100644
--- a/include/asm-s390/setup.h
+++ b/include/asm-s390/setup.h
@@ -8,12 +8,15 @@
 #ifndef _ASM_S390_SETUP_H
 #define _ASM_S390_SETUP_H
 
+#define COMMAND_LINE_SIZE	1024
+
+#define ARCH_COMMAND_LINE_SIZE	896
+
 #ifdef __KERNEL__
 
 #include <asm/types.h>
 
 #define PARMAREA		0x10400
-#define COMMAND_LINE_SIZE 	896
 #define RAMDISK_ORIGIN		0x800000
 #define RAMDISK_SIZE		0x800000
 #define MEMORY_CHUNKS		16	/* max 0x7fff */