x86/PCI: pass correct register value to XSM
authorDaniel De Graaf <dgdegra@tycho.nsa.gov>
Fri, 22 Jun 2012 11:44:54 +0000 (13:44 +0200)
committerDaniel De Graaf <dgdegra@tycho.nsa.gov>
Fri, 22 Jun 2012 11:44:54 +0000 (13:44 +0200)
When attempting to use AMD's extension to access the extended PCI config
space, only the low byte of the register number was being passed to XSM.
Include the correct value of the register if this feature is enabled;
otherwise, bits 24-30 of port cf8 are reserved, so disallow the invalid
access.

Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
Don't fail the permission check except when the MSR can't be read.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
Committed-by: Jan Beulich <jbeulich@suse.com>
xen/arch/x86/traps.c

index f0ef7626f89fcb3cd0fd9bd61aff022a0efad160..767be86a1812d79fb271540ec2b78ffeae7d1872 100644 (file)
@@ -1701,6 +1701,18 @@ static int pci_cfg_ok(struct domain *d, int write, int size)
             return 0;
     }
     start = d->arch.pci_cf8 & 0xFF;
+    /* AMD extended configuration space access? */
+    if ( (d->arch.pci_cf8 & 0x0F000000) &&
+         boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
+         boot_cpu_data.x86 >= 0x10 && boot_cpu_data.x86 <= 0x17 )
+    {
+        uint64_t msr_val;
+
+        if ( rdmsr_safe(MSR_AMD64_NB_CFG, msr_val) )
+            return 0;
+        if ( msr_val & (1ULL << AMD64_NB_CFG_CF8_EXT_ENABLE_BIT) )
+            start |= (d->arch.pci_cf8 >> 16) & 0xF00;
+    }
     end = start + size - 1;
     if (xsm_pci_config_permission(d, machine_bdf, start, end, write))
         return 0;