From mboxrd@z Thu Jan 1 00:00:00 1970 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 A1420C4167B for ; Thu, 9 Nov 2023 07:31:02 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 279A08D00DE; Thu, 9 Nov 2023 02:31:02 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 227608D0073; Thu, 9 Nov 2023 02:31:02 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 0EF848D00DE; Thu, 9 Nov 2023 02:31:02 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0011.hostedemail.com [216.40.44.11]) by kanga.kvack.org (Postfix) with ESMTP id 01B7A8D0073 for ; Thu, 9 Nov 2023 02:31:01 -0500 (EST) Received: from smtpin22.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay06.hostedemail.com (Postfix) with ESMTP id C9B5CB5FE2 for ; Thu, 9 Nov 2023 07:31:01 +0000 (UTC) X-FDA: 81437594322.22.6D7AE23 Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.115]) by imf04.hostedemail.com (Postfix) with ESMTP id B06F340017 for ; Thu, 9 Nov 2023 07:30:58 +0000 (UTC) Authentication-Results: imf04.hostedemail.com; dkim=pass header.d=intel.com header.s=Intel header.b=BcuKXJ4Y; spf=pass (imf04.hostedemail.com: domain of xiaoyao.li@intel.com designates 192.55.52.115 as permitted sender) smtp.mailfrom=xiaoyao.li@intel.com; dmarc=pass (policy=none) header.from=intel.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1699515059; h=from:from:sender: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:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=uQSLjD3WxmuxxUaJ+0GTGndt3h9fvL/TS8fN6OoQSDY=; b=pIZ0R5RrX14TV72wshrq3oXf2erChJae/qvbm2re8kMft1Z0nVA0xjK0KLEdNGH0QfKz56 on0FPlzPOkwUWiZIiNxYzO4gzb8uRrpDXOitWOYT4mL4rWv/ooL66oh5drBH73RRhcuVwb Rwn/MFprlmrmt5P1BeDXoc/BzRdG/LU= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1699515059; a=rsa-sha256; cv=none; b=AQXXLe3h1/rc5E3rMO12wSL5z/naIonb4KtAnJRJF4qwHoaj7V/JEpq0+yn3F2+Wxm+Ze+ 9thOBH4Zn7vWVzW6PdXluCb8lqx1+GPUhIvaAwo/D9/zG5q8R5SIxVXd0l6ZpSIGKyg0zx yXEgtFrhlSju/mywpn4uBpdB3Mbo3HQ= ARC-Authentication-Results: i=1; imf04.hostedemail.com; dkim=pass header.d=intel.com header.s=Intel header.b=BcuKXJ4Y; spf=pass (imf04.hostedemail.com: domain of xiaoyao.li@intel.com designates 192.55.52.115 as permitted sender) smtp.mailfrom=xiaoyao.li@intel.com; dmarc=pass (policy=none) header.from=intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1699515058; x=1731051058; h=message-id:date:mime-version:subject:to:cc:references: from:in-reply-to:content-transfer-encoding; bh=OmUu8rMFPk76SQQBpTj2WfQgKT+KOR/AADQ/USzLx/o=; b=BcuKXJ4YKOJOWv8Mx/kuDrEK8ochN5YkuFqhXp293dhHL9ygKx3ceCVD tqo6hTNzlUgu05qIPlnmEKLWuBoleZfpbhtaBqHTudExRXigxMGQUa1Gb VfO29lC4IZTS4ko8P7KyTlRZIc62Bp8tOxi1MxfnOg1lVrgS8vfTjsD0r 0qOGR+pgJewC82qINZujQ4jsyZTRhFehulreTD3DCc01YQ0a4Yxgxl02A wfO6+l2o5QdCmtBiG3Rr3tZeaeczOC5+31vU/z1TsWLubQ2QysBcL+5q4 ZyO/S6baTF+q1fu+2NttF+VUHD2wEUJ3ZavrozNgpO3+CpnesUydGP832 g==; X-IronPort-AV: E=McAfee;i="6600,9927,10888"; a="389738176" X-IronPort-AV: E=Sophos;i="6.03,288,1694761200"; d="scan'208";a="389738176" Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Nov 2023 23:30:52 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10888"; a="886918888" X-IronPort-AV: E=Sophos;i="6.03,288,1694761200"; d="scan'208";a="886918888" Received: from xiaoyaol-hp-g830.ccr.corp.intel.com (HELO [10.93.9.145]) ([10.93.9.145]) by orsmga004-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Nov 2023 23:30:40 -0800 Message-ID: Date: Thu, 9 Nov 2023 15:30:37 +0800 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH 09/34] KVM: Add KVM_EXIT_MEMORY_FAULT exit to report faults to userspace Content-Language: en-US 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, Xu Yilun , Chao Peng , Fuad Tabba , Jarkko Sakkinen , Anish Moorthy , David Matlack , Yu Zhang , Isaku Yamahata , =?UTF-8?B?TWlja2HDq2wgU2FsYcO8?= =?UTF-8?Q?n?= , Vlastimil Babka , Vishal Annapurve , Ackerley Tng , Maciej Szmigiero , David Hildenbrand , Quentin Perret , Michael Roth , Wang , Liam Merwick , Isaku Yamahata , "Kirill A. Shutemov" References: <20231105163040.14904-1-pbonzini@redhat.com> <20231105163040.14904-10-pbonzini@redhat.com> From: Xiaoyao Li In-Reply-To: <20231105163040.14904-10-pbonzini@redhat.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Rspamd-Queue-Id: B06F340017 X-Rspam-User: X-Stat-Signature: sinf8s4z1d866h9cg995hwrxhzgs6ymf X-Rspamd-Server: rspam03 X-HE-Tag: 1699515058-871578 X-HE-Meta: U2FsdGVkX1+ZhyxnpREfW+iCmycQt1wvt2bsdte35avdbshpEQrXmzUWsAxJlY/29eUuxobZmuOISQF886QcIorySNj6M9YtxtbcpJ+DOY6/KqyjVgwnmd+pYq+cfeRz0zp7HZz6pKebz4GT+CKZMb/Dap/5Tvg8l1JBjrTi9CQbUCARnrtdlO2IcK/4SJwoDC9yCOkK6mmoyVMjRht47pAqdqjRYubDdogatWXUqAJYWFTT9Jjr9aYEnQLhNd85GsvjBPUIl+8MV9POqniQfGCCtVi0T5MTXXrIsr2tBTq3kztnA/Q+kH8AoFCl2rwDhT8psSnUibGccJ8nNNL29KF68m7MbxyJ1rAN7LAdB/IUIQ/92jQpTklx9u2DvGToT+2A3Yq5jjh7UfSAuDRA7++8lY07VJom7k7jW3BZ2eBi2I8SZOCQcknMA63mDsOtNiU0ZBw9T2hXkRqpUvVJXPkhzONCxMfAWdVuOOKStWRSymVStH/kRQ3uyH7cAL3q3gbWZnLNRovcc+4a3OAEuUoNmXSV8BJuefUQyBiw+WxR8MyxZ52lOtuvG47yJNkjJcNhMr7vtQGzZbudFTLk7BlvO3JqPM3Wf47XA0j2zT2DpE/jcasbTQr/nK3++Y060tvG0M4XKZbBhcb0pje1c9ZvBk6Sn0QLpvSngs5fPqtL5yeCNuJockjqKYiA9ZNRB35nS0fjwmrsmaVg1bqI8w3fJQUe4oqfMWLh0wiyyfcaHqd/O8d3F+/+HoW1RN+6igz2Y1A9zM4bFymhbwSVj1mq7FyWyy6r1vbvHiyxlUuREth2lg9eDl/NME37IKYNgzL6qK7O0dWzN017QbmELIY7pHqeuYabqRQ/QjWJISjQHb+Z5WItqvY52fQToFJ4R0jqhlZeBd7rWV5WQitbbqfybHsXr8Q4QgYA3UQnWHyB2jNqPfrha5oosYZiGfPcn44ib+1/qRroR6HhlC5 Ks+BRaxB RLgcrNquWips1dNGCGkmcdhAGTQi+2d90aVC6YKsqcwk2wykzhH5iibKDBZooEVqAZKshz3Wvb3iuHd5+3E5WaS2GzMnxDWWbJ2cd8/reiILXSRa1h5O1A2AzcX9/JNMf1J8GhREMiajXxA4xpKjMI9LqdcuvsWN4GnKL0qjTGcJpu7ya9GNoG7l9sVoq+wgtgw89+ZRhTN/rZhx7r2vZcMaw5zbf9aVxeKd6vHX7heDT9T2Fx/IF0V3+Wk4PFxCLWa4qV412058gNLble7X05HXugQDMZkTloBjDUeZ4FuFeJy2DzoOnSi4bZmh7CN/kmAkLuSfZ6wxq4Erc2kNtZo5qdGMrAjtVKviTQpSwcT2vh/K52waqRPQRjL9y3dAANxYml9+RqOFt4plC2bLK0seBpkADCDs0/cf6Alkb2lbpZBt5xuOfckNKBRdUMa3Ge9bTP4iwUwhFOiQ= 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: On 11/6/2023 12:30 AM, Paolo Bonzini wrote: > From: Chao Peng > > Add a new KVM exit type to allow userspace to handle memory faults that > KVM cannot resolve, but that userspace *may* be able to handle (without > terminating the guest). > > KVM will initially use KVM_EXIT_MEMORY_FAULT to report implicit > conversions between private and shared memory. With guest private memory, > there will be two kind of memory conversions: > > - explicit conversion: happens when the guest explicitly calls into KVM > to map a range (as private or shared) > > - implicit conversion: happens when the guest attempts to access a gfn > that is configured in the "wrong" state (private vs. shared) > > On x86 (first architecture to support guest private memory), explicit > conversions will be reported via KVM_EXIT_HYPERCALL+KVM_HC_MAP_GPA_RANGE, > but reporting KVM_EXIT_HYPERCALL for implicit conversions is undesriable > as there is (obviously) no hypercall, and there is no guarantee that the > guest actually intends to convert between private and shared, i.e. what > KVM thinks is an implicit conversion "request" could actually be the > result of a guest code bug. > > KVM_EXIT_MEMORY_FAULT will be used to report memory faults that appear to > be implicit conversions. > > Note! To allow for future possibilities where KVM reports > KVM_EXIT_MEMORY_FAULT and fills run->memory_fault on _any_ unresolved > fault, KVM returns "-EFAULT" (-1 with errno == EFAULT from userspace's > perspective), not '0'! Due to historical baggage within KVM, exiting to > userspace with '0' from deep callstacks, e.g. in emulation paths, is > infeasible as doing so would require a near-complete overhaul of KVM, > whereas KVM already propagates -errno return codes to userspace even when > the -errno originated in a low level helper. > > Report the gpa+size instead of a single gfn even though the initial usage > is expected to always report single pages. It's entirely possible, likely > even, that KVM will someday support sub-page granularity faults, e.g. > Intel's sub-page protection feature allows for additional protections at > 128-byte granularity. > > Link: https://lore.kernel.org/all/20230908222905.1321305-5-amoorthy@google.com > Link: https://lore.kernel.org/all/ZQ3AmLO2SYv3DszH@google.com > Cc: Anish Moorthy > Cc: David Matlack > Suggested-by: Sean Christopherson > Co-developed-by: Yu Zhang > Signed-off-by: Yu Zhang > Signed-off-by: Chao Peng > Co-developed-by: Sean Christopherson > Signed-off-by: Sean Christopherson > Reviewed-by: Paolo Bonzini > Message-Id: <20231027182217.3615211-10-seanjc@google.com> > Signed-off-by: Paolo Bonzini Reviewed-by: Xiaoyao Li > --- > Documentation/virt/kvm/api.rst | 41 ++++++++++++++++++++++++++++++++++ > arch/x86/kvm/x86.c | 1 + > include/linux/kvm_host.h | 11 +++++++++ > include/uapi/linux/kvm.h | 8 +++++++ > 4 files changed, 61 insertions(+) > > diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst > index bdea1423c5f8..481fb0e2ce90 100644 > --- a/Documentation/virt/kvm/api.rst > +++ b/Documentation/virt/kvm/api.rst > @@ -6846,6 +6846,26 @@ array field represents return values. The userspace should update the return > values of SBI call before resuming the VCPU. For more details on RISC-V SBI > spec refer, https://github.com/riscv/riscv-sbi-doc. > > +:: > + > + /* KVM_EXIT_MEMORY_FAULT */ > + struct { > + __u64 flags; > + __u64 gpa; > + __u64 size; > + } memory_fault; > + > +KVM_EXIT_MEMORY_FAULT indicates the vCPU has encountered a memory fault that > +could not be resolved by KVM. The 'gpa' and 'size' (in bytes) describe the > +guest physical address range [gpa, gpa + size) of the fault. The 'flags' field > +describes properties of the faulting access that are likely pertinent. > +Currently, no flags are defined. > + > +Note! KVM_EXIT_MEMORY_FAULT is unique among all KVM exit reasons in that it > +accompanies a return code of '-1', not '0'! errno will always be set to EFAULT > +or EHWPOISON when KVM exits with KVM_EXIT_MEMORY_FAULT, userspace should assume > +kvm_run.exit_reason is stale/undefined for all other error numbers. > + > :: > > /* KVM_EXIT_NOTIFY */ > @@ -7880,6 +7900,27 @@ This capability is aimed to mitigate the threat that malicious VMs can > cause CPU stuck (due to event windows don't open up) and make the CPU > unavailable to host or other VMs. > > +7.34 KVM_CAP_MEMORY_FAULT_INFO > +------------------------------ > + > +:Architectures: x86 > +:Returns: Informational only, -EINVAL on direct KVM_ENABLE_CAP. > + > +The presence of this capability indicates that KVM_RUN will fill > +kvm_run.memory_fault if KVM cannot resolve a guest page fault VM-Exit, e.g. if > +there is a valid memslot but no backing VMA for the corresponding host virtual > +address. > + > +The information in kvm_run.memory_fault is valid if and only if KVM_RUN returns > +an error with errno=EFAULT or errno=EHWPOISON *and* kvm_run.exit_reason is set > +to KVM_EXIT_MEMORY_FAULT. > + > +Note: Userspaces which attempt to resolve memory faults so that they can retry > +KVM_RUN are encouraged to guard against repeatedly receiving the same > +error/annotated fault. > + > +See KVM_EXIT_MEMORY_FAULT for more information. > + > 8. Other capabilities. > ====================== > > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c > index 7b389f27dffc..8f9d8939b63b 100644 > --- a/arch/x86/kvm/x86.c > +++ b/arch/x86/kvm/x86.c > @@ -4625,6 +4625,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) > case KVM_CAP_ENABLE_CAP: > case KVM_CAP_VM_DISABLE_NX_HUGE_PAGES: > case KVM_CAP_IRQFD_RESAMPLE: > + case KVM_CAP_MEMORY_FAULT_INFO: > r = 1; > break; > case KVM_CAP_EXIT_HYPERCALL: > diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h > index 4e741ff27af3..96aa930536b1 100644 > --- a/include/linux/kvm_host.h > +++ b/include/linux/kvm_host.h > @@ -2327,4 +2327,15 @@ static inline void kvm_account_pgtable_pages(void *virt, int nr) > /* Max number of entries allowed for each kvm dirty ring */ > #define KVM_DIRTY_RING_MAX_ENTRIES 65536 > > +static inline void kvm_prepare_memory_fault_exit(struct kvm_vcpu *vcpu, > + gpa_t gpa, gpa_t size) > +{ > + vcpu->run->exit_reason = KVM_EXIT_MEMORY_FAULT; > + vcpu->run->memory_fault.gpa = gpa; > + vcpu->run->memory_fault.size = size; > + > + /* Flags are not (yet) defined or communicated to userspace. */ > + vcpu->run->memory_fault.flags = 0; > +} > + > #endif > diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h > index 308cc70bd6ab..59010a685007 100644 > --- a/include/uapi/linux/kvm.h > +++ b/include/uapi/linux/kvm.h > @@ -275,6 +275,7 @@ struct kvm_xen_exit { > #define KVM_EXIT_RISCV_CSR 36 > #define KVM_EXIT_NOTIFY 37 > #define KVM_EXIT_LOONGARCH_IOCSR 38 > +#define KVM_EXIT_MEMORY_FAULT 39 > > /* For KVM_EXIT_INTERNAL_ERROR */ > /* Emulate instruction failed. */ > @@ -528,6 +529,12 @@ struct kvm_run { > #define KVM_NOTIFY_CONTEXT_INVALID (1 << 0) > __u32 flags; > } notify; > + /* KVM_EXIT_MEMORY_FAULT */ > + struct { > + __u64 flags; > + __u64 gpa; > + __u64 size; > + } memory_fault; > /* Fix the size of the union. */ > char padding[256]; > }; > @@ -1212,6 +1219,7 @@ struct kvm_ppc_resize_hpt { > #define KVM_CAP_ARM_SUPPORTED_BLOCK_SIZES 229 > #define KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES 230 > #define KVM_CAP_USER_MEMORY2 231 > +#define KVM_CAP_MEMORY_FAULT_INFO 232 > > #ifdef KVM_CAP_IRQ_ROUTING >