ia64/xen-unstable

changeset 19767:cb6f8a34b59a

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>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Jun 16 13:52:13 2009 +0100 (2009-06-16)
parents 133c889c21a7
children 67a0ffade665
files xen/arch/x86/hvm/Makefile xen/arch/x86/hvm/hvm.c xen/arch/x86/hvm/quirks.c
line diff
     1.1 --- a/xen/arch/x86/hvm/Makefile	Tue Jun 16 13:41:17 2009 +0100
     1.2 +++ b/xen/arch/x86/hvm/Makefile	Tue Jun 16 13:52:13 2009 +0100
     1.3 @@ -9,6 +9,7 @@ obj-y += io.o
     1.4  obj-y += irq.o
     1.5  obj-y += mtrr.o
     1.6  obj-y += pmtimer.o
     1.7 +obj-y += quirks.o
     1.8  obj-y += rtc.o
     1.9  obj-y += hpet.o
    1.10  obj-y += vpt.o
     2.1 --- a/xen/arch/x86/hvm/hvm.c	Tue Jun 16 13:41:17 2009 +0100
     2.2 +++ b/xen/arch/x86/hvm/hvm.c	Tue Jun 16 13:52:13 2009 +0100
     2.3 @@ -71,6 +71,8 @@ unsigned long __attribute__ ((__section_
     2.4  
     2.5  void hvm_enable(struct hvm_function_table *fns)
     2.6  {
     2.7 +    extern int hvm_port80_allowed;
     2.8 +
     2.9      BUG_ON(hvm_enabled);
    2.10      printk("HVM: %s enabled\n", fns->name);
    2.11  
    2.12 @@ -79,7 +81,8 @@ void hvm_enable(struct hvm_function_tabl
    2.13       * often used for I/O delays, but the vmexits simply slow things down).
    2.14       */
    2.15      memset(hvm_io_bitmap, ~0, sizeof(hvm_io_bitmap));
    2.16 -    __clear_bit(0x80, hvm_io_bitmap);
    2.17 +    if ( hvm_port80_allowed )
    2.18 +        __clear_bit(0x80, hvm_io_bitmap);
    2.19      __clear_bit(0xed, hvm_io_bitmap);
    2.20  
    2.21      hvm_funcs   = *fns;
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/xen/arch/x86/hvm/quirks.c	Tue Jun 16 13:52:13 2009 +0100
     3.3 @@ -0,0 +1,93 @@
     3.4 +/******************************************************************************
     3.5 + * x86/hvm/quirks.c
     3.6 + * 
     3.7 + * This program is free software; you can redistribute it and/or modify it
     3.8 + * under the terms and conditions of the GNU General Public License,
     3.9 + * version 2, as published by the Free Software Foundation.
    3.10 + *
    3.11 + * This program is distributed in the hope it will be useful, but WITHOUT
    3.12 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    3.13 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
    3.14 + * more details.
    3.15 + *
    3.16 + * You should have received a copy of the GNU General Public License along with
    3.17 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
    3.18 + * Place - Suite 330, Boston, MA 02111-1307 USA.
    3.19 + */
    3.20 +
    3.21 +#include <xen/config.h>
    3.22 +#include <xen/types.h>
    3.23 +#include <xen/init.h>
    3.24 +#include <xen/lib.h>
    3.25 +#include <xen/dmi.h>
    3.26 +
    3.27 +int hvm_port80_allowed = -1;
    3.28 +boolean_param("hvm_port80", hvm_port80_allowed);
    3.29 +
    3.30 +static int __init dmi_hvm_deny_port80(/*const*/ struct dmi_system_id *id)
    3.31 +{
    3.32 +    printk(XENLOG_WARNING "%s: port 0x80 access %s allowed for HVM guests\n",
    3.33 +           id->ident, hvm_port80_allowed > 0 ? "forcibly" : "not");
    3.34 +
    3.35 +    if ( hvm_port80_allowed < 0 )
    3.36 +        hvm_port80_allowed = 0;
    3.37 +
    3.38 +    return 0;
    3.39 +}
    3.40 +
    3.41 +static int __init check_port80(void)
    3.42 +{
    3.43 +    /*
    3.44 +     * Quirk table for systems that misbehave (lock up, etc.) if port
    3.45 +     * 0x80 is used:
    3.46 +     */
    3.47 +    static struct dmi_system_id __initdata hvm_no_port80_dmi_table[] =
    3.48 +    {
    3.49 +        {
    3.50 +            .callback = dmi_hvm_deny_port80,
    3.51 +            .ident    = "Compaq Presario V6000",
    3.52 +            .matches  = {
    3.53 +                DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
    3.54 +                DMI_MATCH(DMI_BOARD_NAME,   "30B7")
    3.55 +            }
    3.56 +        },
    3.57 +        {
    3.58 +            .callback = dmi_hvm_deny_port80,
    3.59 +            .ident    = "HP Pavilion dv9000z",
    3.60 +            .matches  = {
    3.61 +                DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
    3.62 +                DMI_MATCH(DMI_BOARD_NAME,   "30B9")
    3.63 +            }
    3.64 +        },
    3.65 +        {
    3.66 +            .callback = dmi_hvm_deny_port80,
    3.67 +            .ident    = "HP Pavilion dv6000",
    3.68 +            .matches  = {
    3.69 +                DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
    3.70 +                DMI_MATCH(DMI_BOARD_NAME,   "30B8")
    3.71 +            }
    3.72 +        },
    3.73 +        {
    3.74 +            .callback = dmi_hvm_deny_port80,
    3.75 +            .ident    = "HP Pavilion tx1000",
    3.76 +            .matches  = {
    3.77 +                DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
    3.78 +                DMI_MATCH(DMI_BOARD_NAME,   "30BF")
    3.79 +            }
    3.80 +        },
    3.81 +        {
    3.82 +            .callback = dmi_hvm_deny_port80,
    3.83 +            .ident    = "Presario F700",
    3.84 +            .matches  = {
    3.85 +                DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
    3.86 +                DMI_MATCH(DMI_BOARD_NAME,   "30D3")
    3.87 +            }
    3.88 +        },
    3.89 +        { }
    3.90 +    };
    3.91 +
    3.92 +    dmi_check_system(hvm_no_port80_dmi_table);
    3.93 +
    3.94 +    return 0;
    3.95 +}
    3.96 +__initcall(check_port80);