File 19767-hvm-port80-inhibit.patch of Package xen
# HG changeset patch
# User Keir Fraser <keir.fraser@citrix.com>
# Date 1245156733 -3600
# Node ID cb6f8a34b59af59b08c016a64afaba5e71cec79c
# Parent 133c889c21a7596be60ab2a79d51b4ce9ded4521
x86/hvm: don't pass through port 0x80 in a few special cases
In a recent commit (99f85a28a78e96d28907fe036e1671a218fee597), KVM
disabled the passthrough of this port due to known problems on certain
HP laptops (see
http://lkml.indiana.edu/hypermail/linux/kernel/0712.3/0872.html
and http://lkml.indiana.edu/hypermail/linux/kernel/0801.0/2388.html).
For Xen, don't do this globally, but rather based on a DMI black list.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
x86 hvm: Make sure port 0x80 in hvm_io_table[] is set correctly
regardless of execution order of hvm_enable() and check_port80().
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
--- a/xen/arch/x86/hvm/Makefile
+++ b/xen/arch/x86/hvm/Makefile
@@ -9,6 +9,7 @@ obj-y += io.o
obj-y += irq.o
obj-y += mtrr.o
obj-y += pmtimer.o
+obj-y += quirks.o
obj-y += rtc.o
obj-y += hpet.o
obj-y += vpt.o
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -69,6 +69,8 @@ unsigned long __attribute__ ((__section_
void hvm_enable(struct hvm_function_table *fns)
{
+ extern int hvm_port80_allowed;
+
BUG_ON(hvm_enabled);
printk("HVM: %s enabled\n", fns->name);
@@ -77,7 +79,8 @@ void hvm_enable(struct hvm_function_tabl
* delays, but the vmexits simply slow things down).
*/
memset(hvm_io_bitmap, ~0, sizeof(hvm_io_bitmap));
- __clear_bit(0x80, hvm_io_bitmap);
+ if ( hvm_port80_allowed )
+ __clear_bit(0x80, hvm_io_bitmap);
hvm_funcs = *fns;
hvm_enabled = 1;
--- /dev/null
+++ b/xen/arch/x86/hvm/quirks.c
@@ -0,0 +1,98 @@
+/******************************************************************************
+ * x86/hvm/quirks.c
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ */
+
+#include <xen/config.h>
+#include <xen/types.h>
+#include <xen/init.h>
+#include <xen/lib.h>
+#include <xen/dmi.h>
+#include <xen/bitmap.h>
+#include <asm/hvm/support.h>
+
+int hvm_port80_allowed = -1;
+boolean_param("hvm_port80", hvm_port80_allowed);
+
+static int __init dmi_hvm_deny_port80(/*const*/ struct dmi_system_id *id)
+{
+ printk(XENLOG_WARNING "%s: port 0x80 access %s allowed for HVM guests\n",
+ id->ident, hvm_port80_allowed > 0 ? "forcibly" : "not");
+
+ if ( hvm_port80_allowed < 0 )
+ hvm_port80_allowed = 0;
+
+ return 0;
+}
+
+static int __init check_port80(void)
+{
+ /*
+ * Quirk table for systems that misbehave (lock up, etc.) if port
+ * 0x80 is used:
+ */
+ static struct dmi_system_id __initdata hvm_no_port80_dmi_table[] =
+ {
+ {
+ .callback = dmi_hvm_deny_port80,
+ .ident = "Compaq Presario V6000",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
+ DMI_MATCH(DMI_BOARD_NAME, "30B7")
+ }
+ },
+ {
+ .callback = dmi_hvm_deny_port80,
+ .ident = "HP Pavilion dv9000z",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
+ DMI_MATCH(DMI_BOARD_NAME, "30B9")
+ }
+ },
+ {
+ .callback = dmi_hvm_deny_port80,
+ .ident = "HP Pavilion dv6000",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
+ DMI_MATCH(DMI_BOARD_NAME, "30B8")
+ }
+ },
+ {
+ .callback = dmi_hvm_deny_port80,
+ .ident = "HP Pavilion tx1000",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
+ DMI_MATCH(DMI_BOARD_NAME, "30BF")
+ }
+ },
+ {
+ .callback = dmi_hvm_deny_port80,
+ .ident = "Presario F700",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
+ DMI_MATCH(DMI_BOARD_NAME, "30D3")
+ }
+ },
+ { }
+ };
+
+ dmi_check_system(hvm_no_port80_dmi_table);
+
+ if ( !hvm_port80_allowed )
+ __set_bit(0x80, hvm_io_bitmap);
+
+ return 0;
+}
+__initcall(check_port80);