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:
commit
e750c10167
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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:
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user