aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2024-07-30 22:25:37 +1000
committerRichard Henderson <richard.henderson@linaro.org>2024-07-30 22:25:37 +1000
commitda4f7b8561e69112171f52279d23b9014902a398 (patch)
treef35ac3cc6325ef874f7e1b5a6b6b782d37d9a923 /target
parentef009e4b4dc0421464008e6e303b892141ede579 (diff)
parent73188068d7ba40c8a37b4763db38bb1ce24ca07d (diff)
Merge tag 'pull-target-arm-20240730' of https://git.linaro.org/people/pmaydell/qemu-arm into staging
target-arm queue: * hw/char/bcm2835_aux: Fix assert when receive FIFO fills up * hw/arm/smmuv3: Assert input to oas2bits() is valid * target/arm/kvm: Set PMU for host only when available * target/arm/kvm: Do not silently remove PMU * hvf: arm: Properly disable PMU * hvf: arm: Do not advance PC when raising an exception * hw/misc/bcm2835_property: several minor bugfixes * target/arm: Don't assert for 128-bit tile accesses when SVL is 128 * target/arm: Fix UMOPA/UMOPS of 16-bit values * target/arm: Ignore SMCR_EL2.LEN and SVCR_EL2.LEN if EL2 is not enabled * system/physmem: Where we assume we have a RAM MR, assert it * sh4, i386, m68k, xtensa, tricore, arm: fix minor Coverity issues # -----BEGIN PGP SIGNATURE----- # # iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmaotMAZHHBldGVyLm1h # eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3rsAEACIzQDAMKWy8DlB8o4W+a/l # yqGijQ5e0JdAifEA2rsDbnaIs/kqDzVxBc0dgIXDxETe5LVZHB742q4vMbaSpSb2 # P8xuL0Q7NRpcIN4THPwLxW0wED+asaJc2TeyImPQRTRhLgk6yn+/4hpqQRkT0mxe # oxxN8bnx9RssqHZ6pQCv5HYNLex3a7dljXlbjWr4KpRRFSMls1cxPSphsK1aZ1xV # 3NXh/vgHcM0LquwxdF0uaPdPGQ1SyZb5KZ9khd0o4cpDivkns/hXQpyJ45nHsypK # kG/TbFQsXPorprWCqBDOXY9rCM6eBDuK89mClKA34EzukIFlSMfIgxfezCzNIXaU # o/cJCGpSzZnCdvZagEWDzkdryE3QFmmpBFRs8mcS3sb+/gm0O8YyMoCrdV87O3c5 # Y/NY1adOKTVf8FLlT3jR93k4pT6wiqIQND13fN3EbnUqfrGpocSyMD0VsYBj/gij # PHPBFHAwCEDKVZSq6SViXdkS15arqL2V2mnOogeY1v0jTj2YRG3FyjrPOatg6tF5 # 3MoUBjTAp9ENtYHAY6mCr2vAYw6l1xZTKUwkXiO/i8rc4XQQ+A3AHhQLtWdu2K5+ # dv1E7QKur5O6FDmJxB5s/vGppfnkSUD6EEvViNSCj+hX0U9SyT80e/KClMehgJqQ # +oME+fRoBHj1DUw4qasWsg== # =NNxN # -----END PGP SIGNATURE----- # gpg: Signature made Tue 30 Jul 2024 07:39:12 PM AEST # 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] * tag 'pull-target-arm-20240730' of https://git.linaro.org/people/pmaydell/qemu-arm: (21 commits) system/physmem: Where we assume we have a RAM MR, assert it target/sh4: Avoid shift into sign bit in update_itlb_use() target/i386: Remove dead assignment to ss in do_interrupt64() target/m68k: avoid shift into sign bit in dump_address_map() target/xtensa: Make use of 'segment' in pptlb helper less confusing target/tricore: Use unsigned types for bitops in helper_eq_b() target/arm: Ignore SMCR_EL2.LEN and SVCR_EL2.LEN if EL2 is not enabled target/arm: Avoid shifts by -1 in tszimm_shr() and tszimm_shl() target/arm: Fix UMOPA/UMOPS of 16-bit values target/arm: Don't assert for 128-bit tile accesses when SVL is 128 hw/misc/bcm2835_property: Reduce scope of variables in mbox push function hw/misc/bcm2835_property: Restrict scope of start_num, number, otp_row hw/misc/bcm2835_property: Avoid overflow in OTP access properties hw/misc/bcm2835_property: Fix handling of FRAMEBUFFER_SET_PALETTE hvf: arm: Do not advance PC when raising an exception hvf: arm: Properly disable PMU hvf: arm: Raise an exception for sysreg by default target/arm/kvm: Do not silently remove PMU target/arm/kvm: Set PMU for host only when available hw/arm/smmuv3: Assert input to oas2bits() is valid ... Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'target')
-rw-r--r--target/arm/helper.c2
-rw-r--r--target/arm/hvf/hvf.c302
-rw-r--r--target/arm/kvm.c7
-rw-r--r--target/arm/tcg/sme_helper.c8
-rw-r--r--target/arm/tcg/translate-sme.c10
-rw-r--r--target/arm/tcg/translate-sve.c18
-rw-r--r--target/i386/tcg/seg_helper.c5
-rw-r--r--target/m68k/helper.c7
-rw-r--r--target/sh4/helper.c2
-rw-r--r--target/tricore/op_helper.c4
-rw-r--r--target/xtensa/mmu_helper.c4
11 files changed, 195 insertions, 174 deletions
diff --git a/target/arm/helper.c b/target/arm/helper.c
index ce31957235..8fb4b474e8 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -7232,7 +7232,7 @@ uint32_t sve_vqm1_for_el_sm(CPUARMState *env, int el, bool sm)
if (el <= 1 && !el_is_in_host(env, el)) {
len = MIN(len, 0xf & (uint32_t)cr[1]);
}
- if (el <= 2 && arm_feature(env, ARM_FEATURE_EL2)) {
+ if (el <= 2 && arm_is_el2_enabled(env)) {
len = MIN(len, 0xf & (uint32_t)cr[2]);
}
if (arm_feature(env, ARM_FEATURE_EL3)) {
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
index eb090e67a2..c1496ad5be 100644
--- a/target/arm/hvf/hvf.c
+++ b/target/arm/hvf/hvf.c
@@ -1199,57 +1199,61 @@ static bool hvf_sysreg_read_cp(CPUState *cpu, uint32_t reg, uint64_t *val)
return false;
}
-static int hvf_sysreg_read(CPUState *cpu, uint32_t reg, uint32_t rt)
+static int hvf_sysreg_read(CPUState *cpu, uint32_t reg, uint64_t *val)
{
ARMCPU *arm_cpu = ARM_CPU(cpu);
CPUARMState *env = &arm_cpu->env;
- uint64_t val = 0;
+
+ if (arm_feature(env, ARM_FEATURE_PMU)) {
+ switch (reg) {
+ case SYSREG_PMCR_EL0:
+ *val = env->cp15.c9_pmcr;
+ return 0;
+ case SYSREG_PMCCNTR_EL0:
+ pmu_op_start(env);
+ *val = env->cp15.c15_ccnt;
+ pmu_op_finish(env);
+ return 0;
+ case SYSREG_PMCNTENCLR_EL0:
+ *val = env->cp15.c9_pmcnten;
+ return 0;
+ case SYSREG_PMOVSCLR_EL0:
+ *val = env->cp15.c9_pmovsr;
+ return 0;
+ case SYSREG_PMSELR_EL0:
+ *val = env->cp15.c9_pmselr;
+ return 0;
+ case SYSREG_PMINTENCLR_EL1:
+ *val = env->cp15.c9_pminten;
+ return 0;
+ case SYSREG_PMCCFILTR_EL0:
+ *val = env->cp15.pmccfiltr_el0;
+ return 0;
+ case SYSREG_PMCNTENSET_EL0:
+ *val = env->cp15.c9_pmcnten;
+ return 0;
+ case SYSREG_PMUSERENR_EL0:
+ *val = env->cp15.c9_pmuserenr;
+ return 0;
+ case SYSREG_PMCEID0_EL0:
+ case SYSREG_PMCEID1_EL0:
+ /* We can't really count anything yet, declare all events invalid */
+ *val = 0;
+ return 0;
+ }
+ }
switch (reg) {
case SYSREG_CNTPCT_EL0:
- val = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) /
+ *val = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) /
gt_cntfrq_period_ns(arm_cpu);
- break;
- case SYSREG_PMCR_EL0:
- val = env->cp15.c9_pmcr;
- break;
- case SYSREG_PMCCNTR_EL0:
- pmu_op_start(env);
- val = env->cp15.c15_ccnt;
- pmu_op_finish(env);
- break;
- case SYSREG_PMCNTENCLR_EL0:
- val = env->cp15.c9_pmcnten;
- break;
- case SYSREG_PMOVSCLR_EL0:
- val = env->cp15.c9_pmovsr;
- break;
- case SYSREG_PMSELR_EL0:
- val = env->cp15.c9_pmselr;
- break;
- case SYSREG_PMINTENCLR_EL1:
- val = env->cp15.c9_pminten;
- break;
- case SYSREG_PMCCFILTR_EL0:
- val = env->cp15.pmccfiltr_el0;
- break;
- case SYSREG_PMCNTENSET_EL0:
- val = env->cp15.c9_pmcnten;
- break;
- case SYSREG_PMUSERENR_EL0:
- val = env->cp15.c9_pmuserenr;
- break;
- case SYSREG_PMCEID0_EL0:
- case SYSREG_PMCEID1_EL0:
- /* We can't really count anything yet, declare all events invalid */
- val = 0;
- break;
+ return 0;
case SYSREG_OSLSR_EL1:
- val = env->cp15.oslsr_el1;
- break;
+ *val = env->cp15.oslsr_el1;
+ return 0;
case SYSREG_OSDLR_EL1:
/* Dummy register */
- break;
+ return 0;
case SYSREG_ICC_AP0R0_EL1:
case SYSREG_ICC_AP0R1_EL1:
case SYSREG_ICC_AP0R2_EL1:
@@ -1276,9 +1280,8 @@ static int hvf_sysreg_read(CPUState *cpu, uint32_t reg, uint32_t rt)
case SYSREG_ICC_SRE_EL1:
case SYSREG_ICC_CTLR_EL1:
/* Call the TCG sysreg handler. This is only safe for GICv3 regs. */
- if (!hvf_sysreg_read_cp(cpu, reg, &val)) {
- hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized());
- return 1;
+ if (hvf_sysreg_read_cp(cpu, reg, &val)) {
+ return 0;
}
break;
case SYSREG_DBGBVR0_EL1:
@@ -1297,8 +1300,8 @@ static int hvf_sysreg_read(CPUState *cpu, uint32_t reg, uint32_t rt)
case SYSREG_DBGBVR13_EL1:
case SYSREG_DBGBVR14_EL1:
case SYSREG_DBGBVR15_EL1:
- val = env->cp15.dbgbvr[SYSREG_CRM(reg)];
- break;
+ *val = env->cp15.dbgbvr[SYSREG_CRM(reg)];
+ return 0;
case SYSREG_DBGBCR0_EL1:
case SYSREG_DBGBCR1_EL1:
case SYSREG_DBGBCR2_EL1:
@@ -1315,8 +1318,8 @@ static int hvf_sysreg_read(CPUState *cpu, uint32_t reg, uint32_t rt)
case SYSREG_DBGBCR13_EL1:
case SYSREG_DBGBCR14_EL1:
case SYSREG_DBGBCR15_EL1:
- val = env->cp15.dbgbcr[SYSREG_CRM(reg)];
- break;
+ *val = env->cp15.dbgbcr[SYSREG_CRM(reg)];
+ return 0;
case SYSREG_DBGWVR0_EL1:
case SYSREG_DBGWVR1_EL1:
case SYSREG_DBGWVR2_EL1:
@@ -1333,8 +1336,8 @@ static int hvf_sysreg_read(CPUState *cpu, uint32_t reg, uint32_t rt)
case SYSREG_DBGWVR13_EL1:
case SYSREG_DBGWVR14_EL1:
case SYSREG_DBGWVR15_EL1:
- val = env->cp15.dbgwvr[SYSREG_CRM(reg)];
- break;
+ *val = env->cp15.dbgwvr[SYSREG_CRM(reg)];
+ return 0;
case SYSREG_DBGWCR0_EL1:
case SYSREG_DBGWCR1_EL1:
case SYSREG_DBGWCR2_EL1:
@@ -1351,35 +1354,25 @@ static int hvf_sysreg_read(CPUState *cpu, uint32_t reg, uint32_t rt)
case SYSREG_DBGWCR13_EL1:
case SYSREG_DBGWCR14_EL1:
case SYSREG_DBGWCR15_EL1:
- val = env->cp15.dbgwcr[SYSREG_CRM(reg)];
- break;
+ *val = env->cp15.dbgwcr[SYSREG_CRM(reg)];
+ return 0;
default:
if (is_id_sysreg(reg)) {
/* ID system registers read as RES0 */
- val = 0;
- break;
+ *val = 0;
+ return 0;
}
- cpu_synchronize_state(cpu);
- trace_hvf_unhandled_sysreg_read(env->pc, reg,
- SYSREG_OP0(reg),
- SYSREG_OP1(reg),
- SYSREG_CRN(reg),
- SYSREG_CRM(reg),
- SYSREG_OP2(reg));
- hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized());
- return 1;
}
- trace_hvf_sysreg_read(reg,
- SYSREG_OP0(reg),
- SYSREG_OP1(reg),
- SYSREG_CRN(reg),
- SYSREG_CRM(reg),
- SYSREG_OP2(reg),
- val);
- hvf_set_reg(cpu, rt, val);
-
- return 0;
+ cpu_synchronize_state(cpu);
+ trace_hvf_unhandled_sysreg_read(env->pc, reg,
+ SYSREG_OP0(reg),
+ SYSREG_OP1(reg),
+ SYSREG_CRN(reg),
+ SYSREG_CRM(reg),
+ SYSREG_OP2(reg));
+ hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized());
+ return 1;
}
static void pmu_update_irq(CPUARMState *env)
@@ -1498,70 +1491,75 @@ static int hvf_sysreg_write(CPUState *cpu, uint32_t reg, uint64_t val)
SYSREG_OP2(reg),
val);
- switch (reg) {
- case SYSREG_PMCCNTR_EL0:
- pmu_op_start(env);
- env->cp15.c15_ccnt = val;
- pmu_op_finish(env);
- break;
- case SYSREG_PMCR_EL0:
- pmu_op_start(env);
-
- if (val & PMCRC) {
- /* The counter has been reset */
- env->cp15.c15_ccnt = 0;
- }
+ if (arm_feature(env, ARM_FEATURE_PMU)) {
+ switch (reg) {
+ case SYSREG_PMCCNTR_EL0:
+ pmu_op_start(env);
+ env->cp15.c15_ccnt = val;
+ pmu_op_finish(env);
+ return 0;
+ case SYSREG_PMCR_EL0:
+ pmu_op_start(env);
+
+ if (val & PMCRC) {
+ /* The counter has been reset */
+ env->cp15.c15_ccnt = 0;
+ }
- if (val & PMCRP) {
- unsigned int i;
- for (i = 0; i < pmu_num_counters(env); i++) {
- env->cp15.c14_pmevcntr[i] = 0;
+ if (val & PMCRP) {
+ unsigned int i;
+ for (i = 0; i < pmu_num_counters(env); i++) {
+ env->cp15.c14_pmevcntr[i] = 0;
+ }
}
- }
- env->cp15.c9_pmcr &= ~PMCR_WRITABLE_MASK;
- env->cp15.c9_pmcr |= (val & PMCR_WRITABLE_MASK);
+ env->cp15.c9_pmcr &= ~PMCR_WRITABLE_MASK;
+ env->cp15.c9_pmcr |= (val & PMCR_WRITABLE_MASK);
+
+ pmu_op_finish(env);
+ return 0;
+ case SYSREG_PMUSERENR_EL0:
+ env->cp15.c9_pmuserenr = val & 0xf;
+ return 0;
+ case SYSREG_PMCNTENSET_EL0:
+ env->cp15.c9_pmcnten |= (val & pmu_counter_mask(env));
+ return 0;
+ case SYSREG_PMCNTENCLR_EL0:
+ env->cp15.c9_pmcnten &= ~(val & pmu_counter_mask(env));
+ return 0;
+ case SYSREG_PMINTENCLR_EL1:
+ pmu_op_start(env);
+ env->cp15.c9_pminten |= val;
+ pmu_op_finish(env);
+ return 0;
+ case SYSREG_PMOVSCLR_EL0:
+ pmu_op_start(env);
+ env->cp15.c9_pmovsr &= ~val;
+ pmu_op_finish(env);
+ return 0;
+ case SYSREG_PMSWINC_EL0:
+ pmu_op_start(env);
+ pmswinc_write(env, val);
+ pmu_op_finish(env);
+ return 0;
+ case SYSREG_PMSELR_EL0:
+ env->cp15.c9_pmselr = val & 0x1f;
+ return 0;
+ case SYSREG_PMCCFILTR_EL0:
+ pmu_op_start(env);
+ env->cp15.pmccfiltr_el0 = val & PMCCFILTR_EL0;
+ pmu_op_finish(env);
+ return 0;
+ }
+ }
- pmu_op_finish(env);
- break;
- case SYSREG_PMUSERENR_EL0:
- env->cp15.c9_pmuserenr = val & 0xf;
- break;
- case SYSREG_PMCNTENSET_EL0:
- env->cp15.c9_pmcnten |= (val & pmu_counter_mask(env));
- break;
- case SYSREG_PMCNTENCLR_EL0:
- env->cp15.c9_pmcnten &= ~(val & pmu_counter_mask(env));
- break;
- case SYSREG_PMINTENCLR_EL1:
- pmu_op_start(env);
- env->cp15.c9_pminten |= val;
- pmu_op_finish(env);
- break;
- case SYSREG_PMOVSCLR_EL0:
- pmu_op_start(env);
- env->cp15.c9_pmovsr &= ~val;
- pmu_op_finish(env);
- break;
- case SYSREG_PMSWINC_EL0:
- pmu_op_start(env);
- pmswinc_write(env, val);
- pmu_op_finish(env);
- break;
- case SYSREG_PMSELR_EL0:
- env->cp15.c9_pmselr = val & 0x1f;
- break;
- case SYSREG_PMCCFILTR_EL0:
- pmu_op_start(env);
- env->cp15.pmccfiltr_el0 = val & PMCCFILTR_EL0;
- pmu_op_finish(env);
- break;
+ switch (reg) {
case SYSREG_OSLAR_EL1:
env->cp15.oslsr_el1 = val & 1;
- break;
+ return 0;
case SYSREG_OSDLR_EL1:
/* Dummy register */
- break;
+ return 0;
case SYSREG_ICC_AP0R0_EL1:
case SYSREG_ICC_AP0R1_EL1:
case SYSREG_ICC_AP0R2_EL1:
@@ -1588,13 +1586,13 @@ static int hvf_sysreg_write(CPUState *cpu, uint32_t reg, uint64_t val)
case SYSREG_ICC_SGI1R_EL1:
case SYSREG_ICC_SRE_EL1:
/* Call the TCG sysreg handler. This is only safe for GICv3 regs. */
- if (!hvf_sysreg_write_cp(cpu, reg, val)) {
- hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized());
+ if (hvf_sysreg_write_cp(cpu, reg, val)) {
+ return 0;
}
break;
case SYSREG_MDSCR_EL1:
env->cp15.mdscr_el1 = val;
- break;
+ return 0;
case SYSREG_DBGBVR0_EL1:
case SYSREG_DBGBVR1_EL1:
case SYSREG_DBGBVR2_EL1:
@@ -1612,7 +1610,7 @@ static int hvf_sysreg_write(CPUState *cpu, uint32_t reg, uint64_t val)
case SYSREG_DBGBVR14_EL1:
case SYSREG_DBGBVR15_EL1:
env->cp15.dbgbvr[SYSREG_CRM(reg)] = val;
- break;
+ return 0;
case SYSREG_DBGBCR0_EL1:
case SYSREG_DBGBCR1_EL1:
case SYSREG_DBGBCR2_EL1:
@@ -1630,7 +1628,7 @@ static int hvf_sysreg_write(CPUState *cpu, uint32_t reg, uint64_t val)
case SYSREG_DBGBCR14_EL1:
case SYSREG_DBGBCR15_EL1:
env->cp15.dbgbcr[SYSREG_CRM(reg)] = val;
- break;
+ return 0;
case SYSREG_DBGWVR0_EL1:
case SYSREG_DBGWVR1_EL1:
case SYSREG_DBGWVR2_EL1:
@@ -1648,7 +1646,7 @@ static int hvf_sysreg_write(CPUState *cpu, uint32_t reg, uint64_t val)
case SYSREG_DBGWVR14_EL1:
case SYSREG_DBGWVR15_EL1:
env->cp15.dbgwvr[SYSREG_CRM(reg)] = val;
- break;
+ return 0;
case SYSREG_DBGWCR0_EL1:
case SYSREG_DBGWCR1_EL1:
case SYSREG_DBGWCR2_EL1:
@@ -1666,20 +1664,18 @@ static int hvf_sysreg_write(CPUState *cpu, uint32_t reg, uint64_t val)
case SYSREG_DBGWCR14_EL1:
case SYSREG_DBGWCR15_EL1:
env->cp15.dbgwcr[SYSREG_CRM(reg)] = val;
- break;
- default:
- cpu_synchronize_state(cpu);
- trace_hvf_unhandled_sysreg_write(env->pc, reg,
- SYSREG_OP0(reg),
- SYSREG_OP1(reg),
- SYSREG_CRN(reg),
- SYSREG_CRM(reg),
- SYSREG_OP2(reg));
- hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized());
- return 1;
+ return 0;
}
- return 0;
+ cpu_synchronize_state(cpu);
+ trace_hvf_unhandled_sysreg_write(env->pc, reg,
+ SYSREG_OP0(reg),
+ SYSREG_OP1(reg),
+ SYSREG_CRN(reg),
+ SYSREG_CRM(reg),
+ SYSREG_OP2(reg));
+ hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized());
+ return 1;
}
static int hvf_inject_interrupts(CPUState *cpu)
@@ -1944,7 +1940,17 @@ int hvf_vcpu_exec(CPUState *cpu)
int sysreg_ret = 0;
if (isread) {
- sysreg_ret = hvf_sysreg_read(cpu, reg, rt);
+ sysreg_ret = hvf_sysreg_read(cpu, reg, &val);
+ if (!sysreg_ret) {
+ trace_hvf_sysreg_read(reg,
+ SYSREG_OP0(reg),
+ SYSREG_OP1(reg),
+ SYSREG_CRN(reg),
+ SYSREG_CRM(reg),
+ SYSREG_OP2(reg),
+ val);
+ hvf_set_reg(cpu, rt, val);
+ }
} else {
val = hvf_get_reg(cpu, rt);
sysreg_ret = hvf_sysreg_write(cpu, reg, val);
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 70f79eda33..849e2e21b3 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -280,6 +280,7 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
if (kvm_arm_pmu_supported()) {
init.features[0] |= 1 << KVM_ARM_VCPU_PMU_V3;
pmu_supported = true;
+ features |= 1ULL << ARM_FEATURE_PMU;
}
if (!kvm_arm_create_scratch_host_vcpu(cpus_to_try, fdarray, &init)) {
@@ -448,7 +449,6 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
features |= 1ULL << ARM_FEATURE_V8;
features |= 1ULL << ARM_FEATURE_NEON;
features |= 1ULL << ARM_FEATURE_AARCH64;
- features |= 1ULL << ARM_FEATURE_PMU;
features |= 1ULL << ARM_FEATURE_GENERIC_TIMER;
ahcf->features = features;
@@ -1888,13 +1888,8 @@ int kvm_arch_init_vcpu(CPUState *cs)
if (!arm_feature(env, ARM_FEATURE_AARCH64)) {
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_EL1_32BIT;
}
- if (!kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PMU_V3)) {
- cpu->has_pmu = false;
- }
if (cpu->has_pmu) {
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_PMU_V3;
- } else {
- env->features &= ~(1ULL << ARM_FEATURE_PMU);
}
if (cpu_isar_feature(aa64_sve, cpu)) {
assert(kvm_arm_sve_supported());
diff --git a/target/arm/tcg/sme_helper.c b/target/arm/tcg/sme_helper.c
index 50bb088d04..3ba826a6ce 100644
--- a/target/arm/tcg/sme_helper.c
+++ b/target/arm/tcg/sme_helper.c
@@ -1162,10 +1162,10 @@ static uint64_t NAME(uint64_t n, uint64_t m, uint64_t a, uint8_t p, bool neg) \
uint64_t sum = 0; \
/* Apply P to N as a mask, making the inactive elements 0. */ \
n &= expand_pred_h(p); \
- sum += (NTYPE)(n >> 0) * (MTYPE)(m >> 0); \
- sum += (NTYPE)(n >> 16) * (MTYPE)(m >> 16); \
- sum += (NTYPE)(n >> 32) * (MTYPE)(m >> 32); \
- sum += (NTYPE)(n >> 48) * (MTYPE)(m >> 48); \
+ sum += (int64_t)(NTYPE)(n >> 0) * (MTYPE)(m >> 0); \
+ sum += (int64_t)(NTYPE)(n >> 16) * (MTYPE)(m >> 16); \
+ sum += (int64_t)(NTYPE)(n >> 32) * (MTYPE)(m >> 32); \
+ sum += (int64_t)(NTYPE)(n >> 48) * (MTYPE)(m >> 48); \
return neg ? a - sum : a + sum; \
}
diff --git a/target/arm/tcg/translate-sme.c b/target/arm/tcg/translate-sme.c
index 185a8a917b..a50a419af2 100644
--- a/target/arm/tcg/translate-sme.c
+++ b/target/arm/tcg/translate-sme.c
@@ -49,7 +49,15 @@ static TCGv_ptr get_tile_rowcol(DisasContext *s, int esz, int rs,
/* Prepare a power-of-two modulo via extraction of @len bits. */
len = ctz32(streaming_vec_reg_size(s)) - esz;
- if (vertical) {
+ if (!len) {
+ /*
+ * SVL is 128 and the element size is 128. There is exactly
+ * one 128x128 tile in the ZA storage, and so we calculate
+ * (Rs + imm) MOD 1, which is always 0. We need to special case
+ * this because TCG doesn't allow deposit ops with len 0.
+ */
+ tcg_gen_movi_i32(tmp, 0);
+ } else if (vertical) {
/*
* Compute the byte offset of the index within the tile:
* (index % (svl / size)) * size
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
index 798ab2bfb1..a72c262096 100644
--- a/target/arm/tcg/translate-sve.c
+++ b/target/arm/tcg/translate-sve.c
@@ -50,13 +50,27 @@ static int tszimm_esz(DisasContext *s, int x)
static int tszimm_shr(DisasContext *s, int x)
{
- return (16 << tszimm_esz(s, x)) - x;
+ /*
+ * We won't use the tszimm_shr() value if tszimm_esz() returns -1 (the
+ * trans function will check for esz < 0), so we can return any
+ * value we like from here in that case as long as we avoid UB.
+ */
+ int esz = tszimm_esz(s, x);
+ if (esz < 0) {
+ return esz;
+ }
+ return (16 << esz) - x;
}
/* See e.g. LSL (immediate, predicated). */
static int tszimm_shl(DisasContext *s, int x)
{
- return x - (8 << tszimm_esz(s, x));
+ /* As with tszimm_shr(), value will be unused if esz < 0 */
+ int esz = tszimm_esz(s, x);
+ if (esz < 0) {
+ return esz;
+ }
+ return x - (8 << esz);
}
/* The SH bit is in bit 8. Extract the low 8 and shift. */
diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c
index aac092a356..bab552cd53 100644
--- a/target/i386/tcg/seg_helper.c
+++ b/target/i386/tcg/seg_helper.c
@@ -926,7 +926,7 @@ static void do_interrupt64(CPUX86State *env, int intno, int is_int,
target_ulong ptr;
int type, dpl, selector, cpl, ist;
int has_error_code, new_stack;
- uint32_t e1, e2, e3, ss, eflags;
+ uint32_t e1, e2, e3, eflags;
target_ulong old_eip, offset;
bool set_rf;
StackAccess sa;
@@ -1007,7 +1007,6 @@ static void do_interrupt64(CPUX86State *env, int intno, int is_int,
/* to inner privilege */
new_stack = 1;
sa.sp = get_rsp_from_tss(env, ist != 0 ? ist + 3 : dpl);
- ss = 0;
} else {
/* to same privilege */
if (env->eflags & VM_MASK) {
@@ -1040,7 +1039,7 @@ static void do_interrupt64(CPUX86State *env, int intno, int is_int,
env->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK);
if (new_stack) {
- ss = 0 | dpl;
+ uint32_t ss = 0 | dpl; /* SS = NULL selector with RPL = new CPL */
cpu_x86_load_seg_cache(env, R_SS, ss, 0, 0, dpl << DESC_DPL_SHIFT);
}
env->regs[R_ESP] = sa.sp;
diff --git a/target/m68k/helper.c b/target/m68k/helper.c
index 7967ad13cb..4c85badd5d 100644
--- a/target/m68k/helper.c
+++ b/target/m68k/helper.c
@@ -479,7 +479,6 @@ static void print_address_zone(uint32_t logical, uint32_t physical,
static void dump_address_map(CPUM68KState *env, uint32_t root_pointer)
{
- int i, j, k;
int tic_size, tic_shift;
uint32_t tib_mask;
uint32_t tia, tib, tic;
@@ -502,19 +501,19 @@ static void dump_address_map(CPUM68KState *env, uint32_t root_pointer)
tic_shift = 12;
tib_mask = M68K_4K_PAGE_MASK;
}
- for (i = 0; i < M68K_ROOT_POINTER_ENTRIES; i++) {
+ for (unsigned i = 0; i < M68K_ROOT_POINTER_ENTRIES; i++) {
tia = address_space_ldl(cs->as, M68K_POINTER_BASE(root_pointer) + i * 4,
MEMTXATTRS_UNSPECIFIED, &txres);
if (txres != MEMTX_OK || !M68K_UDT_VALID(tia)) {
continue;
}
- for (j = 0; j < M68K_ROOT_POINTER_ENTRIES; j++) {
+ for (unsigned j = 0; j < M68K_ROOT_POINTER_ENTRIES; j++) {
tib = address_space_ldl(cs->as, M68K_POINTER_BASE(tia) + j * 4,
MEMTXATTRS_UNSPECIFIED, &txres);
if (txres != MEMTX_OK || !M68K_UDT_VALID(tib)) {
continue;
}
- for (k = 0; k < tic_size; k++) {
+ for (unsigned k = 0; k < tic_size; k++) {
tic = address_space_ldl(cs->as, (tib & tib_mask) + k * 4,
MEMTXATTRS_UNSPECIFIED, &txres);
if (txres != MEMTX_OK || !M68K_PDT_VALID(tic)) {
diff --git a/target/sh4/helper.c b/target/sh4/helper.c
index 6702910627..9659c69550 100644
--- a/target/sh4/helper.c
+++ b/target/sh4/helper.c
@@ -187,7 +187,7 @@ void superh_cpu_do_interrupt(CPUState *cs)
static void update_itlb_use(CPUSH4State * env, int itlbnb)
{
- uint8_t or_mask = 0, and_mask = (uint8_t) - 1;
+ uint32_t or_mask = 0, and_mask = 0xff;
switch (itlbnb) {
case 0:
diff --git a/target/tricore/op_helper.c b/target/tricore/op_helper.c
index ba9c4444b3..a0d5a0da1d 100644
--- a/target/tricore/op_helper.c
+++ b/target/tricore/op_helper.c
@@ -1505,8 +1505,8 @@ uint32_t helper_sub_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
uint32_t helper_eq_b(target_ulong r1, target_ulong r2)
{
- int32_t ret;
- int32_t i, msk;
+ uint32_t ret, msk;
+ int32_t i;
ret = 0;
msk = 0xff;
diff --git a/target/xtensa/mmu_helper.c b/target/xtensa/mmu_helper.c
index 997b21d389..29b84d5dbf 100644
--- a/target/xtensa/mmu_helper.c
+++ b/target/xtensa/mmu_helper.c
@@ -991,7 +991,7 @@ uint32_t HELPER(rptlb1)(CPUXtensaState *env, uint32_t s)
uint32_t HELPER(pptlb)(CPUXtensaState *env, uint32_t v)
{
unsigned nhits;
- unsigned segment = XTENSA_MPU_PROBE_B;
+ unsigned segment;
unsigned bg_segment;
nhits = xtensa_mpu_lookup(env->mpu_fg, env->config->n_mpu_fg_segments,
@@ -1005,7 +1005,7 @@ uint32_t HELPER(pptlb)(CPUXtensaState *env, uint32_t v)
xtensa_mpu_lookup(env->config->mpu_bg,
env->config->n_mpu_bg_segments,
v, &bg_segment);
- return env->config->mpu_bg[bg_segment].attr | segment;
+ return env->config->mpu_bg[bg_segment].attr | XTENSA_MPU_PROBE_B;
}
}