[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v2 14/16] hw/intc/arm_gic: Restrict priority vie
From: |
Peter Maydell |
Subject: |
Re: [Qemu-devel] [PATCH v2 14/16] hw/intc/arm_gic: Restrict priority view |
Date: |
Tue, 14 Apr 2015 20:32:11 +0100 |
On 30 October 2014 at 22:12, Greg Bellows <address@hidden> wrote:
> From: Fabian Aggeler <address@hidden>
>
> GICs with Security Extensions restrict the non-secure view of the
> interrupt priority and priority mask registers.
>
> Signed-off-by: Fabian Aggeler <address@hidden>
> ---
> hw/intc/arm_gic.c | 66
> +++++++++++++++++++++++++++++++++++++++++++++-----
> hw/intc/gic_internal.h | 3 +++
> 2 files changed, 63 insertions(+), 6 deletions(-)
>
> diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
> index 7eb72df..e01cfdc 100644
> --- a/hw/intc/arm_gic.c
> +++ b/hw/intc/arm_gic.c
> @@ -258,11 +258,66 @@ uint32_t gic_acknowledge_irq(GICState *s, int cpu)
>
> void gic_set_priority(GICState *s, int cpu, int irq, uint8_t val)
> {
> + uint8_t prio = val;
> +
> + if (s->security_extn && ns_access()) {
> + if (GIC_TEST_GROUP0(irq, (1 << cpu))) {
> + return; /* Ignore Non-secure access of Group0 IRQ */
> + }
> + prio = 0x80 | (prio >> 1); /* Non-secure view */
> + }
> +
> if (irq < GIC_INTERNAL) {
> - s->priority1[irq][cpu] = val;
> + s->priority1[irq][cpu] = prio;
> } else {
> - s->priority2[(irq) - GIC_INTERNAL] = val;
> + s->priority2[(irq) - GIC_INTERNAL] = prio;
> + }
> +}
> +
> +uint32_t gic_get_priority(GICState *s, int cpu, int irq)
> +{
> + uint32_t prio = GIC_GET_PRIORITY(irq, cpu);
> +
> + if (s->security_extn && ns_access()) {
> + if (GIC_TEST_GROUP0(irq, (1 << cpu))) {
> + return 0; /* Non-secure access cannot read priority of Group0
> IRQ */
> + }
> + prio = (prio << 1); /* Non-secure view */
> }
> + return prio;
> +}
> +
> +void gic_set_priority_mask(GICState *s, int cpu, uint8_t val)
> +{
> + uint8_t pmask = (val & 0xff);
> +
> + if (s->security_extn && ns_access()) {
> + if (s->priority_mask[cpu] & 0x80) {
> + /* Priority Mask in upper half */
> + pmask = 0x80 | (pmask >> 1);
> + } else {
> + /* Non-secure write ignored if priority mask is in lower half */
> + return;
> + }
> + }
> + s->priority_mask[cpu] = pmask;
> +}
> +
> +uint32_t gic_get_priority_mask(GICState *s, int cpu)
> +{
> + uint32_t pmask = s->priority_mask[cpu];
> +
> + if (s->security_extn && ns_access()) {
> + if (pmask & 0x80) {
> + /* Priority Mask in upper half, return Non-secure view */
> + pmask = (pmask << 1);
> + } else {
> + /* Priority Mask in lower half, RAZ */
> + pmask = 0;
> + }
> + }
> + return pmask;
> +
> }
>
> uint32_t gic_get_cpu_control(GICState *s, int cpu)
> @@ -556,7 +611,7 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr
> offset)
> irq = (offset - 0x400) + GIC_BASE_IRQ;
> if (irq >= s->num_irq)
> goto bad_reg;
> - res = GIC_GET_PRIORITY(irq, cpu);
> + res = gic_get_priority(s, cpu, irq);
> } else if (offset < 0xc00) {
> /* Interrupt CPU Target. */
> if (s->num_cpu == 1 && s->revision != REV_11MPCORE) {
> @@ -920,7 +975,7 @@ static uint32_t gic_cpu_read(GICState *s, int cpu, int
> offset)
> case 0x00: /* Control */
> return gic_get_cpu_control(s, cpu);
> case 0x04: /* Priority mask */
> - return s->priority_mask[cpu];
> + return gic_get_priority_mask(s, cpu);
> case 0x08: /* Binary Point */
> if (s->security_extn && ns_access()) {
> /* BPR is banked. Non-secure copy stored in ABPR. */
> @@ -958,8 +1013,7 @@ static void gic_cpu_write(GICState *s, int cpu, int
> offset, uint32_t value)
> case 0x00: /* Control */
> return gic_set_cpu_control(s, cpu, value);
> case 0x04: /* Priority mask */
> - s->priority_mask[cpu] = (value & 0xff);
> - break;
> + return gic_set_priority_mask(s, cpu, value);
'return some_function_returning_void()' again.
> case 0x08: /* Binary Point */
> if (s->security_extn && ns_access()) {
> /* BPR is banked. Non-secure copy stored in ABPR. */
> diff --git a/hw/intc/gic_internal.h b/hw/intc/gic_internal.h
> index fbb1f66..13fe5a6 100644
> --- a/hw/intc/gic_internal.h
> +++ b/hw/intc/gic_internal.h
> @@ -76,6 +76,9 @@ void gic_complete_irq(GICState *s, int cpu, int irq);
> void gic_update(GICState *s);
> void gic_init_irqs_and_distributor(GICState *s);
> void gic_set_priority(GICState *s, int cpu, int irq, uint8_t val);
> +uint32_t gic_get_priority(GICState *s, int cpu, int irq);
> +void gic_set_priority_mask(GICState *s, int cpu, uint8_t val);
> +uint32_t gic_get_priority_mask(GICState *s, int cpu);
> uint32_t gic_get_cpu_control(GICState *s, int cpu);
> void gic_set_cpu_control(GICState *s, int cpu, uint32_t value);
> uint8_t gic_get_running_priority(GICState *s, int cpu);
> --
> 1.8.3.2
>
-- PMM
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: [Qemu-devel] [PATCH v2 14/16] hw/intc/arm_gic: Restrict priority view,
Peter Maydell <=