[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 14/43] target-arm: Fix descriptor address masking in
From: |
Peter Maydell |
Subject: |
[Qemu-devel] [PULL 14/43] target-arm: Fix descriptor address masking in ARM address translation |
Date: |
Thu, 12 May 2016 14:32:36 +0100 |
From: Sergey Sorokin <address@hidden>
There is a bug in ARM address translation regime with a long-descriptor
format. On the descriptor reading its address is formed from an index
which is a part of the input address. And on the first iteration this index
is incorrectly masked with 'grainsize' mask. But it can be wider according
to pseudo-code.
On the other hand on the iterations other than first the descriptor address
is formed from the previous level descriptor by masking with 'descaddrmask'
value. It always clears just 12 lower bits, but it must clear 'grainsize'
lower bits instead according to pseudo-code.
The patch fixes both cases.
Signed-off-by: Sergey Sorokin <address@hidden>
Message-id: address@hidden
Reviewed-by: Peter Maydell <address@hidden>
Signed-off-by: Peter Maydell <address@hidden>
---
target-arm/helper.c | 29 +++++++++++------------------
1 file changed, 11 insertions(+), 18 deletions(-)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 59efb90..3b76dc3 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -7250,7 +7250,7 @@ static bool get_phys_addr_lpae(CPUARMState *env,
target_ulong address,
uint32_t tg;
uint64_t ttbr;
int ttbr_select;
- hwaddr descaddr, descmask;
+ hwaddr descaddr, indexmask, indexmask_grainsize;
uint32_t tableattrs;
target_ulong page_size;
uint32_t attrs;
@@ -7439,28 +7439,20 @@ static bool get_phys_addr_lpae(CPUARMState *env,
target_ulong address,
level = startlevel;
}
- /* Clear the vaddr bits which aren't part of the within-region address,
- * so that we don't have to special case things when calculating the
- * first descriptor address.
- */
- if (va_size != inputsize) {
- address &= (1ULL << inputsize) - 1;
- }
-
- descmask = (1ULL << (stride + 3)) - 1;
+ indexmask_grainsize = (1ULL << (stride + 3)) - 1;
+ indexmask = (1ULL << (inputsize - (stride * (4 - level)))) - 1;
/* Now we can extract the actual base address from the TTBR */
descaddr = extract64(ttbr, 0, 48);
- descaddr &= ~((1ULL << (inputsize - (stride * (4 - level)))) - 1);
+ descaddr &= ~indexmask;
/* The address field in the descriptor goes up to bit 39 for ARMv7
- * but up to bit 47 for ARMv8.
+ * but up to bit 47 for ARMv8, but we use the descaddrmask
+ * up to bit 39 for AArch32, because we don't need other bits in that case
+ * to construct next descriptor address (anyway they should be all zeroes).
*/
- if (arm_feature(env, ARM_FEATURE_V8)) {
- descaddrmask = 0xfffffffff000ULL;
- } else {
- descaddrmask = 0xfffffff000ULL;
- }
+ descaddrmask = ((1ull << (va_size == 64 ? 48 : 40)) - 1) &
+ ~indexmask_grainsize;
/* Secure accesses start with the page table in secure memory and
* can be downgraded to non-secure at any step. Non-secure accesses
@@ -7472,7 +7464,7 @@ static bool get_phys_addr_lpae(CPUARMState *env,
target_ulong address,
uint64_t descriptor;
bool nstable;
- descaddr |= (address >> (stride * (4 - level))) & descmask;
+ descaddr |= (address >> (stride * (4 - level))) & indexmask;
descaddr &= ~7ULL;
nstable = extract32(tableattrs, 4, 1);
descriptor = arm_ldq_ptw(cs, descaddr, !nstable, mmu_idx, fsr, fi);
@@ -7495,6 +7487,7 @@ static bool get_phys_addr_lpae(CPUARMState *env,
target_ulong address,
*/
tableattrs |= extract64(descriptor, 59, 5);
level++;
+ indexmask = indexmask_grainsize;
continue;
}
/* Block entry at level 1 or 2, or page entry at level 3.
--
1.9.1
- [Qemu-devel] [PULL 18/43] target-arm/translate-a64.c: Use extract32 in disas_ldst_reg_imm9, (continued)
- [Qemu-devel] [PULL 18/43] target-arm/translate-a64.c: Use extract32 in disas_ldst_reg_imm9, Peter Maydell, 2016/05/12
- [Qemu-devel] [PULL 01/43] blizzard: Remove support for DEPTH != 32, Peter Maydell, 2016/05/12
- [Qemu-devel] [PULL 13/43] target-arm: Stage 2 permission fault was fixed in AArch32 state, Peter Maydell, 2016/05/12
- [Qemu-devel] [PULL 11/43] bcm2835_property: use cached values when querying framebuffer, Peter Maydell, 2016/05/12
- [Qemu-devel] [PULL 06/43] hw/intc: QOM'ify imx_avic.c, Peter Maydell, 2016/05/12
- [Qemu-devel] [PULL 15/43] tcg: Add tcg_set_insn_param, Peter Maydell, 2016/05/12
- [Qemu-devel] [PULL 23/43] ACPI: Fix the definition of proximity in AcpiSratMemoryAffinity, Peter Maydell, 2016/05/12
- [Qemu-devel] [PULL 31/43] i.MX: Add sabrelite i.MX6 emulation., Peter Maydell, 2016/05/12
- [Qemu-devel] [PULL 20/43] hw/display: QOM'ify exynos4210_fimd.c, Peter Maydell, 2016/05/12
- [Qemu-devel] [PULL 08/43] hw/intc: QOM'ify slavio_intctl.c, Peter Maydell, 2016/05/12
- [Qemu-devel] [PULL 14/43] target-arm: Fix descriptor address masking in ARM address translation,
Peter Maydell <=
- [Qemu-devel] [PULL 24/43] ACPI: move acpi_build_srat_memory to common place, Peter Maydell, 2016/05/12
- [Qemu-devel] [PULL 04/43] hw/intc: QOM'ify exynos4210_combiner.c, Peter Maydell, 2016/05/12
- [Qemu-devel] [PULL 29/43] i.MX: Add the Freescale SPI Controller, Peter Maydell, 2016/05/12
- [Qemu-devel] [PULL 27/43] i.MX: Add i.MX6 System Reset Controller device., Peter Maydell, 2016/05/12
- [Qemu-devel] [PULL 35/43] hw/arm: QOM'ify armv7m.c, Peter Maydell, 2016/05/12
- [Qemu-devel] [PULL 22/43] ACPI: Add GICC Affinity Structure, Peter Maydell, 2016/05/12
- [Qemu-devel] [PULL 16/43] gen-icount: Use tcg_set_insn_param, Peter Maydell, 2016/05/12
- [Qemu-devel] [PULL 28/43] FIFO: Add a FIFO32 implementation, Peter Maydell, 2016/05/12
- [Qemu-devel] [PULL 32/43] hw/display/blizzard: Expand out macros, Peter Maydell, 2016/05/12
- [Qemu-devel] [PULL 25/43] ACPI: Virt: Generate SRAT table, Peter Maydell, 2016/05/12