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