[PATCH] KVM: ARM: call hyp_cpu_pm_exit at the right place

2019-12-01 Thread Shannon Zhao
It doesn't needs to call hyp_cpu_pm_exit() in init_hyp_mode() when some
error occurs. hyp_cpu_pm_exit() only needs to be called in
kvm_arch_init() if init_subsystems() fails. So move hyp_cpu_pm_exit()
out from teardown_hyp_mode() and call it directly in kvm_arch_init().

Signed-off-by: Shannon Zhao 
---
 virt/kvm/arm/arm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
index 12e0280..3b13ade 100644
--- a/virt/kvm/arm/arm.c
+++ b/virt/kvm/arm/arm.c
@@ -1537,7 +1537,6 @@ static void teardown_hyp_mode(void)
free_hyp_pgds();
for_each_possible_cpu(cpu)
free_page(per_cpu(kvm_arm_hyp_stack_page, cpu));
-   hyp_cpu_pm_exit();
 }
 
 /**
@@ -1751,6 +1750,7 @@ int kvm_arch_init(void *opaque)
return 0;
 
 out_hyp:
+   hyp_cpu_pm_exit();
if (!in_hyp_mode)
teardown_hyp_mode();
 out_err:
-- 
1.8.3.1

___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


[PATCH v2 5/5] target/arm: Add support for missing Jazelle system registers

2019-12-01 Thread Marc Zyngier
QEMU lacks the minimum Jazelle implementation that is required
by the architecture (everything is RAZ or RAZ/WI). Add it
together with the HCR_EL2.TID0 trapping that goes with it.

Signed-off-by: Marc Zyngier 
---
 target/arm/helper.c | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 0ba08d550a..d6fc198a97 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -6040,6 +6040,16 @@ static CPAccessResult access_aa32_tid3(CPUARMState *env, 
const ARMCPRegInfo *ri,
 return CP_ACCESS_OK;
 }
 
+static CPAccessResult access_jazelle(CPUARMState *env, const ARMCPRegInfo *ri,
+ bool isread)
+{
+if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TID0)) {
+return CP_ACCESS_TRAP_EL2;
+}
+
+return CP_ACCESS_OK;
+}
+
 void register_cp_regs_for_features(ARMCPU *cpu)
 {
 /* Register all the coprocessor registers based on feature bits */
@@ -6057,6 +6067,23 @@ void register_cp_regs_for_features(ARMCPU *cpu)
 define_arm_cp_regs(cpu, not_v8_cp_reginfo);
 }
 
+if (cpu_isar_feature(jazelle, cpu)) {
+ARMCPRegInfo jazelle_regs[] = {
+{ .name = "JIDR",
+  .cp = 14, .crn = 0, .crm = 0, .opc1 = 7, .opc2 = 0,
+  .access = PL1_R, .accessfn = access_jazelle,
+  .type = ARM_CP_CONST, .resetvalue = 0 },
+{ .name = "JOSCR",
+  .cp = 14, .crn = 1, .crm = 0, .opc1 = 7, .opc2 = 0,
+  .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
+{ .name = "JMCR",
+  .cp = 14, .crn = 2, .crm = 0, .opc1 = 7, .opc2 = 0,
+  .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
+REGINFO_SENTINEL
+};
+
+define_arm_cp_regs(cpu, jazelle_regs);
+}
 if (arm_feature(env, ARM_FEATURE_V6)) {
 /* The ID registers all have impdef reset values */
 ARMCPRegInfo v6_idregs[] = {
-- 
2.20.1

___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


[PATCH v2 0/5] target/arm: More EL2 trapping fixes

2019-12-01 Thread Marc Zyngier
Hi all,

This series is a follow-up on [1], which tried to address the
remaining missing HCR_EL2.TIDx traps. I've hopefully now adressed the
comments that Peter and Edgar raised.

I've also tried to tackle missing traps generated by HSTR_EL2, which
got completely ignored so far. Note that this results in the use of a
new TB bit, which I understand is a rare resource. I'd welcome
comments on how to handle it differently if at all possible.

Finally, and as a bonus non-feature, I've added support for the
missing Jazelle registers, giving me the opportunity to allow trapping
of JIDR to EL2 using HCR_EL2.TID0. Yay, Christmas! ;-)

I'm now going back to kernel stuff. I swear!

[1] https://patchew.org/QEMU/20191128161718.24361-1-...@kernel.org/

Marc Zyngier (5):
  target/arm: Honor HCR_EL2.TID2 trapping requirements
  target/arm: Honor HCR_EL2.TID1 trapping requirements
  target/arm: Handle trapping to EL2 of AArch32 VMRS instructions
  target/arm: Handle AArch32 CP15 trapping via HSTR_EL2
  target/arm: Add support for missing Jazelle system registers

 target/arm/cpu.h   |   2 +
 target/arm/helper-a64.h|   2 +
 target/arm/helper.c| 100 ++---
 target/arm/op_helper.c |  21 +++
 target/arm/translate-vfp.inc.c |  18 +-
 target/arm/translate.c |   3 +-
 target/arm/translate.h |   2 +
 target/arm/vfp_helper.c|  29 ++
 8 files changed, 165 insertions(+), 12 deletions(-)

-- 
2.20.1

___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


[PATCH v2 4/5] target/arm: Handle AArch32 CP15 trapping via HSTR_EL2

2019-12-01 Thread Marc Zyngier
HSTR_EL2 offers a way to trap ranges of CP15 system register
accesses to EL2, and it looks like this register is completely
ignored by QEMU.

To avoid adding extra .accessfn filters all over the place (which
would have a direct performance impact), let's add a new TB flag
that gets set whenever HSTR_EL2 is non-zero and that QEMU translates
a context where this trap has a chance to apply, and only generate
the extra access check if the hypervisor is actively using this feature.

Tested with a hand-crafted KVM guest accessing CBAR.

Signed-off-by: Marc Zyngier 
---
 target/arm/cpu.h   |  2 ++
 target/arm/helper.c|  6 ++
 target/arm/op_helper.c | 21 +
 target/arm/translate.c |  3 ++-
 target/arm/translate.h |  2 ++
 5 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 83a809d4ba..cebb3511a5 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3215,6 +3215,8 @@ FIELD(TBFLAG_A32, NS, 6, 1)
 FIELD(TBFLAG_A32, VFPEN, 7, 1)  /* Partially cached, minus FPEXC. */
 FIELD(TBFLAG_A32, CONDEXEC, 8, 8)   /* Not cached. */
 FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
+FIELD(TBFLAG_A32, HSTR_ACTIVE, 17, 1)
+
 /* For M profile only, set if FPCCR.LSPACT is set */
 FIELD(TBFLAG_A32, LSPACT, 18, 1)/* Not cached. */
 /* For M profile only, set if we must create a new FP context */
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 93ecab27c0..0ba08d550a 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11283,6 +11283,12 @@ static uint32_t rebuild_hflags_a32(CPUARMState *env, 
int fp_el,
 if (arm_el_is_aa64(env, 1)) {
 flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
 }
+
+if (arm_current_el(env) < 2 && env->cp15.hstr_el2 &&
+(arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
+flags = FIELD_DP32(flags, TBFLAG_A32, HSTR_ACTIVE, 1);
+}
+
 return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
 }
 
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
index b529d6c1bf..681c5f3681 100644
--- a/target/arm/op_helper.c
+++ b/target/arm/op_helper.c
@@ -603,6 +603,26 @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void 
*rip, uint32_t syndrome,
 raise_exception(env, EXCP_UDEF, syndrome, exception_target_el(env));
 }
 
+/* Check for an EL2 trap due to HSTR_EL2. We expect EL0 accesses
+ * to sysregs non accessible at EL0 to have UNDEF-ed already.
+ */
+if (!env->aarch64 && arm_current_el(env) < 2 && ri->cp == 15 &&
+(arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
+uint32_t mask = 1 << ri->crn;
+
+if (ri->type & ARM_CP_64BIT) {
+mask = 1 << ri->crm;
+}
+
+/* T4 and T14 are RES0 */
+mask &= ~((1 << 4) | (1 << 14));
+
+if (env->cp15.hstr_el2 & mask) {
+target_el = 2;
+goto exept;
+}
+}
+
 if (!ri->accessfn) {
 return;
 }
@@ -652,6 +672,7 @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void 
*rip, uint32_t syndrome,
 g_assert_not_reached();
 }
 
+exept:
 raise_exception(env, EXCP_UDEF, syndrome, target_el);
 }
 
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 4d5d4bd888..f162be8434 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -6897,7 +6897,7 @@ static int disas_coproc_insn(DisasContext *s, uint32_t 
insn)
 return 1;
 }
 
-if (ri->accessfn ||
+if (s->hstr_active || ri->accessfn ||
 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
 /* Emit code to perform further access permissions checks at
  * runtime; this may result in an exception.
@@ -10843,6 +10843,7 @@ static void arm_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cs)
!arm_el_is_aa64(env, 3);
 dc->thumb = FIELD_EX32(tb_flags, TBFLAG_A32, THUMB);
 dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR_B);
+dc->hstr_active = FIELD_EX32(tb_flags, TBFLAG_A32, HSTR_ACTIVE);
 dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
 condexec = FIELD_EX32(tb_flags, TBFLAG_A32, CONDEXEC);
 dc->condexec_mask = (condexec & 0xf) << 1;
diff --git a/target/arm/translate.h b/target/arm/translate.h
index dd24f91f26..b837b7fcbf 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -77,6 +77,8 @@ typedef struct DisasContext {
 bool pauth_active;
 /* True with v8.5-BTI and SCTLR_ELx.BT* set.  */
 bool bt;
+/* True if any CP15 access is trapped by HSTR_EL2 */
+bool hstr_active;
 /*
  * >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
  *  < 0, set by the current instruction.
-- 
2.20.1

___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm