[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH] x86: guard against port I/O overlapping the RTC/CMOS range
Since we intercept RTC/CMOS port accesses, let's do so consistently in all cases, i.e. also for e.g. a dword access to [006E,0071]. To avoid the risk of unintended impact on Dom0 code actually doing so (despite the belief that none ought to exist), also extend guest_io_{read,write}() to decompose accesses where some ports are allowed to be directly accessed and some aren't. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> --- a/xen/arch/x86/pv/emul-priv-op.c +++ b/xen/arch/x86/pv/emul-priv-op.c @@ -210,7 +210,7 @@ static bool admin_io_okay(unsigned int p return false; /* We also never permit direct access to the RTC/CMOS registers. */ - if ( ((port & ~1) == RTC_PORT(0)) ) + if ( port <= RTC_PORT(1) && port + bytes > RTC_PORT(0) ) return false; return ioports_access_permitted(d, port, port + bytes - 1); @@ -297,6 +297,17 @@ static uint32_t guest_io_read(unsigned i if ( pci_cfg_ok(currd, port & 3, size, NULL) ) sub_data = pci_conf_read(currd->arch.pci_cf8, port & 3, size); } + else if ( ioports_access_permitted(currd, port, port) ) + { + if ( bytes > 1 && !(port & 1) && + ioports_access_permitted(currd, port, port + 1) ) + { + sub_data = inw(port); + size = 2; + } + else + sub_data = inb(port); + } if ( size == 4 ) return sub_data; @@ -373,25 +384,31 @@ static int read_io(unsigned int port, un return X86EMUL_OKAY; } +static void _guest_io_write(unsigned int port, unsigned int bytes, + uint32_t data) +{ + switch ( bytes ) + { + case 1: + outb((uint8_t)data, port); + if ( amd_acpi_c1e_quirk ) + amd_check_disable_c1e(port, (uint8_t)data); + break; + case 2: + outw((uint16_t)data, port); + break; + case 4: + outl(data, port); + break; + } +} + static void guest_io_write(unsigned int port, unsigned int bytes, uint32_t data, struct domain *currd) { if ( admin_io_okay(port, bytes, currd) ) { - switch ( bytes ) - { - case 1: - outb((uint8_t)data, port); - if ( amd_acpi_c1e_quirk ) - amd_check_disable_c1e(port, (uint8_t)data); - break; - case 2: - outw((uint16_t)data, port); - break; - case 4: - outl(data, port); - break; - } + _guest_io_write(port, bytes, data); return; } @@ -420,6 +437,13 @@ static void guest_io_write(unsigned int if ( pci_cfg_ok(currd, port & 3, size, &data) ) pci_conf_write(currd->arch.pci_cf8, port & 3, size, data); } + else if ( ioports_access_permitted(currd, port, port) ) + { + if ( bytes > 1 && !(port & 1) && + ioports_access_permitted(currd, port, port + 1) ) + size = 2; + _guest_io_write(port, size, data); + } if ( size == 4 ) return;
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |