Message ID | 20211130173257.1274194-1-peter.maydell@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | target/arm: Correct calculation of tlb range invalidate length | expand |
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~
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>
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 --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);
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(-)