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: <1260907788.6521.10.camel@keith-laptop>
Date:	Tue, 15 Dec 2009 12:09:48 -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 drive -v2

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. 


The Device is presented as a special "_rtl_" table to the OS in the
Extended BIOS Data Area.  There is a simple protocol for entering and
exiting the mode at runtime.  This driver creates a simple sysfs
interface to allow a simple entry and exit from RTL mode in the
UFI/BIOS. 


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

---

--- linux-2.6.32/drivers/misc/ibmrtl/ibm_rtl.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.32-rtl/drivers/misc/ibmrtl/ibm_rtl.c	2009-12-14 16:37:19.000000000 -0800
@@ -0,0 +1,189 @@
+/*
+ * IBM Premium Real-Time 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2008, 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 <asm/byteorder.h>
+#include "rtl.h"
+
+static spinlock_t rtl_lock;
+static void __iomem *rtl_table;
+static void __iomem *edba_map;
+
+static int ibm_rtl_write(u8 value)
+{
+	int count = 0, ret = 0;
+	u32 cmd_prt_value, cmd_port_addr;
+
+	if ((value != RTL_ENABLE) && (value != RTL_DISABLE))
+		return -EINVAL;
+
+	spin_lock(&rtl_lock);
+
+	if (readb(rtl_table+RTL_STATE) != value) {
+		writeb(value, (rtl_table+RTL_CMD));
+
+		/* Trigger the command to be processed*/
+		cmd_prt_value = readw(rtl_table + RTL_CMD_PORT_VALUE);
+		cmd_port_addr = readw(rtl_table + RTL_CMD_PORT_ADDR);
+		outb(cmd_prt_value, cmd_port_addr);
+
+		/* Wait for the command to finish */
+		while (readb(rtl_table+RTL_CMD)) {
+			mdelay(10);
+			if (count++ > 10000) {
+				printk(KERN_ERR "IBM_RTL: Hardware not "
+					"responding to mode switch request\n");
+				spin_unlock(&rtl_lock);
+				return -EIO;
+			}
+		}
+
+		if (readb(rtl_table + RTL_CMD_STATUS))
+			ret = -EIO;
+	}
+
+	spin_unlock(&rtl_lock);
+
+	return ret;
+}
+
+static ssize_t rtl_show_version(struct sysdev_class *dev, char *buf)
+{
+	return sprintf(buf, "%d\n", (int) readb(rtl_table+RTL_VERSION));
+}
+
+static ssize_t rtl_show_state(struct sysdev_class *dev, char *buf)
+{
+	return sprintf(buf, "%d\n", readb(rtl_table+RTL_STATE));
+}
+
+static ssize_t rtl_set_state(struct sysdev_class *dev, const char *buf,
+				 size_t size)
+{
+	ssize_t ret;
+
+	if (size != 2)
+		return -EINVAL;
+
+	switch (buf[0]) {
+	case '0':
+		ret = ibm_rtl_write(RTL_DISABLE);
+		break;
+	case '1':
+		ret = ibm_rtl_write(RTL_ENABLE);
+		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_size, ebda_addr;
+	unsigned int ebda_kb;
+	u32 *table;
+	int ret;
+
+	/* Get the address for the Extende Biso Data Area */
+	ebda_addr = *(u16 *) phys_to_virt(EDBA_ADDR);
+	ebda_addr <<= 4;
+	edba_map = ioremap(ebda_addr, 4);
+	if (!edba_map)
+		return -ENOMEM;
+
+	/* First word in the EDBA is the Size in KB */
+	ebda_kb = *(u32 *) edba_map;
+	ebda_size = ebda_kb*1024;
+	iounmap(edba_map);
+
+	/* Remap the whole table */
+	edba_map = ioremap(ebda_addr, ebda_size);
+	if (!edba_map)
+		return -ENOMEM;
+
+	for (table = (u32 *) edba_map ; \
+			table < (u32 *) edba_map + ebda_size/4; table++)
+		if (*table == RTL_MAGIC_IDENT) {
+			rtl_table = table;
+			ret = rtl_setup_sysfs();
+			return ret;
+		}
+
+	ret = -ENODEV;
+	iounmap(edba_map);
+	return ret;
+}
+
+void cleanup_module(void)
+{
+	rtl_teardown_sysfs();
+	iounmap(edba_map);
+}
+
+MODULE_LICENSE("GPL");
diff -urN linux-2.6.32/drivers/misc/ibmrtl/Makefile linux-2.6.32-rtl/drivers/misc/ibmrtl/Makefile
--- linux-2.6.32/drivers/misc/ibmrtl/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.32-rtl/drivers/misc/ibmrtl/Makefile	2009-12-11 10:24:23.000000000 -0800
@@ -0,0 +1 @@
+obj-$(CONFIG_IBM_RTL) := ibm_rtl.o
diff -urN linux-2.6.32/drivers/misc/ibmrtl/rtl.h linux-2.6.32-rtl/drivers/misc/ibmrtl/rtl.h
--- linux-2.6.32/drivers/misc/ibmrtl/rtl.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.32-rtl/drivers/misc/ibmrtl/rtl.h	2009-12-11 10:24:23.000000000 -0800
@@ -0,0 +1,27 @@
+#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
+
+#define EDBA_ADDR 0x40E
+#define RTL_ENABLE 1
+#define RTL_DISABLE 2
diff -urN linux-2.6.32/drivers/misc/Kconfig linux-2.6.32-rtl/drivers/misc/Kconfig
--- linux-2.6.32/drivers/misc/Kconfig	2009-12-02 19:51:21.000000000 -0800
+++ linux-2.6.32-rtl/drivers/misc/Kconfig	2009-12-11 10:24:23.000000000 -0800
@@ -76,6 +76,22 @@
 	  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_MPPARSE && PCI && EXPERIMENTAL
+        ---help---
+	  Enable support for IBM Premium 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 receive cpu generated SMIs for recoverable errors.  Use of this
+	  feature without proper support may void your hardware warranty.
+
+	  If the proper bios support is found the driver will load and create
+	  /sys/devices/system/ibm_rtl/.  The "state" variable 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)"
 	depends on PCI
diff -urN linux-2.6.32/drivers/misc/Makefile linux-2.6.32-rtl/drivers/misc/Makefile
--- linux-2.6.32/drivers/misc/Makefile	2009-12-02 19:51:21.000000000 -0800
+++ linux-2.6.32-rtl/drivers/misc/Makefile	2009-12-11 10:24:23.000000000 -0800
@@ -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