Provide support for FIQ interrupts
This patch introduces support for FIQ virtual interrupts by adding
an "interrupt type" configuration for each INTID.
Following changes are done:
- Helpers added to inject a virtual FIQ by setting HCR_EL2.VF
- hf_interrupt_enable hypervisor call updated with a new
"interrupt type" argument
Nominally, we intend to signal an NS interrupt to a SP as a virtual FIQ
using GICv3. The same interrupt can be signaled as a virtual IRQ if such
option is passed in the Hafnium interrupt enable call.
The reasoning is to ease migration of TEEs relying on receiving physical
Group1 NS/Group0 interrupts as FIQ (or foreign interrupts).
The same TEE now running as a Secure Partition receives a virtual FIQ
for a NS interrupt (or Group0 interrupt).
As mentioned above, there is also the flexibility to receive all
interrupts (Group1 S/Group1 NS/Group0) to the same vIRQ vector.
Change-Id: I78daf1ae226ea9cc01f65da36ae31ed9fff84f42
Signed-off-by: Manish Pandey <manish.pandey2@arm.com>
Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
diff --git a/inc/hf/api.h b/inc/hf/api.h
index e72d3cd..6a636a4 100644
--- a/inc/hf/api.h
+++ b/inc/hf/api.h
@@ -27,7 +27,8 @@
struct vcpu *api_abort(struct vcpu *current);
struct vcpu *api_wake_up(struct vcpu *current, struct vcpu *target_vcpu);
-int64_t api_interrupt_enable(uint32_t intid, bool enable, struct vcpu *current);
+int64_t api_interrupt_enable(uint32_t intid, bool enable,
+ enum interrupt_type type, struct vcpu *current);
uint32_t api_interrupt_get(struct vcpu *current);
int64_t api_interrupt_inject(ffa_vm_id_t target_vm_id,
ffa_vcpu_index_t target_vcpu_idx, uint32_t intid,
diff --git a/inc/hf/vcpu.h b/inc/hf/vcpu.h
index 3668c8d..7a2bdf3 100644
--- a/inc/hf/vcpu.h
+++ b/inc/hf/vcpu.h
@@ -41,12 +41,16 @@
uint32_t interrupt_enabled[HF_NUM_INTIDS / INTERRUPT_REGISTER_BITS];
/** Bitfield keeping track of which interrupts are pending. */
uint32_t interrupt_pending[HF_NUM_INTIDS / INTERRUPT_REGISTER_BITS];
+ /** Bitfield recording the interrupt pin configuration. */
+ uint32_t interrupt_type[HF_NUM_INTIDS / INTERRUPT_REGISTER_BITS];
/**
* The number of interrupts which are currently both enabled and
- * pending. i.e. the number of bits set in interrupt_enable &
- * interrupt_pending.
+ * pending. Count independently virtual IRQ and FIQ interrupt types
+ * i.e. the sum of the two counters is the number of bits set in
+ * interrupt_enable & interrupt_pending.
*/
- uint32_t enabled_and_pending_count;
+ uint32_t enabled_and_pending_irq_count;
+ uint32_t enabled_and_pending_fiq_count;
};
struct vcpu_fault_info {
@@ -116,3 +120,41 @@
struct vcpu_fault_info *f);
void vcpu_reset(struct vcpu *vcpu);
+
+static inline void vcpu_irq_count_increment(struct vcpu_locked vcpu_locked)
+{
+ vcpu_locked.vcpu->interrupts.enabled_and_pending_irq_count++;
+}
+
+static inline void vcpu_irq_count_decrement(struct vcpu_locked vcpu_locked)
+{
+ vcpu_locked.vcpu->interrupts.enabled_and_pending_irq_count--;
+}
+
+static inline void vcpu_fiq_count_increment(struct vcpu_locked vcpu_locked)
+{
+ vcpu_locked.vcpu->interrupts.enabled_and_pending_fiq_count++;
+}
+
+static inline void vcpu_fiq_count_decrement(struct vcpu_locked vcpu_locked)
+{
+ vcpu_locked.vcpu->interrupts.enabled_and_pending_fiq_count--;
+}
+
+static inline uint32_t vcpu_interrupt_irq_count_get(
+ struct vcpu_locked vcpu_locked)
+{
+ return vcpu_locked.vcpu->interrupts.enabled_and_pending_irq_count;
+}
+
+static inline uint32_t vcpu_interrupt_fiq_count_get(
+ struct vcpu_locked vcpu_locked)
+{
+ return vcpu_locked.vcpu->interrupts.enabled_and_pending_fiq_count;
+}
+
+static inline uint32_t vcpu_interrupt_count_get(struct vcpu_locked vcpu_locked)
+{
+ return vcpu_locked.vcpu->interrupts.enabled_and_pending_irq_count +
+ vcpu_locked.vcpu->interrupts.enabled_and_pending_fiq_count;
+}