[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 0/7] target/arm: Handle VTCR_EL2 bits shared between S and NS EL2
From: |
Peter Maydell |
Subject: |
[PATCH 0/7] target/arm: Handle VTCR_EL2 bits shared between S and NS EL2 |
Date: |
Thu, 14 Jul 2022 14:22:56 +0100 |
In https://gitlab.com/qemu-project/qemu/-/issues/1103 Idan pointed
out that our regime_tcr() function doesn't handle the fact that some
of the config bits for the Secure stage 2 translation regime are
shared with NS EL2 and stored in VTCR_EL2 rather than VSTCR_EL2.
Currently the only visible effect of this is that if the guest tries
to enable LPA2 via VTCR_EL2.DS QEMU will incorrectly fail to honour
this for Secure stage 2 translations.
The final patch in this series fixes this, by synthesizing a
VTCR_EL2 format value for Secure stage 2 by merging together
the shared VTCR_EL2 fields into the VSTCR_EL2 value.
The first six patches get rid of a very longstanding
micro-optimization of our TCR register handling that gets in the way
of fixing the bug. Currently regime_tcr() returns a pointer to a TCR
struct, which contains both the 64-bit TCR value and also two
'base_mask' and 'mask' values, which are pre-calculated when the
register is written. Those values are used only in the
get_level1_table_address() function. That function is called once
per page table walk for 32-bit short-descriptor page tables only.
The pre-calculation saves only a handful of logical shifting and
masking instructions, which is a tiny amount of overhead compared to
everything else we need to do on a guest page table walk. Conversely
the microoptimization adds extra complexity on TCR register writes,
and code complexity handling the TCR struct. It therefore no longer
seems to be pulling its weight, and we're better off without it,
rather than jumping through hoops to come up with a fix to the
VSTCR_EL2 issue that lets us retain it.
thanks
-- PMM
Peter Maydell (7):
target/arm: Define and use new regime_tcr_value() function
target/arm: Calculate mask/base_mask in get_level1_table_address()
target/arm: Fold regime_tcr() and regime_tcr_value() together
target/arm: Fix big-endian host handling of VTCR
target/arm: Store VTCR_EL2, VSTCR_EL2 registers as uint64_t
target/arm: Store TCR_EL* registers as uint64_t
target/arm: Honour VTCR_EL2 bits in Secure EL2
target/arm/cpu.h | 31 ++++++++++----
target/arm/internals.h | 34 +++++++++++----
target/arm/cpu.c | 2 +-
target/arm/debug_helper.c | 2 +-
target/arm/helper.c | 87 +++++++++++----------------------------
target/arm/ptw.c | 38 +++++++++--------
target/arm/tlb_helper.c | 2 +-
7 files changed, 96 insertions(+), 100 deletions(-)
--
2.25.1
- [PATCH 0/7] target/arm: Handle VTCR_EL2 bits shared between S and NS EL2,
Peter Maydell <=
- [PATCH 2/7] target/arm: Calculate mask/base_mask in get_level1_table_address(), Peter Maydell, 2022/07/14
- [PATCH 1/7] target/arm: Define and use new regime_tcr_value() function, Peter Maydell, 2022/07/14
- [PATCH 3/7] target/arm: Fold regime_tcr() and regime_tcr_value() together, Peter Maydell, 2022/07/14
- [PATCH 4/7] target/arm: Fix big-endian host handling of VTCR, Peter Maydell, 2022/07/14
- [PATCH 5/7] target/arm: Store VTCR_EL2, VSTCR_EL2 registers as uint64_t, Peter Maydell, 2022/07/14