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 0af1943697..599c0f752b 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -235,6 +235,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); @@ -1340,7 +1347,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"; @@ -1360,6 +1367,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++) { @@ -1534,7 +1544,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 a5b3d8f7da..14ef1a9d37 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -3408,4 +3408,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.478.gd926399ef9-goog