[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 09/28] hw/intc/gic: RAZ/WI non-sec access to sec inte
From: |
Peter Maydell |
Subject: |
[Qemu-devel] [PULL 09/28] hw/intc/gic: RAZ/WI non-sec access to sec interrupts |
Date: |
Mon, 6 Jun 2016 15:47:26 +0100 |
From: Jens Wiklander <address@hidden>
Treat non-secure accesses to registers and bits in registers of secure
interrupts as RAZ/WI.
Signed-off-by: Jens Wiklander <address@hidden>
Message-id: address@hidden
Reviewed-by: Peter Maydell <address@hidden>
Signed-off-by: Peter Maydell <address@hidden>
---
hw/intc/arm_gic.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 62 insertions(+), 6 deletions(-)
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index 06a22e0..b30cc91 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -661,6 +661,11 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr
offset, MemTxAttrs attrs)
goto bad_reg;
res = 0;
for (i = 0; i < 8; i++) {
+ if (s->security_extn && !attrs.secure &&
+ !GIC_TEST_GROUP(irq + i, 1 << cpu)) {
+ continue; /* Ignore Non-secure access of Group0 IRQ */
+ }
+
if (GIC_TEST_ENABLED(irq + i, cm)) {
res |= (1 << i);
}
@@ -677,6 +682,11 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr
offset, MemTxAttrs attrs)
res = 0;
mask = (irq < GIC_INTERNAL) ? cm : ALL_CPU_MASK;
for (i = 0; i < 8; i++) {
+ if (s->security_extn && !attrs.secure &&
+ !GIC_TEST_GROUP(irq + i, 1 << cpu)) {
+ continue; /* Ignore Non-secure access of Group0 IRQ */
+ }
+
if (gic_test_pending(s, irq + i, mask)) {
res |= (1 << i);
}
@@ -689,6 +699,11 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr
offset, MemTxAttrs attrs)
res = 0;
mask = (irq < GIC_INTERNAL) ? cm : ALL_CPU_MASK;
for (i = 0; i < 8; i++) {
+ if (s->security_extn && !attrs.secure &&
+ !GIC_TEST_GROUP(irq + i, 1 << cpu)) {
+ continue; /* Ignore Non-secure access of Group0 IRQ */
+ }
+
if (GIC_TEST_ACTIVE(irq + i, mask)) {
res |= (1 << i);
}
@@ -722,6 +737,11 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr
offset, MemTxAttrs attrs)
goto bad_reg;
res = 0;
for (i = 0; i < 4; i++) {
+ if (s->security_extn && !attrs.secure &&
+ !GIC_TEST_GROUP(irq + i, 1 << cpu)) {
+ continue; /* Ignore Non-secure access of Group0 IRQ */
+ }
+
if (GIC_TEST_MODEL(irq + i))
res |= (1 << (i * 2));
if (GIC_TEST_EDGE_TRIGGER(irq + i))
@@ -742,7 +762,12 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr
offset, MemTxAttrs attrs)
/* GICD_SPENDSGIRn */
}
- res = s->sgi_pending[irq][cpu];
+ if (s->security_extn && !attrs.secure &&
+ !GIC_TEST_GROUP(irq, 1 << cpu)) {
+ res = 0; /* Ignore Non-secure access of Group0 IRQ */
+ } else {
+ res = s->sgi_pending[irq][cpu];
+ }
} else if (offset < 0xfd0) {
goto bad_reg;
} else if (offset < 0x1000) {
@@ -862,6 +887,11 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
(irq < GIC_INTERNAL) ? (1 << cpu) : GIC_TARGET(irq + i);
int cm = (irq < GIC_INTERNAL) ? (1 << cpu) : ALL_CPU_MASK;
+ if (s->security_extn && !attrs.secure &&
+ !GIC_TEST_GROUP(irq + i, 1 << cpu)) {
+ continue; /* Ignore Non-secure access of Group0 IRQ */
+ }
+
if (!GIC_TEST_ENABLED(irq + i, cm)) {
DPRINTF("Enabled IRQ %d\n", irq + i);
trace_gic_enable_irq(irq + i);
@@ -889,6 +919,11 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
if (value & (1 << i)) {
int cm = (irq < GIC_INTERNAL) ? (1 << cpu) : ALL_CPU_MASK;
+ if (s->security_extn && !attrs.secure &&
+ !GIC_TEST_GROUP(irq + i, 1 << cpu)) {
+ continue; /* Ignore Non-secure access of Group0 IRQ */
+ }
+
if (GIC_TEST_ENABLED(irq + i, cm)) {
DPRINTF("Disabled IRQ %d\n", irq + i);
trace_gic_disable_irq(irq + i);
@@ -907,6 +942,11 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
for (i = 0; i < 8; i++) {
if (value & (1 << i)) {
+ if (s->security_extn && !attrs.secure &&
+ !GIC_TEST_GROUP(irq + i, 1 << cpu)) {
+ continue; /* Ignore Non-secure access of Group0 IRQ */
+ }
+
GIC_SET_PENDING(irq + i, GIC_TARGET(irq + i));
}
}
@@ -920,6 +960,11 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
}
for (i = 0; i < 8; i++) {
+ if (s->security_extn && !attrs.secure &&
+ !GIC_TEST_GROUP(irq + i, 1 << cpu)) {
+ continue; /* Ignore Non-secure access of Group0 IRQ */
+ }
+
/* ??? This currently clears the pending bit for all CPUs, even
for per-CPU interrupts. It's unclear whether this is the
corect behavior. */
@@ -960,6 +1005,11 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
if (irq < GIC_NR_SGIS)
value |= 0xaa;
for (i = 0; i < 4; i++) {
+ if (s->security_extn && !attrs.secure &&
+ !GIC_TEST_GROUP(irq + i, 1 << cpu)) {
+ continue; /* Ignore Non-secure access of Group0 IRQ */
+ }
+
if (s->revision == REV_11MPCORE || s->revision == REV_NVIC) {
if (value & (1 << (i * 2))) {
GIC_SET_MODEL(irq + i);
@@ -983,9 +1033,12 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
}
irq = (offset - 0xf10);
- s->sgi_pending[irq][cpu] &= ~value;
- if (s->sgi_pending[irq][cpu] == 0) {
- GIC_CLEAR_PENDING(irq, 1 << cpu);
+ if (!s->security_extn || attrs.secure ||
+ GIC_TEST_GROUP(irq, 1 << cpu)) {
+ s->sgi_pending[irq][cpu] &= ~value;
+ if (s->sgi_pending[irq][cpu] == 0) {
+ GIC_CLEAR_PENDING(irq, 1 << cpu);
+ }
}
} else if (offset < 0xf30) {
/* GICD_SPENDSGIRn */
@@ -994,8 +1047,11 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
}
irq = (offset - 0xf20);
- GIC_SET_PENDING(irq, 1 << cpu);
- s->sgi_pending[irq][cpu] |= value;
+ if (!s->security_extn || attrs.secure ||
+ GIC_TEST_GROUP(irq, 1 << cpu)) {
+ GIC_SET_PENDING(irq, 1 << cpu);
+ s->sgi_pending[irq][cpu] |= value;
+ }
} else {
goto bad_reg;
}
--
1.9.1
- [Qemu-devel] [PULL 00/28] target-arm queue, Peter Maydell, 2016/06/06
- [Qemu-devel] [PULL 15/28] xlnx-zynqmp: Use the in kernel GIC model for KVM runs, Peter Maydell, 2016/06/06
- [Qemu-devel] [PULL 16/28] hw/ptimer: Fix issues caused by the adjusted timer limit value, Peter Maydell, 2016/06/06
- [Qemu-devel] [PULL 17/28] hw/ptimer: Perform counter wrap around if timer already expired, Peter Maydell, 2016/06/06
- [Qemu-devel] [PULL 19/28] hw/ptimer: Support "on the fly" timer mode switch, Peter Maydell, 2016/06/06
- [Qemu-devel] [PULL 11/28] hw/arm/virt: Reject gic-version=host for non-KVM, Peter Maydell, 2016/06/06
- [Qemu-devel] [PULL 06/28] target-arm: kvm64: set guest PMUv3 feature bit if supported, Peter Maydell, 2016/06/06
- [Qemu-devel] [PULL 09/28] hw/intc/gic: RAZ/WI non-sec access to sec interrupts,
Peter Maydell <=
- [Qemu-devel] [PULL 26/28] char: get rid of qemu_char_get_next_serial, Peter Maydell, 2016/06/06
- [Qemu-devel] [PULL 24/28] hw/char: QOM'ify stm32f2xx_usart model, Peter Maydell, 2016/06/06
- [Qemu-devel] [PULL 07/28] hw/arm/virt: Add PMU node for virt machine, Peter Maydell, 2016/06/06
- [Qemu-devel] [PULL 01/28] target-arm: Add the HSTR_EL2 register, Peter Maydell, 2016/06/06
- [Qemu-devel] [PULL 02/28] target-arm: A64: Create Instruction Syndromes for Data Aborts, Peter Maydell, 2016/06/06
- [Qemu-devel] [PULL 08/28] hw/arm/virt-acpi-build: Add PMU IRQ number in ACPI table, Peter Maydell, 2016/06/06
- [Qemu-devel] [PULL 12/28] xlnx-zynqmp: Add a secure prop to en/disable ARM Security Extensions, Peter Maydell, 2016/06/06
- [Qemu-devel] [PULL 05/28] hw/arm/virt: fix limit of 64-bit ACPI/ECAM PCI MMIO range, Peter Maydell, 2016/06/06
- [Qemu-devel] [PULL 03/28] target-arm: Set IL bit in syndromes for insn abort, watchpoint, swstep, Peter Maydell, 2016/06/06
- [Qemu-devel] [PULL 13/28] xlnx-zynqmp: Make the RPU subsystem optional, Peter Maydell, 2016/06/06