From nobody Wed Apr 26 07:59:35 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 4Q5rqq5VqBz47PQF; Wed, 26 Apr 2023 07:59:35 +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 4Q5rqq51V1z4bYf; Wed, 26 Apr 2023 07:59:35 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1682495975; 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=Ngl/wwoQlTZPXjmU7qnXkZqV4ocxvILh3dpLR4I4nDY=; b=jLSrFHvSOZU9lNyb/G4MXS6Urrk3+HICG+rjGsVzb3QHRjqoXn/9L5RcuXE66zrECQuHJv ntOp+zZBCcnEGI7+B7Ap6zUwWdVkxUpa4eTJobftzEMmNcZGT7na1WZyq6q4f+B4ZDxLb8 DTZxEif9qNuZwr6i+ayqmnto1RpVzPZvLHpJIqQUd96J0nfFOFFnYn6XAhu7jGpKzc8JQk 7T7x3A4oYax59Ppglc+CGZJyzuAEtkuQpxtysvUggEjrrrLRcbJK3/dcLdNSiUZFxQI/5j 7cGFxERnD7KspP9mOTMNUvKTTlgPjTOvgkI5hadvlQ56LCCcQBgdw4ZDdI+QaA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1682495975; 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=Ngl/wwoQlTZPXjmU7qnXkZqV4ocxvILh3dpLR4I4nDY=; b=AshCjOTnySeBAjS6Nc+bRImASgG2wECtcOBfwMYoGQn4OJbxV9gcAuuz5r94lDF2PTXkDY wA51BAykGssAn/xE9w+p5nIoUCrpZOpSJhAIWh9HC6NVbWkXRhXtP+RyzAAPjeS/l9OUKe ZUzU8cAXtfCQxUrWOQZm/atO4tejn6W2oYqn6A97m7M0a/YaKbPeJl7shLjYLVEEghJ2ZM UwYbm9qVwfp1dY+VDej/K19i+UYkmW3PaT+Sk4PsmeR/b77qT3d1Y2pIH69mNdwDdosTy/ 2idnhI/pU1BAhfGkSn7pwsAIBYplsP5kgrsADm7IWBj+hbrfKfZAGoDMKje1Yg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1682495975; a=rsa-sha256; cv=none; b=I2U53D1PwOY2H64Mppa8b5I4yUOz4xU9ueGuzz3cGx4Lq4tP2LjkNeieSI0eUQvw+v9YJA Fz7ym0U7eh8jAf+jKGTmfRLKUnEmO4nenHeNHszuniuT6XLr2TA9CcPcUN5HONXYK38Z0i fvryOkuFdMygxvCHOqEA/Rpp6sPjs7/KTiGbhCSOZXhsE9fjnoja3oTiBuBHVMB0B/jw/k fhLnPJs8B23vY8yDImvR53HtbO5KMbLPadYvf+1vrdfpZcCyev9eeCSqFlFpvdZDfSVlBI yROVYWPqU8MhywLOt0kAagyoHnUYPgYT+ADKwOvcjyX4bcgCNrDwY50W3uby0A== 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 4Q5rqq3jdXzRJ2; Wed, 26 Apr 2023 07:59:35 +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 33Q7xZth059734; Wed, 26 Apr 2023 07:59:35 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 33Q7xZEm059733; Wed, 26 Apr 2023 07:59:35 GMT (envelope-from git) Date: Wed, 26 Apr 2023 07:59:35 GMT Message-Id: <202304260759.33Q7xZEm059733@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: =?utf-8?Q?Corvin=20K=C3=B6hne?= Subject: git: 5597f564870e - main - bhyve: add allocation function to E820 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: corvink X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 5597f564870e94d56111dec638b8859423c936a9 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by corvink: URL: https://cgit.FreeBSD.org/src/commit/?id=5597f564870e94d56111dec638b8859423c936a9 commit 5597f564870e94d56111dec638b8859423c936a9 Author: Corvin Köhne AuthorDate: 2021-09-09 09:37:03 +0000 Commit: Corvin Köhne CommitDate: 2023-04-26 07:58:34 +0000 bhyve: add allocation function to E820 This function makes it easy to allocate new E820 entries. It will be used to allocate graphics memory for Intel integrated graphic devices. Reviewed by: markj MFC after: 1 week Sponsored by: Beckhoff Automation GmbH & Co. KG Differential Revision: https://reviews.freebsd.org/D39547 --- usr.sbin/bhyve/e820.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++ usr.sbin/bhyve/e820.h | 16 ++++++++ 2 files changed, 120 insertions(+) diff --git a/usr.sbin/bhyve/e820.c b/usr.sbin/bhyve/e820.c index 95b83c056b9b..922381d032ce 100644 --- a/usr.sbin/bhyve/e820.c +++ b/usr.sbin/bhyve/e820.c @@ -20,6 +20,14 @@ #include "e820.h" #include "qemu_fwcfg.h" +/* + * E820 always uses 64 bit entries. Emulation code will use vm_paddr_t since it + * works on physical addresses. If vm_paddr_t is larger than uint64_t E820 can't + * hold all possible physical addresses and we can get into trouble. + */ +static_assert(sizeof(vm_paddr_t) <= sizeof(uint64_t), + "Unable to represent physical memory by E820 table"); + #define E820_FWCFG_FILE_NAME "etc/e820" #define KB (1024UL) @@ -282,6 +290,102 @@ e820_add_memory_hole(const uint64_t base, const uint64_t end) return (0); } +static uint64_t +e820_alloc_highest(const uint64_t max_address, const uint64_t length, + const uint64_t alignment, const enum e820_memory_type type) +{ + struct e820_element *element; + + TAILQ_FOREACH_REVERSE(element, &e820_table, e820_table, chain) { + uint64_t address, base, end; + + end = MIN(max_address, element->end); + base = roundup2(element->base, alignment); + + /* + * If end - length == 0, we would allocate memory at address 0. This + * address is mostly unusable and we should avoid allocating it. + * Therefore, search for another block in that case. + */ + if (element->type != E820_TYPE_MEMORY || end < base || + end - base < length || end - length == 0) { + continue; + } + + address = rounddown2(end - length, alignment); + + if (e820_add_entry(address, address + length, type) != 0) { + return (0); + } + + return (address); + } + + return (0); +} + +static uint64_t +e820_alloc_lowest(const uint64_t min_address, const uint64_t length, + const uint64_t alignment, const enum e820_memory_type type) +{ + struct e820_element *element; + + TAILQ_FOREACH(element, &e820_table, chain) { + uint64_t base, end; + + end = element->end; + base = MAX(min_address, roundup2(element->base, alignment)); + + /* + * If base == 0, we would allocate memory at address 0. This + * address is mostly unusable and we should avoid allocating it. + * Therefore, search for another block in that case. + */ + if (element->type != E820_TYPE_MEMORY || end < base || + end - base < length || base == 0) { + continue; + } + + if (e820_add_entry(base, base + length, type) != 0) { + return (0); + } + + return (base); + } + + return (0); +} + +uint64_t +e820_alloc(const uint64_t address, const uint64_t length, + const uint64_t alignment, const enum e820_memory_type type, + const enum e820_allocation_strategy strategy) +{ + assert(powerof2(alignment)); + assert((address & (alignment - 1)) == 0); + + switch (strategy) { + case E820_ALLOCATE_ANY: + /* + * Allocate any address. Therefore, ignore the address parameter + * and reuse the code path for allocating the lowest address. + */ + return (e820_alloc_lowest(0, length, alignment, type)); + case E820_ALLOCATE_LOWEST: + return (e820_alloc_lowest(address, length, alignment, type)); + case E820_ALLOCATE_HIGHEST: + return (e820_alloc_highest(address, length, alignment, type)); + case E820_ALLOCATE_SPECIFIC: + if (e820_add_entry(address, address + length, type) != 0) { + return (0); + } + + return (address); + } + + return (0); +} + int e820_init(struct vmctx *const ctx) { diff --git a/usr.sbin/bhyve/e820.h b/usr.sbin/bhyve/e820.h index 6843ad5dc736..8b8e23422e1f 100644 --- a/usr.sbin/bhyve/e820.h +++ b/usr.sbin/bhyve/e820.h @@ -18,11 +18,27 @@ enum e820_memory_type { E820_TYPE_NVS = 4 }; +enum e820_allocation_strategy { + /* allocate any address */ + E820_ALLOCATE_ANY, + /* allocate lowest address larger than address */ + E820_ALLOCATE_LOWEST, + /* allocate highest address lower than address */ + E820_ALLOCATE_HIGHEST, + /* allocate a specific address */ + E820_ALLOCATE_SPECIFIC +}; + struct e820_entry { uint64_t base; uint64_t length; uint32_t type; } __packed; +#define E820_ALIGNMENT_NONE 1 + +uint64_t e820_alloc(const uint64_t address, const uint64_t length, + const uint64_t alignment, const enum e820_memory_type type, + const enum e820_allocation_strategy strategy); struct qemu_fwcfg_item *e820_get_fwcfg_item(void); int e820_init(struct vmctx *const ctx);