From patchwork Fri Oct 27 18:21:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 13438935 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3B5A0C25B47 for ; Fri, 27 Oct 2023 18:22:48 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id A8D5C8000F; Fri, 27 Oct 2023 14:22:44 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 99F398000C; Fri, 27 Oct 2023 14:22:44 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 7A64D8000F; Fri, 27 Oct 2023 14:22:44 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0012.hostedemail.com [216.40.44.12]) by kanga.kvack.org (Postfix) with ESMTP id 5FB1B8000C for ; Fri, 27 Oct 2023 14:22:44 -0400 (EDT) Received: from smtpin12.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay06.hostedemail.com (Postfix) with ESMTP id 3E9E1B591C for ; Fri, 27 Oct 2023 18:22:44 +0000 (UTC) X-FDA: 81392062248.12.138E6B7 Received: from mail-yb1-f201.google.com (mail-yb1-f201.google.com [209.85.219.201]) by imf22.hostedemail.com (Postfix) with ESMTP id 62791C0007 for ; Fri, 27 Oct 2023 18:22:42 +0000 (UTC) Authentication-Results: imf22.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b="k/uwxAUa"; spf=pass (imf22.hostedemail.com: domain of 38f87ZQYKCBIAws51uy66y3w.u64305CF-442Dsu2.69y@flex--seanjc.bounces.google.com designates 209.85.219.201 as permitted sender) smtp.mailfrom=38f87ZQYKCBIAws51uy66y3w.u64305CF-442Dsu2.69y@flex--seanjc.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1698430962; h=from:from:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=7QvlKvGCf16Xr+uDo8e13B+5xMJ1JYvNFtX+dCaVrEc=; b=leYP+qA94ooU0yjb+9P7xRwvHfvxAVEawIVJlHNloOhXZ2yn+/JLZcFREofReW97i2w7bz wxHWTmSHbTzgunDtfY0aRMyhrFV3eSg6/+daZVCw/H1/UAV8LHJ9lRLSKWIDwXaQWjmJZx ksOMuglkgtkm2WbaaTI4jyAP5qYgvtg= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1698430962; a=rsa-sha256; cv=none; b=Q1GxulZ5eSQFhLb5DPFAs18BnHJhSslVMiaQbYFjdyhuB8+sXkfoXUsGKj+a6UYL8RH1X4 M/791eOzlQmuZcLbtq/4spAiB6CV0YSlhycBc1y30lv2ruCgQ92PMUAP8JjHP7zr2ytwwN NgUZnthmNpqKJflSisuAj7fLN/+WKHo= ARC-Authentication-Results: i=1; imf22.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b="k/uwxAUa"; spf=pass (imf22.hostedemail.com: domain of 38f87ZQYKCBIAws51uy66y3w.u64305CF-442Dsu2.69y@flex--seanjc.bounces.google.com designates 209.85.219.201 as permitted sender) smtp.mailfrom=38f87ZQYKCBIAws51uy66y3w.u64305CF-442Dsu2.69y@flex--seanjc.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-d9a5a3f2d4fso1710463276.3 for ; Fri, 27 Oct 2023 11:22:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1698430961; x=1699035761; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=7QvlKvGCf16Xr+uDo8e13B+5xMJ1JYvNFtX+dCaVrEc=; b=k/uwxAUa7uk1XdVQgDy7CTGKwNqHCeSXejZVjuu/tjbNsckc9PWh57AhR/SPXXTPJf lFCpIOvf2kGvOAKfiAJNng8e2TP44j0VGkvz+n0zlA0/KE3k0uhx6uMTUUHlDwEaImnv i49fZAkElCmI4Bc5fOYoFxWVX9cZBY2nmbjCm7I1HsHdYUxxB8sMsdC3XKEjIdBR/UCU rmpk+HlR87W+jOSKG4VVMN0+ZR5r7o6WB5d8lXgaYngdrb99tt64CNMj/0G2nMCRCn0N rlZ90ZFQLqStpUzVzMSR4lhOv/VQesvIeSeiPTOZdEnRGtM0YjC1mskKOHbMcDL73Dag 7ZkA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698430961; x=1699035761; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=7QvlKvGCf16Xr+uDo8e13B+5xMJ1JYvNFtX+dCaVrEc=; b=aLpcldUhKN6oKWDmOUU4Tn1V/Jtv93oIVucWkibRdFUt5fxDs6CGS/H9Zhk21SLOVF o63xqDs5XzpUjCS4OqTYY26LV/ttklwSct9wz3xbSBMK4rahbDdcGCR8fgYD8rsbR7CV 8nptDHlcjvVGdhOVFxyOcJ6Y/1iz1G45jKFQMT9kkDDcXbnpAYSb34tzIU/I3YNvnmzJ wojeZFoKmsSg4LoOFIqYl8y2yP1BIamGN1vTGuTwCHJPeIgEwKgAs8X5WreAgw7Xu5VW jpPa2YqgUJLSBU7lKccMEkOzcb88vJv7lOWHTBBE4cpHK+v2xJmCWxKvBoAXabe0Qp3J +QTQ== X-Gm-Message-State: AOJu0YyXPEKUF0873gV8Jwm1lAG03vnHHLX61YLdCfN18srSyvc3y0JD N1hzQsMv9Kf4P+RjBzMKH6zP/NSzUsg= X-Google-Smtp-Source: AGHT+IEGteVk64WoocowFgc++46Ydn1QrcnOyupSkq+rT/SBtiB9CXAW8K00cqUCj/t8cf8Aji8XyxJUQTQ= X-Received: from zagreus.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5c37]) (user=seanjc job=sendgmr) by 2002:a25:abe2:0:b0:da0:48e1:5f46 with SMTP id v89-20020a25abe2000000b00da048e15f46mr66725ybi.9.1698430961446; Fri, 27 Oct 2023 11:22:41 -0700 (PDT) Reply-To: Sean Christopherson Date: Fri, 27 Oct 2023 11:21:50 -0700 In-Reply-To: <20231027182217.3615211-1-seanjc@google.com> Mime-Version: 1.0 References: <20231027182217.3615211-1-seanjc@google.com> X-Mailer: git-send-email 2.42.0.820.g83a721a137-goog Message-ID: <20231027182217.3615211-9-seanjc@google.com> Subject: [PATCH v13 08/35] KVM: Introduce KVM_SET_USER_MEMORY_REGION2 From: Sean Christopherson To: Paolo Bonzini , Marc Zyngier , Oliver Upton , Huacai Chen , Michael Ellerman , Anup Patel , Paul Walmsley , Palmer Dabbelt , Albert Ou , Sean Christopherson , Alexander Viro , Christian Brauner , "Matthew Wilcox (Oracle)" , Andrew Morton Cc: kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-mips@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, kvm-riscv@lists.infradead.org, linux-riscv@lists.infradead.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, Xiaoyao Li , Xu Yilun , Chao Peng , Fuad Tabba , Jarkko Sakkinen , Anish Moorthy , David Matlack , Yu Zhang , Isaku Yamahata , " =?utf-8?q?Micka=C3=ABl_Sala?= =?utf-8?q?=C3=BCn?= " , Vlastimil Babka , Vishal Annapurve , Ackerley Tng , Maciej Szmigiero , David Hildenbrand , Quentin Perret , Michael Roth , Wang , Liam Merwick , Isaku Yamahata , "Kirill A . Shutemov" X-Stat-Signature: jexgifax89gzzy6yuqh5k8nzamgowigy X-Rspamd-Server: rspam10 X-Rspamd-Queue-Id: 62791C0007 X-Rspam-User: X-HE-Tag: 1698430962-891779 X-HE-Meta: U2FsdGVkX19mw/Xd9zl6G6Zz5SO6D2IABLDyO0Zzy3l1GRac2q9+xLmpCfX0kG8ZVghIayUSpZwOxtYdvk9A1ZcoiogpCgCBpNKWuJ+FA3hiAVPiGZcBMin21ec747zHDXCoPb/or4EI4jZ8WhHYEObInimnZm/P77mTIlIMWRISSIAfh0RoQE7P1MMgX+BfX94vNylf1g9N9k4+y7/w0I265G+2KGRn1aXRzROAphiKYH09DO5MLWojF9xmnMiTyzz9ifTRN8fn2Cibo8Jeg1jlcm1ZizkjK00kfIgLd4NI/6PB66/6Chzcy1FpCXWX7WfqWyOqtEylrNO8wT8UPkZWI5hpco/UJSZnzNSczXGTg0OlDN9lX8nqGNDmgQSVg7atLCkVcO3jjJhIsizeVBvYdA4Ydj1MiPrEeVf9ndwEE0R0JNg2q8JucW/oykDmU6LEVPg1Qj5mFDCH0ypCl6jtn4ZqNwn8SMndhDt9qtGtkT2M3x7qmhLKoSFvx60GHkhQZK6VfdpCytj3DqIYU5Eu5yh573lWosR+GVDwq/+EQXe8OOhGGMNhlTGqq64X00sy5hQg2dESlJwW7rhu2yC2YXqz1fc8CHYNmqG/hjT3VQ9iobBYhcg8YRIxCg06Es3DMFATQFSssohw+meVZb1KlNR1XhBgqfwDzDHQuW+6BfcJOgfO8h9yAF941p5OBj+IvIWS45LgjGd39VbY+NC6+6wTUBAYC1nD5QqwqOQpwftTtJxmh8IeSjy6R3Ywd9FVCSKfIHfz1edUn2sIUjABoC50wI8P3PHnIJcFLRCEB2a7QAsohuuJ2As7KVWWrvNHoFtntv4tqRqywwku4A1/hUWg37tySFXQTDRTTSstyJfk9UnTTCdvrAiYL9X+Qv1SbsIKX+QohtE6ZGjP9E+LkAtEwpL0raIteeE3w3EeYHJxiJkHZ3jHsIzkGwsYK/zeP/M5Z0cse5BtP2s MzT4UGRG V94gm1EFCeO+6dUIDOLCI45cdmV1r9H3Y8F8ozynuLrfqEf3hF0YjVeq4Cic986IDD3n3NDOU1arUIa6UTdP3fzGfiyqSzYxeOwKxvFlhtMiRAkQrUPLN4l64bWZtITI59Ys7utT+o8H3t9gE+kYrRvwA3x6EA5SD/x94bghx7HFy40Cetw3Z1FAiIPiRuE1i8fO0hdUJnJRw4zME2mDGrPyEnXyg6pjYEcZlnmyeHA4U5uCozZQZg3KHnd8+KVPCaF4FfFESu75AuMJ4ykGTYiBNp8sr76gA7NEhBkacxGJ3yZixgJ1zKPRmqgYqvweP6hAr129LY2oDu451di5l00mZDk0WBscNQ9QZci04Ye/1FqY+Y9SSNOyg+5e62BsFXNEO/4nYr6D1ad+7jW4eN2x+rmF+fTlBF6UBYDdJiMWzYDfLfvD22FdaJGeBgfsvv60Is8hWM2Fd7UnBxWv9GXuJT/zzHtVVX4kkmWuAYuMiyMqZGDh/j+Yq0MJWBK/BYD/u9HDzFYP7SVfkXejPnRAlMbYEk+q5N8w6qtexw5JEZe9LRO3j6wLd3Nd5/ST5ph5FJ5qKqeb9Alj/NAeEG/yfpD3rgUrezQfT1lJmpOzkKnSJBM3N8iAe37Y+9k1x3ntKR1XDZ2siPD3qzWn4nOsEtPxl3qx1S62UrweKJmMkvX9EOOgNj+t5Wpi/kBw2Z9qehnMZ7n0CGvyfirYI8szqfPfbnx2Wt2Bo8T3a3VTRJk3AI1ZzmM0newPVtXGRW5IfnqRIO6+QXx30VOt2LGuTclPSdcTnUtS+rz4/F3iGUFJqEQKmJ5usyi8J2yf5+H3u9v79EPhHViLcxvAOeBV4MrX42clGJgfEMoD/fHslSNRSg+EIMvFkZezDHVSjv7EKc4cYI3O3q/ozPaJEyEe8+8UtJLPoiwyXFBHymxNtj7I= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Introduce a "version 2" of KVM_SET_USER_MEMORY_REGION so that additional information can be supplied without setting userspace up to fail. The padding in the new kvm_userspace_memory_region2 structure will be used to pass a file descriptor in addition to the userspace_addr, i.e. allow userspace to point at a file descriptor and map memory into a guest that is NOT mapped into host userspace. Alternatively, KVM could simply add "struct kvm_userspace_memory_region2" without a new ioctl(), but as Paolo pointed out, adding a new ioctl() makes detection of bad flags a bit more robust, e.g. if the new fd field is guarded only by a flag and not a new ioctl(), then a userspace bug (setting a "bad" flag) would generate out-of-bounds access instead of an -EINVAL error. Cc: Jarkko Sakkinen Reviewed-by: Paolo Bonzini Reviewed-by: Xiaoyao Li Signed-off-by: Sean Christopherson Reviewed-by: Fuad Tabba Tested-by: Fuad Tabba --- Documentation/virt/kvm/api.rst | 21 +++++++++++++++++++ arch/x86/kvm/x86.c | 2 +- include/linux/kvm_host.h | 4 ++-- include/uapi/linux/kvm.h | 13 ++++++++++++ virt/kvm/kvm_main.c | 38 +++++++++++++++++++++++++++------- 5 files changed, 67 insertions(+), 11 deletions(-) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 21a7578142a1..ace984acc125 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -6070,6 +6070,27 @@ writes to the CNTVCT_EL0 and CNTPCT_EL0 registers using the SET_ONE_REG interface. No error will be returned, but the resulting offset will not be applied. +4.139 KVM_SET_USER_MEMORY_REGION2 +--------------------------------- + +:Capability: KVM_CAP_USER_MEMORY2 +:Architectures: all +:Type: vm ioctl +:Parameters: struct kvm_userspace_memory_region2 (in) +:Returns: 0 on success, -1 on error + +:: + + struct kvm_userspace_memory_region2 { + __u32 slot; + __u32 flags; + __u64 guest_phys_addr; + __u64 memory_size; /* bytes */ + __u64 userspace_addr; /* start of the userspace allocated memory */ + }; + +See KVM_SET_USER_MEMORY_REGION. + 5. The kvm_run structure ======================== diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 41cce5031126..6409914428ca 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -12455,7 +12455,7 @@ void __user * __x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa, } for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) { - struct kvm_userspace_memory_region m; + struct kvm_userspace_memory_region2 m; m.slot = id | (i << 16); m.flags = 0; diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 5faba69403ac..4e741ff27af3 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -1146,9 +1146,9 @@ enum kvm_mr_change { }; int kvm_set_memory_region(struct kvm *kvm, - const struct kvm_userspace_memory_region *mem); + const struct kvm_userspace_memory_region2 *mem); int __kvm_set_memory_region(struct kvm *kvm, - const struct kvm_userspace_memory_region *mem); + const struct kvm_userspace_memory_region2 *mem); void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *slot); void kvm_arch_memslots_updated(struct kvm *kvm, u64 gen); int kvm_arch_prepare_memory_region(struct kvm *kvm, diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 13065dd96132..bd1abe067f28 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -95,6 +95,16 @@ struct kvm_userspace_memory_region { __u64 userspace_addr; /* start of the userspace allocated memory */ }; +/* for KVM_SET_USER_MEMORY_REGION2 */ +struct kvm_userspace_memory_region2 { + __u32 slot; + __u32 flags; + __u64 guest_phys_addr; + __u64 memory_size; + __u64 userspace_addr; + __u64 pad[16]; +}; + /* * The bit 0 ~ bit 15 of kvm_userspace_memory_region::flags are visible for * userspace, other bits are reserved for kvm internal use which are defined @@ -1192,6 +1202,7 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_COUNTER_OFFSET 227 #define KVM_CAP_ARM_EAGER_SPLIT_CHUNK_SIZE 228 #define KVM_CAP_ARM_SUPPORTED_BLOCK_SIZES 229 +#define KVM_CAP_USER_MEMORY2 230 #ifdef KVM_CAP_IRQ_ROUTING @@ -1473,6 +1484,8 @@ struct kvm_vfio_spapr_tce { struct kvm_userspace_memory_region) #define KVM_SET_TSS_ADDR _IO(KVMIO, 0x47) #define KVM_SET_IDENTITY_MAP_ADDR _IOW(KVMIO, 0x48, __u64) +#define KVM_SET_USER_MEMORY_REGION2 _IOW(KVMIO, 0x49, \ + struct kvm_userspace_memory_region2) /* enable ucontrol for s390 */ struct kvm_s390_ucas_mapping { diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 6e708017064d..3f5b7c2c5327 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -1578,7 +1578,7 @@ static void kvm_replace_memslot(struct kvm *kvm, } } -static int check_memory_region_flags(const struct kvm_userspace_memory_region *mem) +static int check_memory_region_flags(const struct kvm_userspace_memory_region2 *mem) { u32 valid_flags = KVM_MEM_LOG_DIRTY_PAGES; @@ -1980,7 +1980,7 @@ static bool kvm_check_memslot_overlap(struct kvm_memslots *slots, int id, * Must be called holding kvm->slots_lock for write. */ int __kvm_set_memory_region(struct kvm *kvm, - const struct kvm_userspace_memory_region *mem) + const struct kvm_userspace_memory_region2 *mem) { struct kvm_memory_slot *old, *new; struct kvm_memslots *slots; @@ -2084,7 +2084,7 @@ int __kvm_set_memory_region(struct kvm *kvm, EXPORT_SYMBOL_GPL(__kvm_set_memory_region); int kvm_set_memory_region(struct kvm *kvm, - const struct kvm_userspace_memory_region *mem) + const struct kvm_userspace_memory_region2 *mem) { int r; @@ -2096,7 +2096,7 @@ int kvm_set_memory_region(struct kvm *kvm, EXPORT_SYMBOL_GPL(kvm_set_memory_region); static int kvm_vm_ioctl_set_memory_region(struct kvm *kvm, - struct kvm_userspace_memory_region *mem) + struct kvm_userspace_memory_region2 *mem) { if ((u16)mem->slot >= KVM_USER_MEM_SLOTS) return -EINVAL; @@ -4566,6 +4566,7 @@ static int kvm_vm_ioctl_check_extension_generic(struct kvm *kvm, long arg) { switch (arg) { case KVM_CAP_USER_MEMORY: + case KVM_CAP_USER_MEMORY2: case KVM_CAP_DESTROY_MEMORY_REGION_WORKS: case KVM_CAP_JOIN_MEMORY_REGIONS_WORKS: case KVM_CAP_INTERNAL_ERROR_DATA: @@ -4821,6 +4822,14 @@ static int kvm_vm_ioctl_get_stats_fd(struct kvm *kvm) return fd; } +#define SANITY_CHECK_MEM_REGION_FIELD(field) \ +do { \ + BUILD_BUG_ON(offsetof(struct kvm_userspace_memory_region, field) != \ + offsetof(struct kvm_userspace_memory_region2, field)); \ + BUILD_BUG_ON(sizeof_field(struct kvm_userspace_memory_region, field) != \ + sizeof_field(struct kvm_userspace_memory_region2, field)); \ +} while (0) + static long kvm_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { @@ -4843,15 +4852,28 @@ static long kvm_vm_ioctl(struct file *filp, r = kvm_vm_ioctl_enable_cap_generic(kvm, &cap); break; } + case KVM_SET_USER_MEMORY_REGION2: case KVM_SET_USER_MEMORY_REGION: { - struct kvm_userspace_memory_region kvm_userspace_mem; + struct kvm_userspace_memory_region2 mem; + unsigned long size; + + if (ioctl == KVM_SET_USER_MEMORY_REGION) + size = sizeof(struct kvm_userspace_memory_region); + else + size = sizeof(struct kvm_userspace_memory_region2); + + /* Ensure the common parts of the two structs are identical. */ + SANITY_CHECK_MEM_REGION_FIELD(slot); + SANITY_CHECK_MEM_REGION_FIELD(flags); + SANITY_CHECK_MEM_REGION_FIELD(guest_phys_addr); + SANITY_CHECK_MEM_REGION_FIELD(memory_size); + SANITY_CHECK_MEM_REGION_FIELD(userspace_addr); r = -EFAULT; - if (copy_from_user(&kvm_userspace_mem, argp, - sizeof(kvm_userspace_mem))) + if (copy_from_user(&mem, argp, size)) goto out; - r = kvm_vm_ioctl_set_memory_region(kvm, &kvm_userspace_mem); + r = kvm_vm_ioctl_set_memory_region(kvm, &mem); break; } case KVM_GET_DIRTY_LOG: {