From nobody Mon Feb 9 03:14:28 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1747740805; cv=none; d=zohomail.com; s=zohoarc; b=NgiAVbxLpLLfkhLvzvYK4HdyKeDDQAsYdaKtRyLtdo/hoLX9KmV+w2pEQZpnxtRIuDK8F0deNDNyynJCKYeJVH9cVlCSOw0TGbY643bFWFhgmb4xeJ66mDSbEK87KIMjNDLf68Ga6L36MC0GEzBtBfyORnFuyDvXkOyUbWyKpzg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1747740805; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=1nUtVlExxdhKd/HsSeA0eTTcYYMS+gfpzYc5w0MxzG0=; b=LNwiIUiKrpIQI3f2+Dp81tMtxYzUPXtYdhugY82w8lyZaIv2IrfPnM1E4U0Ugh2H8pv9eiaF8W46YbXL3GWMgaUIxh3d47xUm0n65Ue8Zn/+sWCx8bBusXFjglxTkBhWjaYCbVhK1UXlvKqFNBqOiboV60C9buXedG7nWJMt8DI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1747740805789786.6370379278616; Tue, 20 May 2025 04:33:25 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uHLCD-00089e-1v; Tue, 20 May 2025 07:31:45 -0400 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 1uHLCA-00088z-Mw for qemu-devel@nongnu.org; Tue, 20 May 2025 07:31:42 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uHLC7-0001HZ-K5 for qemu-devel@nongnu.org; Tue, 20 May 2025 07:31:42 -0400 Received: from DESKTOP-TUU1E5L.fritz.box (unknown [172.201.77.43]) by linux.microsoft.com (Postfix) with ESMTPSA id D119120277D6; Tue, 20 May 2025 04:31:35 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com D119120277D6 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1747740698; bh=1nUtVlExxdhKd/HsSeA0eTTcYYMS+gfpzYc5w0MxzG0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nQEgqMa7ZNGjTo30jhc2EE20c8cjCsZdi8AGrh9UAfHxgDZZVdZRGDmNIKfysjh3R /q01aHqUVsDmxVKktwh8Gq0ds8GzJ9EEEoJxyRObiRJVt+0wkJXTCnm0MJ+8+gj5nS iOvzYltHUzycjNZdfHCvGJVgh69/x7LD9cVKoz98= From: Magnus Kulke To: magnuskulke@microsoft.com, qemu-devel@nongnu.org, liuwe@microsoft.com Cc: Paolo Bonzini , "Michael S. Tsirkin" , Wei Liu , Phil Dennis-Jordan , Roman Bolshakov , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Zhao Liu , Richard Henderson , Cameron Esfahani , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Subject: [RFC PATCH 09/25] accel/mshv: Register guest memory regions with hypervisor Date: Tue, 20 May 2025 13:30:02 +0200 Message-Id: <20250520113018.49569-10-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250520113018.49569-1-magnuskulke@linux.microsoft.com> References: <20250520113018.49569-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@linux.microsoft.com; helo=linux.microsoft.com X-Spam_score_int: -19 X-Spam_score: -2.0 X-Spam_bar: -- X-Spam_report: (-2.0 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham 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+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1747740807032116600 Content-Type: text/plain; charset="utf-8" Handle region_add events by invoking the MSHV memory registration ioctl to map guest memory into the hypervisor partition. This allows the guest to access memory through MSHV-managed mappings. Note that this assumes the hypervisor will accept regions that overlap in userspace_addr. Currently that's not the case, it will be addressed in a later commit in the series. Signed-off-by: Magnus Kulke --- accel/mshv/mem.c | 116 ++++++++++++++++++++++++++++++++++++++-- accel/mshv/trace-events | 1 + include/system/mshv.h | 11 ++++ 3 files changed, 125 insertions(+), 3 deletions(-) diff --git a/accel/mshv/mem.c b/accel/mshv/mem.c index eddd83ae83..2bbeae4f4a 100644 --- a/accel/mshv/mem.c +++ b/accel/mshv/mem.c @@ -13,13 +13,123 @@ =20 #include "qemu/osdep.h" #include "qemu/error-report.h" +#include "hw/hyperv/linux-mshv.h" #include "system/address-spaces.h" #include "system/mshv.h" +#include "exec/memattrs.h" +#include +#include "trace.h" + +static int set_guest_memory(int vm_fd, const mshv_user_mem_region *region) +{ + int ret; + + ret =3D ioctl(vm_fd, MSHV_SET_GUEST_MEMORY, region); + if (ret < 0) { + error_report("failed to set guest memory"); + return -errno; + } + + return 0; +} + +static int map_or_unmap(int vm_fd, const MshvMemoryRegion *mr, bool add) +{ + struct mshv_user_mem_region region =3D {0}; + + region.guest_pfn =3D mr->guest_phys_addr >> MSHV_PAGE_SHIFT; + region.size =3D mr->memory_size; + region.userspace_addr =3D mr->userspace_addr; + + if (!add) { + region.flags |=3D (1 << MSHV_SET_MEM_BIT_UNMAP); + return set_guest_memory(vm_fd, ®ion); + } + + region.flags =3D (1 << MSHV_SET_MEM_BIT_EXECUTABLE); + if (!mr->readonly) { + region.flags |=3D (1 << MSHV_SET_MEM_BIT_WRITABLE); + } + + return set_guest_memory(vm_fd, ®ion); +} + +static int set_memory(const MshvMemoryRegion *mshv_mr, bool add) +{ + int ret =3D 0; + + if (!mshv_mr) { + error_report("Invalid mshv_mr"); + return -1; + } + + trace_mshv_set_memory(add, mshv_mr->guest_phys_addr, + mshv_mr->memory_size, + mshv_mr->userspace_addr, mshv_mr->readonly, + ret); + return map_or_unmap(mshv_state->vm, mshv_mr, add); +} + +/* + * Calculate and align the start address and the size of the section. + * Return the size. If the size is 0, the aligned section is empty. + */ +static hwaddr align_section(MemoryRegionSection *section, hwaddr *start) +{ + hwaddr size =3D int128_get64(section->size); + hwaddr delta, aligned; + + /* + * works in page size chunks, but the function may be called + * with sub-page size and unaligned start address. Pad the start + * address to next and truncate size to previous page boundary. + */ + aligned =3D ROUND_UP(section->offset_within_address_space, + qemu_real_host_page_size()); + delta =3D aligned - section->offset_within_address_space; + *start =3D aligned; + if (delta > size) { + return 0; + } + + return (size - delta) & qemu_real_host_page_mask(); +} =20 void mshv_set_phys_mem(MshvMemoryListener *mml, MemoryRegionSection *secti= on, bool add) { - error_report("unimplemented"); - abort(); -} + int ret =3D 0; + MemoryRegion *area =3D section->mr; + bool writable =3D !area->readonly && !area->rom_device; + hwaddr start_addr, mr_offset, size; + void *ram; + MshvMemoryRegion tmp, *mshv_mr =3D &tmp; + + if (!memory_region_is_ram(area)) { + if (writable) { + return; + } + } + + size =3D align_section(section, &start_addr); + if (!size) { + return; + } + + mr_offset =3D section->offset_within_region + start_addr - + section->offset_within_address_space; =20 + ram =3D memory_region_get_ram_ptr(area) + mr_offset; + + memset(mshv_mr, 0, sizeof(*mshv_mr)); + mshv_mr->guest_phys_addr =3D start_addr; + mshv_mr->memory_size =3D size; + mshv_mr->readonly =3D !writable; + mshv_mr->userspace_addr =3D (uint64_t)ram; + + ret =3D set_memory(mshv_mr, add); + if (ret < 0) { + error_report("Failed to set memory region"); + abort(); + } +} diff --git a/accel/mshv/trace-events b/accel/mshv/trace-events index f99e8c5a41..63625192ec 100644 --- a/accel/mshv/trace-events +++ b/accel/mshv/trace-events @@ -1,3 +1,4 @@ # See docs/devel/tracing.rst for syntax documentation. =20 +mshv_set_memory(bool add, uint64_t gpa, uint64_t size, uint64_t user_addr,= bool readonly, int ret) "[add =3D %d] gpa =3D %lx size =3D %lx user =3D %l= x readonly =3D %d result =3D %d" mshv_hvcall_args(const char* hvcall, uint16_t code, uint16_t in_sz) "built= args for '%s' code: %d in_sz: %d" diff --git a/include/system/mshv.h b/include/system/mshv.h index 398cda3254..bed28b48a9 100644 --- a/include/system/mshv.h +++ b/include/system/mshv.h @@ -32,6 +32,8 @@ #define CONFIG_MSHV_IS_POSSIBLE #endif =20 +#define MSHV_PAGE_SHIFT 12 + =20 #ifdef CONFIG_MSHV_IS_POSSIBLE extern bool mshv_allowed; @@ -84,6 +86,15 @@ int mshv_hvcall(int mshv_fd, const struct mshv_root_hvca= ll *args); =20 =20 /* memory */ +typedef struct MshvMemoryRegion { + uint64_t guest_phys_addr; + uint64_t memory_size; + uint64_t userspace_addr; + bool readonly; +} MshvMemoryRegion; + +int mshv_add_mem(int vm_fd, const MshvMemoryRegion *mr); +int mshv_remove_mem(int vm_fd, const MshvMemoryRegion *mr); void mshv_set_phys_mem(MshvMemoryListener *mml, MemoryRegionSection *secti= on, bool add); /* interrupt */ --=20 2.34.1