1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /******************************************************************************
3  * x86/hvm/quirks.c
4  */
5 
6 #include <xen/types.h>
7 #include <xen/init.h>
8 #include <xen/lib.h>
9 #include <xen/dmi.h>
10 #include <xen/bitmap.h>
11 #include <xen/param.h>
12 #include <asm/hvm/support.h>
13 
14 int8_t __ro_after_init hvm_port80_allowed = -1;
15 boolean_param("hvm_port80", hvm_port80_allowed);
16 
dmi_hvm_deny_port80(const struct dmi_system_id * id)17 static int __init cf_check dmi_hvm_deny_port80(const struct dmi_system_id *id)
18 {
19     printk(XENLOG_WARNING "%s: port 0x80 access %s allowed for HVM guests\n",
20            id->ident, hvm_port80_allowed > 0 ? "forcibly" : "not");
21 
22     if ( hvm_port80_allowed < 0 )
23         hvm_port80_allowed = 0;
24 
25     return 0;
26 }
27 
check_port80(void)28 static int __init cf_check check_port80(void)
29 {
30     /*
31      * Quirk table for systems that misbehave (lock up, etc.) if port
32      * 0x80 is used:
33      */
34     static const struct dmi_system_id __initconstrel hvm_no_port80_dmi_table[] =
35     {
36         {
37             .callback = dmi_hvm_deny_port80,
38             .ident    = "Compaq Presario V6000",
39 	    DMI_MATCH2(
40                 DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
41                 DMI_MATCH(DMI_BOARD_NAME,   "30B7")),
42         },
43         {
44             .callback = dmi_hvm_deny_port80,
45             .ident    = "HP Pavilion dv9000z",
46 	    DMI_MATCH2(
47                 DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
48                 DMI_MATCH(DMI_BOARD_NAME,   "30B9")),
49         },
50         {
51             .callback = dmi_hvm_deny_port80,
52             .ident    = "HP Pavilion dv6000",
53 	    DMI_MATCH2(
54                 DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
55                 DMI_MATCH(DMI_BOARD_NAME,   "30B8")),
56         },
57         {
58             .callback = dmi_hvm_deny_port80,
59             .ident    = "HP Pavilion tx1000",
60 	    DMI_MATCH2(
61                 DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
62                 DMI_MATCH(DMI_BOARD_NAME,   "30BF")),
63         },
64         {
65             .callback = dmi_hvm_deny_port80,
66             .ident    = "Presario F700",
67 	    DMI_MATCH2(
68                 DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
69                 DMI_MATCH(DMI_BOARD_NAME,   "30D3")),
70         },
71         { }
72     };
73 
74     dmi_check_system(hvm_no_port80_dmi_table);
75 
76     if ( !hvm_port80_allowed )
77         __set_bit(0x80, hvm_io_bitmap);
78 
79     return 0;
80 }
81 __initcall(check_port80);
82