mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-27 05:20:50 +00:00
target-arm queue:
* Fix regression booting Trusted Firmware * Honor HCR_E2H and HCR_TGE in ats_write64() * Copy the entire vector in DO_ZIP * Fix Privileged Access Never (PAN) for aarch32 * Make TLBIOS and TLBIRANGE ops trap on HCR_EL2.TTLB * Set SCR_EL3.HXEn when direct booting kernel * Set SME and SVE EL3 vector lengths when direct booting kernel -----BEGIN PGP SIGNATURE----- iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmNk+KkZHHBldGVyLm1h eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3vUsD/9SYZP3ne2OZxBe8he98jJ5 6apODiBksBLUM+1bKEoYW8Kw4XpS10I1Tbnxe7n0bNAfIiZlsZ7HJAJaYWy4MX4k Bq0v1EIFo+Obumocc14ZzWcw9yPpHOGavKHXfPxTtIw0amtOmh3aMBPuOZKiMSaq TdI/8654DbAOY3Hp/r6WnXwEgAc23kx/PtGhQFdU4iWhzTdeQeFkgCCsVMO02zFQ ZM4wiAATpfNfgf5+Wxoin6RQ8nI9PF+Xf7HhN3d1CiXju3vOl+geYNkubJzIopv1 itLcnvduYE6+5oJsnXZ4FDNO6/nnqWRNqtyDf0/NjLROfj84BPJpZqMX+FR6Q0I0 d+4/oEw4A46qfaS5b4/YelbJOiUgiViWU1Xs3g2dkeTMT8CyGfDrJ2HRDKN7AaHo llL7s1calkX2oSs+gU0BAw8xRETGwMBSOpF6JmPVh277LjvWfN1vsJzVUG3wrSXL G7qa2h+fHV5Xu876sc/i0+d4qHuqcE/EU86VQ6X40f+dRzN02rkSCPAxzGFwLXOr 8fl5MsX6z5pqcubnzxkhi66ZHc6fXsvtUjKBxyrVpMyjMlV9PTJ2Q1RCgVctErXk lDzsLuplzPSjZBy3Peib/rLnmYUxJHyPe0RFYIumzZv/UHwL4GjZgkI842UVBpAL FvIGblcCXHhdP4UFvqgZhw== =Fcb4 -----END PGP SIGNATURE----- Merge tag 'pull-target-arm-20221104' of https://git.linaro.org/people/pmaydell/qemu-arm into staging target-arm queue: * Fix regression booting Trusted Firmware * Honor HCR_E2H and HCR_TGE in ats_write64() * Copy the entire vector in DO_ZIP * Fix Privileged Access Never (PAN) for aarch32 * Make TLBIOS and TLBIRANGE ops trap on HCR_EL2.TTLB * Set SCR_EL3.HXEn when direct booting kernel * Set SME and SVE EL3 vector lengths when direct booting kernel # -----BEGIN PGP SIGNATURE----- # # iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmNk+KkZHHBldGVyLm1h # eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3vUsD/9SYZP3ne2OZxBe8he98jJ5 # 6apODiBksBLUM+1bKEoYW8Kw4XpS10I1Tbnxe7n0bNAfIiZlsZ7HJAJaYWy4MX4k # Bq0v1EIFo+Obumocc14ZzWcw9yPpHOGavKHXfPxTtIw0amtOmh3aMBPuOZKiMSaq # TdI/8654DbAOY3Hp/r6WnXwEgAc23kx/PtGhQFdU4iWhzTdeQeFkgCCsVMO02zFQ # ZM4wiAATpfNfgf5+Wxoin6RQ8nI9PF+Xf7HhN3d1CiXju3vOl+geYNkubJzIopv1 # itLcnvduYE6+5oJsnXZ4FDNO6/nnqWRNqtyDf0/NjLROfj84BPJpZqMX+FR6Q0I0 # d+4/oEw4A46qfaS5b4/YelbJOiUgiViWU1Xs3g2dkeTMT8CyGfDrJ2HRDKN7AaHo # llL7s1calkX2oSs+gU0BAw8xRETGwMBSOpF6JmPVh277LjvWfN1vsJzVUG3wrSXL # G7qa2h+fHV5Xu876sc/i0+d4qHuqcE/EU86VQ6X40f+dRzN02rkSCPAxzGFwLXOr # 8fl5MsX6z5pqcubnzxkhi66ZHc6fXsvtUjKBxyrVpMyjMlV9PTJ2Q1RCgVctErXk # lDzsLuplzPSjZBy3Peib/rLnmYUxJHyPe0RFYIumzZv/UHwL4GjZgkI842UVBpAL # FvIGblcCXHhdP4UFvqgZhw== # =Fcb4 # -----END PGP SIGNATURE----- # gpg: Signature made Fri 04 Nov 2022 07:34:01 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-20221104' of https://git.linaro.org/people/pmaydell/qemu-arm: target/arm: Two fixes for secure ptw target/arm: Honor HCR_E2H and HCR_TGE in ats_write64() target/arm: Copy the entire vector in DO_ZIP target/arm: Fix Privileged Access Never (PAN) for aarch32 target/arm: Make TLBIOS and TLBIRANGE ops trap on HCR_EL2.TTLB hw/arm/boot: Set SCR_EL3.HXEn when booting kernel hw/arm/boot: Set SME and SVE EL3 vector lengths when booting kernel Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
commit
6295a58ad1
@ -764,10 +764,15 @@ static void do_cpu_reset(void *opaque)
|
|||||||
}
|
}
|
||||||
if (cpu_isar_feature(aa64_sve, cpu)) {
|
if (cpu_isar_feature(aa64_sve, cpu)) {
|
||||||
env->cp15.cptr_el[3] |= R_CPTR_EL3_EZ_MASK;
|
env->cp15.cptr_el[3] |= R_CPTR_EL3_EZ_MASK;
|
||||||
|
env->vfp.zcr_el[3] = 0xf;
|
||||||
}
|
}
|
||||||
if (cpu_isar_feature(aa64_sme, cpu)) {
|
if (cpu_isar_feature(aa64_sme, cpu)) {
|
||||||
env->cp15.cptr_el[3] |= R_CPTR_EL3_ESM_MASK;
|
env->cp15.cptr_el[3] |= R_CPTR_EL3_ESM_MASK;
|
||||||
env->cp15.scr_el3 |= SCR_ENTP2;
|
env->cp15.scr_el3 |= SCR_ENTP2;
|
||||||
|
env->vfp.smcr_el[3] = 0xf;
|
||||||
|
}
|
||||||
|
if (cpu_isar_feature(aa64_hcx, cpu)) {
|
||||||
|
env->cp15.scr_el3 |= SCR_HXEN;
|
||||||
}
|
}
|
||||||
/* AArch64 kernels never boot in secure mode */
|
/* AArch64 kernels never boot in secure mode */
|
||||||
assert(!info->secure_boot);
|
assert(!info->secure_boot);
|
||||||
|
@ -3501,19 +3501,22 @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
|
|||||||
MMUAccessType access_type = ri->opc2 & 1 ? MMU_DATA_STORE : MMU_DATA_LOAD;
|
MMUAccessType access_type = ri->opc2 & 1 ? MMU_DATA_STORE : MMU_DATA_LOAD;
|
||||||
ARMMMUIdx mmu_idx;
|
ARMMMUIdx mmu_idx;
|
||||||
int secure = arm_is_secure_below_el3(env);
|
int secure = arm_is_secure_below_el3(env);
|
||||||
|
uint64_t hcr_el2 = arm_hcr_el2_eff(env);
|
||||||
|
bool regime_e20 = (hcr_el2 & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE);
|
||||||
|
|
||||||
switch (ri->opc2 & 6) {
|
switch (ri->opc2 & 6) {
|
||||||
case 0:
|
case 0:
|
||||||
switch (ri->opc1) {
|
switch (ri->opc1) {
|
||||||
case 0: /* AT S1E1R, AT S1E1W, AT S1E1RP, AT S1E1WP */
|
case 0: /* AT S1E1R, AT S1E1W, AT S1E1RP, AT S1E1WP */
|
||||||
if (ri->crm == 9 && (env->pstate & PSTATE_PAN)) {
|
if (ri->crm == 9 && (env->pstate & PSTATE_PAN)) {
|
||||||
mmu_idx = ARMMMUIdx_Stage1_E1_PAN;
|
mmu_idx = regime_e20 ?
|
||||||
|
ARMMMUIdx_E20_2_PAN : ARMMMUIdx_Stage1_E1_PAN;
|
||||||
} else {
|
} else {
|
||||||
mmu_idx = ARMMMUIdx_Stage1_E1;
|
mmu_idx = regime_e20 ? ARMMMUIdx_E20_2 : ARMMMUIdx_Stage1_E1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 4: /* AT S1E2R, AT S1E2W */
|
case 4: /* AT S1E2R, AT S1E2W */
|
||||||
mmu_idx = ARMMMUIdx_E2;
|
mmu_idx = hcr_el2 & HCR_E2H ? ARMMMUIdx_E20_2 : ARMMMUIdx_E2;
|
||||||
break;
|
break;
|
||||||
case 6: /* AT S1E3R, AT S1E3W */
|
case 6: /* AT S1E3R, AT S1E3W */
|
||||||
mmu_idx = ARMMMUIdx_E3;
|
mmu_idx = ARMMMUIdx_E3;
|
||||||
@ -3524,13 +3527,13 @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2: /* AT S1E0R, AT S1E0W */
|
case 2: /* AT S1E0R, AT S1E0W */
|
||||||
mmu_idx = ARMMMUIdx_Stage1_E0;
|
mmu_idx = regime_e20 ? ARMMMUIdx_E20_0 : ARMMMUIdx_Stage1_E0;
|
||||||
break;
|
break;
|
||||||
case 4: /* AT S12E1R, AT S12E1W */
|
case 4: /* AT S12E1R, AT S12E1W */
|
||||||
mmu_idx = ARMMMUIdx_E10_1;
|
mmu_idx = regime_e20 ? ARMMMUIdx_E20_2 : ARMMMUIdx_E10_1;
|
||||||
break;
|
break;
|
||||||
case 6: /* AT S12E0R, AT S12E0W */
|
case 6: /* AT S12E0R, AT S12E0W */
|
||||||
mmu_idx = ARMMMUIdx_E10_0;
|
mmu_idx = regime_e20 ? ARMMMUIdx_E20_0 : ARMMMUIdx_E10_0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
@ -6717,51 +6720,51 @@ static const ARMCPRegInfo pauth_reginfo[] = {
|
|||||||
static const ARMCPRegInfo tlbirange_reginfo[] = {
|
static const ARMCPRegInfo tlbirange_reginfo[] = {
|
||||||
{ .name = "TLBI_RVAE1IS", .state = ARM_CP_STATE_AA64,
|
{ .name = "TLBI_RVAE1IS", .state = ARM_CP_STATE_AA64,
|
||||||
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 1,
|
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 1,
|
||||||
.access = PL1_W, .type = ARM_CP_NO_RAW,
|
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
|
||||||
.writefn = tlbi_aa64_rvae1is_write },
|
.writefn = tlbi_aa64_rvae1is_write },
|
||||||
{ .name = "TLBI_RVAAE1IS", .state = ARM_CP_STATE_AA64,
|
{ .name = "TLBI_RVAAE1IS", .state = ARM_CP_STATE_AA64,
|
||||||
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 3,
|
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 3,
|
||||||
.access = PL1_W, .type = ARM_CP_NO_RAW,
|
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
|
||||||
.writefn = tlbi_aa64_rvae1is_write },
|
.writefn = tlbi_aa64_rvae1is_write },
|
||||||
{ .name = "TLBI_RVALE1IS", .state = ARM_CP_STATE_AA64,
|
{ .name = "TLBI_RVALE1IS", .state = ARM_CP_STATE_AA64,
|
||||||
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 5,
|
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 5,
|
||||||
.access = PL1_W, .type = ARM_CP_NO_RAW,
|
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
|
||||||
.writefn = tlbi_aa64_rvae1is_write },
|
.writefn = tlbi_aa64_rvae1is_write },
|
||||||
{ .name = "TLBI_RVAALE1IS", .state = ARM_CP_STATE_AA64,
|
{ .name = "TLBI_RVAALE1IS", .state = ARM_CP_STATE_AA64,
|
||||||
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 7,
|
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 7,
|
||||||
.access = PL1_W, .type = ARM_CP_NO_RAW,
|
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
|
||||||
.writefn = tlbi_aa64_rvae1is_write },
|
.writefn = tlbi_aa64_rvae1is_write },
|
||||||
{ .name = "TLBI_RVAE1OS", .state = ARM_CP_STATE_AA64,
|
{ .name = "TLBI_RVAE1OS", .state = ARM_CP_STATE_AA64,
|
||||||
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 1,
|
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 1,
|
||||||
.access = PL1_W, .type = ARM_CP_NO_RAW,
|
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
|
||||||
.writefn = tlbi_aa64_rvae1is_write },
|
.writefn = tlbi_aa64_rvae1is_write },
|
||||||
{ .name = "TLBI_RVAAE1OS", .state = ARM_CP_STATE_AA64,
|
{ .name = "TLBI_RVAAE1OS", .state = ARM_CP_STATE_AA64,
|
||||||
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 3,
|
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 3,
|
||||||
.access = PL1_W, .type = ARM_CP_NO_RAW,
|
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
|
||||||
.writefn = tlbi_aa64_rvae1is_write },
|
.writefn = tlbi_aa64_rvae1is_write },
|
||||||
{ .name = "TLBI_RVALE1OS", .state = ARM_CP_STATE_AA64,
|
{ .name = "TLBI_RVALE1OS", .state = ARM_CP_STATE_AA64,
|
||||||
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 5,
|
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 5,
|
||||||
.access = PL1_W, .type = ARM_CP_NO_RAW,
|
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
|
||||||
.writefn = tlbi_aa64_rvae1is_write },
|
.writefn = tlbi_aa64_rvae1is_write },
|
||||||
{ .name = "TLBI_RVAALE1OS", .state = ARM_CP_STATE_AA64,
|
{ .name = "TLBI_RVAALE1OS", .state = ARM_CP_STATE_AA64,
|
||||||
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 7,
|
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 7,
|
||||||
.access = PL1_W, .type = ARM_CP_NO_RAW,
|
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
|
||||||
.writefn = tlbi_aa64_rvae1is_write },
|
.writefn = tlbi_aa64_rvae1is_write },
|
||||||
{ .name = "TLBI_RVAE1", .state = ARM_CP_STATE_AA64,
|
{ .name = "TLBI_RVAE1", .state = ARM_CP_STATE_AA64,
|
||||||
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 1,
|
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 1,
|
||||||
.access = PL1_W, .type = ARM_CP_NO_RAW,
|
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
|
||||||
.writefn = tlbi_aa64_rvae1_write },
|
.writefn = tlbi_aa64_rvae1_write },
|
||||||
{ .name = "TLBI_RVAAE1", .state = ARM_CP_STATE_AA64,
|
{ .name = "TLBI_RVAAE1", .state = ARM_CP_STATE_AA64,
|
||||||
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 3,
|
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 3,
|
||||||
.access = PL1_W, .type = ARM_CP_NO_RAW,
|
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
|
||||||
.writefn = tlbi_aa64_rvae1_write },
|
.writefn = tlbi_aa64_rvae1_write },
|
||||||
{ .name = "TLBI_RVALE1", .state = ARM_CP_STATE_AA64,
|
{ .name = "TLBI_RVALE1", .state = ARM_CP_STATE_AA64,
|
||||||
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 5,
|
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 5,
|
||||||
.access = PL1_W, .type = ARM_CP_NO_RAW,
|
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
|
||||||
.writefn = tlbi_aa64_rvae1_write },
|
.writefn = tlbi_aa64_rvae1_write },
|
||||||
{ .name = "TLBI_RVAALE1", .state = ARM_CP_STATE_AA64,
|
{ .name = "TLBI_RVAALE1", .state = ARM_CP_STATE_AA64,
|
||||||
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 7,
|
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 7,
|
||||||
.access = PL1_W, .type = ARM_CP_NO_RAW,
|
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
|
||||||
.writefn = tlbi_aa64_rvae1_write },
|
.writefn = tlbi_aa64_rvae1_write },
|
||||||
{ .name = "TLBI_RIPAS2E1IS", .state = ARM_CP_STATE_AA64,
|
{ .name = "TLBI_RIPAS2E1IS", .state = ARM_CP_STATE_AA64,
|
||||||
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 2,
|
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 2,
|
||||||
@ -6832,27 +6835,27 @@ static const ARMCPRegInfo tlbirange_reginfo[] = {
|
|||||||
static const ARMCPRegInfo tlbios_reginfo[] = {
|
static const ARMCPRegInfo tlbios_reginfo[] = {
|
||||||
{ .name = "TLBI_VMALLE1OS", .state = ARM_CP_STATE_AA64,
|
{ .name = "TLBI_VMALLE1OS", .state = ARM_CP_STATE_AA64,
|
||||||
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 0,
|
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 0,
|
||||||
.access = PL1_W, .type = ARM_CP_NO_RAW,
|
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
|
||||||
.writefn = tlbi_aa64_vmalle1is_write },
|
.writefn = tlbi_aa64_vmalle1is_write },
|
||||||
{ .name = "TLBI_VAE1OS", .state = ARM_CP_STATE_AA64,
|
{ .name = "TLBI_VAE1OS", .state = ARM_CP_STATE_AA64,
|
||||||
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 1,
|
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 1,
|
||||||
.access = PL1_W, .type = ARM_CP_NO_RAW,
|
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
|
||||||
.writefn = tlbi_aa64_vae1is_write },
|
.writefn = tlbi_aa64_vae1is_write },
|
||||||
{ .name = "TLBI_ASIDE1OS", .state = ARM_CP_STATE_AA64,
|
{ .name = "TLBI_ASIDE1OS", .state = ARM_CP_STATE_AA64,
|
||||||
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 2,
|
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 2,
|
||||||
.access = PL1_W, .type = ARM_CP_NO_RAW,
|
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
|
||||||
.writefn = tlbi_aa64_vmalle1is_write },
|
.writefn = tlbi_aa64_vmalle1is_write },
|
||||||
{ .name = "TLBI_VAAE1OS", .state = ARM_CP_STATE_AA64,
|
{ .name = "TLBI_VAAE1OS", .state = ARM_CP_STATE_AA64,
|
||||||
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 3,
|
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 3,
|
||||||
.access = PL1_W, .type = ARM_CP_NO_RAW,
|
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
|
||||||
.writefn = tlbi_aa64_vae1is_write },
|
.writefn = tlbi_aa64_vae1is_write },
|
||||||
{ .name = "TLBI_VALE1OS", .state = ARM_CP_STATE_AA64,
|
{ .name = "TLBI_VALE1OS", .state = ARM_CP_STATE_AA64,
|
||||||
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 5,
|
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 5,
|
||||||
.access = PL1_W, .type = ARM_CP_NO_RAW,
|
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
|
||||||
.writefn = tlbi_aa64_vae1is_write },
|
.writefn = tlbi_aa64_vae1is_write },
|
||||||
{ .name = "TLBI_VAALE1OS", .state = ARM_CP_STATE_AA64,
|
{ .name = "TLBI_VAALE1OS", .state = ARM_CP_STATE_AA64,
|
||||||
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 7,
|
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 7,
|
||||||
.access = PL1_W, .type = ARM_CP_NO_RAW,
|
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
|
||||||
.writefn = tlbi_aa64_vae1is_write },
|
.writefn = tlbi_aa64_vae1is_write },
|
||||||
{ .name = "TLBI_ALLE2OS", .state = ARM_CP_STATE_AA64,
|
{ .name = "TLBI_ALLE2OS", .state = ARM_CP_STATE_AA64,
|
||||||
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 0,
|
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 0,
|
||||||
@ -11003,6 +11006,15 @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static bool arm_pan_enabled(CPUARMState *env)
|
||||||
|
{
|
||||||
|
if (is_a64(env)) {
|
||||||
|
return env->pstate & PSTATE_PAN;
|
||||||
|
} else {
|
||||||
|
return env->uncached_cpsr & CPSR_PAN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ARMMMUIdx arm_mmu_idx_el(CPUARMState *env, int el)
|
ARMMMUIdx arm_mmu_idx_el(CPUARMState *env, int el)
|
||||||
{
|
{
|
||||||
ARMMMUIdx idx;
|
ARMMMUIdx idx;
|
||||||
@ -11023,7 +11035,7 @@ ARMMMUIdx arm_mmu_idx_el(CPUARMState *env, int el)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
if (env->pstate & PSTATE_PAN) {
|
if (arm_pan_enabled(env)) {
|
||||||
idx = ARMMMUIdx_E10_1_PAN;
|
idx = ARMMMUIdx_E10_1_PAN;
|
||||||
} else {
|
} else {
|
||||||
idx = ARMMMUIdx_E10_1;
|
idx = ARMMMUIdx_E10_1;
|
||||||
@ -11032,7 +11044,7 @@ ARMMMUIdx arm_mmu_idx_el(CPUARMState *env, int el)
|
|||||||
case 2:
|
case 2:
|
||||||
/* Note that TGE does not apply at EL2. */
|
/* Note that TGE does not apply at EL2. */
|
||||||
if (arm_hcr_el2_eff(env) & HCR_E2H) {
|
if (arm_hcr_el2_eff(env) & HCR_E2H) {
|
||||||
if (env->pstate & PSTATE_PAN) {
|
if (arm_pan_enabled(env)) {
|
||||||
idx = ARMMMUIdx_E20_2_PAN;
|
idx = ARMMMUIdx_E20_2_PAN;
|
||||||
} else {
|
} else {
|
||||||
idx = ARMMMUIdx_E20_2;
|
idx = ARMMMUIdx_E20_2;
|
||||||
|
@ -503,12 +503,11 @@ static bool get_level1_table_address(CPUARMState *env, ARMMMUIdx mmu_idx,
|
|||||||
* @mmu_idx: MMU index indicating required translation regime
|
* @mmu_idx: MMU index indicating required translation regime
|
||||||
* @ap: The 3-bit access permissions (AP[2:0])
|
* @ap: The 3-bit access permissions (AP[2:0])
|
||||||
* @domain_prot: The 2-bit domain access permissions
|
* @domain_prot: The 2-bit domain access permissions
|
||||||
|
* @is_user: TRUE if accessing from PL0
|
||||||
*/
|
*/
|
||||||
static int ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx,
|
static int ap_to_rw_prot_is_user(CPUARMState *env, ARMMMUIdx mmu_idx,
|
||||||
int ap, int domain_prot)
|
int ap, int domain_prot, bool is_user)
|
||||||
{
|
{
|
||||||
bool is_user = regime_is_user(env, mmu_idx);
|
|
||||||
|
|
||||||
if (domain_prot == 3) {
|
if (domain_prot == 3) {
|
||||||
return PAGE_READ | PAGE_WRITE;
|
return PAGE_READ | PAGE_WRITE;
|
||||||
}
|
}
|
||||||
@ -552,6 +551,20 @@ static int ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Translate section/page access permissions to page R/W protection flags
|
||||||
|
* @env: CPUARMState
|
||||||
|
* @mmu_idx: MMU index indicating required translation regime
|
||||||
|
* @ap: The 3-bit access permissions (AP[2:0])
|
||||||
|
* @domain_prot: The 2-bit domain access permissions
|
||||||
|
*/
|
||||||
|
static int ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx,
|
||||||
|
int ap, int domain_prot)
|
||||||
|
{
|
||||||
|
return ap_to_rw_prot_is_user(env, mmu_idx, ap, domain_prot,
|
||||||
|
regime_is_user(env, mmu_idx));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Translate section/page access permissions to page R/W protection flags.
|
* Translate section/page access permissions to page R/W protection flags.
|
||||||
* @ap: The 2-bit simple AP (AP[2:1])
|
* @ap: The 2-bit simple AP (AP[2:1])
|
||||||
@ -720,6 +733,7 @@ static bool get_phys_addr_v6(CPUARMState *env, S1Translate *ptw,
|
|||||||
hwaddr phys_addr;
|
hwaddr phys_addr;
|
||||||
uint32_t dacr;
|
uint32_t dacr;
|
||||||
bool ns;
|
bool ns;
|
||||||
|
int user_prot;
|
||||||
|
|
||||||
/* Pagetable walk. */
|
/* Pagetable walk. */
|
||||||
/* Lookup l1 descriptor. */
|
/* Lookup l1 descriptor. */
|
||||||
@ -831,8 +845,10 @@ static bool get_phys_addr_v6(CPUARMState *env, S1Translate *ptw,
|
|||||||
goto do_fault;
|
goto do_fault;
|
||||||
}
|
}
|
||||||
result->f.prot = simple_ap_to_rw_prot(env, mmu_idx, ap >> 1);
|
result->f.prot = simple_ap_to_rw_prot(env, mmu_idx, ap >> 1);
|
||||||
|
user_prot = simple_ap_to_rw_prot_is_user(ap >> 1, 1);
|
||||||
} else {
|
} else {
|
||||||
result->f.prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
|
result->f.prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
|
||||||
|
user_prot = ap_to_rw_prot_is_user(env, mmu_idx, ap, domain_prot, 1);
|
||||||
}
|
}
|
||||||
if (result->f.prot && !xn) {
|
if (result->f.prot && !xn) {
|
||||||
result->f.prot |= PAGE_EXEC;
|
result->f.prot |= PAGE_EXEC;
|
||||||
@ -842,6 +858,14 @@ static bool get_phys_addr_v6(CPUARMState *env, S1Translate *ptw,
|
|||||||
fi->type = ARMFault_Permission;
|
fi->type = ARMFault_Permission;
|
||||||
goto do_fault;
|
goto do_fault;
|
||||||
}
|
}
|
||||||
|
if (regime_is_pan(env, mmu_idx) &&
|
||||||
|
!regime_is_user(env, mmu_idx) &&
|
||||||
|
user_prot &&
|
||||||
|
access_type != MMU_INST_FETCH) {
|
||||||
|
/* Privileged Access Never fault */
|
||||||
|
fi->type = ARMFault_Permission;
|
||||||
|
goto do_fault;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (ns) {
|
if (ns) {
|
||||||
/* The NS bit will (as required by the architecture) have no effect if
|
/* The NS bit will (as required by the architecture) have no effect if
|
||||||
@ -1357,7 +1381,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
|
|||||||
descaddr |= (address >> (stride * (4 - level))) & indexmask;
|
descaddr |= (address >> (stride * (4 - level))) & indexmask;
|
||||||
descaddr &= ~7ULL;
|
descaddr &= ~7ULL;
|
||||||
nstable = extract32(tableattrs, 4, 1);
|
nstable = extract32(tableattrs, 4, 1);
|
||||||
if (!nstable) {
|
if (nstable) {
|
||||||
/*
|
/*
|
||||||
* Stage2_S -> Stage2 or Phys_S -> Phys_NS
|
* Stage2_S -> Stage2 or Phys_S -> Phys_NS
|
||||||
* Assert that the non-secure idx are even, and relative order.
|
* Assert that the non-secure idx are even, and relative order.
|
||||||
@ -2671,6 +2695,13 @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
|
|||||||
bool is_secure = ptw->in_secure;
|
bool is_secure = ptw->in_secure;
|
||||||
ARMMMUIdx s1_mmu_idx;
|
ARMMMUIdx s1_mmu_idx;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The page table entries may downgrade secure to non-secure, but
|
||||||
|
* cannot upgrade an non-secure translation regime's attributes
|
||||||
|
* to secure.
|
||||||
|
*/
|
||||||
|
result->f.attrs.secure = is_secure;
|
||||||
|
|
||||||
switch (mmu_idx) {
|
switch (mmu_idx) {
|
||||||
case ARMMMUIdx_Phys_S:
|
case ARMMMUIdx_Phys_S:
|
||||||
case ARMMMUIdx_Phys_NS:
|
case ARMMMUIdx_Phys_NS:
|
||||||
@ -2712,12 +2743,6 @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* The page table entries may downgrade secure to non-secure, but
|
|
||||||
* cannot upgrade an non-secure translation regime's attributes
|
|
||||||
* to secure.
|
|
||||||
*/
|
|
||||||
result->f.attrs.secure = is_secure;
|
|
||||||
result->f.attrs.user = regime_is_user(env, mmu_idx);
|
result->f.attrs.user = regime_is_user(env, mmu_idx);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2773,7 +2798,8 @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
|
|||||||
if (regime_using_lpae_format(env, mmu_idx)) {
|
if (regime_using_lpae_format(env, mmu_idx)) {
|
||||||
return get_phys_addr_lpae(env, ptw, address, access_type, false,
|
return get_phys_addr_lpae(env, ptw, address, access_type, false,
|
||||||
result, fi);
|
result, fi);
|
||||||
} else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
|
} else if (arm_feature(env, ARM_FEATURE_V7) ||
|
||||||
|
regime_sctlr(env, mmu_idx) & SCTLR_XP) {
|
||||||
return get_phys_addr_v6(env, ptw, address, access_type, result, fi);
|
return get_phys_addr_v6(env, ptw, address, access_type, result, fi);
|
||||||
} else {
|
} else {
|
||||||
return get_phys_addr_v5(env, ptw, address, access_type, result, fi);
|
return get_phys_addr_v5(env, ptw, address, access_type, result, fi);
|
||||||
|
@ -3366,10 +3366,10 @@ void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
|
|||||||
/* We produce output faster than we consume input. \
|
/* We produce output faster than we consume input. \
|
||||||
Therefore we must be mindful of possible overlap. */ \
|
Therefore we must be mindful of possible overlap. */ \
|
||||||
if (unlikely((vn - vd) < (uintptr_t)oprsz)) { \
|
if (unlikely((vn - vd) < (uintptr_t)oprsz)) { \
|
||||||
vn = memcpy(&tmp_n, vn, oprsz_2); \
|
vn = memcpy(&tmp_n, vn, oprsz); \
|
||||||
} \
|
} \
|
||||||
if (unlikely((vm - vd) < (uintptr_t)oprsz)) { \
|
if (unlikely((vm - vd) < (uintptr_t)oprsz)) { \
|
||||||
vm = memcpy(&tmp_m, vm, oprsz_2); \
|
vm = memcpy(&tmp_m, vm, oprsz); \
|
||||||
} \
|
} \
|
||||||
for (i = 0; i < oprsz_2; i += sizeof(TYPE)) { \
|
for (i = 0; i < oprsz_2; i += sizeof(TYPE)) { \
|
||||||
*(TYPE *)(vd + H(2 * i + 0)) = *(TYPE *)(vn + odd_ofs + H(i)); \
|
*(TYPE *)(vd + H(2 * i + 0)) = *(TYPE *)(vn + odd_ofs + H(i)); \
|
||||||
|
Loading…
Reference in New Issue
Block a user