[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v3 11/20] intc/arm_gic: Implement virtualization ext
From: |
Luc Michel |
Subject: |
[Qemu-devel] [PATCH v3 11/20] intc/arm_gic: Implement virtualization extensions in gic_acknowledge_irq |
Date: |
Fri, 29 Jun 2018 15:29:45 +0200 |
Implement virtualization extensions in the gic_acknowledge_irq()
function. This function changes the state of the highest priority IRQ
from pending to active.
When the current CPU is a vCPU, modifying the state of an IRQ modifies
the corresponding LR entry. However if we clear the pending flag before
setting the active one, we lose track of the LR entry as it becomes
invalid. The next call to gic_get_lr_entry() will fail.
To overcome this issue, we call gic_activate_irq() before
gic_clear_pending(). This does not change the general behaviour of
gic_acknowledge_irq.
We also move the SGI case in gic_clear_pending_sgi() to enhance
code readability as the virtualization extensions support adds a if-else
level.
Signed-off-by: Luc Michel <address@hidden>
---
hw/intc/arm_gic.c | 52 ++++++++++++++++++++++++++++++-----------------
1 file changed, 33 insertions(+), 19 deletions(-)
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index d61c2dd557..a7577ac073 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -366,17 +366,44 @@ static void gic_drop_prio(GICState *s, int cpu, int group)
s->running_priority[cpu] = gic_get_prio_from_apr_bits(s, cpu);
}
+static inline uint32_t gic_clear_pending_sgi(GICState *s, int irq, int cpu)
+{
+ int src;
+ uint32_t ret;
+
+ if (!gic_is_vcpu(cpu)) {
+ /* Lookup the source CPU for the SGI and clear this in the
+ * sgi_pending map. Return the src and clear the overall pending
+ * state on this CPU if the SGI is not pending from any CPUs.
+ */
+ assert(s->sgi_pending[irq][cpu] != 0);
+ src = ctz32(s->sgi_pending[irq][cpu]);
+ s->sgi_pending[irq][cpu] &= ~(1 << src);
+ if (s->sgi_pending[irq][cpu] == 0) {
+ gic_clear_pending(s, irq, cpu);
+ }
+ ret = irq | ((src & 0x7) << 10);
+ } else {
+ uint32_t *lr_entry = gic_get_lr_entry(s, irq, cpu);
+ src = GICH_LR_CPUID(*lr_entry);
+
+ gic_clear_pending(s, irq, cpu);
+ ret = irq | (src << 10);
+ }
+
+ return ret;
+}
+
uint32_t gic_acknowledge_irq(GICState *s, int cpu, MemTxAttrs attrs)
{
- int ret, irq, src;
- int cm = 1 << cpu;
+ int ret, irq;
/* gic_get_current_pending_irq() will return 1022 or 1023 appropriately
* for the case where this GIC supports grouping and the pending interrupt
* is in the wrong group.
*/
irq = gic_get_current_pending_irq(s, cpu, attrs);
- trace_gic_acknowledge_irq(cpu, irq);
+ trace_gic_acknowledge_irq(gic_get_vcpu_real_id(cpu), irq);
if (irq >= GIC_MAXIRQ) {
DPRINTF("ACK, no pending interrupt or it is hidden: %d\n", irq);
@@ -388,6 +415,8 @@ uint32_t gic_acknowledge_irq(GICState *s, int cpu,
MemTxAttrs attrs)
return 1023;
}
+ gic_activate_irq(s, cpu, irq);
+
if (s->revision == REV_11MPCORE) {
/* Clear pending flags for both level and edge triggered interrupts.
* Level triggered IRQs will be reasserted once they become inactive.
@@ -396,28 +425,13 @@ uint32_t gic_acknowledge_irq(GICState *s, int cpu,
MemTxAttrs attrs)
ret = irq;
} else {
if (irq < GIC_NR_SGIS) {
- /* Lookup the source CPU for the SGI and clear this in the
- * sgi_pending map. Return the src and clear the overall pending
- * state on this CPU if the SGI is not pending from any CPUs.
- */
- assert(s->sgi_pending[irq][cpu] != 0);
- src = ctz32(s->sgi_pending[irq][cpu]);
- s->sgi_pending[irq][cpu] &= ~(1 << src);
- if (s->sgi_pending[irq][cpu] == 0) {
- gic_clear_pending(s, irq, cpu);
- }
- ret = irq | ((src & 0x7) << 10);
+ ret = gic_clear_pending_sgi(s, irq, cpu);
} else {
- /* Clear pending state for both level and edge triggered
- * interrupts. (level triggered interrupts with an active line
- * remain pending, see gic_test_pending)
- */
gic_clear_pending(s, irq, cpu);
ret = irq;
}
}
- gic_activate_irq(s, cpu, irq);
gic_update(s);
DPRINTF("ACK %d\n", irq);
return ret;
--
2.17.1
- [Qemu-devel] [PATCH v3 13/20] intc/arm_gic: Implement virtualization extensions in gic_cpu_(read|write), (continued)
- [Qemu-devel] [PATCH v3 13/20] intc/arm_gic: Implement virtualization extensions in gic_cpu_(read|write), Luc Michel, 2018/06/29
- [Qemu-devel] [PATCH v3 01/20] intc/arm_gic: Implement write to GICD_ISACTIVERn and GICD_ICACTIVERn registers, Luc Michel, 2018/06/29
- [Qemu-devel] [PATCH v3 07/20] intc/arm_gic: Add virtualization extensions helper macros and functions, Luc Michel, 2018/06/29
- [Qemu-devel] [PATCH v3 10/20] intc/arm_gic: Implement virtualization extensions in gic_(activate_irq|drop_prio), Luc Michel, 2018/06/29
- [Qemu-devel] [PATCH v3 15/20] intc/arm_gic: Implement the virtual interface registers, Luc Michel, 2018/06/29
- [Qemu-devel] [PATCH v3 03/20] intc/arm_gic: Remove some dead code and put some functions static, Luc Michel, 2018/06/29
- [Qemu-devel] [PATCH v3 06/20] intc/arm_gic: Add virtual interface register definitions, Luc Michel, 2018/06/29
- [Qemu-devel] [PATCH v3 09/20] intc/arm_gic: Add virtualization enabled IRQ helper functions, Luc Michel, 2018/06/29
- [Qemu-devel] [PATCH v3 12/20] intc/arm_gic: Implement virtualization extensions in gic_complete_irq, Luc Michel, 2018/06/29
- [Qemu-devel] [PATCH v3 17/20] intc/arm_gic: Implement maintenance interrupt generation, Luc Michel, 2018/06/29
- [Qemu-devel] [PATCH v3 11/20] intc/arm_gic: Implement virtualization extensions in gic_acknowledge_irq,
Luc Michel <=
- [Qemu-devel] [PATCH v3 18/20] intc/arm_gic: Improve traces, Luc Michel, 2018/06/29
- [Qemu-devel] [PATCH v3 16/20] intc/arm_gic: Implement gic_update_virt() function, Luc Michel, 2018/06/29
- [Qemu-devel] [PATCH v3 02/20] intc/arm_gic: Refactor operations on the distributor, Luc Michel, 2018/06/29
- [Qemu-devel] [PATCH v3 05/20] intc/arm_gic: Add the virtualization extensions to the GIC state, Luc Michel, 2018/06/29
- [Qemu-devel] [PATCH v3 20/20] arm/virt: Add support for GICv2 virtualization extensions, Luc Michel, 2018/06/29
- [Qemu-devel] [PATCH v3 19/20] xlnx-zynqmp: Improve GIC wiring and MMIO mapping, Luc Michel, 2018/06/29
- [Qemu-devel] [PATCH v3 14/20] intc/arm_gic: Wire the vCPU interface, Luc Michel, 2018/06/29
- [Qemu-devel] [PATCH v3 08/20] intc/arm_gic: Refactor secure/ns access check in the CPU interface, Luc Michel, 2018/06/29
- [Qemu-devel] [PATCH v3 04/20] vmstate.h: Provide VMSTATE_UINT16_SUB_ARRAY, Luc Michel, 2018/06/29