[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.