summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorJoao Martins <joao.m.martins@oracle.com>2022-07-19 18:00:12 +0100
committerMichael S. Tsirkin <mst@redhat.com>2022-07-26 10:40:58 -0400
commit1caab5cf86bdf02fa71079c4ca4a3c0748f39eb5 (patch)
tree12c1ede82ceca535f04952db9c984b947e29b571 /hw
parent8288a8286d00e074b765f1d47ee61159ed5291fd (diff)
i386/pc: bounds check phys-bits against max used GPA
Calculate max *used* GPA against the CPU maximum possible address and error out if the former surprasses the latter. This ensures max used GPA is reacheable by configured phys-bits. Default phys-bits on Qemu is TCG_PHYS_ADDR_BITS (40) which is enough for the CPU to address 1Tb (0xff ffff ffff) or 1010G (0xfc ffff ffff) in AMD hosts with IOMMU. This is preparation for AMD guests with >1010G, where it will want relocate ram-above-4g to be after 1Tb instead of 4G. Signed-off-by: Joao Martins <joao.m.martins@oracle.com> Acked-by: Igor Mammedov <imammedo@redhat.com> Message-Id: <20220719170014.27028-10-joao.m.martins@oracle.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/i386/pc.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index ebc27e4cb7..56d8c179ea 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -879,6 +879,18 @@ static uint64_t pc_get_cxl_range_end(PCMachineState *pcms)
return start;
}
+static hwaddr pc_max_used_gpa(PCMachineState *pcms, uint64_t pci_hole64_size)
+{
+ X86CPU *cpu = X86_CPU(first_cpu);
+
+ /* 32-bit systems don't have hole64 thus return max CPU address */
+ if (cpu->phys_bits <= 32) {
+ return ((hwaddr)1 << cpu->phys_bits) - 1;
+ }
+
+ return pc_pci_hole64_start() + pci_hole64_size - 1;
+}
+
void pc_memory_init(PCMachineState *pcms,
MemoryRegion *system_memory,
MemoryRegion *rom_memory,
@@ -893,7 +905,9 @@ void pc_memory_init(PCMachineState *pcms,
MachineClass *mc = MACHINE_GET_CLASS(machine);
PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
X86MachineState *x86ms = X86_MACHINE(pcms);
+ hwaddr maxphysaddr, maxusedaddr;
hwaddr cxl_base, cxl_resv_end = 0;
+ X86CPU *cpu = X86_CPU(first_cpu);
assert(machine->ram_size == x86ms->below_4g_mem_size +
x86ms->above_4g_mem_size);
@@ -901,6 +915,19 @@ void pc_memory_init(PCMachineState *pcms,
linux_boot = (machine->kernel_filename != NULL);
/*
+ * phys-bits is required to be appropriately configured
+ * to make sure max used GPA is reachable.
+ */
+ maxusedaddr = pc_max_used_gpa(pcms, pci_hole64_size);
+ maxphysaddr = ((hwaddr)1 << cpu->phys_bits) - 1;
+ if (maxphysaddr < maxusedaddr) {
+ error_report("Address space limit 0x%"PRIx64" < 0x%"PRIx64
+ " phys-bits too low (%u)",
+ maxphysaddr, maxusedaddr, cpu->phys_bits);
+ exit(EXIT_FAILURE);
+ }
+
+ /*
* Split single memory region and use aliases to address portions of it,
* done for backwards compatibility with older qemus.
*/