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>
This commit is contained in:
Marc Zyngier 2022-01-14 14:07:40 +00:00 committed by Peter Maydell
parent 3715c251cc
commit d9afe24c29
1 changed files with 28 additions and 6 deletions

View File

@ -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;