From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34829) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bgubB-00060f-0Y for qemu-devel@nongnu.org; Mon, 05 Sep 2016 10:10:10 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bgub5-0006sN-Q2 for qemu-devel@nongnu.org; Mon, 05 Sep 2016 10:10:07 -0400 Received: from mail-wm0-x22f.google.com ([2a00:1450:400c:c09::22f]:36714) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bgub4-0006s9-Rw for qemu-devel@nongnu.org; Mon, 05 Sep 2016 10:10:03 -0400 Received: by mail-wm0-x22f.google.com with SMTP id b187so21591841wme.1 for ; Mon, 05 Sep 2016 07:10:02 -0700 (PDT) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Mon, 5 Sep 2016 15:09:44 +0100 Message-Id: <20160905140944.5379-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Subject: [Qemu-devel] [RFC PATCH] hw/intc/arm_gic: handle Set-Active/Clear-Active registers List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: peter.maydell@linaro.org, =?UTF-8?q?Alex=20Benn=C3=A9e?= , "open list:ARM cores" I noticed while testing with modern kernels and -d guest_errors warnings about invalid writes to the GIC. For GICv2 these registers certainly should work so I've implemented both. As the code is common between all the various GICs writes to GICD_ISACTIVERn is checked to ensure it is not a RO register for v1 GICs. Signed-off-by: Alex Bennée --- hw/intc/arm_gic.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index b30cc91..423a4ae 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -972,9 +972,38 @@ static void gic_dist_writeb(void *opaque, hwaddr offset, GIC_CLEAR_PENDING(irq + i, ALL_CPU_MASK); } } + } else if (offset < 0x380) { + /* Interrupt Set-Active */ + irq = (offset - 0x300) * 8 + GIC_BASE_IRQ; + if (irq >= s->num_irq || s->revision < 2) + goto bad_reg; + + 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 (value & (1 << i)) { + GIC_SET_ACTIVE(irq + i, 1 << cpu); + } + } } else if (offset < 0x400) { - /* Interrupt Active. */ - goto bad_reg; + /* Interrupt Clear-Active */ + irq = (offset - 0x380) * 8 + GIC_BASE_IRQ; + if (irq >= s->num_irq) + goto bad_reg; + + 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 (value & (1 << i)) { + GIC_CLEAR_ACTIVE(irq + i, 1 << cpu); + } + } } else if (offset < 0x800) { /* Interrupt Priority. */ irq = (offset - 0x400) + GIC_BASE_IRQ; -- 2.9.3