Message ID | 1466694717-556963-1-git-send-email-afarallax@yandex.ru |
---|---|
State | New |
Headers | show |
23.06.2016, 18:12, "Sergey Sorokin" <afarallax@yandex.ru>:
Some PL2 related TLBI system registers are missed in AArch32
implementation. The patch fixes it.
Signed-off-by: Sergey Sorokin <[1]afarallax@yandex.ru>
---
 target-arm/helper.c | 148
++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 148 insertions(+)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 35ff772..73c844f 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -572,6 +572,111 @@ static void tlbimvaa_is_write(CPUARMState
*env, const ARMCPRegInfo *ri,
     }
 }
+static void tlbiall_nsnh_write(CPUARMState *env, const ARMCPRegInfo
*ri,
+ uint64_t value)
+{
+ CPUState *cs = ENV_GET_CPU(env);
+
+ if (arm_feature(env, ARM_FEATURE_EL2)) {
+ tlb_flush_by_mmuidx(cs, ARMMMUIdx_S12NSE1, ARMMMUIdx_S12NSE0,
+ ARMMMUIdx_S2NS, -1);
+ } else {
+ tlb_flush_by_mmuidx(cs, ARMMMUIdx_S12NSE1, ARMMMUIdx_S12NSE0, -1);
+ }
+}
+
+static void tlbiall_nsnh_is_write(CPUARMState *env, const
ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ bool has_el2 = arm_feature(env, ARM_FEATURE_EL2);
+ CPUState *other_cs;
+
+ CPU_FOREACH(other_cs) {
+ if (has_el2) {
+ tlb_flush_by_mmuidx(other_cs, ARMMMUIdx_S12NSE1,
+ ARMMMUIdx_S12NSE0, ARMMMUIdx_S2NS, -1);
+ } else {
+ tlb_flush_by_mmuidx(other_cs, ARMMMUIdx_S12NSE1,
+ ARMMMUIdx_S12NSE0, -1);
+ }
+ }
+}
+
+static void tlbiipas2_write(CPUARMState *env, const ARMCPRegInfo
*ri,
+ uint64_t value)
+{
+ /* Invalidate by IPA. This has to invalidate any structures that
+ * contain only stage 2 translation information, but does not need
+ * to apply to structures that contain combined stage 1 and stage 2
+ * translation information.
+ * This must NOP if EL2 isn't implemented or SCR_EL3.NS is zero.
+ */
+ CPUState *cs = ENV_GET_CPU(env);
+ uint64_t pageaddr;
+
+ if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 &
SCR_NS)) {
+ return;
+ }
+
+ pageaddr = sextract64(value << 12, 0, 40);
+
+ tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdx_S2NS, -1);
+}
+
+static void tlbiipas2_is_write(CPUARMState *env, const ARMCPRegInfo
*ri,
+ uint64_t value)
+{
+ CPUState *other_cs;
+ uint64_t pageaddr;
+
+ if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 &
SCR_NS)) {
+ return;
+ }
+
+ pageaddr = sextract64(value << 12, 0, 40);
+
+ CPU_FOREACH(other_cs) {
+ tlb_flush_page_by_mmuidx(other_cs, pageaddr, ARMMMUIdx_S2NS, -1);
+ }
+}
+
+static void tlbiall_hyp_write(CPUARMState *env, const ARMCPRegInfo
*ri,
+ uint64_t value)
+{
+ CPUState *cs = ENV_GET_CPU(env);
+
+ tlb_flush_by_mmuidx(cs, ARMMMUIdx_S1E2, -1);
+}
+
+static void tlbiall_hyp_is_write(CPUARMState *env, const
ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ CPUState *other_cs;
+
+ CPU_FOREACH(other_cs) {
+ tlb_flush_by_mmuidx(other_cs, ARMMMUIdx_S1E2, -1);
+ }
+}
+
+static void tlbimva_hyp_write(CPUARMState *env, const ARMCPRegInfo
*ri,
+ uint64_t value)
+{
+ CPUState *cs = ENV_GET_CPU(env);
+
+ tlb_flush_page_by_mmuidx(cs, value & TARGET_PAGE_MASK,
ARMMMUIdx_S1E2, -1);
+}
+
+static void tlbimva_hyp_is_write(CPUARMState *env, const
ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ CPUState *other_cs;
+ uint64_t pageaddr = value & TARGET_PAGE_MASK;
+
+ CPU_FOREACH(other_cs) {
+ tlb_flush_page_by_mmuidx(other_cs, pageaddr, ARMMMUIdx_S1E2, -1);
+ }
+}
+
 static const ARMCPRegInfo cp_reginfo[] = {
     /* Define the secure and non-secure FCSE identifier CP
registers
      * separately because there is no secure bank in V8 (no
_EL3). This allows
@@ -1238,6 +1343,14 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
       .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn =
tlbiasid_write },
     { .name = "TLBIMVAA", .cp = 15, .opc1 = 0, .crn = 8, .crm
= 7, .opc2 = 3,
       .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn =
tlbimvaa_write },
+ { .name = "TLBIALLNSNH",
+ .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4,
+ .type = ARM_CP_NO_RAW, .access = PL2_W,
+ .writefn = tlbiall_nsnh_write },
+ { .name = "TLBIALLNSNHIS",
+ .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4,
+ .type = ARM_CP_NO_RAW, .access = PL2_W,
+ .writefn = tlbiall_nsnh_is_write },
     REGINFO_SENTINEL
 };
@@ -3273,6 +3386,22 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
       .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn =
tlbimva_write },
     { .name = "TLBIMVAAL", .cp = 15, .opc1 = 0, .crn = 8, .crm
= 7, .opc2 = 7,
       .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn =
tlbimvaa_write },
+ { .name = "TLBIIPAS2",
+ .cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
+ .type = ARM_CP_NO_RAW, .access = PL2_W,
+ .writefn = tlbiipas2_write },
+ { .name = "TLBIIPAS2IS",
+ .cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
+ .type = ARM_CP_NO_RAW, .access = PL2_W,
+ .writefn = tlbiipas2_is_write },
+ { .name = "TLBIIPAS2L",
+ .cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5,
+ .type = ARM_CP_NO_RAW, .access = PL2_W,
+ .writefn = tlbiipas2_write },
+ { .name = "TLBIIPAS2LIS",
+ .cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
+ .type = ARM_CP_NO_RAW, .access = PL2_W,
+ .writefn = tlbiipas2_is_write },
     /* 32 bit cache operations */
     { .name = "ICIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm
= 1, .opc2 = 0,
       .type = ARM_CP_NOP, .access = PL1_W },
@@ -3605,6 +3734,25 @@ static const ARMCPRegInfo el2_cp_reginfo[] =
{
     { .name = "HTTBR", .cp = 15, .opc1 = 4, .crm = 2,
       .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS,
       .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[2])
},
+ { .name = "TLBIALLH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7,
.opc2 = 0,
+ .type = ARM_CP_NO_RAW, .access = PL2_W,
+ .writefn = tlbiall_hyp_write },
+ { .name = "TLBIALLHIS", .cp = 15, .opc1 = 4, .crn = 8, .crm = 3,
.opc2 = 0,
+ .type = ARM_CP_NO_RAW, .access = PL2_W,
+ .writefn = tlbiall_hyp_is_write },
+ { .name = "TLBIMVAH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7,
.opc2 = 1,
+ .type = ARM_CP_NO_RAW, .access = PL2_W,
+ .writefn = tlbimva_hyp_write },
+ { .name = "TLBIMVAHIS", .cp = 15, .opc1 = 4, .crn = 8, .crm = 3,
.opc2 = 1,
+ .type = ARM_CP_NO_RAW, .access = PL2_W,
+ .writefn = tlbimva_hyp_is_write },
+ { .name = "TLBIMVALH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7,
.opc2 = 5,
+ .type = ARM_CP_NO_RAW, .access = PL2_W,
+ .writefn = tlbimva_hyp_write },
+ { .name = "TLBIMVALHIS",
+ .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 5,
+ .type = ARM_CP_NO_RAW, .access = PL2_W,
+ .writefn = tlbimva_hyp_is_write },
     { .name = "TLBI_ALLE2", .state = ARM_CP_STATE_AA64,
       .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0,
       .type = ARM_CP_NO_RAW, .access = PL2_W,
--
1.9.3
ping
http://patchwork.ozlabs.org/patch/639688/
References
Visible links
1. mailto:afarallax@yandex.ru
Hidden links:
2. http://patchwork.ozlabs.org/patch/639688/
ping http://patchwork.ozlabs.org/patch/639688/
On 23 June 2016 at 16:11, Sergey Sorokin <afarallax@yandex.ru> wrote: > Some PL2 related TLBI system registers are missed in AArch32 > implementation. The patch fixes it. > > Signed-off-by: Sergey Sorokin <afarallax@yandex.ru> > --- > target-arm/helper.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 148 insertions(+) Apologies for the delayed review, I think I missed this patch and failed to put it in my to-review queue. A couple of minor points below but most of this is good. > +static void tlbimva_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri, > + uint64_t value) > +{ > + CPUState *cs = ENV_GET_CPU(env); > + > + tlb_flush_page_by_mmuidx(cs, value & TARGET_PAGE_MASK, ARMMMUIdx_S1E2, -1); TARGET_PAGE_MASK isn't what you think it is (TARGET_PAGE_BITS is only 10). You need to do something that's definitely a 12 bit mask (use extract32, or MAKE_64BIT_MASK, or a literal, I don't care much). > +} > + > +static void tlbimva_hyp_is_write(CPUARMState *env, const ARMCPRegInfo *ri, > + uint64_t value) > +{ > + CPUState *other_cs; > + uint64_t pageaddr = value & TARGET_PAGE_MASK; Ditto. > + > + CPU_FOREACH(other_cs) { > + tlb_flush_page_by_mmuidx(other_cs, pageaddr, ARMMMUIdx_S1E2, -1); > + } > +} > + > static const ARMCPRegInfo cp_reginfo[] = { > /* Define the secure and non-secure FCSE identifier CP registers > * separately because there is no secure bank in V8 (no _EL3). This allows > @@ -1238,6 +1343,14 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { > .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiasid_write }, > { .name = "TLBIMVAA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3, > .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimvaa_write }, > + { .name = "TLBIALLNSNH", > + .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4, > + .type = ARM_CP_NO_RAW, .access = PL2_W, > + .writefn = tlbiall_nsnh_write }, > + { .name = "TLBIALLNSNHIS", > + .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4, > + .type = ARM_CP_NO_RAW, .access = PL2_W, > + .writefn = tlbiall_nsnh_is_write }, These don't exist on v7 unless the virtualization extensions are present (though they do exist on v8 without EL3). > REGINFO_SENTINEL > }; > > @@ -3273,6 +3386,22 @@ static const ARMCPRegInfo v8_cp_reginfo[] = { > .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write }, > { .name = "TLBIMVAAL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7, > .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimvaa_write }, > + { .name = "TLBIIPAS2", > + .cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1, > + .type = ARM_CP_NO_RAW, .access = PL2_W, > + .writefn = tlbiipas2_write }, > + { .name = "TLBIIPAS2IS", > + .cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1, > + .type = ARM_CP_NO_RAW, .access = PL2_W, > + .writefn = tlbiipas2_is_write }, > + { .name = "TLBIIPAS2L", > + .cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5, > + .type = ARM_CP_NO_RAW, .access = PL2_W, > + .writefn = tlbiipas2_write }, > + { .name = "TLBIIPAS2LIS", > + .cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5, > + .type = ARM_CP_NO_RAW, .access = PL2_W, > + .writefn = tlbiipas2_is_write }, > /* 32 bit cache operations */ > { .name = "ICIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0, > .type = ARM_CP_NOP, .access = PL1_W }, > @@ -3605,6 +3734,25 @@ static const ARMCPRegInfo el2_cp_reginfo[] = { > { .name = "HTTBR", .cp = 15, .opc1 = 4, .crm = 2, > .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS, > .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[2]) }, > + { .name = "TLBIALLH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0, > + .type = ARM_CP_NO_RAW, .access = PL2_W, > + .writefn = tlbiall_hyp_write }, > + { .name = "TLBIALLHIS", .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 0, > + .type = ARM_CP_NO_RAW, .access = PL2_W, > + .writefn = tlbiall_hyp_is_write }, > + { .name = "TLBIMVAH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 1, > + .type = ARM_CP_NO_RAW, .access = PL2_W, > + .writefn = tlbimva_hyp_write }, > + { .name = "TLBIMVAHIS", .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 1, > + .type = ARM_CP_NO_RAW, .access = PL2_W, > + .writefn = tlbimva_hyp_is_write }, > + { .name = "TLBIMVALH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 5, > + .type = ARM_CP_NO_RAW, .access = PL2_W, > + .writefn = tlbimva_hyp_write }, This doesn't exist on v7. > + { .name = "TLBIMVALHIS", > + .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 5, > + .type = ARM_CP_NO_RAW, .access = PL2_W, > + .writefn = tlbimva_hyp_is_write }, Nor does this. > { .name = "TLBI_ALLE2", .state = ARM_CP_STATE_AA64, > .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0, > .type = ARM_CP_NO_RAW, .access = PL2_W, > -- > 1.9.3 thanks -- PMM
11.07.2016, 20:39, "Peter Maydell" <peter.maydell@linaro.org>: >> + >> + CPU_FOREACH(other_cs) { >> + tlb_flush_page_by_mmuidx(other_cs, pageaddr, ARMMMUIdx_S1E2, -1); >> + } >> +} >> + >> static const ARMCPRegInfo cp_reginfo[] = { >> /* Define the secure and non-secure FCSE identifier CP registers >> * separately because there is no secure bank in V8 (no _EL3). This allows >> @@ -1238,6 +1343,14 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { >> .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiasid_write }, >> { .name = "TLBIMVAA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3, >> .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimvaa_write }, >> + { .name = "TLBIALLNSNH", >> + .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4, >> + .type = ARM_CP_NO_RAW, .access = PL2_W, >> + .writefn = tlbiall_nsnh_write }, >> + { .name = "TLBIALLNSNHIS", >> + .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4, >> + .type = ARM_CP_NO_RAW, .access = PL2_W, >> + .writefn = tlbiall_nsnh_is_write }, > > These don't exist on v7 unless the virtualization extensions are present > (though they do exist on v8 without EL3). So I should check arm_feature(env, ARM_FEATURE_EL2) to add these registers, e.g. by moving them to el2_cp_reginfo, right?
On 11 July 2016 at 19:23, Sergey Sorokin <afarallax@yandex.ru> wrote: > 11.07.2016, 20:39, "Peter Maydell" <peter.maydell@linaro.org>: >>> + >>> + CPU_FOREACH(other_cs) { >>> + tlb_flush_page_by_mmuidx(other_cs, pageaddr, ARMMMUIdx_S1E2, -1); >>> + } >>> +} >>> + >>> static const ARMCPRegInfo cp_reginfo[] = { >>> /* Define the secure and non-secure FCSE identifier CP registers >>> * separately because there is no secure bank in V8 (no _EL3). This allows >>> @@ -1238,6 +1343,14 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { >>> .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiasid_write }, >>> { .name = "TLBIMVAA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3, >>> .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimvaa_write }, >>> + { .name = "TLBIALLNSNH", >>> + .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4, >>> + .type = ARM_CP_NO_RAW, .access = PL2_W, >>> + .writefn = tlbiall_nsnh_write }, >>> + { .name = "TLBIALLNSNHIS", >>> + .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4, >>> + .type = ARM_CP_NO_RAW, .access = PL2_W, >>> + .writefn = tlbiall_nsnh_is_write }, >> >> These don't exist on v7 unless the virtualization extensions are present >> (though they do exist on v8 without EL3). > > So I should check arm_feature(env, ARM_FEATURE_EL2) to add these registers, > e.g. by moving them to el2_cp_reginfo, right? That would make them incorrectly not exist for v8-without-EL3, I think. If there isn't a suitable reginfo array for this case, you might need to either list them in two arrays or add a new array. thanks -- PMM
11.07.2016, 21:36, "Peter Maydell" <peter.maydell@linaro.org>: > On 11 July 2016 at 19:23, Sergey Sorokin <afarallax@yandex.ru> wrote: >> 11.07.2016, 20:39, "Peter Maydell" <peter.maydell@linaro.org>: >>>> + >>>> + CPU_FOREACH(other_cs) { >>>> + tlb_flush_page_by_mmuidx(other_cs, pageaddr, ARMMMUIdx_S1E2, -1); >>>> + } >>>> +} >>>> + >>>> static const ARMCPRegInfo cp_reginfo[] = { >>>> /* Define the secure and non-secure FCSE identifier CP registers >>>> * separately because there is no secure bank in V8 (no _EL3). This allows >>>> @@ -1238,6 +1343,14 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { >>>> .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiasid_write }, >>>> { .name = "TLBIMVAA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3, >>>> .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimvaa_write }, >>>> + { .name = "TLBIALLNSNH", >>>> + .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4, >>>> + .type = ARM_CP_NO_RAW, .access = PL2_W, >>>> + .writefn = tlbiall_nsnh_write }, >>>> + { .name = "TLBIALLNSNHIS", >>>> + .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4, >>>> + .type = ARM_CP_NO_RAW, .access = PL2_W, >>>> + .writefn = tlbiall_nsnh_is_write }, >>> >>> These don't exist on v7 unless the virtualization extensions are present >>> (though they do exist on v8 without EL3). >> >> So I should check arm_feature(env, ARM_FEATURE_EL2) to add these registers, >> e.g. by moving them to el2_cp_reginfo, right? > > That would make them incorrectly not exist for v8-without-EL3, I think. > If there isn't a suitable reginfo array for this case, you might need > to either list them in two arrays or add a new array. > > thanks > -- PMM Table G4-25 Effect of the TLB maintenance instructions says: b. Available only in an implementation that includes EL2. So seems they should be in el2_cp_reginfo which is exist regardless EL3 enabled. And also I need to fix tlbiall_nsnh_[is_]write functions accordingly.
On 11 July 2016 at 19:47, Sergey Sorokin <afarallax@yandex.ru> wrote: [re TLBIALLNSNH and TLBIALLNSNHIS] > Table G4-25 Effect of the TLB maintenance instructions says: > b. Available only in an implementation that includes EL2. > > So seems they should be in el2_cp_reginfo which is exist regardless EL3 enabled. > And also I need to fix tlbiall_nsnh_[is_]write functions accordingly. Ah, yes. I was looking at the register description, which doesn't mention that it's an EL2-only operation. el2_cp_reginfo is the right place, then. thanks -- PMM
diff --git a/target-arm/helper.c b/target-arm/helper.c index 35ff772..73c844f 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -572,6 +572,111 @@ static void tlbimvaa_is_write(CPUARMState *env, const ARMCPRegInfo *ri, } } +static void tlbiall_nsnh_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + CPUState *cs = ENV_GET_CPU(env); + + if (arm_feature(env, ARM_FEATURE_EL2)) { + tlb_flush_by_mmuidx(cs, ARMMMUIdx_S12NSE1, ARMMMUIdx_S12NSE0, + ARMMMUIdx_S2NS, -1); + } else { + tlb_flush_by_mmuidx(cs, ARMMMUIdx_S12NSE1, ARMMMUIdx_S12NSE0, -1); + } +} + +static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + bool has_el2 = arm_feature(env, ARM_FEATURE_EL2); + CPUState *other_cs; + + CPU_FOREACH(other_cs) { + if (has_el2) { + tlb_flush_by_mmuidx(other_cs, ARMMMUIdx_S12NSE1, + ARMMMUIdx_S12NSE0, ARMMMUIdx_S2NS, -1); + } else { + tlb_flush_by_mmuidx(other_cs, ARMMMUIdx_S12NSE1, + ARMMMUIdx_S12NSE0, -1); + } + } +} + +static void tlbiipas2_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + /* Invalidate by IPA. This has to invalidate any structures that + * contain only stage 2 translation information, but does not need + * to apply to structures that contain combined stage 1 and stage 2 + * translation information. + * This must NOP if EL2 isn't implemented or SCR_EL3.NS is zero. + */ + CPUState *cs = ENV_GET_CPU(env); + uint64_t pageaddr; + + if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) { + return; + } + + pageaddr = sextract64(value << 12, 0, 40); + + tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdx_S2NS, -1); +} + +static void tlbiipas2_is_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + CPUState *other_cs; + uint64_t pageaddr; + + if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) { + return; + } + + pageaddr = sextract64(value << 12, 0, 40); + + CPU_FOREACH(other_cs) { + tlb_flush_page_by_mmuidx(other_cs, pageaddr, ARMMMUIdx_S2NS, -1); + } +} + +static void tlbiall_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + CPUState *cs = ENV_GET_CPU(env); + + tlb_flush_by_mmuidx(cs, ARMMMUIdx_S1E2, -1); +} + +static void tlbiall_hyp_is_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + CPUState *other_cs; + + CPU_FOREACH(other_cs) { + tlb_flush_by_mmuidx(other_cs, ARMMMUIdx_S1E2, -1); + } +} + +static void tlbimva_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + CPUState *cs = ENV_GET_CPU(env); + + tlb_flush_page_by_mmuidx(cs, value & TARGET_PAGE_MASK, ARMMMUIdx_S1E2, -1); +} + +static void tlbimva_hyp_is_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + CPUState *other_cs; + uint64_t pageaddr = value & TARGET_PAGE_MASK; + + CPU_FOREACH(other_cs) { + tlb_flush_page_by_mmuidx(other_cs, pageaddr, ARMMMUIdx_S1E2, -1); + } +} + static const ARMCPRegInfo cp_reginfo[] = { /* Define the secure and non-secure FCSE identifier CP registers * separately because there is no secure bank in V8 (no _EL3). This allows @@ -1238,6 +1343,14 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiasid_write }, { .name = "TLBIMVAA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3, .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimvaa_write }, + { .name = "TLBIALLNSNH", + .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbiall_nsnh_write }, + { .name = "TLBIALLNSNHIS", + .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbiall_nsnh_is_write }, REGINFO_SENTINEL }; @@ -3273,6 +3386,22 @@ static const ARMCPRegInfo v8_cp_reginfo[] = { .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write }, { .name = "TLBIMVAAL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7, .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimvaa_write }, + { .name = "TLBIIPAS2", + .cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbiipas2_write }, + { .name = "TLBIIPAS2IS", + .cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbiipas2_is_write }, + { .name = "TLBIIPAS2L", + .cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbiipas2_write }, + { .name = "TLBIIPAS2LIS", + .cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbiipas2_is_write }, /* 32 bit cache operations */ { .name = "ICIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0, .type = ARM_CP_NOP, .access = PL1_W }, @@ -3605,6 +3734,25 @@ static const ARMCPRegInfo el2_cp_reginfo[] = { { .name = "HTTBR", .cp = 15, .opc1 = 4, .crm = 2, .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS, .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[2]) }, + { .name = "TLBIALLH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbiall_hyp_write }, + { .name = "TLBIALLHIS", .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 0, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbiall_hyp_is_write }, + { .name = "TLBIMVAH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 1, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbimva_hyp_write }, + { .name = "TLBIMVAHIS", .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 1, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbimva_hyp_is_write }, + { .name = "TLBIMVALH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 5, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbimva_hyp_write }, + { .name = "TLBIMVALHIS", + .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 5, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbimva_hyp_is_write }, { .name = "TLBI_ALLE2", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0, .type = ARM_CP_NO_RAW, .access = PL2_W,
Some PL2 related TLBI system registers are missed in AArch32 implementation. The patch fixes it. Signed-off-by: Sergey Sorokin <afarallax@yandex.ru> --- target-arm/helper.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+)