[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] target/arm: Allow only specific instructions based on the SCTLR_
From: |
Idan Horowitz |
Subject: |
[PATCH] target/arm: Allow only specific instructions based on the SCTLR_EL1.UCI bit |
Date: |
Fri, 14 Jan 2022 02:40:33 +0200 |
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.horowitz@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
- [PATCH] target/arm: Allow only specific instructions based on the SCTLR_EL1.UCI bit,
Idan Horowitz <=