From nobody Tue Mar 15 11:10:03 2022 X-Original-To: dev-commits-src-main@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 64E8F1A0AAEA; Tue, 15 Mar 2022 11:10:04 +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 4KHrKS0X18z3DQh; Tue, 15 Mar 2022 11:10:04 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1647342604; 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=Ghpo5FVaezEBHPICR9ZOvdAK38UuSUBHvhMXBr96Jyc=; b=GIztkCRCqB76SWQaVk8do85DnXuSsth6AERamhQn4NwtWaQYjF/U5U5eaqSwruqeD0LbUO o1XXSeBzQ+Jfy/B0UbsJHyDGvivMZqzbL6Z9e72zNQhLZxFRC7WRr5mmieX78D+Oths9Dq lD4HJccu2Wu8u0MLwtsma3smsvK784nwR0JNfHLD0DPViRznjDtgdXDYa2meOIZ7WmNJxA NCsKz6NbFWOQRKViE4h1vf6ib/rUv2xb6+HymEedjoQh+h6ZGZbxts7aOprSSLBMGCUsNx 6dqGHDiwK8j9HoUgkaGQSCaHA39d7oFa+iGMeISqdUSX9DQy9l114gCCz3v/jQ== 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 8C4BF20937; Tue, 15 Mar 2022 11:10:03 +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 22FBA3cN096718; Tue, 15 Mar 2022 11:10:03 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 22FBA3g4096715; Tue, 15 Mar 2022 11:10:03 GMT (envelope-from git) Date: Tue, 15 Mar 2022 11:10:03 GMT Message-Id: <202203151110.22FBA3g4096715@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: f2e36d47e3be - main - Make page size dynamic in libkvm for arm64 List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@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: f2e36d47e3be31ce819e28d8178b6695556a9e53 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1647342604; 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=Ghpo5FVaezEBHPICR9ZOvdAK38UuSUBHvhMXBr96Jyc=; b=bOA0U+u3wTOtyr6MOwtT8KfqOZ/ZnHYEvnwM+MLkj9siXHMGgpK//DY5wUIPe3Qk4kMVyJ asV2f1EGjvjrnJ7EIAo9OyvWHOerC8n6zyG0g+AfpOhl9mN+Ou7ktJCrkeFEpW+D6PNcD8 kWY7ak6xjdRfbwZg7C7h6qlgFEAxaSWUzpB7WNH4qh82Tiq8IqgGOXMTcCBfv0xer7kzCD hCt3YItWt8fMJeqy634cwEpBmubhW/MkT79mQSHvCC5dYOnR+CtR2XHje9VPb5pU2mD8wh jTluuO7YCIACu8gJE4os54/6OB5TlYkbNEtQLt+gTHB2ZCz3ng6r8pUVUTN0UA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1647342604; a=rsa-sha256; cv=none; b=WWPW+LVBQxBB1xQxw6cLt23xY7LmDE3RVJkvkASvfUJ9yTOVE1CfvyMmIMon+eKt7aZhvi PgsnuM+aHgdQotK57P6ik2LU5b4aXvbH0wujB3U33N5ruGOV9jiDdjR2eBvKFkC2HVmoPa 3ou3f8g1ITm0ptH7DNCnXePzqdWUGDsnpaYYkgXOhXruE0k1bvKu7XGDQGSDJXQdnlNbZW xDBcuFO7jLIaHe6TjjIw4RP1fR55YnTlIK6CoVvyMm104pNXlOihkZxR4qFwZi5tKpfy4j T2drPmymKVe2PtxC55z2mPAo3eRHZ8r+XdbvGAcCuZ35CrW2Bn3S/g57mD80tQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=f2e36d47e3be31ce819e28d8178b6695556a9e53 commit f2e36d47e3be31ce819e28d8178b6695556a9e53 Author: Andrew Turner AuthorDate: 2022-03-14 12:40:25 +0000 Commit: Andrew Turner CommitDate: 2022-03-15 09:52:15 +0000 Make page size dynamic in libkvm for arm64 To allow for a future 16k or 64k page size we need to tell libkvm which is being used. Add a flag field in unused space in minidumphdr and use it to signal between the different options. Reviewed by: markj Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D34548 --- lib/libkvm/kvm_aarch64.h | 15 ++++---- lib/libkvm/kvm_minidump_aarch64.c | 79 ++++++++++++++++++++++++++------------ sys/arm64/arm64/minidump_machdep.c | 1 + sys/arm64/include/minidump.h | 7 +++- 4 files changed, 69 insertions(+), 33 deletions(-) diff --git a/lib/libkvm/kvm_aarch64.h b/lib/libkvm/kvm_aarch64.h index fbbd869ab425..fdbdafde025b 100644 --- a/lib/libkvm/kvm_aarch64.h +++ b/lib/libkvm/kvm_aarch64.h @@ -35,9 +35,11 @@ typedef uint64_t aarch64_physaddr_t; typedef uint64_t aarch64_pte_t; -#define AARCH64_PAGE_SHIFT 12 -#define AARCH64_PAGE_SIZE (1 << AARCH64_PAGE_SHIFT) -#define AARCH64_PAGE_MASK (AARCH64_PAGE_SIZE - 1) +#define AARCH64_PAGE_SHIFT_4K 12 +#define AARCH64_PAGE_SIZE_4K (1 << AARCH64_PAGE_SHIFT_4K) + +#define AARCH64_PAGE_SHIFT_16K 14 +#define AARCH64_PAGE_SIZE_16K (1 << AARCH64_PAGE_SHIFT_16K) /* Source: arm64/include/pte.h */ #define AARCH64_ATTR_MASK 0xfffc000000000fff @@ -49,17 +51,14 @@ typedef uint64_t aarch64_pte_t; #define AARCH64_ATTR_DESCR_MASK 3 -#define AARCH64_L3_SHIFT 12 +#define AARCH64_L3_SHIFT_4K 12 +#define AARCH64_L3_SHIFT_16K 14 #define AARCH64_L3_PAGE 0x3 #ifdef __aarch64__ -_Static_assert(PAGE_SHIFT == AARCH64_PAGE_SHIFT, "PAGE_SHIFT mismatch"); -_Static_assert(PAGE_SIZE == AARCH64_PAGE_SIZE, "PAGE_SIZE mismatch"); -_Static_assert(PAGE_MASK == AARCH64_PAGE_MASK, "PAGE_MASK mismatch"); _Static_assert(ATTR_MASK == AARCH64_ATTR_MASK, "ATTR_MASK mismatch"); _Static_assert(ATTR_DESCR_MASK == AARCH64_ATTR_DESCR_MASK, "ATTR_DESCR_MASK mismatch"); -_Static_assert(L3_SHIFT == AARCH64_L3_SHIFT, "L3_SHIFT mismatch"); _Static_assert(L3_PAGE == AARCH64_L3_PAGE, "L3_PAGE mismatch"); #endif diff --git a/lib/libkvm/kvm_minidump_aarch64.c b/lib/libkvm/kvm_minidump_aarch64.c index 7fd4219fbf21..5e9ac739406f 100644 --- a/lib/libkvm/kvm_minidump_aarch64.c +++ b/lib/libkvm/kvm_minidump_aarch64.c @@ -47,10 +47,13 @@ __FBSDID("$FreeBSD$"); #include "kvm_private.h" #include "kvm_aarch64.h" -#define aarch64_round_page(x) roundup2((kvaddr_t)(x), AARCH64_PAGE_SIZE) +#define aarch64_round_page(x, size) roundup2((kvaddr_t)(x), size) +#define aarch64_trunc_page(x, size) rounddown2((kvaddr_t)(x), size) struct vmstate { struct minidumphdr hdr; + size_t page_size; + u_int l3_shift; }; static aarch64_pte_t @@ -102,7 +105,7 @@ _aarch64_minidump_initvtop(kvm_t *kd) } vmst->hdr.version = le32toh(vmst->hdr.version); - if (vmst->hdr.version != MINIDUMP_VERSION && vmst->hdr.version != 1) { + if (vmst->hdr.version > MINIDUMP_VERSION || vmst->hdr.version < 1) { _kvm_err(kd, kd->program, "wrong minidump version. " "Expected %d got %d", MINIDUMP_VERSION, vmst->hdr.version); return (-1); @@ -114,28 +117,56 @@ _aarch64_minidump_initvtop(kvm_t *kd) vmst->hdr.dmapphys = le64toh(vmst->hdr.dmapphys); vmst->hdr.dmapbase = le64toh(vmst->hdr.dmapbase); vmst->hdr.dmapend = le64toh(vmst->hdr.dmapend); - vmst->hdr.dumpavailsize = vmst->hdr.version == MINIDUMP_VERSION ? - le32toh(vmst->hdr.dumpavailsize) : 0; + /* dumpavailsize added in version 2 */ + if (vmst->hdr.version >= 2) { + vmst->hdr.dumpavailsize = le32toh(vmst->hdr.dumpavailsize); + } else { + vmst->hdr.dumpavailsize = 0; + } + /* flags added in version 3 */ + if (vmst->hdr.version >= 3) { + vmst->hdr.flags = le32toh(vmst->hdr.flags); + } else { + vmst->hdr.flags = MINIDUMP_FLAG_PS_4K; + } + + switch (vmst->hdr.flags & MINIDUMP_FLAG_PS_MASK) { + case MINIDUMP_FLAG_PS_4K: + vmst->page_size = AARCH64_PAGE_SIZE_4K; + vmst->l3_shift = AARCH64_L3_SHIFT_4K; + break; + case MINIDUMP_FLAG_PS_16K: + vmst->page_size = AARCH64_PAGE_SIZE_16K; + vmst->l3_shift = AARCH64_L3_SHIFT_16K; + break; + default: + _kvm_err(kd, kd->program, "unknown page size flag %x", + vmst->hdr.flags & MINIDUMP_FLAG_PS_MASK); + return (-1); + } /* Skip header and msgbuf */ - dump_avail_off = AARCH64_PAGE_SIZE + aarch64_round_page(vmst->hdr.msgbufsize); + dump_avail_off = vmst->page_size + + aarch64_round_page(vmst->hdr.msgbufsize, vmst->page_size); /* Skip dump_avail */ - off = dump_avail_off + aarch64_round_page(vmst->hdr.dumpavailsize); + off = dump_avail_off + + aarch64_round_page(vmst->hdr.dumpavailsize, vmst->page_size); /* build physical address lookup table for sparse pages */ - sparse_off = off + aarch64_round_page(vmst->hdr.bitmapsize) + - aarch64_round_page(vmst->hdr.pmapsize); + sparse_off = off + + aarch64_round_page(vmst->hdr.bitmapsize, vmst->page_size) + + aarch64_round_page(vmst->hdr.pmapsize, vmst->page_size); if (_kvm_pt_init(kd, vmst->hdr.dumpavailsize, dump_avail_off, - vmst->hdr.bitmapsize, off, sparse_off, AARCH64_PAGE_SIZE) == -1) { + vmst->hdr.bitmapsize, off, sparse_off, vmst->page_size) == -1) { return (-1); } - off += aarch64_round_page(vmst->hdr.bitmapsize); + off += aarch64_round_page(vmst->hdr.bitmapsize, vmst->page_size); if (_kvm_pmap_init(kd, vmst->hdr.pmapsize, off) == -1) { return (-1); } - off += aarch64_round_page(vmst->hdr.pmapsize); + off += aarch64_round_page(vmst->hdr.pmapsize, vmst->page_size); return (0); } @@ -151,12 +182,12 @@ _aarch64_minidump_vatop(kvm_t *kd, kvaddr_t va, off_t *pa) off_t ofs; vm = kd->vmst; - offset = va & AARCH64_PAGE_MASK; + offset = va & (kd->vmst->page_size - 1); if (va >= vm->hdr.dmapbase && va < vm->hdr.dmapend) { - a = (va - vm->hdr.dmapbase + vm->hdr.dmapphys) & - ~AARCH64_PAGE_MASK; - ofs = _kvm_pt_find(kd, a, AARCH64_PAGE_SIZE); + a = aarch64_trunc_page(va - vm->hdr.dmapbase + vm->hdr.dmapphys, + kd->vmst->page_size); + ofs = _kvm_pt_find(kd, a, kd->vmst->page_size); if (ofs == -1) { _kvm_err(kd, kd->program, "_aarch64_minidump_vatop: " "direct map address 0x%jx not in minidump", @@ -164,9 +195,9 @@ _aarch64_minidump_vatop(kvm_t *kd, kvaddr_t va, off_t *pa) goto invalid; } *pa = ofs + offset; - return (AARCH64_PAGE_SIZE - offset); + return (kd->vmst->page_size - offset); } else if (va >= vm->hdr.kernbase) { - l3_index = (va - vm->hdr.kernbase) >> AARCH64_L3_SHIFT; + l3_index = (va - vm->hdr.kernbase) >> kd->vmst->l3_shift; if (l3_index >= vm->hdr.pmapsize / sizeof(l3)) goto invalid; l3 = _aarch64_pte_get(kd, l3_index); @@ -176,7 +207,7 @@ _aarch64_minidump_vatop(kvm_t *kd, kvaddr_t va, off_t *pa) goto invalid; } a = l3 & ~AARCH64_ATTR_MASK; - ofs = _kvm_pt_find(kd, a, AARCH64_PAGE_SIZE); + ofs = _kvm_pt_find(kd, a, kd->vmst->page_size); if (ofs == -1) { _kvm_err(kd, kd->program, "_aarch64_minidump_vatop: " "physical address 0x%jx not in minidump", @@ -184,7 +215,7 @@ _aarch64_minidump_vatop(kvm_t *kd, kvaddr_t va, off_t *pa) goto invalid; } *pa = ofs + offset; - return (AARCH64_PAGE_SIZE - offset); + return (kd->vmst->page_size - offset); } else { _kvm_err(kd, kd->program, "_aarch64_minidump_vatop: virtual address 0x%jx not minidumped", @@ -252,26 +283,26 @@ _aarch64_minidump_walk_pages(kvm_t *kd, kvm_walk_pages_cb_t *cb, void *arg) if ((pte & AARCH64_ATTR_DESCR_MASK) != AARCH64_L3_PAGE) continue; - va = vm->hdr.kernbase + (pteindex << AARCH64_L3_SHIFT); + va = vm->hdr.kernbase + (pteindex << kd->vmst->l3_shift); pa = pte & ~AARCH64_ATTR_MASK; dva = vm->hdr.dmapbase + pa; if (!_kvm_visit_cb(kd, cb, arg, pa, va, dva, - _aarch64_entry_to_prot(pte), AARCH64_PAGE_SIZE, 0)) { + _aarch64_entry_to_prot(pte), kd->vmst->page_size, 0)) { goto out; } } while (_kvm_bitmap_next(&bm, &bmindex)) { - pa = _kvm_bit_id_pa(kd, bmindex, AARCH64_PAGE_SIZE); + pa = _kvm_bit_id_pa(kd, bmindex, kd->vmst->page_size); if (pa == _KVM_PA_INVALID) break; dva = vm->hdr.dmapbase + pa; - if (vm->hdr.dmapend < (dva + AARCH64_PAGE_SIZE)) + if (vm->hdr.dmapend < (dva + kd->vmst->page_size)) break; va = 0; prot = VM_PROT_READ | VM_PROT_WRITE; if (!_kvm_visit_cb(kd, cb, arg, pa, va, dva, - prot, AARCH64_PAGE_SIZE, 0)) { + prot, kd->vmst->page_size, 0)) { goto out; } } diff --git a/sys/arm64/arm64/minidump_machdep.c b/sys/arm64/arm64/minidump_machdep.c index ac5a7b271b85..e05a19fc1c41 100644 --- a/sys/arm64/arm64/minidump_machdep.c +++ b/sys/arm64/arm64/minidump_machdep.c @@ -239,6 +239,7 @@ cpu_minidumpsys(struct dumperinfo *di, const struct minidumpstate *state) mdhdr.dmapbase = DMAP_MIN_ADDRESS; mdhdr.dmapend = DMAP_MAX_ADDRESS; mdhdr.dumpavailsize = round_page(sizeof(dump_avail)); + mdhdr.flags = MINIDUMP_FLAG_PS_4K; dump_init_header(di, &kdh, KERNELDUMPMAGIC, KERNELDUMP_AARCH64_VERSION, dumpsize); diff --git a/sys/arm64/include/minidump.h b/sys/arm64/include/minidump.h index 87aaffc5ec87..c27d2c71bc12 100644 --- a/sys/arm64/include/minidump.h +++ b/sys/arm64/include/minidump.h @@ -31,7 +31,7 @@ #define _MACHINE_MINIDUMP_H_ 1 #define MINIDUMP_MAGIC "minidump FreeBSD/arm64" -#define MINIDUMP_VERSION 2 +#define MINIDUMP_VERSION 3 struct minidumphdr { char magic[24]; @@ -44,6 +44,11 @@ struct minidumphdr { uint64_t dmapbase; uint64_t dmapend; uint32_t dumpavailsize; +#define MINIDUMP_FLAG_PS_MASK (3 << 0) +#define MINIDUMP_FLAG_PS_4K (0 << 0) +#define MINIDUMP_FLAG_PS_16K (1 << 0) +/* MINIDUMP_FLAG_PS_64K (2 << 0) */ + uint32_t flags; }; #endif /* _MACHINE_MINIDUMP_H_ */