Merge tag 'selinux-pr-20210629' of git://git.kernel.org/pub/scm/linux/kernel/git...
[sfrench/cifs-2.6.git] / include / kvm / arm_vgic.h
index ec621180ef094c24d9a87b169d6531dcdf066987..e602d848fc1ab7291fe04dc56745bc41e28b8b1c 100644 (file)
@@ -72,6 +72,9 @@ struct vgic_global {
        bool                    has_gicv4;
        bool                    has_gicv4_1;
 
+       /* Pseudo GICv3 from outer space */
+       bool                    no_hw_deactivation;
+
        /* GIC system register CPU interface */
        struct static_key_false gicv3_cpuif;
 
@@ -89,6 +92,26 @@ enum vgic_irq_config {
        VGIC_CONFIG_LEVEL
 };
 
+/*
+ * Per-irq ops overriding some common behavious.
+ *
+ * Always called in non-preemptible section and the functions can use
+ * kvm_arm_get_running_vcpu() to get the vcpu pointer for private IRQs.
+ */
+struct irq_ops {
+       /* Per interrupt flags for special-cased interrupts */
+       unsigned long flags;
+
+#define VGIC_IRQ_SW_RESAMPLE   BIT(0)  /* Clear the active state for resampling */
+
+       /*
+        * Callback function pointer to in-kernel devices that can tell us the
+        * state of the input level of mapped level-triggered IRQ faster than
+        * peaking into the physical GIC.
+        */
+       bool (*get_input_level)(int vintid);
+};
+
 struct vgic_irq {
        raw_spinlock_t irq_lock;        /* Protects the content of the struct */
        struct list_head lpi_list;      /* Used to link all LPIs together */
@@ -126,21 +149,17 @@ struct vgic_irq {
        u8 group;                       /* 0 == group 0, 1 == group 1 */
        enum vgic_irq_config config;    /* Level or edge */
 
-       /*
-        * Callback function pointer to in-kernel devices that can tell us the
-        * state of the input level of mapped level-triggered IRQ faster than
-        * peaking into the physical GIC.
-        *
-        * Always called in non-preemptible section and the functions can use
-        * kvm_arm_get_running_vcpu() to get the vcpu pointer for private
-        * IRQs.
-        */
-       bool (*get_input_level)(int vintid);
+       struct irq_ops *ops;
 
        void *owner;                    /* Opaque pointer to reserve an interrupt
                                           for in-kernel devices. */
 };
 
+static inline bool vgic_irq_needs_resampling(struct vgic_irq *irq)
+{
+       return irq->ops && (irq->ops->flags & VGIC_IRQ_SW_RESAMPLE);
+}
+
 struct vgic_register_region;
 struct vgic_its;
 
@@ -352,7 +371,7 @@ void kvm_vgic_init_cpu_hardware(void);
 int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid,
                        bool level, void *owner);
 int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, unsigned int host_irq,
-                         u32 vintid, bool (*get_input_level)(int vindid));
+                         u32 vintid, struct irq_ops *ops);
 int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int vintid);
 bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int vintid);