From nobody Wed May 31 14:20:14 2023 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4QWWct5nS2z4Ym8Q; Wed, 31 May 2023 14:20:14 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4QWWct52MJz4FWp; Wed, 31 May 2023 14:20:14 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1685542814; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=ERq3sKmMSabQ/CuTYrrqirqiwuxITLKGdG3moC0hVsE=; b=jkNP2CFTSb3laoMWrxEf0caZ//bIoQJe3YpE94Hyu8VFwaFCRkCTUEcZdhmr+fd7s7xFIB qmDU70M8XQrFOv5akG9GeLYY1RrhBbUOzoPqKAa0n/Np4+wrNaIKut4/Z6ybQt4SVcAf2R r96PGXz+NaGD8h/JIpwUhw/cOQ3oXTvHwPC1ctXwzkbLvcey9pDSfPi88c6rlQ2zevOuML +PqXNMVIt/sW9Pn+1qCkNTC821otYP/pa+JGoTFkgkUq0PlL+sizg+LlcquUaGGl7vLPRI PVKLYroNTo+iHtyukJCfjQ5hhyPzpibNYPBe54Z+uIfy6ejm44+FXPzbwTl0Yw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1685542814; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=ERq3sKmMSabQ/CuTYrrqirqiwuxITLKGdG3moC0hVsE=; b=aEjE4Spmyg8aJLVuAm10F+7HBED6q3i4w5dpqKHOX717jGmP0BI8/0oJ/ZGFhMljlC3/r3 hSUSTNpMJjoJNOrU0yw6CvheVBGZgswbLN5nIdyRtD5VH6jcK2WDBwElq1jz7WsvoY4uGO wMtCLhSyHXFgmn59l5Jnn893dfhMjLbHw2Rt71Q1jNQQBAYUSc8vs5yMJP8Fbx90MkbK4A uDJgj74HfioPB1eWtCsJJaJczYSBORdDcFXSVGUQCAfhuzZdbco9T6Viq/uGYg1xq01RRH iTT6rtUHSXTH3/UBvsbyxOaAsNXSSkCa0mB6Tn4/W6aV7UEocjbqk6E7nQPFww== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1685542814; a=rsa-sha256; cv=none; b=m0GwUhJXHrpnByvW6YeLyzy6vViCPcmH4+2beDTkxOKVImZGzP3Ysp4nGgTTwSnwUkxo/0 mBsLuvdRdwdkGGm5KZcn2xkkgEajnUIDUINeJsol5Y2SBJf3noQqsyfqjNBnaVH9fAQvIX m2KHUCdxMYxkY+NybE8Pm4Gcgut70Rz7+rbMDABE8B2f3hXj4OT81+2YeK68jYX8o8tVD3 pwjbCHfzFoTeZxvhIsDXJWohZaZDmASKQsQ9IYBEk7KIYEW5o+orhbH5dIs9SbR23W23Rc y9o0Oyp8YwZmAZLsPoJlDX9iZq2i+uYLQSPPS+NeFWdatefo40wRnbHewV2jtw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4QWWct47b7zcts; Wed, 31 May 2023 14:20:14 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 34VEKEsf017833; Wed, 31 May 2023 14:20:14 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 34VEKEZw017826; Wed, 31 May 2023 14:20:14 GMT (envelope-from git) Date: Wed, 31 May 2023 14:20:14 GMT Message-Id: <202305311420.34VEKEZw017826@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Andrew Turner Subject: git: ae16cbfdd2a1 - main - gicv3: Use an offset to find the redist registers List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: andrew X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: ae16cbfdd2a1821f69d166c4fc4cdbb4b8d5ef62 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=ae16cbfdd2a1821f69d166c4fc4cdbb4b8d5ef62 commit ae16cbfdd2a1821f69d166c4fc4cdbb4b8d5ef62 Author: Andrew Turner AuthorDate: 2023-05-25 08:22:03 +0000 Commit: Andrew Turner CommitDate: 2023-05-31 14:10:41 +0000 gicv3: Use an offset to find the redist registers To find the redistributor registers use the resource we have already found and add an offset. This removed the need to create a per-redistributor resource as it can now be a pointer to the resource found in attach. While here check the offset is within the bounds of the resource. Some ACPI tables list each redistributor as a separate memory range, even if they are physically contiguous. In this case we may not have each resource virtually contiguous with neighbouring resources. This can lead to a data abort when reading past the resource range. Reviewed by: kevans Sponsored by: Arm Ltd Differential Revision: https://reviews.freebsd.org/D40263 --- sys/arm64/arm64/gic_v3.c | 41 ++++++++++++++++++++++++----------------- sys/arm64/arm64/gic_v3_var.h | 12 +++++++----- sys/arm64/arm64/gicv3_its.c | 3 ++- 3 files changed, 33 insertions(+), 23 deletions(-) diff --git a/sys/arm64/arm64/gic_v3.c b/sys/arm64/arm64/gic_v3.c index e9754797d095..d108cabfe4d9 100644 --- a/sys/arm64/arm64/gic_v3.c +++ b/sys/arm64/arm64/gic_v3.c @@ -226,7 +226,8 @@ gic_r_read_4(device_t dev, bus_size_t offset) struct resource *rdist; sc = device_get_softc(dev); - rdist = &sc->gic_redists.pcpu[PCPU_GET(cpuid)]->res; + rdist = sc->gic_redists.pcpu[PCPU_GET(cpuid)]->res; + offset += sc->gic_redists.pcpu[PCPU_GET(cpuid)]->offset; return (bus_read_4(rdist, offset)); } @@ -237,7 +238,8 @@ gic_r_read_8(device_t dev, bus_size_t offset) struct resource *rdist; sc = device_get_softc(dev); - rdist = &sc->gic_redists.pcpu[PCPU_GET(cpuid)]->res; + rdist = sc->gic_redists.pcpu[PCPU_GET(cpuid)]->res; + offset += sc->gic_redists.pcpu[PCPU_GET(cpuid)]->offset; return (bus_read_8(rdist, offset)); } @@ -248,7 +250,8 @@ gic_r_write_4(device_t dev, bus_size_t offset, uint32_t val) struct resource *rdist; sc = device_get_softc(dev); - rdist = &sc->gic_redists.pcpu[PCPU_GET(cpuid)]->res; + rdist = sc->gic_redists.pcpu[PCPU_GET(cpuid)]->res; + offset += sc->gic_redists.pcpu[PCPU_GET(cpuid)]->offset; bus_write_4(rdist, offset, val); } @@ -259,7 +262,8 @@ gic_r_write_8(device_t dev, bus_size_t offset, uint64_t val) struct resource *rdist; sc = device_get_softc(dev); - rdist = &sc->gic_redists.pcpu[PCPU_GET(cpuid)]->res; + rdist = sc->gic_redists.pcpu[PCPU_GET(cpuid)]->res; + offset += sc->gic_redists.pcpu[PCPU_GET(cpuid)]->offset; bus_write_8(rdist, offset, val); } @@ -1215,6 +1219,7 @@ static void gic_v3_wait_for_rwp(struct gic_v3_softc *sc, enum gic_v3_xdist xdist) { struct resource *res; + bus_size_t offset; u_int cpuid; size_t us_left = 1000000; @@ -1223,16 +1228,18 @@ gic_v3_wait_for_rwp(struct gic_v3_softc *sc, enum gic_v3_xdist xdist) switch (xdist) { case DIST: res = sc->gic_dist; + offset = 0; break; case REDIST: - res = &sc->gic_redists.pcpu[cpuid]->res; + res = sc->gic_redists.pcpu[cpuid]->res; + offset = sc->gic_redists.pcpu[PCPU_GET(cpuid)]->offset; break; default: KASSERT(0, ("%s: Attempt to wait for unknown RWP", __func__)); return; } - while ((bus_read_4(res, GICD_CTLR) & GICD_CTLR_RWP) != 0) { + while ((bus_read_4(res, offset + GICD_CTLR) & GICD_CTLR_RWP) != 0) { DELAY(1); if (us_left-- == 0) panic("GICD Register write pending for too long"); @@ -1377,8 +1384,8 @@ gic_v3_redist_alloc(struct gic_v3_softc *sc) static int gic_v3_redist_find(struct gic_v3_softc *sc) { - struct resource r_res; - bus_space_handle_t r_bsh; + struct resource *r_res; + bus_size_t offset; uint64_t aff; uint64_t typer; uint32_t pidr2; @@ -1399,10 +1406,9 @@ gic_v3_redist_find(struct gic_v3_softc *sc) /* Iterate through Re-Distributor regions */ for (i = 0; i < sc->gic_redists.nregions; i++) { /* Take a copy of the region's resource */ - r_res = *sc->gic_redists.regions[i]; - r_bsh = rman_get_bushandle(&r_res); + r_res = sc->gic_redists.regions[i]; - pidr2 = bus_read_4(&r_res, GICR_PIDR2); + pidr2 = bus_read_4(r_res, GICR_PIDR2); switch (GICR_PIDR2_ARCH(pidr2)) { case GICR_PIDR2_ARCH_GICv3: /* fall through */ case GICR_PIDR2_ARCH_GICv4: @@ -1413,13 +1419,15 @@ gic_v3_redist_find(struct gic_v3_softc *sc) return (ENODEV); } + offset = 0; do { - typer = bus_read_8(&r_res, GICR_TYPER); + typer = bus_read_8(r_res, offset + GICR_TYPER); if ((typer >> GICR_TYPER_AFF_SHIFT) == aff) { KASSERT(sc->gic_redists.pcpu[cpuid] != NULL, ("Invalid pointer to per-CPU redistributor")); /* Copy res contents to its final destination */ sc->gic_redists.pcpu[cpuid]->res = r_res; + sc->gic_redists.pcpu[cpuid]->offset = offset; sc->gic_redists.pcpu[cpuid]->lpi_enabled = false; if (bootverbose) { device_printf(sc->dev, @@ -1429,14 +1437,13 @@ gic_v3_redist_find(struct gic_v3_softc *sc) return (0); } - r_bsh += (GICR_RD_BASE_SIZE + GICR_SGI_BASE_SIZE); + offset += (GICR_RD_BASE_SIZE + GICR_SGI_BASE_SIZE); if ((typer & GICR_TYPER_VLPIS) != 0) { - r_bsh += + offset += (GICR_VLPI_BASE_SIZE + GICR_RESERVED_SIZE); } - - rman_set_bushandle(&r_res, r_bsh); - } while ((typer & GICR_TYPER_LAST) == 0); + } while (offset < rman_get_size(r_res) && + (typer & GICR_TYPER_LAST) == 0); } device_printf(sc->dev, "No Re-Distributor found for CPU%u\n", cpuid); diff --git a/sys/arm64/arm64/gic_v3_var.h b/sys/arm64/arm64/gic_v3_var.h index 9fa8b82e16bc..47e73c1ab3b7 100644 --- a/sys/arm64/arm64/gic_v3_var.h +++ b/sys/arm64/arm64/gic_v3_var.h @@ -40,8 +40,9 @@ DECLARE_CLASS(gic_v3_driver); struct gic_v3_irqsrc; struct redist_pcpu { - struct resource res; /* mem resource for redist */ + struct resource *res; /* mem resource for redist */ vm_offset_t pend_base; + bus_size_t offset; bool lpi_enabled; /* redist LPI configured? */ }; @@ -137,8 +138,8 @@ void gic_r_write_8(device_t, bus_size_t, uint64_t var); u_int cpu = PCPU_GET(cpuid); \ \ bus_read_##len( \ - &(sc)->gic_redists.pcpu[cpu]->res, \ - (reg)); \ + (sc)->gic_redists.pcpu[cpu]->res, \ + (sc)->gic_redists.pcpu[cpu]->offset + (reg)); \ }) #define gic_r_write(sc, len, reg, val) \ @@ -146,8 +147,9 @@ void gic_r_write_8(device_t, bus_size_t, uint64_t var); u_int cpu = PCPU_GET(cpuid); \ \ bus_write_##len( \ - &(sc)->gic_redists.pcpu[cpu]->res, \ - (reg), (val)); \ + (sc)->gic_redists.pcpu[cpu]->res, \ + (sc)->gic_redists.pcpu[cpu]->offset + (reg), \ + (val)); \ }) #endif /* _GIC_V3_VAR_H_ */ diff --git a/sys/arm64/arm64/gicv3_its.c b/sys/arm64/arm64/gicv3_its.c index 9c8f87e74f31..57351a7e76aa 100644 --- a/sys/arm64/arm64/gicv3_its.c +++ b/sys/arm64/arm64/gicv3_its.c @@ -723,7 +723,8 @@ its_init_cpu(device_t dev, struct gicv3_its_softc *sc) if ((gic_its_read_8(sc, GITS_TYPER) & GITS_TYPER_PTA) != 0) { /* This ITS wants the redistributor physical address */ - target = vtophys(rman_get_virtual(&rpcpu->res)); + target = vtophys((vm_offset_t)rman_get_virtual(rpcpu->res) + + rpcpu->offset); } else { /* This ITS wants the unique processor number */ target = GICR_TYPER_CPUNUM(gic_r_read_8(gicv3, GICR_TYPER)) <<