/* PPI state tracking for GICv5-based guests */
struct {
- /*
- * For tracking the PPI pending state, we need both the entry
- * state and exit state to correctly detect edges as it is
- * possible that an interrupt has been injected in software in
- * the interim.
- */
- DECLARE_BITMAP(pendr_entry, VGIC_V5_NR_PRIVATE_IRQS);
- DECLARE_BITMAP(pendr_exit, VGIC_V5_NR_PRIVATE_IRQS);
+ DECLARE_BITMAP(pendr, VGIC_V5_NR_PRIVATE_IRQS);
/* The saved state of the regs when leaving the guest */
DECLARE_BITMAP(activer_exit, VGIC_V5_NR_PRIVATE_IRQS);
bitmap_write(host_data_ptr(vgic_v5_ppi_state)->activer_exit,
read_sysreg_s(SYS_ICH_PPI_ACTIVER0_EL2), 0, 64);
- bitmap_write(host_data_ptr(vgic_v5_ppi_state)->pendr_exit,
+ bitmap_write(host_data_ptr(vgic_v5_ppi_state)->pendr,
read_sysreg_s(SYS_ICH_PPI_PENDR0_EL2), 0, 64);
cpu_if->vgic_ppi_priorityr[0] = read_sysreg_s(SYS_ICH_PPI_PRIORITYR0_EL2);
if (VGIC_V5_NR_PRIVATE_IRQS == 128) {
bitmap_write(host_data_ptr(vgic_v5_ppi_state)->activer_exit,
read_sysreg_s(SYS_ICH_PPI_ACTIVER1_EL2), 64, 64);
- bitmap_write(host_data_ptr(vgic_v5_ppi_state)->pendr_exit,
+ bitmap_write(host_data_ptr(vgic_v5_ppi_state)->pendr,
read_sysreg_s(SYS_ICH_PPI_PENDR1_EL2), 64, 64);
cpu_if->vgic_ppi_priorityr[8] = read_sysreg_s(SYS_ICH_PPI_PRIORITYR8_EL2);
SYS_ICH_PPI_ENABLER0_EL2);
/* Update the pending state of the NON-DVI'd PPIs, only */
- bitmap_andnot(pendr, host_data_ptr(vgic_v5_ppi_state)->pendr_entry,
+ bitmap_andnot(pendr, host_data_ptr(vgic_v5_ppi_state)->pendr,
cpu_if->vgic_ppi_dvir, VGIC_V5_NR_PRIVATE_IRQS);
write_sysreg_s(bitmap_read(pendr, 0, 64), SYS_ICH_PPI_PENDR0_EL2);
void vgic_v5_fold_ppi_state(struct kvm_vcpu *vcpu)
{
struct vgic_v5_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v5;
- DECLARE_BITMAP(changed_active, VGIC_V5_NR_PRIVATE_IRQS);
- DECLARE_BITMAP(changed_pending, VGIC_V5_NR_PRIVATE_IRQS);
- DECLARE_BITMAP(changed_bits, VGIC_V5_NR_PRIVATE_IRQS);
- unsigned long *activer, *pendr_entry, *pendr;
+ unsigned long *activer, *pendr;
int i;
activer = host_data_ptr(vgic_v5_ppi_state)->activer_exit;
- pendr_entry = host_data_ptr(vgic_v5_ppi_state)->pendr_entry;
- pendr = host_data_ptr(vgic_v5_ppi_state)->pendr_exit;
+ pendr = host_data_ptr(vgic_v5_ppi_state)->pendr;
- bitmap_xor(changed_active, cpu_if->vgic_ppi_activer, activer,
- VGIC_V5_NR_PRIVATE_IRQS);
- bitmap_xor(changed_pending, pendr_entry, pendr,
- VGIC_V5_NR_PRIVATE_IRQS);
- bitmap_or(changed_bits, changed_active, changed_pending,
- VGIC_V5_NR_PRIVATE_IRQS);
-
- for_each_set_bit(i, changed_bits, VGIC_V5_NR_PRIVATE_IRQS) {
+ for_each_set_bit(i, vcpu->kvm->arch.vgic.gicv5_vm.vgic_ppi_mask,
+ VGIC_V5_NR_PRIVATE_IRQS) {
u32 intid = vgic_v5_make_ppi(i);
struct vgic_irq *irq;
* incoming changes are merged with the outgoing changes on the return
* path.
*/
- bitmap_copy(host_data_ptr(vgic_v5_ppi_state)->pendr_entry, pendr,
- VGIC_V5_NR_PRIVATE_IRQS);
-
- /*
- * Make sure that we can correctly detect "edges" in the PPI
- * state. There's a path where we never actually enter the guest, and
- * failure to do this risks losing pending state
- */
- bitmap_copy(host_data_ptr(vgic_v5_ppi_state)->pendr_exit, pendr,
+ bitmap_copy(host_data_ptr(vgic_v5_ppi_state)->pendr, pendr,
VGIC_V5_NR_PRIVATE_IRQS);
}