From patchwork Fri Nov 11 18:25:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 623762 Delivered-To: patch@linaro.org Received: by 2002:a17:522:c983:b0:460:3032:e3c4 with SMTP id kr3csp959528pvb; Fri, 11 Nov 2022 10:32:46 -0800 (PST) X-Google-Smtp-Source: AA0mqf54DvlVp/Y9P3zmofvecIIDWNnibmusz34UeU0fowYBhr5qDxtQfppm9FtHFDxlW5bY9Tcw X-Received: by 2002:a05:620a:cec:b0:6fa:9a8b:1 with SMTP id c12-20020a05620a0cec00b006fa9a8b0001mr2118030qkj.207.1668191566474; Fri, 11 Nov 2022 10:32:46 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1668191566; cv=none; d=google.com; s=arc-20160816; b=FR9rPkeGpvaizRrtm7uw3AzODvVvZy+pMDsPb+HLGzWhghdAqeNQDr5mXI0kgsuf81 cRh3H9N42yr45PX58AZo4NGREcK1fdE7Ktg4B1KXL68i028b60fPrGr12cBdwWstf5qH gTrGChyCJPdAuhxMnqcT/4KAz4jr2iPDvgImXhySubhFLswo8SM3vqswxX5WCYSK+n2Z mNB5mh5Dp12Y/7NzPdnLWZ/9sWzJrrhQGF5CiOGZRLX5bX4AvkG8H5gIbs6U+TO5nyhO pvtG12oD5E2fMpb2EsxXHIP6jfRFEIiGckNDaLFyFIUIJO1p66ETB5w2PK0sHA+SztMd l5EA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=Wj2jpKFKaCJfkPE6OoW08uPMwZbV7IZcdHHoNHuye0E=; b=wZOF9pVSAtwBlr1ZRwCs4pqBMZk8LjQ91rxomjoWGPJ1mS5NYKKQ3SbA0h23VPiohh 7e4JA37utxv0oE4DuSSDJntgvHV+N5+YaD5yIYanXtQR2UBCV0tk+jfwK5Lf7EVeQy7O 9KToF7BWr1BYk1P4qNsvzgok5xlhtH41wdo8RQ28f/5MKR5ostS5UogpRDnXeSFlJFRj 7vme99oqBV/VTic+IOO+AmR4wJsYhW1V1lo3nRNRKKbF1TeUGjPIUAXCbyO8Z1EpB37/ /tAh1xUlSvyvg9vTHXO0mDl2z8hT6prwK3M2/KTu9/J9LE6w/OW3rUACjES8umD56jDh xfDw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=AItZgk5+; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id d6-20020a05620a158600b006cec0749c1bsi1347587qkk.306.2022.11.11.10.32.46 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Fri, 11 Nov 2022 10:32:46 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=AItZgk5+; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1otYiy-00087n-8w; Fri, 11 Nov 2022 13:25:56 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1otYir-00084n-46 for qemu-devel@nongnu.org; Fri, 11 Nov 2022 13:25:49 -0500 Received: from mail-wr1-x430.google.com ([2a00:1450:4864:20::430]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1otYik-0005Fq-Eb for qemu-devel@nongnu.org; Fri, 11 Nov 2022 13:25:48 -0500 Received: by mail-wr1-x430.google.com with SMTP id d9so2818749wrm.13 for ; Fri, 11 Nov 2022 10:25:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Wj2jpKFKaCJfkPE6OoW08uPMwZbV7IZcdHHoNHuye0E=; b=AItZgk5++O/TvV5hJ0FHkaaImlcCgkVIlFScFFxdShONe6/I3cH+cpIpGgB8C3hKoI LOePtu4CWeCKga4rEswk+/uYlK7oiiZJp1H7xiw4vrKiQGhnCsCioQyaz7+XiRF9pOEI Kk5A/NvtvPVBvOxI7C1g1kZmP/oB3Pu3E9NjbiWAQ9OQyN0Gs88YFT7U2B/+GNknXdeT ozMyhVtWqvUpdIlJT5qYPwq5psBg+Ug19dp9YIiOLbh1yHAfHf0rP5THy/t1VoKrfR5s nGgowqaT+3uSYDhyOEgB3EUVZCXCNUd2P6lWdQmgWVLphyfxIqFyesiKVC/i39SG/5zR Qcjw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Wj2jpKFKaCJfkPE6OoW08uPMwZbV7IZcdHHoNHuye0E=; b=wHRhd0eaHs53ed7mtik1rG5TXgea/hw7gFo1e2iib1CRHsQ5FwbKkkaerJWaGG08T8 3QRLthRpyB6aZ49fRqrTvCSm6GOKNFxZbbf+XBRYFA79eNIlCZtofNZrthRVtoxOBmc/ Bj8svjdOnl9RsOpQaDqJf73OYGKGqvDQ0Eyo7mqZBdb4VEIROga82Dd681U1aW5rjkF5 RPm4XGcfv0HF3646o652m0Pf96Et7yKtgLgFKBoeRMne//ciCQdzQit053zYR5LNSZEt dLFrPTlleOWGK9yr3AcfuH5CHjEi4nD7+C9JmKkNHwTkgLShlY6XVErUt4idH4ktbeQy tagg== X-Gm-Message-State: ANoB5pmGa7vzFKhqtWK3AdBLihySVHF91VjFhRO0Hy5/rL8mb3/3F0ev 48D9hmTlcqfr4a43kUOsK4kbDQ== X-Received: by 2002:adf:fc4a:0:b0:22e:307c:cc39 with SMTP id e10-20020adffc4a000000b0022e307ccc39mr2007963wrs.690.1668191140897; Fri, 11 Nov 2022 10:25:40 -0800 (PST) Received: from zen.linaroharston ([185.81.254.11]) by smtp.gmail.com with ESMTPSA id ay19-20020a05600c1e1300b003c6bbe910fdsm11410141wmb.9.2022.11.11.10.25.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Nov 2022 10:25:39 -0800 (PST) Received: from zen.lan (localhost [127.0.0.1]) by zen.linaroharston (Postfix) with ESMTP id 592331FFBF; Fri, 11 Nov 2022 18:25:36 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: qemu-devel@nongnu.org Cc: f4bug@amsat.org, =?utf-8?q?Alex_Benn=C3=A9e?= , Richard Henderson , Peter Maydell , qemu-arm@nongnu.org (open list:ARM cores) Subject: [PATCH v5 07/20] hw/intc/gic: use MxTxAttrs to divine accessing CPU Date: Fri, 11 Nov 2022 18:25:22 +0000 Message-Id: <20221111182535.64844-8-alex.bennee@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221111182535.64844-1-alex.bennee@linaro.org> References: <20221111182535.64844-1-alex.bennee@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::430; envelope-from=alex.bennee@linaro.org; helo=mail-wr1-x430.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org Now that MxTxAttrs encodes a CPU we should use that to figure it out. This solves edge cases like accessing via gdbstub or qtest. As we should only be processing accesses from CPU cores we can push the CPU extraction logic out to the main access functions. If the access does not come from a CPU we log it and fail the transaction with MEMTX_ACCESS_ERROR. Reviewed-by: Richard Henderson Signed-off-by: Alex Bennée Resolves: https://gitlab.com/qemu-project/qemu/-/issues/124 --- v2 - update for new field - bool asserts v3 - fail non-CPU transactions v5 - split gic_valid_cpu from gic_get_current_cpu and use this - fix dud return false from gic_valid_cpu() --- hw/intc/arm_gic.c | 159 +++++++++++++++++++++++++++++----------------- 1 file changed, 102 insertions(+), 57 deletions(-) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 65b1ef7151..62f36b247f 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -56,17 +56,38 @@ static const uint8_t gic_id_gicv2[] = { 0x04, 0x00, 0x00, 0x00, 0x90, 0xb4, 0x2b, 0x00, 0x0d, 0xf0, 0x05, 0xb1 }; -static inline int gic_get_current_cpu(GICState *s) + +/* + * The GIC should only be accessed by the CPU so if it is not we + * should fail the transaction (it would either be a bug in how we've + * wired stuff up, a limitation of the translator or the guest doing + * something weird like programming a DMA master to write to the MMIO + * region). + * + * Note the cpu_index is global and we currently don't have any models + * with multiple SoC's with different CPUs. However if we did we would + * need to transform the cpu_index into the socket core. + */ + +static bool gic_valid_cpu(MemTxAttrs attrs) { - if (!qtest_enabled() && s->num_cpu > 1) { - return current_cpu->cpu_index; + if (attrs.requester_type != MTRT_CPU) { + qemu_log_mask(LOG_UNIMP | LOG_GUEST_ERROR, + "%s: saw non-CPU transaction", __func__); + return false; } - return 0; + return true; +} + +static inline int gic_get_current_cpu(GICState *s, MemTxAttrs attrs) +{ + g_assert(attrs.requester_id < s->num_cpu); + return attrs.requester_id; } -static inline int gic_get_current_vcpu(GICState *s) +static inline int gic_get_current_vcpu(GICState *s, MemTxAttrs attrs) { - return gic_get_current_cpu(s) + GIC_NCPU; + return gic_get_current_cpu(s, attrs) + GIC_NCPU; } /* Return true if this GIC config has interrupt groups, which is @@ -945,17 +966,14 @@ static void gic_complete_irq(GICState *s, int cpu, int irq, MemTxAttrs attrs) * Although this is named a byte read we don't always return bytes and * rely on the calling function oring bits together. */ -static uint32_t gic_dist_readb(void *opaque, hwaddr offset, MemTxAttrs attrs) +static uint32_t gic_dist_readb(GICState *s, int cpu, hwaddr offset, MemTxAttrs attrs) { - GICState *s = (GICState *)opaque; uint32_t res; int irq; int i; - int cpu; int cm; int mask; - cpu = gic_get_current_cpu(s); cm = 1 << cpu; if (offset < 0x100) { if (offset < 0xc) { @@ -1168,19 +1186,27 @@ bad_reg: static MemTxResult gic_dist_read(void *opaque, hwaddr offset, uint64_t *data, unsigned size, MemTxAttrs attrs) { + GICState *s = (GICState *)opaque; + int cpu; + + if (!gic_valid_cpu(attrs)) { + return MEMTX_ACCESS_ERROR; + } + cpu = gic_get_current_cpu(s, attrs); + switch (size) { case 1: - *data = gic_dist_readb(opaque, offset, attrs); + *data = gic_dist_readb(s, cpu, offset, attrs); break; case 2: - *data = gic_dist_readb(opaque, offset, attrs); - *data |= gic_dist_readb(opaque, offset + 1, attrs) << 8; + *data = gic_dist_readb(s, cpu, offset, attrs); + *data |= gic_dist_readb(s, cpu, offset + 1, attrs) << 8; break; case 4: - *data = gic_dist_readb(opaque, offset, attrs); - *data |= gic_dist_readb(opaque, offset + 1, attrs) << 8; - *data |= gic_dist_readb(opaque, offset + 2, attrs) << 16; - *data |= gic_dist_readb(opaque, offset + 3, attrs) << 24; + *data = gic_dist_readb(s, cpu, offset, attrs); + *data |= gic_dist_readb(s, cpu, offset + 1, attrs) << 8; + *data |= gic_dist_readb(s, cpu, offset + 2, attrs) << 16; + *data |= gic_dist_readb(s, cpu, offset + 3, attrs) << 24; break; default: return MEMTX_ERROR; @@ -1190,15 +1216,12 @@ static MemTxResult gic_dist_read(void *opaque, hwaddr offset, uint64_t *data, return MEMTX_OK; } -static void gic_dist_writeb(void *opaque, hwaddr offset, +static void gic_dist_writeb(GICState *s, int cpu, hwaddr offset, uint32_t value, MemTxAttrs attrs) { - GICState *s = (GICState *)opaque; int irq; int i; - int cpu; - cpu = gic_get_current_cpu(s); if (offset < 0x100) { if (offset == 0) { if (s->security_extn && !attrs.secure) { @@ -1475,24 +1498,21 @@ bad_reg: "gic_dist_writeb: Bad offset %x\n", (int)offset); } -static void gic_dist_writew(void *opaque, hwaddr offset, +static void gic_dist_writew(GICState *s, int cpu, hwaddr offset, uint32_t value, MemTxAttrs attrs) { - gic_dist_writeb(opaque, offset, value & 0xff, attrs); - gic_dist_writeb(opaque, offset + 1, value >> 8, attrs); + gic_dist_writeb(s, cpu, offset, value & 0xff, attrs); + gic_dist_writeb(s, cpu, offset + 1, value >> 8, attrs); } -static void gic_dist_writel(void *opaque, hwaddr offset, +static void gic_dist_writel(GICState *s, int cpu, hwaddr offset, uint32_t value, MemTxAttrs attrs) { - GICState *s = (GICState *)opaque; if (offset == 0xf00) { - int cpu; int irq; int mask; int target_cpu; - cpu = gic_get_current_cpu(s); irq = value & 0xf; switch ((value >> 24) & 3) { case 0: @@ -1519,24 +1539,32 @@ static void gic_dist_writel(void *opaque, hwaddr offset, gic_update(s); return; } - gic_dist_writew(opaque, offset, value & 0xffff, attrs); - gic_dist_writew(opaque, offset + 2, value >> 16, attrs); + gic_dist_writew(s, cpu, offset, value & 0xffff, attrs); + gic_dist_writew(s, cpu, offset + 2, value >> 16, attrs); } static MemTxResult gic_dist_write(void *opaque, hwaddr offset, uint64_t data, unsigned size, MemTxAttrs attrs) { + GICState *s = (GICState *)opaque; + int cpu; + + if (!gic_valid_cpu(attrs)) { + return MEMTX_ACCESS_ERROR; + } + cpu = gic_get_current_cpu(s, attrs); + trace_gic_dist_write(offset, size, data); switch (size) { case 1: - gic_dist_writeb(opaque, offset, data, attrs); + gic_dist_writeb(s, cpu, offset, data, attrs); return MEMTX_OK; case 2: - gic_dist_writew(opaque, offset, data, attrs); + gic_dist_writew(s, cpu, offset, data, attrs); return MEMTX_OK; case 4: - gic_dist_writel(opaque, offset, data, attrs); + gic_dist_writel(s, cpu, offset, data, attrs); return MEMTX_OK; default: return MEMTX_ERROR; @@ -1796,7 +1824,10 @@ static MemTxResult gic_thiscpu_read(void *opaque, hwaddr addr, uint64_t *data, unsigned size, MemTxAttrs attrs) { GICState *s = (GICState *)opaque; - return gic_cpu_read(s, gic_get_current_cpu(s), addr, data, attrs); + if (!gic_valid_cpu(attrs)) { + return MEMTX_ACCESS_ERROR; + } + return gic_cpu_read(s, gic_get_current_cpu(s, attrs), addr, data, attrs); } static MemTxResult gic_thiscpu_write(void *opaque, hwaddr addr, @@ -1804,7 +1835,10 @@ static MemTxResult gic_thiscpu_write(void *opaque, hwaddr addr, MemTxAttrs attrs) { GICState *s = (GICState *)opaque; - return gic_cpu_write(s, gic_get_current_cpu(s), addr, value, attrs); + if (!gic_valid_cpu(attrs)) { + return MEMTX_ACCESS_ERROR; + } + return gic_cpu_write(s, gic_get_current_cpu(s, attrs), addr, value, attrs); } /* Wrappers to read/write the GIC CPU interface for a specific CPU. @@ -1833,8 +1867,10 @@ static MemTxResult gic_thisvcpu_read(void *opaque, hwaddr addr, uint64_t *data, unsigned size, MemTxAttrs attrs) { GICState *s = (GICState *)opaque; - - return gic_cpu_read(s, gic_get_current_vcpu(s), addr, data, attrs); + if (!gic_valid_cpu(attrs)) { + return MEMTX_ACCESS_ERROR; + } + return gic_cpu_read(s, gic_get_current_vcpu(s, attrs), addr, data, attrs); } static MemTxResult gic_thisvcpu_write(void *opaque, hwaddr addr, @@ -1842,8 +1878,10 @@ static MemTxResult gic_thisvcpu_write(void *opaque, hwaddr addr, MemTxAttrs attrs) { GICState *s = (GICState *)opaque; - - return gic_cpu_write(s, gic_get_current_vcpu(s), addr, value, attrs); + if (!gic_valid_cpu(attrs)) { + return MEMTX_ACCESS_ERROR; + } + return gic_cpu_write(s, gic_get_current_vcpu(s, attrs), addr, value, attrs); } static uint32_t gic_compute_eisr(GICState *s, int cpu, int lr_start) @@ -1874,9 +1912,8 @@ static uint32_t gic_compute_elrsr(GICState *s, int cpu, int lr_start) return ret; } -static void gic_vmcr_write(GICState *s, uint32_t value, MemTxAttrs attrs) +static void gic_vmcr_write(GICState *s, int vcpu, uint32_t value, MemTxAttrs attrs) { - int vcpu = gic_get_current_vcpu(s); uint32_t ctlr; uint32_t abpr; uint32_t bpr; @@ -1893,11 +1930,10 @@ static void gic_vmcr_write(GICState *s, uint32_t value, MemTxAttrs attrs) gic_set_priority_mask(s, vcpu, prio_mask, attrs); } -static MemTxResult gic_hyp_read(void *opaque, int cpu, hwaddr addr, +static MemTxResult gic_hyp_read(GICState *s, int cpu, hwaddr addr, uint64_t *data, MemTxAttrs attrs) { - GICState *s = ARM_GIC(opaque); - int vcpu = cpu + GIC_NCPU; + int vcpu = gic_get_current_vcpu(s, attrs); switch (addr) { case A_GICH_HCR: /* Hypervisor Control */ @@ -1961,11 +1997,10 @@ static MemTxResult gic_hyp_read(void *opaque, int cpu, hwaddr addr, return MEMTX_OK; } -static MemTxResult gic_hyp_write(void *opaque, int cpu, hwaddr addr, +static MemTxResult gic_hyp_write(GICState *s, int cpu, hwaddr addr, uint64_t value, MemTxAttrs attrs) { - GICState *s = ARM_GIC(opaque); - int vcpu = cpu + GIC_NCPU; + int vcpu = gic_get_current_vcpu(s, attrs); trace_gic_hyp_write(addr, value); @@ -1975,12 +2010,13 @@ static MemTxResult gic_hyp_write(void *opaque, int cpu, hwaddr addr, break; case A_GICH_VMCR: /* Virtual Machine Control */ - gic_vmcr_write(s, value, attrs); + gic_vmcr_write(s, vcpu, value, attrs); break; case A_GICH_APR: /* Active Priorities */ s->h_apr[cpu] = value; - s->running_priority[vcpu] = gic_get_prio_from_apr_bits(s, vcpu); + s->running_priority[vcpu] = + gic_get_prio_from_apr_bits(s, vcpu); break; case A_GICH_LR0 ... A_GICH_LR63: /* List Registers */ @@ -2007,20 +2043,24 @@ static MemTxResult gic_hyp_write(void *opaque, int cpu, hwaddr addr, } static MemTxResult gic_thiscpu_hyp_read(void *opaque, hwaddr addr, uint64_t *data, - unsigned size, MemTxAttrs attrs) + unsigned size, MemTxAttrs attrs) { GICState *s = (GICState *)opaque; - - return gic_hyp_read(s, gic_get_current_cpu(s), addr, data, attrs); + if (!gic_valid_cpu(attrs)) { + return MEMTX_ACCESS_ERROR; + } + return gic_hyp_read(s, gic_get_current_cpu(s, attrs), addr, data, attrs); } static MemTxResult gic_thiscpu_hyp_write(void *opaque, hwaddr addr, - uint64_t value, unsigned size, - MemTxAttrs attrs) + uint64_t value, unsigned size, + MemTxAttrs attrs) { GICState *s = (GICState *)opaque; - - return gic_hyp_write(s, gic_get_current_cpu(s), addr, value, attrs); + if (!gic_valid_cpu(attrs)) { + return MEMTX_ACCESS_ERROR; + } + return gic_hyp_write(s, gic_get_current_cpu(s, attrs), addr, value, attrs); } static MemTxResult gic_do_hyp_read(void *opaque, hwaddr addr, uint64_t *data, @@ -2029,6 +2069,9 @@ static MemTxResult gic_do_hyp_read(void *opaque, hwaddr addr, uint64_t *data, GICState **backref = (GICState **)opaque; GICState *s = *backref; int id = (backref - s->backref); + if (!gic_valid_cpu(attrs)) { + return MEMTX_ACCESS_ERROR; + } return gic_hyp_read(s, id, addr, data, attrs); } @@ -2040,9 +2083,11 @@ static MemTxResult gic_do_hyp_write(void *opaque, hwaddr addr, GICState **backref = (GICState **)opaque; GICState *s = *backref; int id = (backref - s->backref); + if (!gic_valid_cpu(attrs)) { + return MEMTX_ACCESS_ERROR; + } return gic_hyp_write(s, id + GIC_NCPU, addr, value, attrs); - } static const MemoryRegionOps gic_ops[2] = {