Use the new SMMU property to make the SMMU OAS match the CPU PARANGE. That's according to SMMU manual ARM IHI 0070F.b: 6.3.6 SMMU_IDR5, OAS must match the system physical address size.
Signed-off-by: Mostafa Saleh <smost...@google.com> --- hw/arm/virt.c | 14 ++++++++++++-- target/arm/cpu.h | 2 ++ target/arm/cpu64.c | 5 +++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 3c93c0c0a6..f203b1f8e1 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -252,6 +252,13 @@ static bool ns_el2_virt_timer_present(void) arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu); } +/* We rely on CPU to define system OAS. */ +static int32_t get_system_oas(void) +{ + ARMCPU *cpu = ARM_CPU(qemu_get_cpu(0)); + return cpu_arm_get_oas(cpu); +} + static void create_fdt(VirtMachineState *vms) { MachineState *ms = MACHINE(vms); @@ -1384,7 +1391,7 @@ static void create_pcie_irq_map(const MachineState *ms, } static void create_smmu(const VirtMachineState *vms, - PCIBus *bus) + PCIBus *bus, int32_t oas) { char *node; const char compat[] = "arm,smmu-v3"; @@ -1404,6 +1411,9 @@ static void create_smmu(const VirtMachineState *vms, object_property_set_link(OBJECT(dev), "primary-bus", OBJECT(bus), &error_abort); + + qdev_prop_set_uint64(dev, "oas", oas); + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); for (i = 0; i < NUM_SMMU_IRQS; i++) { @@ -1578,7 +1588,7 @@ static void create_pcie(VirtMachineState *vms) switch (vms->iommu) { case VIRT_IOMMU_SMMUV3: - create_smmu(vms, vms->bus); + create_smmu(vms, vms->bus, get_system_oas()); qemu_fdt_setprop_cells(ms->fdt, nodename, "iommu-map", 0x0, vms->iommu_phandle, 0x0, 0x10000); break; diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 17efc5d565..68261ffbf9 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -3287,4 +3287,6 @@ static inline target_ulong cpu_untagged_addr(CPUState *cs, target_ulong x) } #endif +int32_t cpu_arm_get_oas(ARMCPU *cpu); + #endif diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 985b1efe16..08da83c082 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -787,6 +787,11 @@ static const gchar *aarch64_gdb_arch_name(CPUState *cs) return "aarch64"; } +int32_t cpu_arm_get_oas(ARMCPU *cpu) +{ + return FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE); +} + static void aarch64_cpu_class_init(ObjectClass *oc, void *data) { CPUClass *cc = CPU_CLASS(oc); -- 2.44.0.769.g3c40516874-goog