diff options
author | Marc Zyngier <maz@kernel.org> | 2022-01-14 14:07:40 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2022-01-20 11:47:53 +0000 |
commit | d9afe24c29a0985b29d7535b2f1615affbd1a888 (patch) | |
tree | 1d7e33949ec7626e71337e4d8b47fd2199a4c6cc | |
parent | 3715c251cc781b263fbd7f7c535fde7a4da401c3 (diff) | |
download | qemu-d9afe24c29a0985b29d7535b2f1615affbd1a888.zip qemu-d9afe24c29a0985b29d7535b2f1615affbd1a888.tar.gz qemu-d9afe24c29a0985b29d7535b2f1615affbd1a888.tar.bz2 |
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 <maz@kernel.org>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Message-id: 20220114140741.1358263-6-maz@kernel.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | hw/arm/virt.c | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 8627f5a..8d02c22 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; |