The SCTLR_EL1.UCI bit only affects a subset of cache maintenance instructions as specified by the specification. Any other cache maintenance instructions must still be trapped from EL0.
Signed-off-by: Idan Horowitz <idan.horow...@gmail.com> --- target/arm/helper.c | 68 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 52 insertions(+), 16 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index cfca0f5ba6..ac75a268aa 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -4217,7 +4217,7 @@ static const ARMCPRegInfo ssbs_reginfo = { .readfn = aa64_ssbs_read, .writefn = aa64_ssbs_write }; -static CPAccessResult aa64_cacheop_poc_access(CPUARMState *env, +static CPAccessResult aa64_cacheop_poc_uci_access(CPUARMState *env, const ARMCPRegInfo *ri, bool isread) { @@ -4239,7 +4239,7 @@ static CPAccessResult aa64_cacheop_poc_access(CPUARMState *env, return CP_ACCESS_OK; } -static CPAccessResult aa64_cacheop_pou_access(CPUARMState *env, +static CPAccessResult aa64_cacheop_pou_uci_access(CPUARMState *env, const ARMCPRegInfo *ri, bool isread) { @@ -4261,6 +4261,42 @@ static CPAccessResult aa64_cacheop_pou_access(CPUARMState *env, return CP_ACCESS_OK; } +static CPAccessResult aa64_cacheop_poc_access(CPUARMState *env, + const ARMCPRegInfo *ri, + bool isread) +{ + /* Cache invalidate/clean to Point of Coherency or Persistence... */ + switch (arm_current_el(env)) { + case 0: + return CP_ACCESS_TRAP; + case 1: + /* ... EL1 must trap to EL2 if HCR_EL2.TPCP is set. */ + if (arm_hcr_el2_eff(env) & HCR_TPCP) { + return CP_ACCESS_TRAP_EL2; + } + break; + } + return CP_ACCESS_OK; +} + +static CPAccessResult aa64_cacheop_pou_access(CPUARMState *env, + const ARMCPRegInfo *ri, + bool isread) +{ + /* Cache invalidate/clean to Point of Unification... */ + switch (arm_current_el(env)) { + case 0: + return CP_ACCESS_TRAP; + case 1: + /* ... EL1 must trap to EL2 if HCR_EL2.TPU is set. */ + if (arm_hcr_el2_eff(env) & HCR_TPU) { + return CP_ACCESS_TRAP_EL2; + } + break; + } + return CP_ACCESS_OK; +} + /* See: D4.7.2 TLB maintenance requirements and the TLB maintenance instructions * Page D4-1736 (DDI0487A.b) */ @@ -4846,7 +4882,7 @@ static const ARMCPRegInfo v8_cp_reginfo[] = { { .name = "IC_IVAU", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 5, .opc2 = 1, .access = PL0_W, .type = ARM_CP_NOP, - .accessfn = aa64_cacheop_pou_access }, + .accessfn = aa64_cacheop_pou_uci_access }, { .name = "DC_IVAC", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 1, .access = PL1_W, .accessfn = aa64_cacheop_poc_access, @@ -4857,18 +4893,18 @@ static const ARMCPRegInfo v8_cp_reginfo[] = { { .name = "DC_CVAC", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 10, .opc2 = 1, .access = PL0_W, .type = ARM_CP_NOP, - .accessfn = aa64_cacheop_poc_access }, + .accessfn = aa64_cacheop_poc_uci_access }, { .name = "DC_CSW", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 2, .access = PL1_W, .accessfn = access_tsw, .type = ARM_CP_NOP }, { .name = "DC_CVAU", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 11, .opc2 = 1, .access = PL0_W, .type = ARM_CP_NOP, - .accessfn = aa64_cacheop_pou_access }, + .accessfn = aa64_cacheop_pou_uci_access }, { .name = "DC_CIVAC", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 14, .opc2 = 1, .access = PL0_W, .type = ARM_CP_NOP, - .accessfn = aa64_cacheop_poc_access }, + .accessfn = aa64_cacheop_poc_uci_access }, { .name = "DC_CISW", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 2, .access = PL1_W, .accessfn = access_tsw, .type = ARM_CP_NOP }, @@ -7102,7 +7138,7 @@ static const ARMCPRegInfo dcpop_reg[] = { { .name = "DC_CVAP", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 12, .opc2 = 1, .access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END, - .accessfn = aa64_cacheop_poc_access, .writefn = dccvap_writefn }, + .accessfn = aa64_cacheop_poc_uci_access, .writefn = dccvap_writefn }, REGINFO_SENTINEL }; @@ -7110,7 +7146,7 @@ static const ARMCPRegInfo dcpodp_reg[] = { { .name = "DC_CVADP", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 13, .opc2 = 1, .access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END, - .accessfn = aa64_cacheop_poc_access, .writefn = dccvap_writefn }, + .accessfn = aa64_cacheop_poc_uci_access, .writefn = dccvap_writefn }, REGINFO_SENTINEL }; #endif /*CONFIG_USER_ONLY*/ @@ -7227,35 +7263,35 @@ static const ARMCPRegInfo mte_el0_cacheop_reginfo[] = { { .name = "DC_CGVAC", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 10, .opc2 = 3, .type = ARM_CP_NOP, .access = PL0_W, - .accessfn = aa64_cacheop_poc_access }, + .accessfn = aa64_cacheop_poc_uci_access }, { .name = "DC_CGDVAC", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 10, .opc2 = 5, .type = ARM_CP_NOP, .access = PL0_W, - .accessfn = aa64_cacheop_poc_access }, + .accessfn = aa64_cacheop_poc_uci_access }, { .name = "DC_CGVAP", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 12, .opc2 = 3, .type = ARM_CP_NOP, .access = PL0_W, - .accessfn = aa64_cacheop_poc_access }, + .accessfn = aa64_cacheop_poc_uci_access }, { .name = "DC_CGDVAP", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 12, .opc2 = 5, .type = ARM_CP_NOP, .access = PL0_W, - .accessfn = aa64_cacheop_poc_access }, + .accessfn = aa64_cacheop_poc_uci_access }, { .name = "DC_CGVADP", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 13, .opc2 = 3, .type = ARM_CP_NOP, .access = PL0_W, - .accessfn = aa64_cacheop_poc_access }, + .accessfn = aa64_cacheop_poc_uci_access }, { .name = "DC_CGDVADP", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 13, .opc2 = 5, .type = ARM_CP_NOP, .access = PL0_W, - .accessfn = aa64_cacheop_poc_access }, + .accessfn = aa64_cacheop_poc_uci_access }, { .name = "DC_CIGVAC", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 14, .opc2 = 3, .type = ARM_CP_NOP, .access = PL0_W, - .accessfn = aa64_cacheop_poc_access }, + .accessfn = aa64_cacheop_poc_uci_access }, { .name = "DC_CIGDVAC", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 14, .opc2 = 5, .type = ARM_CP_NOP, .access = PL0_W, - .accessfn = aa64_cacheop_poc_access }, + .accessfn = aa64_cacheop_poc_uci_access }, { .name = "DC_GVA", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 4, .opc2 = 3, .access = PL0_W, .type = ARM_CP_DC_GVA, -- 2.34.1