lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <1234312633.15410.546.camel@keith-laptop>
Date:	Tue, 10 Feb 2009 16:37:13 -0800
From:	Keith Mannthey <kmannth@...ibm.com>
To:	lkml <linux-kernel@...r.kernel.org>
Cc:	John Stultz <johnstul@...ibm.com>
Subject: [RFC][Patch] IBM Real-Time "SMI Free" mode driver

This driver supports the Real-Time Linux (RTL) BIOS feature.  The RTL
feature allows non-fatal System Management Interrupts (SMIs) to be
disabled on supported IBM platforms (LS21, LS22 and HS21xm blades).  

This driver creates a simple sysfs interface to allow a simple entry and
exit from RTL mode in the BIOS. 

Signed-off-by:  Keith Mannthey <kmannth@...ibm.com>

---

diff -urN linux-2.6.29-rc3-git7-orig/drivers/misc/ibmrtl/ibm_rtl.c linux-2.6.29-rc3-git7/drivers/misc/ibmrtl/ibm_rtl.c
--- linux-2.6.29-rc3-git7-orig/drivers/misc/ibmrtl/ibm_rtl.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.29-rc3-git7/drivers/misc/ibmrtl/ibm_rtl.c	2009-02-10 13:58:21.000000000 -0500
@@ -0,0 +1,205 @@
+/*
+ * IBM Real Time Linux Mode Device Driver
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) IBM Corporation, 2009
+ *
+ * Author: Keith Mannthey <kmannth@...ibm.com>
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include "rtl.h"
+
+static unsigned int table_addr;
+
+int ibm_rtl_write(u8 value)
+{
+	int ret = 0;
+	void __iomem *rtl;
+
+	/* only valid value is 0 and 1 */
+	if (value > 1) {
+		ret = -EINVAL;
+		goto err_out;
+	}
+
+	rtl = ioremap(table_addr, RTL_TABLE_SIZE);
+
+	if (!rtl) {
+		printk(KERN_WARNING "Could not ioremap RTL table\n");
+		ret = -ENOMEM;
+		goto err_out;
+	}
+
+	if (readb(rtl+RTL_STATE) != value) {
+		if (value == 1)
+			writeb(1, (rtl+RTL_CMD));
+		else
+			writeb(2, (rtl+RTL_CMD));
+
+		/*write special command*/
+		outb(bios_to_value(rtl, RTL_CMD_PORT_VALUE),
+			bios_to_value(rtl, RTL_CMD_PORT_ADDR));
+
+		while (readb(rtl+RTL_CMD))
+			msleep(10);
+
+		if (readb(rtl+RTL_CMD_STATUS))
+			ret = -EIO;
+	}
+
+	iounmap(rtl);
+err_out:
+	return ret;
+}
+
+static ssize_t rtl_show_version(struct sysdev_class *dev, char * buf)
+{
+	int ret;
+	void  __iomem *rtl;
+
+	rtl = ioremap(table_addr, RTL_TABLE_SIZE);
+
+	if (!rtl) {
+		ret = -ENOMEM;
+		goto err_out;
+	}
+	ret = sprintf(buf, "%d\n", (int)readb(rtl+RTL_VERSION));
+
+	iounmap(rtl);
+err_out:
+	return ret;
+}
+
+static ssize_t rtl_show_state(struct sysdev_class *dev, char *buf)
+{
+	int ret;
+	void __iomem *rtl;
+
+	rtl = ioremap(table_addr, RTL_TABLE_SIZE);
+
+	if (!rtl) {
+		printk(KERN_WARNING "Could not ioremap RTL table\n");
+		ret = -ENOMEM;
+		goto err_out;
+	}
+	ret = sprintf(buf, "%d\n", readb(rtl+RTL_STATE));
+
+	iounmap(rtl);
+err_out:
+	return ret;
+}
+
+static ssize_t rtl_set_state(struct sysdev_class *dev, const char *buf,
+								size_t size)
+{
+	ssize_t ret;
+	switch (buf[0]) {
+	case '0':
+		ret = ibm_rtl_write(0);
+		break;
+	case '1':
+		ret = ibm_rtl_write(1);
+		break;
+	default:
+		ret = -EINVAL;
+	}
+	if (ret >= 0)
+		ret = size;
+
+	return ret;
+}
+
+static struct sysdev_class class_rtl = {
+	.name	= "ibm_rtl",
+};
+
+static SYSDEV_CLASS_ATTR(version, S_IRUGO, rtl_show_version, NULL);
+static SYSDEV_CLASS_ATTR(state, 0600, rtl_show_state, rtl_set_state);
+
+static struct sysdev_class_attribute *rtl_attributes[] = {
+	&attr_version,
+	&attr_state,
+	NULL
+};
+
+
+static int rtl_setup_sysfs(void)
+{
+	int ret, i;
+	ret = sysdev_class_register(&class_rtl);
+
+	if (!ret) {
+		for (i = 0; rtl_attributes[i]; i++)
+			sysdev_class_create_file(&class_rtl, rtl_attributes[i]);
+	}
+	return ret;
+}
+
+static void rtl_teardown_sysfs(void)
+{
+	int i;
+	for (i = 0; rtl_attributes[i]; i++)
+		sysdev_class_remove_file(&class_rtl, rtl_attributes[i]);
+	sysdev_class_unregister(&class_rtl);
+	return;
+}
+
+/* only allow the modules to load if the _RTL_ table can be found*/
+int init_module(void)
+{
+	unsigned long ebda_addr, ebda_size;
+	void __iomem *data, *d;
+	int ret, i;
+
+	/*get the address for the RTL table from the EBDA */
+	ebda_addr = *(unsigned short *)phys_to_virt(0x40E);
+	ebda_addr <<= 4;
+	ebda_size = 64*1024;
+
+	data = ioremap(ebda_addr, ebda_size);
+	d = data;
+	if (!data) {
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	for (i = 0 ; i < ebda_size/4; i++) {
+		unsigned int *tmp = (unsigned int *) data++;
+		if (*tmp == RTL_MAGIC_IDENT) {
+			table_addr = ebda_addr + i;
+			ret = rtl_setup_sysfs();
+			goto exit;
+		}
+	}
+
+	ret = -ENODEV;
+
+exit:
+	iounmap(d);
+	return ret;
+}
+
+void cleanup_module(void)
+{
+	rtl_teardown_sysfs();
+}
+
+MODULE_LICENSE("GPL");
diff -urN linux-2.6.29-rc3-git7-orig/drivers/misc/ibmrtl/Makefile linux-2.6.29-rc3-git7/drivers/misc/ibmrtl/Makefile
--- linux-2.6.29-rc3-git7-orig/drivers/misc/ibmrtl/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.29-rc3-git7/drivers/misc/ibmrtl/Makefile	2009-02-05 12:38:35.000000000 -0500
@@ -0,0 +1 @@
+obj-$(CONFIG_IBM_RTL) := ibm_rtl.o
diff -urN linux-2.6.29-rc3-git7-orig/drivers/misc/ibmrtl/rtl.h linux-2.6.29-rc3-git7/drivers/misc/ibmrtl/rtl.h
--- linux-2.6.29-rc3-git7-orig/drivers/misc/ibmrtl/rtl.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.29-rc3-git7/drivers/misc/ibmrtl/rtl.h	2009-02-10 13:58:12.000000000 -0500
@@ -0,0 +1,49 @@
+/*
+ * IBM Real Time Linux Mode Device Driver
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) IBM Corporation, 2009
+ *
+ * Author: Keith Mannthey <kmannth@...ibm.com>
+ *
+ */
+
+#include <linux/io.h>
+
+/* The RTL table looks something like
+	u8 signature[5];
+	u8 version;
+	u8 RT_Status;
+	u8 Command;
+	u8 CommandStatus;
+	u8 CMDAddressType;
+	u8 CmdGranularity;
+	u8 CmdOffset;
+	u16 Reserve1;
+	u8 CmdPortAddress[4];
+	u8 CmdPortValue[4];
+*/
+#define RTL_TABLE_SIZE 0x16
+#define RTL_MAGIC_IDENT (('L'<<24)|('T'<<16)|('R'<<8)|'_')
+#define RTL_VERSION 0x5
+#define RTL_STATE 0x6
+#define RTL_CMD 0x7
+#define RTL_CMD_STATUS 0x8
+#define RTL_CMD_PORT_ADDR 0xE
+#define RTL_CMD_PORT_VALUE 0x12
+
+/*needed to decode CmdPortAddress and CmdPortValue*/
+#define bios_to_value(rtl, offset) (u32)((readb(rtl+(offset+1)) << 8) + \
+							readb(rtl+offset))
diff -urN linux-2.6.29-rc3-git7-orig/drivers/misc/Kconfig linux-2.6.29-rc3-git7/drivers/misc/Kconfig
--- linux-2.6.29-rc3-git7-orig/drivers/misc/Kconfig	2009-02-05 12:29:22.000000000 -0500
+++ linux-2.6.29-rc3-git7/drivers/misc/Kconfig	2009-02-05 12:45:48.000000000 -0500
@@ -75,6 +75,21 @@
 	  website <http://www.pc.ibm.com/ww/eserver/xseries/serverproven> for
 	  information on the specific driver level and support statement
 	  for your IBM server.
+config IBM_RTL
+        tristate "Device driver to enable IBM PRTL support"
+        depends on X86 && PCI && EXPERIMENTAL
+        ---help---
+	  Enable support for IBM Preimium Real Time Mode (PRTM).
+	  This module will allow you the enter and exit PRTM in the BIOS via
+	  sysfs on platforms that support this feature.  System in PRTM will
+	  not recive cpu generated SMIs for recoverable errors.  Use of this
+	  feature without proper support may void your hardware warrenty.
+
+	  If the proper bios support is found the driver will load and create
+	  /sys/devices/system/ibm_rtl/.  The "state" varable will indicate
+	  weather or not the BIOS is in PRTM.
+	  state = 0 (BIOS SMI's on)
+	  state = 1 (BIOS SMI's off)
 
 config PHANTOM
 	tristate "Sensable PHANToM (PCI)"
diff -urN linux-2.6.29-rc3-git7-orig/drivers/misc/Makefile linux-2.6.29-rc3-git7/drivers/misc/Makefile
--- linux-2.6.29-rc3-git7-orig/drivers/misc/Makefile	2009-02-05 12:29:22.000000000 -0500
+++ linux-2.6.29-rc3-git7/drivers/misc/Makefile	2009-02-05 12:39:54.000000000 -0500
@@ -3,6 +3,7 @@
 #
 
 obj-$(CONFIG_IBM_ASM)		+= ibmasm/
+obj-$(CONFIG_IBM_RTL)		+= ibmrtl/
 obj-$(CONFIG_HDPU_FEATURES)	+= hdpuftrs/
 obj-$(CONFIG_ATMEL_PWM)		+= atmel_pwm.o
 obj-$(CONFIG_ATMEL_SSC)		+= atmel-ssc.o


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ