aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/traps.c
diff options
context:
space:
mode:
authorDaniel De Graaf <dgdegra@tycho.nsa.gov>2012-06-22 13:44:54 +0200
committerDaniel De Graaf <dgdegra@tycho.nsa.gov>2012-06-22 13:44:54 +0200
commit1448429664da9a3c33fc64cbbdde6508b86ecb2e (patch)
tree5ed1058f8ba243503e36d0d08a86ea6a3dbe4651 /xen/arch/x86/traps.c
parent56b3130c1a4ffc3c1a045559240261b892b9b880 (diff)
downloadxen-1448429664da9a3c33fc64cbbdde6508b86ecb2e.tar.gz
xen-1448429664da9a3c33fc64cbbdde6508b86ecb2e.tar.bz2
xen-1448429664da9a3c33fc64cbbdde6508b86ecb2e.zip
x86/PCI: pass correct register value to XSM
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>
Diffstat (limited to 'xen/arch/x86/traps.c')
-rw-r--r--xen/arch/x86/traps.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index f0ef7626f8..767be86a18 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -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;