diff mbox series

target/arm: Correct calculation of tlb range invalidate length

Message ID 20211130173257.1274194-1-peter.maydell@linaro.org
State New
Headers show
Series target/arm: Correct calculation of tlb range invalidate length | expand

Commit Message

Peter Maydell Nov. 30, 2021, 5:32 p.m. UTC
The calculation of the length of TLB range invalidate operations
in tlbi_aa64_range_get_length() is incorrect in two ways:
 * the NUM field is 5 bits, but we read only 4 bits
 * we miscalculate the page_shift value, because of an
   off-by-one error:
    TG 0b00 is invalid
    TG 0b01 is 4K granule size == 4096 == 2^12
    TG 0b10 is 16K granule size == 16384 == 2^14
    TG 0b11 is 64K granule size == 65536 == 2^16
   so page_shift should be (TG - 1) * 2 + 12

Thanks to the bug report submitter Cha HyunSoo for identifying
both these errors.

Fixes: 84940ed82552d3c
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/734
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
Not marked for-6.2 because this isn't a regression: we
shipped the TLBI range invalidate support in 6.1.
I have no repro case for this issue, but this doesn't break
booting an aarch64 kernel, at least.
---
 target/arm/helper.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

Comments

Richard Henderson Nov. 30, 2021, 5:44 p.m. UTC | #1
On 11/30/21 6:32 PM, Peter Maydell wrote:
> The calculation of the length of TLB range invalidate operations
> in tlbi_aa64_range_get_length() is incorrect in two ways:
>   * the NUM field is 5 bits, but we read only 4 bits
>   * we miscalculate the page_shift value, because of an
>     off-by-one error:
>      TG 0b00 is invalid
>      TG 0b01 is 4K granule size == 4096 == 2^12
>      TG 0b10 is 16K granule size == 16384 == 2^14
>      TG 0b11 is 64K granule size == 65536 == 2^16
>     so page_shift should be (TG - 1) * 2 + 12
> 
> Thanks to the bug report submitter Cha HyunSoo for identifying
> both these errors.
> 
> Fixes: 84940ed82552d3c
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/734
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> Not marked for-6.2 because this isn't a regression: we
> shipped the TLBI range invalidate support in 6.1.
> I have no repro case for this issue, but this doesn't break
> booting an aarch64 kernel, at least.
> ---

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~
Alex Bennée Nov. 30, 2021, 8:10 p.m. UTC | #2
Peter Maydell <peter.maydell@linaro.org> writes:

> The calculation of the length of TLB range invalidate operations
> in tlbi_aa64_range_get_length() is incorrect in two ways:
>  * the NUM field is 5 bits, but we read only 4 bits
>  * we miscalculate the page_shift value, because of an
>    off-by-one error:
>     TG 0b00 is invalid
>     TG 0b01 is 4K granule size == 4096 == 2^12
>     TG 0b10 is 16K granule size == 16384 == 2^14
>     TG 0b11 is 64K granule size == 65536 == 2^16
>    so page_shift should be (TG - 1) * 2 + 12
>
> Thanks to the bug report submitter Cha HyunSoo for identifying
> both these errors.
>
> Fixes: 84940ed82552d3c

Fixes: 84940ed825 (target/arm: Add support for FEAT_TLBIRANGE)

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Philippe Mathieu-Daudé Dec. 1, 2021, 1:08 p.m. UTC | #3
On 11/30/21 18:32, Peter Maydell wrote:
> The calculation of the length of TLB range invalidate operations
> in tlbi_aa64_range_get_length() is incorrect in two ways:
>  * the NUM field is 5 bits, but we read only 4 bits
>  * we miscalculate the page_shift value, because of an
>    off-by-one error:
>     TG 0b00 is invalid
>     TG 0b01 is 4K granule size == 4096 == 2^12
>     TG 0b10 is 16K granule size == 16384 == 2^14
>     TG 0b11 is 64K granule size == 65536 == 2^16
>    so page_shift should be (TG - 1) * 2 + 12
> 
> Thanks to the bug report submitter Cha HyunSoo for identifying
> both these errors.
> 
> Fixes: 84940ed82552d3c
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/734
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> Not marked for-6.2 because this isn't a regression: we
> shipped the TLBI range invalidate support in 6.1.
> I have no repro case for this issue, but this doesn't break
> booting an aarch64 kernel, at least.
> ---
>  target/arm/helper.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
diff mbox series

Patch

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 9b317899a66..db837d53bd9 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -4519,18 +4519,18 @@  static uint64_t tlbi_aa64_range_get_length(CPUARMState *env,
     uint64_t exponent;
     uint64_t length;
 
-    num = extract64(value, 39, 4);
+    num = extract64(value, 39, 5);
     scale = extract64(value, 44, 2);
     page_size_granule = extract64(value, 46, 2);
 
-    page_shift = page_size_granule * 2 + 12;
-
     if (page_size_granule == 0) {
         qemu_log_mask(LOG_GUEST_ERROR, "Invalid page size granule %d\n",
                       page_size_granule);
         return 0;
     }
 
+    page_shift = (page_size_granule - 1) * 2 + 12;
+
     exponent = (5 * scale) + 1;
     length = (num + 1) << (exponent + page_shift);