Unfortunately it turned out the original Linux code had more issues: We want to place the region above 4G in any case (even if TOM2 isn't enabled or invalid), and the base mask definition was improperly typed (thus causing shifts by FAM10H_MMIO_CONF_BASE_SHIFT to produce other than the intended result). Fixing this in turn allowed simplifying the MMIO region detection code, as regions ending below TOM2 now aren't of interest anymore. Signed-off-by: Jan Beulich --- a/xen/include/asm-x86/msr-index.h +++ b/xen/include/asm-x86/msr-index.h @@ -246,7 +246,7 @@ #define FAM10H_MMIO_CONF_ENABLE (1<<0) #define FAM10H_MMIO_CONF_BUSRANGE_MASK 0xf #define FAM10H_MMIO_CONF_BUSRANGE_SHIFT 2 -#define FAM10H_MMIO_CONF_BASE_MASK 0xfffffff +#define FAM10H_MMIO_CONF_BASE_MASK 0xfffffffULL #define FAM10H_MMIO_CONF_BASE_SHIFT 20 /* AMD Microcode MSRs */ --- a/xen/arch/x86/x86_64/mmconf-fam10h.c +++ b/xen/arch/x86/x86_64/mmconf-fam10h.c @@ -28,7 +28,7 @@ static struct pci_hostbridge_probe pci_p { 0xff, 0, PCI_VENDOR_ID_AMD, 0x1200 }, }; -#define UNIT (1ULL << (5 + 3 + 12)) +#define UNIT (1ULL << FAM10H_MMIO_CONF_BASE_SHIFT) #define MASK (~(UNIT - 1)) #define SIZE (UNIT << 8) /* need to avoid (0xfd<<32) and (0xfe<<32), ht used space */ @@ -68,12 +68,12 @@ static void __init get_fam10h_pci_mmconf /* TOP_MEM2 is not enabled? */ if (!(val & (1<<21))) { - tom2 = 0; + tom2 = 1ULL << 32; } else { /* TOP_MEM2 */ address = MSR_K8_TOP_MEM2; rdmsrl(address, val); - tom2 = val & 0xffffff800000ULL; + tom2 = max(val & 0xffffff800000ULL, 1ULL << 32); } /* @@ -89,7 +89,7 @@ static void __init get_fam10h_pci_mmconf val = pci_conf_read32(bus, slot, 1, 0x84 + (i << 3)); end = ((val & 0xffffff00) << 8) | 0xffff; /* 39:16 on 31:8*/ - if (!end) + if (end < tom2) continue; for (j = hi_mmio_num; j; --j) { @@ -119,13 +119,13 @@ static void __init get_fam10h_pci_mmconf if (start > tom2 && BASE_VALID(start)) goto out; start = (range[hi_mmio_num - 1].end + UNIT) & MASK; - if (start > tom2 && BASE_VALID(start)) + if (BASE_VALID(start)) goto out; /* need to find window between ranges */ for (i = 1; i < hi_mmio_num; i++) { start = (range[i - 1].end + UNIT) & MASK; end = range[i].start & MASK; - if (end >= start + SIZE && start > tom2 && BASE_VALID(start)) + if (end >= start + SIZE && BASE_VALID(start)) goto out; } return;