target-arm queue:

* virt: Diagnose attempts to enable MTE or virt when using HVF accelerator
  * GICv3 ITS: Allow clearing of ITS CTLR Enabled bit
  * GICv3: Update cached state after LPI state changes
  * GICv3: Fix handling of LPIs in list registers
 -----BEGIN PGP SIGNATURE-----
 
 iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmGkrMYZHHBldGVyLm1h
 eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3jFCD/9QHZGiKLBkcJx1PNKqtpLh
 OIg3xheECzLT6KVQMQGxYwxo5oeKApjmny5F+/LsuP5y9PxgiFgxeh1OnEj8Z4gZ
 r6CIqWw9+Gpyye9tUCfB7SqAJvGTDKyfxJg8PVILT/+LTDPjubZ0QCQH67ktCI5+
 oYA44QlTS2z3+oPCPmrj5d09h3u1V62vSJzGF1agQKUUZ2YFN3KYJwAjPr/utvkC
 0lBx/qM/kwWGP0JRUvD+fzR+wie6ebMub5TlTr1UtUxNiju53ITPYf6rLdj8KNS7
 rfGToIJxz7o2RjRyy3sLBEn/YzLnKlS61BXf9wEdDNtKiiMkvXCkzILGCFkydmvW
 qdo2NSOXAsk8F1qwo0Ca3YGuRMy9jCPlE3FSEz7F6OL2cp5VgpjK54yJVlPG4vaT
 xqAJ7JhHu64r9jDfdM1MWvaUPQ5Aggk3QL8HKhEFb4RwKg+VGsh2kz7LC51whfw7
 ocEq5YVGuy59ERD3MFsDS/KK2UvLUB0bXgOtAi/wbjpr8QYRgGZAticOoj5zHeOe
 dvAEfbzecGfB5frOvB4K1Xw9PsJrPT1IgK9T/G67E6gpmd6WS5hh3YXrGrHgYHrX
 fZ/KOBM1390NuaZ5tIgPZsSJAyJJIPt/tFrRic0XV/6m7svpwPfSNQZ+eJPdW3m+
 qa9XLvxR6P3bU+2OkeKXfA==
 =/KcE
 -----END PGP SIGNATURE-----

Merge tag 'pull-target-arm-20211129' of https://git.linaro.org/people/pmaydell/qemu-arm into staging

target-arm queue:
 * virt: Diagnose attempts to enable MTE or virt when using HVF accelerator
 * GICv3 ITS: Allow clearing of ITS CTLR Enabled bit
 * GICv3: Update cached state after LPI state changes
 * GICv3: Fix handling of LPIs in list registers

# gpg: Signature made Mon 29 Nov 2021 11:34:46 AM CET
# 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]

* tag 'pull-target-arm-20211129' of https://git.linaro.org/people/pmaydell/qemu-arm:
  hw/intc/arm_gicv3: fix handling of LPIs in list registers
  hw/intc/arm_gicv3: Add new gicv3_intid_is_special() function
  hw/intc/arm_gicv3: Update cached state after LPI state changes
  hw/intc: cannot clear GICv3 ITS CTLR[Enabled] bit
  hw/arm/virt: Extend nested and mte checks to hvf

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2021-11-29 11:56:07 +01:00
commit e750c10167
6 changed files with 61 additions and 20 deletions

View File

@ -49,6 +49,7 @@
#include "sysemu/runstate.h" #include "sysemu/runstate.h"
#include "sysemu/tpm.h" #include "sysemu/tpm.h"
#include "sysemu/kvm.h" #include "sysemu/kvm.h"
#include "sysemu/hvf.h"
#include "hw/loader.h" #include "hw/loader.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "qemu/bitops.h" #include "qemu/bitops.h"
@ -1969,15 +1970,17 @@ static void machvirt_init(MachineState *machine)
exit(1); exit(1);
} }
if (vms->virt && kvm_enabled()) { if (vms->virt && (kvm_enabled() || hvf_enabled())) {
error_report("mach-virt: KVM does not support providing " error_report("mach-virt: %s does not support providing "
"Virtualization extensions to the guest CPU"); "Virtualization extensions to the guest CPU",
kvm_enabled() ? "KVM" : "HVF");
exit(1); exit(1);
} }
if (vms->mte && kvm_enabled()) { if (vms->mte && (kvm_enabled() || hvf_enabled())) {
error_report("mach-virt: KVM does not support providing " error_report("mach-virt: %s does not support providing "
"MTE to the guest CPU"); "MTE to the guest CPU",
kvm_enabled() ? "KVM" : "HVF");
exit(1); exit(1);
} }

View File

@ -186,7 +186,9 @@ static void gicv3_redist_update_noirqset(GICv3CPUState *cs)
* interrupt has reduced in priority and any other interrupt could * interrupt has reduced in priority and any other interrupt could
* now be the new best one). * now be the new best one).
*/ */
if (!seenbetter && cs->hppi.prio != 0xff && cs->hppi.irq < GIC_INTERNAL) { if (!seenbetter && cs->hppi.prio != 0xff &&
(cs->hppi.irq < GIC_INTERNAL ||
cs->hppi.irq >= GICV3_LPI_INTID_START)) {
gicv3_full_update_noirqset(cs->gic); gicv3_full_update_noirqset(cs->gic);
} }
} }
@ -354,7 +356,7 @@ static void arm_gicv3_post_load(GICv3State *s)
* pending interrupt, but don't set IRQ or FIQ lines. * pending interrupt, but don't set IRQ or FIQ lines.
*/ */
for (i = 0; i < s->num_cpu; i++) { for (i = 0; i < s->num_cpu; i++) {
gicv3_redist_update_lpi(&s->cpu[i]); gicv3_redist_update_lpi_only(&s->cpu[i]);
} }
gicv3_full_update_noirqset(s); gicv3_full_update_noirqset(s);
/* Repopulate the cache of GICv3CPUState pointers for target CPUs */ /* Repopulate the cache of GICv3CPUState pointers for target CPUs */

View File

@ -653,7 +653,7 @@ static uint64_t icv_iar_read(CPUARMState *env, const ARMCPRegInfo *ri)
if (thisgrp == grp && icv_hppi_can_preempt(cs, lr)) { if (thisgrp == grp && icv_hppi_can_preempt(cs, lr)) {
intid = ich_lr_vintid(lr); intid = ich_lr_vintid(lr);
if (intid < INTID_SECURE) { if (!gicv3_intid_is_special(intid)) {
icv_activate_irq(cs, idx, grp); icv_activate_irq(cs, idx, grp);
} else { } else {
/* Interrupt goes from Pending to Invalid */ /* Interrupt goes from Pending to Invalid */
@ -997,7 +997,7 @@ static uint64_t icc_iar0_read(CPUARMState *env, const ARMCPRegInfo *ri)
intid = icc_hppir0_value(cs, env); intid = icc_hppir0_value(cs, env);
} }
if (!(intid >= INTID_SECURE && intid <= INTID_SPURIOUS)) { if (!gicv3_intid_is_special(intid)) {
icc_activate_irq(cs, intid); icc_activate_irq(cs, intid);
} }
@ -1020,7 +1020,7 @@ static uint64_t icc_iar1_read(CPUARMState *env, const ARMCPRegInfo *ri)
intid = icc_hppir1_value(cs, env); intid = icc_hppir1_value(cs, env);
} }
if (!(intid >= INTID_SECURE && intid <= INTID_SPURIOUS)) { if (!gicv3_intid_is_special(intid)) {
icc_activate_irq(cs, intid); icc_activate_irq(cs, intid);
} }
@ -1265,8 +1265,7 @@ static void icv_eoir_write(CPUARMState *env, const ARMCPRegInfo *ri,
trace_gicv3_icv_eoir_write(ri->crm == 8 ? 0 : 1, trace_gicv3_icv_eoir_write(ri->crm == 8 ? 0 : 1,
gicv3_redist_affid(cs), value); gicv3_redist_affid(cs), value);
if (irq >= GICV3_MAXIRQ) { if (gicv3_intid_is_special(irq)) {
/* Also catches special interrupt numbers and LPIs */
return; return;
} }

View File

@ -896,13 +896,14 @@ static bool its_writel(GICv3ITSState *s, hwaddr offset,
switch (offset) { switch (offset) {
case GITS_CTLR: case GITS_CTLR:
s->ctlr |= (value & ~(s->ctlr)); if (value & R_GITS_CTLR_ENABLED_MASK) {
s->ctlr |= ITS_CTLR_ENABLED;
if (s->ctlr & ITS_CTLR_ENABLED) {
extract_table_params(s); extract_table_params(s);
extract_cmdq_params(s); extract_cmdq_params(s);
s->creadr = 0; s->creadr = 0;
process_cmdq(s); process_cmdq(s);
} else {
s->ctlr &= ~ITS_CTLR_ENABLED;
} }
break; break;
case GITS_CBASER: case GITS_CBASER:

View File

@ -256,9 +256,10 @@ static MemTxResult gicr_writel(GICv3CPUState *cs, hwaddr offset,
cs->gicr_ctlr |= GICR_CTLR_ENABLE_LPIS; cs->gicr_ctlr |= GICR_CTLR_ENABLE_LPIS;
/* Check for any pending interr in pending table */ /* Check for any pending interr in pending table */
gicv3_redist_update_lpi(cs); gicv3_redist_update_lpi(cs);
gicv3_redist_update(cs);
} else { } else {
cs->gicr_ctlr &= ~GICR_CTLR_ENABLE_LPIS; cs->gicr_ctlr &= ~GICR_CTLR_ENABLE_LPIS;
/* cs->hppi might have been an LPI; recalculate */
gicv3_redist_update(cs);
} }
} }
return MEMTX_OK; return MEMTX_OK;
@ -571,7 +572,7 @@ static void gicv3_redist_check_lpi_priority(GICv3CPUState *cs, int irq)
} }
} }
void gicv3_redist_update_lpi(GICv3CPUState *cs) void gicv3_redist_update_lpi_only(GICv3CPUState *cs)
{ {
/* /*
* This function scans the LPI pending table and for each pending * This function scans the LPI pending table and for each pending
@ -614,6 +615,12 @@ void gicv3_redist_update_lpi(GICv3CPUState *cs)
} }
} }
void gicv3_redist_update_lpi(GICv3CPUState *cs)
{
gicv3_redist_update_lpi_only(cs);
gicv3_redist_update(cs);
}
void gicv3_redist_lpi_pending(GICv3CPUState *cs, int irq, int level) void gicv3_redist_lpi_pending(GICv3CPUState *cs, int irq, int level)
{ {
/* /*
@ -651,6 +658,7 @@ void gicv3_redist_lpi_pending(GICv3CPUState *cs, int irq, int level)
*/ */
if (level) { if (level) {
gicv3_redist_check_lpi_priority(cs, irq); gicv3_redist_check_lpi_priority(cs, irq);
gicv3_redist_update(cs);
} else { } else {
if (irq == cs->hpplpi.irq) { if (irq == cs->hpplpi.irq) {
gicv3_redist_update_lpi(cs); gicv3_redist_update_lpi(cs);
@ -673,8 +681,6 @@ void gicv3_redist_process_lpi(GICv3CPUState *cs, int irq, int level)
/* set/clear the pending bit for this irq */ /* set/clear the pending bit for this irq */
gicv3_redist_lpi_pending(cs, irq, level); gicv3_redist_lpi_pending(cs, irq, level);
gicv3_redist_update(cs);
} }
void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level) void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level)

View File

@ -411,6 +411,19 @@ FIELD(MAPC, RDBASE, 16, 32)
/* Functions internal to the emulated GICv3 */ /* Functions internal to the emulated GICv3 */
/**
* gicv3_intid_is_special:
* @intid: interrupt ID
*
* Return true if @intid is a special interrupt ID (1020 to
* 1023 inclusive). This corresponds to the GIC spec pseudocode
* IsSpecial() function.
*/
static inline bool gicv3_intid_is_special(int intid)
{
return intid >= INTID_SECURE && intid <= INTID_SPURIOUS;
}
/** /**
* gicv3_redist_update: * gicv3_redist_update:
* @cs: GICv3CPUState for this redistributor * @cs: GICv3CPUState for this redistributor
@ -463,7 +476,24 @@ void gicv3_dist_set_irq(GICv3State *s, int irq, int level);
void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level); void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level);
void gicv3_redist_process_lpi(GICv3CPUState *cs, int irq, int level); void gicv3_redist_process_lpi(GICv3CPUState *cs, int irq, int level);
void gicv3_redist_lpi_pending(GICv3CPUState *cs, int irq, int level); void gicv3_redist_lpi_pending(GICv3CPUState *cs, int irq, int level);
/**
* gicv3_redist_update_lpi:
* @cs: GICv3CPUState
*
* Scan the LPI pending table and recalculate the highest priority
* pending LPI and also the overall highest priority pending interrupt.
*/
void gicv3_redist_update_lpi(GICv3CPUState *cs); void gicv3_redist_update_lpi(GICv3CPUState *cs);
/**
* gicv3_redist_update_lpi_only:
* @cs: GICv3CPUState
*
* Scan the LPI pending table and recalculate cs->hpplpi only,
* without calling gicv3_redist_update() to recalculate the overall
* highest priority pending interrupt. This should be called after
* an incoming migration has loaded new state.
*/
void gicv3_redist_update_lpi_only(GICv3CPUState *cs);
void gicv3_redist_send_sgi(GICv3CPUState *cs, int grp, int irq, bool ns); void gicv3_redist_send_sgi(GICv3CPUState *cs, int grp, int irq, bool ns);
void gicv3_init_cpuif(GICv3State *s); void gicv3_init_cpuif(GICv3State *s);