mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge tag 'pull-target-arm-20221010' of https://git.linaro.org/people/pmaydell/qemu-arm into staging
target-arm queue: * Retry KVM_CREATE_VM call if it fails EINTR * allow setting SCR_EL3.EnTP2 when FEAT_SME is implemented * docs/nuvoton: Update URL for images * refactoring of page table walk code * hw/arm/boot: set CPTR_EL3.ESM and SCR_EL3.EnTP2 when booting Linux with EL3 * Don't allow guest to use unimplemented granule sizes * Report FEAT_GTG support # -----BEGIN PGP SIGNATURE----- # # iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmNEK54ZHHBldGVyLm1h # eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3kzHD/9StYmulAf0iwe1ZNp6NavK # CioOgZi6XyZl4rS2DrCf6/IO5XRFJP68byZd4Po554r2jcPc149yTuQAn4wb7d5e # kejMZRQeWsXdxschhoVzDp9fgfzyZBn9X+gbdEZFFPWzOHMyWuu4cTok0dAKQvQY # tZDLGmKeTv4MRUFJCri0310Sq0T0v/nAX/AyFtpvIr2SBx7DVCWYY02s5R4Yy5+M # ntDWb0j12r78/bPwI1ll+g19JXUV5Tfh9AsbcYjKv45kdftz/Xc8fBiSiEpxyMrF # mnVrr3kesZHOYAnOr2K1MnwsF0vU41kRg7kMRqSnu7pZXlI/8tmRyXoPR3c2aDbW # Q5HWtsA48j2h0CJ0ESzl5SQnl3TSPa94m/HmpRSBFrYkU727QgnWDhUmBb4n54xs # 9iBJDhcKGZLq68CB2+j6ENdRNTndolr14OwwEns0lbkoiCKUOQY3AigtZJQGRBGM # J5r3ED7jfTWpvP6vpp5X484fK6KVprSMxsRFDkmiwhbb3J+WtKLxbSlgsWIrkZ7s # +JgTGfGB8sD9hJVuFZYyPQb/XWP8Bb8jfgsLsTu1vW9Xs1ASrLimFYdRO3hhwSg3 # c5yubz6Vu9GB/JYh7hGprlMD5Yv48AA3if70hOu2d4P8A4OitavT7o+4Thwqjhds # cSV1RsBJ8ha6L3CziZaKrQ== # =s+1f # -----END PGP SIGNATURE----- # gpg: Signature made Mon 10 Oct 2022 10:26:38 EDT # gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE # gpg: issuer "peter.maydell@linaro.org" # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [full] # gpg: aka "Peter Maydell <pmaydell@gmail.com>" [full] # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [full] # gpg: aka "Peter Maydell <peter@archaic.org.uk>" [unknown] # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * tag 'pull-target-arm-20221010' of https://git.linaro.org/people/pmaydell/qemu-arm: (28 commits) docs/system/arm/emulation.rst: Report FEAT_GTG support target/arm: Use ARMGranuleSize in ARMVAParameters target/arm: Don't allow guest to use unimplemented granule sizes hw/arm/boot: set CPTR_EL3.ESM and SCR_EL3.EnTP2 when booting Linux with EL3 target/arm: Use tlb_set_page_full target/arm: Fix cacheattr in get_phys_addr_disabled target/arm: Split out get_phys_addr_disabled target/arm: Fix ATS12NSO* from S PL1 target/arm: Pass HCR to attribute subroutines. target/arm: Remove env argument from combined_attrs_fwb target/arm: Hoist read of *is_secure in S1_ptw_translate target/arm: Introduce arm_hcr_el2_eff_secstate target/arm: Drop secure check for HCR.TGE vs SCTLR_EL1.M target/arm: Reorg regime_translation_disabled target/arm: Fold secure and non-secure a-profile mmu indexes target/arm: Add is_secure parameter to do_ats_write target/arm: Merge regime_is_secure into get_phys_addr target/arm: Add TBFLAG_M32.SECURE target/arm: Add is_secure parameter to v7m_read_half_insn target/arm: Split out get_phys_addr_with_secure ... Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
@@ -31,6 +31,7 @@ the following architecture extensions:
|
||||
- FEAT_FRINTTS (Floating-point to integer instructions)
|
||||
- FEAT_FlagM (Flag manipulation instructions v2)
|
||||
- FEAT_FlagM2 (Enhancements to flag manipulation instructions)
|
||||
- FEAT_GTG (Guest translation granule size)
|
||||
- FEAT_HCX (Support for the HCRX_EL2 register)
|
||||
- FEAT_HPDS (Hierarchical permission disables)
|
||||
- FEAT_I8MM (AArch64 Int8 matrix multiplication instructions)
|
||||
|
||||
@@ -82,9 +82,9 @@ Boot options
|
||||
|
||||
The Nuvoton machines can boot from an OpenBMC firmware image, or directly into
|
||||
a kernel using the ``-kernel`` option. OpenBMC images for ``quanta-gsj`` and
|
||||
possibly others can be downloaded from the OpenPOWER jenkins :
|
||||
possibly others can be downloaded from the OpenBMC jenkins :
|
||||
|
||||
https://openpower.xyz/
|
||||
https://jenkins.openbmc.org/
|
||||
|
||||
The firmware image should be attached as an MTD drive. Example :
|
||||
|
||||
|
||||
@@ -763,6 +763,10 @@ static void do_cpu_reset(void *opaque)
|
||||
if (cpu_isar_feature(aa64_sve, cpu)) {
|
||||
env->cp15.cptr_el[3] |= R_CPTR_EL3_EZ_MASK;
|
||||
}
|
||||
if (cpu_isar_feature(aa64_sme, cpu)) {
|
||||
env->cp15.cptr_el[3] |= R_CPTR_EL3_ESM_MASK;
|
||||
env->cp15.scr_el3 |= SCR_ENTP2;
|
||||
}
|
||||
/* AArch64 kernels never boot in secure mode */
|
||||
assert(!info->secure_boot);
|
||||
/* This hook is only supported for AArch32 currently:
|
||||
|
||||
@@ -32,6 +32,6 @@
|
||||
# define TARGET_PAGE_BITS_MIN 10
|
||||
#endif
|
||||
|
||||
#define NB_MMU_MODES 15
|
||||
#define NB_MMU_MODES 8
|
||||
|
||||
#endif
|
||||
|
||||
+101
-80
@@ -1664,33 +1664,33 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
|
||||
|
||||
#define HPFAR_NS (1ULL << 63)
|
||||
|
||||
#define SCR_NS (1U << 0)
|
||||
#define SCR_IRQ (1U << 1)
|
||||
#define SCR_FIQ (1U << 2)
|
||||
#define SCR_EA (1U << 3)
|
||||
#define SCR_FW (1U << 4)
|
||||
#define SCR_AW (1U << 5)
|
||||
#define SCR_NET (1U << 6)
|
||||
#define SCR_SMD (1U << 7)
|
||||
#define SCR_HCE (1U << 8)
|
||||
#define SCR_SIF (1U << 9)
|
||||
#define SCR_RW (1U << 10)
|
||||
#define SCR_ST (1U << 11)
|
||||
#define SCR_TWI (1U << 12)
|
||||
#define SCR_TWE (1U << 13)
|
||||
#define SCR_TLOR (1U << 14)
|
||||
#define SCR_TERR (1U << 15)
|
||||
#define SCR_APK (1U << 16)
|
||||
#define SCR_API (1U << 17)
|
||||
#define SCR_EEL2 (1U << 18)
|
||||
#define SCR_EASE (1U << 19)
|
||||
#define SCR_NMEA (1U << 20)
|
||||
#define SCR_FIEN (1U << 21)
|
||||
#define SCR_ENSCXT (1U << 25)
|
||||
#define SCR_ATA (1U << 26)
|
||||
#define SCR_FGTEN (1U << 27)
|
||||
#define SCR_ECVEN (1U << 28)
|
||||
#define SCR_TWEDEN (1U << 29)
|
||||
#define SCR_NS (1ULL << 0)
|
||||
#define SCR_IRQ (1ULL << 1)
|
||||
#define SCR_FIQ (1ULL << 2)
|
||||
#define SCR_EA (1ULL << 3)
|
||||
#define SCR_FW (1ULL << 4)
|
||||
#define SCR_AW (1ULL << 5)
|
||||
#define SCR_NET (1ULL << 6)
|
||||
#define SCR_SMD (1ULL << 7)
|
||||
#define SCR_HCE (1ULL << 8)
|
||||
#define SCR_SIF (1ULL << 9)
|
||||
#define SCR_RW (1ULL << 10)
|
||||
#define SCR_ST (1ULL << 11)
|
||||
#define SCR_TWI (1ULL << 12)
|
||||
#define SCR_TWE (1ULL << 13)
|
||||
#define SCR_TLOR (1ULL << 14)
|
||||
#define SCR_TERR (1ULL << 15)
|
||||
#define SCR_APK (1ULL << 16)
|
||||
#define SCR_API (1ULL << 17)
|
||||
#define SCR_EEL2 (1ULL << 18)
|
||||
#define SCR_EASE (1ULL << 19)
|
||||
#define SCR_NMEA (1ULL << 20)
|
||||
#define SCR_FIEN (1ULL << 21)
|
||||
#define SCR_ENSCXT (1ULL << 25)
|
||||
#define SCR_ATA (1ULL << 26)
|
||||
#define SCR_FGTEN (1ULL << 27)
|
||||
#define SCR_ECVEN (1ULL << 28)
|
||||
#define SCR_TWEDEN (1ULL << 29)
|
||||
#define SCR_TWEDEL MAKE_64BIT_MASK(30, 4)
|
||||
#define SCR_TME (1ULL << 34)
|
||||
#define SCR_AMVOFFEN (1ULL << 35)
|
||||
@@ -2412,15 +2412,15 @@ static inline bool arm_is_secure(CPUARMState *env)
|
||||
* Return true if the current security state has AArch64 EL2 or AArch32 Hyp.
|
||||
* This corresponds to the pseudocode EL2Enabled()
|
||||
*/
|
||||
static inline bool arm_is_el2_enabled_secstate(CPUARMState *env, bool secure)
|
||||
{
|
||||
return arm_feature(env, ARM_FEATURE_EL2)
|
||||
&& (!secure || (env->cp15.scr_el3 & SCR_EEL2));
|
||||
}
|
||||
|
||||
static inline bool arm_is_el2_enabled(CPUARMState *env)
|
||||
{
|
||||
if (arm_feature(env, ARM_FEATURE_EL2)) {
|
||||
if (arm_is_secure_below_el3(env)) {
|
||||
return (env->cp15.scr_el3 & SCR_EEL2) != 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return arm_is_el2_enabled_secstate(env, arm_is_secure_below_el3(env));
|
||||
}
|
||||
|
||||
#else
|
||||
@@ -2434,6 +2434,11 @@ static inline bool arm_is_secure(CPUARMState *env)
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool arm_is_el2_enabled_secstate(CPUARMState *env, bool secure)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool arm_is_el2_enabled(CPUARMState *env)
|
||||
{
|
||||
return false;
|
||||
@@ -2446,6 +2451,7 @@ static inline bool arm_is_el2_enabled(CPUARMState *env)
|
||||
* "for all purposes other than a direct read or write access of HCR_EL2."
|
||||
* Not included here is HCR_RW.
|
||||
*/
|
||||
uint64_t arm_hcr_el2_eff_secstate(CPUARMState *env, bool secure);
|
||||
uint64_t arm_hcr_el2_eff(CPUARMState *env);
|
||||
uint64_t arm_hcrx_el2_eff(CPUARMState *env);
|
||||
|
||||
@@ -2884,26 +2890,27 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
|
||||
* table over and over.
|
||||
* 6. we need separate EL1/EL2 mmu_idx for handling the Privileged Access
|
||||
* Never (PAN) bit within PSTATE.
|
||||
* 7. we fold together the secure and non-secure regimes for A-profile,
|
||||
* because there are no banked system registers for aarch64, so the
|
||||
* process of switching between secure and non-secure is
|
||||
* already heavyweight.
|
||||
*
|
||||
* This gives us the following list of cases:
|
||||
*
|
||||
* NS EL0 EL1&0 stage 1+2 (aka NS PL0)
|
||||
* NS EL1 EL1&0 stage 1+2 (aka NS PL1)
|
||||
* NS EL1 EL1&0 stage 1+2 +PAN
|
||||
* NS EL0 EL2&0
|
||||
* NS EL2 EL2&0
|
||||
* NS EL2 EL2&0 +PAN
|
||||
* NS EL2 (aka NS PL2)
|
||||
* S EL0 EL1&0 (aka S PL0)
|
||||
* S EL1 EL1&0 (not used if EL3 is 32 bit)
|
||||
* S EL1 EL1&0 +PAN
|
||||
* S EL3 (aka S PL1)
|
||||
* EL0 EL1&0 stage 1+2 (aka NS PL0)
|
||||
* EL1 EL1&0 stage 1+2 (aka NS PL1)
|
||||
* EL1 EL1&0 stage 1+2 +PAN
|
||||
* EL0 EL2&0
|
||||
* EL2 EL2&0
|
||||
* EL2 EL2&0 +PAN
|
||||
* EL2 (aka NS PL2)
|
||||
* EL3 (aka S PL1)
|
||||
*
|
||||
* for a total of 11 different mmu_idx.
|
||||
* for a total of 8 different mmu_idx.
|
||||
*
|
||||
* R profile CPUs have an MPU, but can use the same set of MMU indexes
|
||||
* as A profile. They only need to distinguish NS EL0 and NS EL1 (and
|
||||
* NS EL2 if we ever model a Cortex-R52).
|
||||
* as A profile. They only need to distinguish EL0 and EL1 (and
|
||||
* EL2 if we ever model a Cortex-R52).
|
||||
*
|
||||
* M profile CPUs are rather different as they do not have a true MMU.
|
||||
* They have the following different MMU indexes:
|
||||
@@ -2942,9 +2949,6 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
|
||||
#define ARM_MMU_IDX_NOTLB 0x20 /* does not have a TLB */
|
||||
#define ARM_MMU_IDX_M 0x40 /* M profile */
|
||||
|
||||
/* Meanings of the bits for A profile mmu idx values */
|
||||
#define ARM_MMU_IDX_A_NS 0x8
|
||||
|
||||
/* Meanings of the bits for M profile mmu idx values */
|
||||
#define ARM_MMU_IDX_M_PRIV 0x1
|
||||
#define ARM_MMU_IDX_M_NEGPRI 0x2
|
||||
@@ -2958,22 +2962,14 @@ typedef enum ARMMMUIdx {
|
||||
/*
|
||||
* A-profile.
|
||||
*/
|
||||
ARMMMUIdx_SE10_0 = 0 | ARM_MMU_IDX_A,
|
||||
ARMMMUIdx_SE20_0 = 1 | ARM_MMU_IDX_A,
|
||||
ARMMMUIdx_SE10_1 = 2 | ARM_MMU_IDX_A,
|
||||
ARMMMUIdx_SE20_2 = 3 | ARM_MMU_IDX_A,
|
||||
ARMMMUIdx_SE10_1_PAN = 4 | ARM_MMU_IDX_A,
|
||||
ARMMMUIdx_SE20_2_PAN = 5 | ARM_MMU_IDX_A,
|
||||
ARMMMUIdx_SE2 = 6 | ARM_MMU_IDX_A,
|
||||
ARMMMUIdx_SE3 = 7 | ARM_MMU_IDX_A,
|
||||
|
||||
ARMMMUIdx_E10_0 = ARMMMUIdx_SE10_0 | ARM_MMU_IDX_A_NS,
|
||||
ARMMMUIdx_E20_0 = ARMMMUIdx_SE20_0 | ARM_MMU_IDX_A_NS,
|
||||
ARMMMUIdx_E10_1 = ARMMMUIdx_SE10_1 | ARM_MMU_IDX_A_NS,
|
||||
ARMMMUIdx_E20_2 = ARMMMUIdx_SE20_2 | ARM_MMU_IDX_A_NS,
|
||||
ARMMMUIdx_E10_1_PAN = ARMMMUIdx_SE10_1_PAN | ARM_MMU_IDX_A_NS,
|
||||
ARMMMUIdx_E20_2_PAN = ARMMMUIdx_SE20_2_PAN | ARM_MMU_IDX_A_NS,
|
||||
ARMMMUIdx_E2 = ARMMMUIdx_SE2 | ARM_MMU_IDX_A_NS,
|
||||
ARMMMUIdx_E10_0 = 0 | ARM_MMU_IDX_A,
|
||||
ARMMMUIdx_E20_0 = 1 | ARM_MMU_IDX_A,
|
||||
ARMMMUIdx_E10_1 = 2 | ARM_MMU_IDX_A,
|
||||
ARMMMUIdx_E20_2 = 3 | ARM_MMU_IDX_A,
|
||||
ARMMMUIdx_E10_1_PAN = 4 | ARM_MMU_IDX_A,
|
||||
ARMMMUIdx_E20_2_PAN = 5 | ARM_MMU_IDX_A,
|
||||
ARMMMUIdx_E2 = 6 | ARM_MMU_IDX_A,
|
||||
ARMMMUIdx_E3 = 7 | ARM_MMU_IDX_A,
|
||||
|
||||
/*
|
||||
* These are not allocated TLBs and are used only for AT system
|
||||
@@ -2982,9 +2978,6 @@ typedef enum ARMMMUIdx {
|
||||
ARMMMUIdx_Stage1_E0 = 0 | ARM_MMU_IDX_NOTLB,
|
||||
ARMMMUIdx_Stage1_E1 = 1 | ARM_MMU_IDX_NOTLB,
|
||||
ARMMMUIdx_Stage1_E1_PAN = 2 | ARM_MMU_IDX_NOTLB,
|
||||
ARMMMUIdx_Stage1_SE0 = 3 | ARM_MMU_IDX_NOTLB,
|
||||
ARMMMUIdx_Stage1_SE1 = 4 | ARM_MMU_IDX_NOTLB,
|
||||
ARMMMUIdx_Stage1_SE1_PAN = 5 | ARM_MMU_IDX_NOTLB,
|
||||
/*
|
||||
* Not allocated a TLB: used only for second stage of an S12 page
|
||||
* table walk, or for descriptor loads during first stage of an S1
|
||||
@@ -2992,8 +2985,8 @@ typedef enum ARMMMUIdx {
|
||||
* then various TLB flush insns which currently are no-ops or flush
|
||||
* only stage 1 MMU indexes will need to change to flush stage 2.
|
||||
*/
|
||||
ARMMMUIdx_Stage2 = 6 | ARM_MMU_IDX_NOTLB,
|
||||
ARMMMUIdx_Stage2_S = 7 | ARM_MMU_IDX_NOTLB,
|
||||
ARMMMUIdx_Stage2 = 3 | ARM_MMU_IDX_NOTLB,
|
||||
ARMMMUIdx_Stage2_S = 4 | ARM_MMU_IDX_NOTLB,
|
||||
|
||||
/*
|
||||
* M-profile.
|
||||
@@ -3023,14 +3016,7 @@ typedef enum ARMMMUIdxBit {
|
||||
TO_CORE_BIT(E2),
|
||||
TO_CORE_BIT(E20_2),
|
||||
TO_CORE_BIT(E20_2_PAN),
|
||||
TO_CORE_BIT(SE10_0),
|
||||
TO_CORE_BIT(SE20_0),
|
||||
TO_CORE_BIT(SE10_1),
|
||||
TO_CORE_BIT(SE20_2),
|
||||
TO_CORE_BIT(SE10_1_PAN),
|
||||
TO_CORE_BIT(SE20_2_PAN),
|
||||
TO_CORE_BIT(SE2),
|
||||
TO_CORE_BIT(SE3),
|
||||
TO_CORE_BIT(E3),
|
||||
|
||||
TO_CORE_BIT(MUser),
|
||||
TO_CORE_BIT(MPriv),
|
||||
@@ -3203,6 +3189,8 @@ FIELD(TBFLAG_M32, NEW_FP_CTXT_NEEDED, 3, 1) /* Not cached. */
|
||||
FIELD(TBFLAG_M32, FPCCR_S_WRONG, 4, 1) /* Not cached. */
|
||||
/* Set if MVE insns are definitely not predicated by VPR or LTPSIZE */
|
||||
FIELD(TBFLAG_M32, MVE_NO_PRED, 5, 1) /* Not cached. */
|
||||
/* Set if in secure mode */
|
||||
FIELD(TBFLAG_M32, SECURE, 6, 1)
|
||||
|
||||
/*
|
||||
* Bit usage when in AArch64 state
|
||||
@@ -4109,6 +4097,39 @@ static inline bool isar_feature_aa64_tgran16_2_lpa2(const ARMISARegisters *id)
|
||||
return t >= 3 || (t == 0 && isar_feature_aa64_tgran16_lpa2(id));
|
||||
}
|
||||
|
||||
static inline bool isar_feature_aa64_tgran4(const ARMISARegisters *id)
|
||||
{
|
||||
return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4) >= 0;
|
||||
}
|
||||
|
||||
static inline bool isar_feature_aa64_tgran16(const ARMISARegisters *id)
|
||||
{
|
||||
return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16) >= 1;
|
||||
}
|
||||
|
||||
static inline bool isar_feature_aa64_tgran64(const ARMISARegisters *id)
|
||||
{
|
||||
return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN64) >= 0;
|
||||
}
|
||||
|
||||
static inline bool isar_feature_aa64_tgran4_2(const ARMISARegisters *id)
|
||||
{
|
||||
unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4_2);
|
||||
return t >= 2 || (t == 0 && isar_feature_aa64_tgran4(id));
|
||||
}
|
||||
|
||||
static inline bool isar_feature_aa64_tgran16_2(const ARMISARegisters *id)
|
||||
{
|
||||
unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16_2);
|
||||
return t >= 2 || (t == 0 && isar_feature_aa64_tgran16(id));
|
||||
}
|
||||
|
||||
static inline bool isar_feature_aa64_tgran64_2(const ARMISARegisters *id)
|
||||
{
|
||||
unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN64_2);
|
||||
return t >= 2 || (t == 0 && isar_feature_aa64_tgran64(id));
|
||||
}
|
||||
|
||||
static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
|
||||
{
|
||||
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
|
||||
|
||||
+206
-126
File diff suppressed because it is too large
Load Diff
+74
-76
@@ -649,78 +649,24 @@ static inline bool regime_has_2_ranges(ARMMMUIdx mmu_idx)
|
||||
case ARMMMUIdx_Stage1_E0:
|
||||
case ARMMMUIdx_Stage1_E1:
|
||||
case ARMMMUIdx_Stage1_E1_PAN:
|
||||
case ARMMMUIdx_Stage1_SE0:
|
||||
case ARMMMUIdx_Stage1_SE1:
|
||||
case ARMMMUIdx_Stage1_SE1_PAN:
|
||||
case ARMMMUIdx_E10_0:
|
||||
case ARMMMUIdx_E10_1:
|
||||
case ARMMMUIdx_E10_1_PAN:
|
||||
case ARMMMUIdx_E20_0:
|
||||
case ARMMMUIdx_E20_2:
|
||||
case ARMMMUIdx_E20_2_PAN:
|
||||
case ARMMMUIdx_SE10_0:
|
||||
case ARMMMUIdx_SE10_1:
|
||||
case ARMMMUIdx_SE10_1_PAN:
|
||||
case ARMMMUIdx_SE20_0:
|
||||
case ARMMMUIdx_SE20_2:
|
||||
case ARMMMUIdx_SE20_2_PAN:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return true if this address translation regime is secure */
|
||||
static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx)
|
||||
{
|
||||
switch (mmu_idx) {
|
||||
case ARMMMUIdx_E10_0:
|
||||
case ARMMMUIdx_E10_1:
|
||||
case ARMMMUIdx_E10_1_PAN:
|
||||
case ARMMMUIdx_E20_0:
|
||||
case ARMMMUIdx_E20_2:
|
||||
case ARMMMUIdx_E20_2_PAN:
|
||||
case ARMMMUIdx_Stage1_E0:
|
||||
case ARMMMUIdx_Stage1_E1:
|
||||
case ARMMMUIdx_Stage1_E1_PAN:
|
||||
case ARMMMUIdx_E2:
|
||||
case ARMMMUIdx_Stage2:
|
||||
case ARMMMUIdx_MPrivNegPri:
|
||||
case ARMMMUIdx_MUserNegPri:
|
||||
case ARMMMUIdx_MPriv:
|
||||
case ARMMMUIdx_MUser:
|
||||
return false;
|
||||
case ARMMMUIdx_SE3:
|
||||
case ARMMMUIdx_SE10_0:
|
||||
case ARMMMUIdx_SE10_1:
|
||||
case ARMMMUIdx_SE10_1_PAN:
|
||||
case ARMMMUIdx_SE20_0:
|
||||
case ARMMMUIdx_SE20_2:
|
||||
case ARMMMUIdx_SE20_2_PAN:
|
||||
case ARMMMUIdx_Stage1_SE0:
|
||||
case ARMMMUIdx_Stage1_SE1:
|
||||
case ARMMMUIdx_Stage1_SE1_PAN:
|
||||
case ARMMMUIdx_SE2:
|
||||
case ARMMMUIdx_Stage2_S:
|
||||
case ARMMMUIdx_MSPrivNegPri:
|
||||
case ARMMMUIdx_MSUserNegPri:
|
||||
case ARMMMUIdx_MSPriv:
|
||||
case ARMMMUIdx_MSUser:
|
||||
return true;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool regime_is_pan(CPUARMState *env, ARMMMUIdx mmu_idx)
|
||||
{
|
||||
switch (mmu_idx) {
|
||||
case ARMMMUIdx_Stage1_E1_PAN:
|
||||
case ARMMMUIdx_Stage1_SE1_PAN:
|
||||
case ARMMMUIdx_E10_1_PAN:
|
||||
case ARMMMUIdx_E20_2_PAN:
|
||||
case ARMMMUIdx_SE10_1_PAN:
|
||||
case ARMMMUIdx_SE20_2_PAN:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@@ -731,30 +677,20 @@ static inline bool regime_is_pan(CPUARMState *env, ARMMMUIdx mmu_idx)
|
||||
static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
|
||||
{
|
||||
switch (mmu_idx) {
|
||||
case ARMMMUIdx_SE20_0:
|
||||
case ARMMMUIdx_SE20_2:
|
||||
case ARMMMUIdx_SE20_2_PAN:
|
||||
case ARMMMUIdx_E20_0:
|
||||
case ARMMMUIdx_E20_2:
|
||||
case ARMMMUIdx_E20_2_PAN:
|
||||
case ARMMMUIdx_Stage2:
|
||||
case ARMMMUIdx_Stage2_S:
|
||||
case ARMMMUIdx_SE2:
|
||||
case ARMMMUIdx_E2:
|
||||
return 2;
|
||||
case ARMMMUIdx_SE3:
|
||||
case ARMMMUIdx_E3:
|
||||
return 3;
|
||||
case ARMMMUIdx_SE10_0:
|
||||
case ARMMMUIdx_Stage1_SE0:
|
||||
return arm_el_is_aa64(env, 3) ? 1 : 3;
|
||||
case ARMMMUIdx_SE10_1:
|
||||
case ARMMMUIdx_SE10_1_PAN:
|
||||
case ARMMMUIdx_E10_0:
|
||||
case ARMMMUIdx_Stage1_E0:
|
||||
return arm_el_is_aa64(env, 3) || !arm_is_secure_below_el3(env) ? 1 : 3;
|
||||
case ARMMMUIdx_Stage1_E1:
|
||||
case ARMMMUIdx_Stage1_E1_PAN:
|
||||
case ARMMMUIdx_Stage1_SE1:
|
||||
case ARMMMUIdx_Stage1_SE1_PAN:
|
||||
case ARMMMUIdx_E10_0:
|
||||
case ARMMMUIdx_E10_1:
|
||||
case ARMMMUIdx_E10_1_PAN:
|
||||
case ARMMMUIdx_MPrivNegPri:
|
||||
@@ -996,9 +932,6 @@ static inline bool arm_mmu_idx_is_stage1_of_2(ARMMMUIdx mmu_idx)
|
||||
case ARMMMUIdx_Stage1_E0:
|
||||
case ARMMMUIdx_Stage1_E1:
|
||||
case ARMMMUIdx_Stage1_E1_PAN:
|
||||
case ARMMMUIdx_Stage1_SE0:
|
||||
case ARMMMUIdx_Stage1_SE1:
|
||||
case ARMMMUIdx_Stage1_SE1_PAN:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@@ -1065,6 +998,35 @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id)
|
||||
return valid;
|
||||
}
|
||||
|
||||
/* Granule size (i.e. page size) */
|
||||
typedef enum ARMGranuleSize {
|
||||
/* Same order as TG0 encoding */
|
||||
Gran4K,
|
||||
Gran64K,
|
||||
Gran16K,
|
||||
GranInvalid,
|
||||
} ARMGranuleSize;
|
||||
|
||||
/**
|
||||
* arm_granule_bits: Return address size of the granule in bits
|
||||
*
|
||||
* Return the address size of the granule in bits. This corresponds
|
||||
* to the pseudocode TGxGranuleBits().
|
||||
*/
|
||||
static inline int arm_granule_bits(ARMGranuleSize gran)
|
||||
{
|
||||
switch (gran) {
|
||||
case Gran64K:
|
||||
return 16;
|
||||
case Gran16K:
|
||||
return 14;
|
||||
case Gran4K:
|
||||
return 12;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Parameters of a given virtual address, as extracted from the
|
||||
* translation control register (TCR) for a given regime.
|
||||
@@ -1077,10 +1039,9 @@ typedef struct ARMVAParameters {
|
||||
bool tbi : 1;
|
||||
bool epd : 1;
|
||||
bool hpd : 1;
|
||||
bool using16k : 1;
|
||||
bool using64k : 1;
|
||||
bool tsz_oob : 1; /* tsz has been clamped to legal range */
|
||||
bool ds : 1;
|
||||
ARMGranuleSize gran : 2;
|
||||
} ARMVAParameters;
|
||||
|
||||
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
|
||||
@@ -1138,13 +1099,50 @@ typedef struct ARMCacheAttrs {
|
||||
|
||||
/* Fields that are valid upon success. */
|
||||
typedef struct GetPhysAddrResult {
|
||||
hwaddr phys;
|
||||
target_ulong page_size;
|
||||
int prot;
|
||||
MemTxAttrs attrs;
|
||||
CPUTLBEntryFull f;
|
||||
ARMCacheAttrs cacheattrs;
|
||||
} GetPhysAddrResult;
|
||||
|
||||
/**
|
||||
* get_phys_addr_with_secure: get the physical address for a virtual address
|
||||
* @env: CPUARMState
|
||||
* @address: virtual address to get physical address for
|
||||
* @access_type: 0 for read, 1 for write, 2 for execute
|
||||
* @mmu_idx: MMU index indicating required translation regime
|
||||
* @is_secure: security state for the access
|
||||
* @result: set on translation success.
|
||||
* @fi: set to fault info if the translation fails
|
||||
*
|
||||
* Find the physical address corresponding to the given virtual address,
|
||||
* by doing a translation table walk on MMU based systems or using the
|
||||
* MPU state on MPU based systems.
|
||||
*
|
||||
* Returns false if the translation was successful. Otherwise, phys_ptr, attrs,
|
||||
* prot and page_size may not be filled in, and the populated fsr value provides
|
||||
* information on why the translation aborted, in the format of a
|
||||
* DFSR/IFSR fault register, with the following caveats:
|
||||
* * we honour the short vs long DFSR format differences.
|
||||
* * the WnR bit is never set (the caller must do this).
|
||||
* * for PSMAv5 based systems we don't bother to return a full FSR format
|
||||
* value.
|
||||
*/
|
||||
bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
|
||||
MMUAccessType access_type,
|
||||
ARMMMUIdx mmu_idx, bool is_secure,
|
||||
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
|
||||
__attribute__((nonnull));
|
||||
|
||||
/**
|
||||
* get_phys_addr: get the physical address for a virtual address
|
||||
* @env: CPUARMState
|
||||
* @address: virtual address to get physical address for
|
||||
* @access_type: 0 for read, 1 for write, 2 for execute
|
||||
* @mmu_idx: MMU index indicating required translation regime
|
||||
* @result: set on translation success.
|
||||
* @fi: set to fault info if the translation fails
|
||||
*
|
||||
* Similarly, but use the security regime of @mmu_idx.
|
||||
*/
|
||||
bool get_phys_addr(CPUARMState *env, target_ulong address,
|
||||
MMUAccessType access_type, ARMMMUIdx mmu_idx,
|
||||
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
|
||||
|
||||
+3
-1
@@ -79,7 +79,9 @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
|
||||
if (max_vm_pa_size < 0) {
|
||||
max_vm_pa_size = 0;
|
||||
}
|
||||
vmfd = ioctl(kvmfd, KVM_CREATE_VM, max_vm_pa_size);
|
||||
do {
|
||||
vmfd = ioctl(kvmfd, KVM_CREATE_VM, max_vm_pa_size);
|
||||
} while (vmfd == -1 && errno == EINTR);
|
||||
if (vmfd < 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
+14
-15
@@ -223,8 +223,8 @@ static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
|
||||
}
|
||||
goto pend_fault;
|
||||
}
|
||||
address_space_stl_le(arm_addressspace(cs, res.attrs), res.phys, value,
|
||||
res.attrs, &txres);
|
||||
address_space_stl_le(arm_addressspace(cs, res.f.attrs), res.f.phys_addr,
|
||||
value, res.f.attrs, &txres);
|
||||
if (txres != MEMTX_OK) {
|
||||
/* BusFault trying to write the data */
|
||||
if (mode == STACK_LAZYFP) {
|
||||
@@ -298,8 +298,8 @@ static bool v7m_stack_read(ARMCPU *cpu, uint32_t *dest, uint32_t addr,
|
||||
goto pend_fault;
|
||||
}
|
||||
|
||||
value = address_space_ldl(arm_addressspace(cs, res.attrs), res.phys,
|
||||
res.attrs, &txres);
|
||||
value = address_space_ldl(arm_addressspace(cs, res.f.attrs),
|
||||
res.f.phys_addr, res.f.attrs, &txres);
|
||||
if (txres != MEMTX_OK) {
|
||||
/* BusFault trying to read the data */
|
||||
qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.UNSTKERR\n");
|
||||
@@ -1981,7 +1981,7 @@ static bool do_v7m_function_return(ARMCPU *cpu)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool v7m_read_half_insn(ARMCPU *cpu, ARMMMUIdx mmu_idx,
|
||||
static bool v7m_read_half_insn(ARMCPU *cpu, ARMMMUIdx mmu_idx, bool secure,
|
||||
uint32_t addr, uint16_t *insn)
|
||||
{
|
||||
/*
|
||||
@@ -2003,8 +2003,7 @@ static bool v7m_read_half_insn(ARMCPU *cpu, ARMMMUIdx mmu_idx,
|
||||
ARMMMUFaultInfo fi = {};
|
||||
MemTxResult txres;
|
||||
|
||||
v8m_security_lookup(env, addr, MMU_INST_FETCH, mmu_idx,
|
||||
regime_is_secure(env, mmu_idx), &sattrs);
|
||||
v8m_security_lookup(env, addr, MMU_INST_FETCH, mmu_idx, secure, &sattrs);
|
||||
if (!sattrs.nsc || sattrs.ns) {
|
||||
/*
|
||||
* This must be the second half of the insn, and it straddles a
|
||||
@@ -2023,8 +2022,8 @@ static bool v7m_read_half_insn(ARMCPU *cpu, ARMMMUIdx mmu_idx,
|
||||
qemu_log_mask(CPU_LOG_INT, "...really MemManage with CFSR.IACCVIOL\n");
|
||||
return false;
|
||||
}
|
||||
*insn = address_space_lduw_le(arm_addressspace(cs, res.attrs), res.phys,
|
||||
res.attrs, &txres);
|
||||
*insn = address_space_lduw_le(arm_addressspace(cs, res.f.attrs),
|
||||
res.f.phys_addr, res.f.attrs, &txres);
|
||||
if (txres != MEMTX_OK) {
|
||||
env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_IBUSERR_MASK;
|
||||
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_BUS, false);
|
||||
@@ -2070,8 +2069,8 @@ static bool v7m_read_sg_stack_word(ARMCPU *cpu, ARMMMUIdx mmu_idx,
|
||||
}
|
||||
return false;
|
||||
}
|
||||
value = address_space_ldl(arm_addressspace(cs, res.attrs), res.phys,
|
||||
res.attrs, &txres);
|
||||
value = address_space_ldl(arm_addressspace(cs, res.f.attrs),
|
||||
res.f.phys_addr, res.f.attrs, &txres);
|
||||
if (txres != MEMTX_OK) {
|
||||
/* BusFault trying to read the data */
|
||||
qemu_log_mask(CPU_LOG_INT,
|
||||
@@ -2109,7 +2108,7 @@ static bool v7m_handle_execute_nsc(ARMCPU *cpu)
|
||||
/* We want to do the MPU lookup as secure; work out what mmu_idx that is */
|
||||
mmu_idx = arm_v7m_mmu_idx_for_secstate(env, true);
|
||||
|
||||
if (!v7m_read_half_insn(cpu, mmu_idx, env->regs[15], &insn)) {
|
||||
if (!v7m_read_half_insn(cpu, mmu_idx, true, env->regs[15], &insn)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2125,7 +2124,7 @@ static bool v7m_handle_execute_nsc(ARMCPU *cpu)
|
||||
goto gen_invep;
|
||||
}
|
||||
|
||||
if (!v7m_read_half_insn(cpu, mmu_idx, env->regs[15] + 2, &insn)) {
|
||||
if (!v7m_read_half_insn(cpu, mmu_idx, true, env->regs[15] + 2, &insn)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2818,8 +2817,8 @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
|
||||
} else {
|
||||
mrvalid = true;
|
||||
}
|
||||
r = res.prot & PAGE_READ;
|
||||
rw = res.prot & PAGE_WRITE;
|
||||
r = res.f.prot & PAGE_READ;
|
||||
rw = res.f.prot & PAGE_WRITE;
|
||||
} else {
|
||||
r = false;
|
||||
rw = false;
|
||||
|
||||
+305
-265
File diff suppressed because it is too large
Load Diff
@@ -227,17 +227,16 @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
|
||||
* target page size are handled specially, so for those we
|
||||
* pass in the exact addresses.
|
||||
*/
|
||||
if (res.page_size >= TARGET_PAGE_SIZE) {
|
||||
res.phys &= TARGET_PAGE_MASK;
|
||||
if (res.f.lg_page_size >= TARGET_PAGE_BITS) {
|
||||
res.f.phys_addr &= TARGET_PAGE_MASK;
|
||||
address &= TARGET_PAGE_MASK;
|
||||
}
|
||||
/* Notice and record tagged memory. */
|
||||
if (cpu_isar_feature(aa64_mte, cpu) && res.cacheattrs.attrs == 0xf0) {
|
||||
arm_tlb_mte_tagged(&res.attrs) = true;
|
||||
arm_tlb_mte_tagged(&res.f.attrs) = true;
|
||||
}
|
||||
|
||||
tlb_set_page_with_attrs(cs, address, res.phys, res.attrs,
|
||||
res.prot, mmu_idx, res.page_size);
|
||||
tlb_set_page_full(cs, mmu_idx, address, &res.f);
|
||||
return true;
|
||||
} else if (probe) {
|
||||
return false;
|
||||
|
||||
@@ -111,14 +111,6 @@ static int get_a64_user_mem_index(DisasContext *s)
|
||||
case ARMMMUIdx_E20_2_PAN:
|
||||
useridx = ARMMMUIdx_E20_0;
|
||||
break;
|
||||
case ARMMMUIdx_SE10_1:
|
||||
case ARMMMUIdx_SE10_1_PAN:
|
||||
useridx = ARMMMUIdx_SE10_0;
|
||||
break;
|
||||
case ARMMMUIdx_SE20_2:
|
||||
case ARMMMUIdx_SE20_2_PAN:
|
||||
useridx = ARMMMUIdx_SE20_0;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
@@ -237,16 +237,12 @@ static inline int get_a32_user_mem_index(DisasContext *s)
|
||||
* otherwise, access as if at PL0.
|
||||
*/
|
||||
switch (s->mmu_idx) {
|
||||
case ARMMMUIdx_E3:
|
||||
case ARMMMUIdx_E2: /* this one is UNPREDICTABLE */
|
||||
case ARMMMUIdx_E10_0:
|
||||
case ARMMMUIdx_E10_1:
|
||||
case ARMMMUIdx_E10_1_PAN:
|
||||
return arm_to_core_mmu_idx(ARMMMUIdx_E10_0);
|
||||
case ARMMMUIdx_SE3:
|
||||
case ARMMMUIdx_SE10_0:
|
||||
case ARMMMUIdx_SE10_1:
|
||||
case ARMMMUIdx_SE10_1_PAN:
|
||||
return arm_to_core_mmu_idx(ARMMMUIdx_SE10_0);
|
||||
case ARMMMUIdx_MUser:
|
||||
case ARMMMUIdx_MPriv:
|
||||
return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
|
||||
@@ -9351,8 +9347,7 @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
|
||||
dc->vfp_enabled = 1;
|
||||
dc->be_data = MO_TE;
|
||||
dc->v7m_handler_mode = EX_TBFLAG_M32(tb_flags, HANDLER);
|
||||
dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
|
||||
regime_is_secure(env, dc->mmu_idx);
|
||||
dc->v8m_secure = EX_TBFLAG_M32(tb_flags, SECURE);
|
||||
dc->v8m_stackcheck = EX_TBFLAG_M32(tb_flags, STACKCHECK);
|
||||
dc->v8m_fpccr_s_wrong = EX_TBFLAG_M32(tb_flags, FPCCR_S_WRONG);
|
||||
dc->v7m_new_fp_ctxt_needed =
|
||||
|
||||
Reference in New Issue
Block a user