From d9afe24c29a0985b29d7535b2f1615affbd1a888 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Fri, 14 Jan 2022 14:07:40 +0000 Subject: [PATCH] hw/arm/virt: Disable highmem devices that don't fit in the PA range In order to only keep the highmem devices that actually fit in the PA range, check their location against the range and update highest_gpa if they fit. If they don't, mark them as disabled. Signed-off-by: Marc Zyngier Reviewed-by: Eric Auger Message-id: 20220114140741.1358263-6-maz@kernel.org Signed-off-by: Peter Maydell --- hw/arm/virt.c | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 8627f5ab95..8d02c2267d 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -1719,21 +1719,43 @@ static void virt_set_memmap(VirtMachineState *vms, int pa_bits) base = vms->memmap[VIRT_MEM].base + LEGACY_RAMLIMIT_BYTES; } + /* We know for sure that at least the memory fits in the PA space */ + vms->highest_gpa = memtop - 1; + for (i = VIRT_LOWMEMMAP_LAST; i < ARRAY_SIZE(extended_memmap); i++) { hwaddr size = extended_memmap[i].size; + bool fits; base = ROUND_UP(base, size); vms->memmap[i].base = base; vms->memmap[i].size = size; + + /* + * Check each device to see if they fit in the PA space, + * moving highest_gpa as we go. + * + * For each device that doesn't fit, disable it. + */ + fits = (base + size) <= BIT_ULL(pa_bits); + if (fits) { + vms->highest_gpa = base + size - 1; + } + + switch (i) { + case VIRT_HIGH_GIC_REDIST2: + vms->highmem_redists &= fits; + break; + case VIRT_HIGH_PCIE_ECAM: + vms->highmem_ecam &= fits; + break; + case VIRT_HIGH_PCIE_MMIO: + vms->highmem_mmio &= fits; + break; + } + base += size; } - /* - * If base fits within pa_bits, all good. If it doesn't, limit it - * to the end of RAM, which is guaranteed to fit within pa_bits. - */ - vms->highest_gpa = (base <= BIT_ULL(pa_bits) ? base : memtop) - 1; - if (device_memory_size > 0) { ms->device_memory = g_malloc0(sizeof(*ms->device_memory)); ms->device_memory->base = device_memory_base; -- 2.11.0