[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86: Fix emulation of PCI access register at I/O port 0xcf8.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1208336662 -3600 # Node ID 1ac2a314aa3cf10bb0e264942cdae7fda945d7b8 # Parent c777e572a4672f1ebddd95e95b94ca1e1e9e01ca x86: Fix emulation of PCI access register at I/O port 0xcf8. The register is only visible for DWORD accesses. Furthermore, some chipsets place other registers in the range 0xf8-0xcfb for sub-DWORD accesses. Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx> --- xen/arch/x86/domain_build.c | 4 ++-- xen/arch/x86/traps.c | 32 +++++++++++++++----------------- 2 files changed, 17 insertions(+), 19 deletions(-) diff -r c777e572a467 -r 1ac2a314aa3c xen/arch/x86/domain_build.c --- a/xen/arch/x86/domain_build.c Wed Apr 16 09:45:44 2008 +0100 +++ b/xen/arch/x86/domain_build.c Wed Apr 16 10:04:22 2008 +0100 @@ -957,8 +957,8 @@ int __init construct_dom0( rc |= ioports_deny_access(dom0, 0x40, 0x43); /* PIT Channel 2 / PC Speaker Control. */ rc |= ioports_deny_access(dom0, 0x61, 0x61); - /* PCI configuration spaces. */ - rc |= ioports_deny_access(dom0, 0xcf8, 0xcff); + /* PCI configuration space (NB. 0xcf8 has special treatment). */ + rc |= ioports_deny_access(dom0, 0xcfc, 0xcff); /* Command-line I/O ranges. */ process_dom0_ioports_disable(); diff -r c777e572a467 -r 1ac2a314aa3c xen/arch/x86/traps.c --- a/xen/arch/x86/traps.c Wed Apr 16 09:45:44 2008 +0100 +++ b/xen/arch/x86/traps.c Wed Apr 16 10:04:22 2008 +0100 @@ -1399,6 +1399,13 @@ static int admin_io_okay( unsigned int port, unsigned int bytes, struct vcpu *v, struct cpu_user_regs *regs) { + /* + * Port 0xcf8 (CONFIG_ADDRESS) is only visible for DWORD accesses. + * We never permit direct access to that register. + */ + if ( (port == 0xcf8) && (bytes == 4) ) + return 0; + return ioports_access_permitted(v->domain, port, port + bytes - 1); } @@ -1431,10 +1438,10 @@ static uint32_t guest_io_read( { sub_data = pv_pit_handler(port, 0, 0); } - else if ( (port & 0xfffc) == 0xcf8 ) - { - size = min(bytes, 4 - (port & 3)); - sub_data = v->domain->arch.pci_cf8 >> ((port & 3) * 8); + else if ( (port == 0xcf8) && (bytes == 4) ) + { + size = 4; + sub_data = v->domain->arch.pci_cf8; } else if ( ((port & 0xfffc) == 0xcfc) && IS_PRIV(v->domain) ) { @@ -1489,19 +1496,10 @@ static void guest_io_write( { pv_pit_handler(port, (uint8_t)data, 1); } - else if ( (port & 0xfffc) == 0xcf8 ) - { - size = min(bytes, 4 - (port & 3)); - if ( size == 4 ) - { - v->domain->arch.pci_cf8 = data; - } - else - { - uint32_t mask = ((1u << (size * 8)) - 1) << ((port & 3) * 8); - v->domain->arch.pci_cf8 &= ~mask; - v->domain->arch.pci_cf8 |= (data << ((port & 3) * 8)) & mask; - } + else if ( (port == 0xcf8) && (bytes == 4) ) + { + size = 4; + v->domain->arch.pci_cf8 = data; } else if ( ((port & 0xfffc) == 0xcfc) && IS_PRIV(v->domain) ) { _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |