From patchwork Tue Sep 10 15:21:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolas Wipper X-Patchwork-Id: 13798753 Received: from smtp-fw-52004.amazon.com (smtp-fw-52004.amazon.com [52.119.213.154]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C5B4819ABB6; Tue, 10 Sep 2024 15:22:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=52.119.213.154 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725981758; cv=none; b=SD/N8Jo+8sf+4HmrB23QBwO/WLbUbKWmz7eU314EOZ/9zE8YPNrUKLQL5L+es8zPCjwbfDs8HprMiez/9hUKyvzLuIwerflpzHf1ZQaVohuVaoQ3mcGROglirozDDRHFAAFVwj/zp5ASZPHcHVgVVQ8uqcAuFLOJZtsful2Ts4M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725981758; c=relaxed/simple; bh=B/K2QUnoSkS4ZvGZwey8z+/mNvJkvwtcoAo//x+7GQk=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=b22ptN2yPgFW2DaX+/ty6xrKgrUmloCnRdNji1zUmSqdo6pYgQBNNvKgDt7p60nOZBWF+muQBiP3y2n6v2hjXbyFbo3g2mJ+BkuTbkmaWS1ZzOCMZMMjy0bzgkSXBJnIJoof5/FZTGWigVYFJxTrfzFd5WZID8ZHh600f3VWUGc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de; spf=pass smtp.mailfrom=amazon.de; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b=R5vVlrEn; arc=none smtp.client-ip=52.119.213.154 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amazon.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b="R5vVlrEn" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazon201209; t=1725981756; x=1757517756; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=NC1az9/hAILYnJFLiqNcORpyqC2hQx+wOpC0bECqtHU=; b=R5vVlrEn453Ei4Y5fhEsyz3AEMyiFQg5oo9Bl8vpN2zvo+EJKj/gaiZF yUmAhTMdZA2jGNJM1OFZFfXw2PjE1qR2uYW104UEYOBhEPc3eSMDt/XdP /fxRr0X4zCsqVeW54Jx7EaZCLqSf2fF3NjonaUfJOKEgU799xI31VMeWO U=; X-IronPort-AV: E=Sophos;i="6.10,217,1719878400"; d="scan'208";a="230917179" Received: from iad12-co-svc-p1-lb1-vlan2.amazon.com (HELO smtpout.prod.us-west-2.prod.farcaster.email.amazon.dev) ([10.43.8.2]) by smtp-border-fw-52004.iad7.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Sep 2024 15:22:32 +0000 Received: from EX19MTAEUA001.ant.amazon.com [10.0.43.254:48425] by smtpin.naws.eu-west-1.prod.farcaster.email.amazon.dev [10.0.1.162:2525] with esmtp (Farcaster) id 56079a0b-55b2-49ad-8775-ef55f4079c09; Tue, 10 Sep 2024 15:22:30 +0000 (UTC) X-Farcaster-Flow-ID: 56079a0b-55b2-49ad-8775-ef55f4079c09 Received: from EX19D041EUB004.ant.amazon.com (10.252.61.113) by EX19MTAEUA001.ant.amazon.com (10.252.50.223) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Tue, 10 Sep 2024 15:22:29 +0000 Received: from EX19MTAUEA001.ant.amazon.com (10.252.134.203) by EX19D041EUB004.ant.amazon.com (10.252.61.113) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Tue, 10 Sep 2024 15:22:28 +0000 Received: from dev-dsk-nikwip-1b-bc9ec026.eu-west-1.amazon.com (10.253.74.52) by mail-relay.amazon.com (10.252.134.102) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34 via Frontend Transport; Tue, 10 Sep 2024 15:22:27 +0000 From: Nikolas Wipper To: Paolo Bonzini , Sean Christopherson , Vitaly Kuznetsov CC: Nicolas Saenz Julienne , Alexander Graf , James Gowans , , Thomas Gleixner , "Ingo Molnar" , Borislav Petkov , Dave Hansen , , , , , , , , Nikolas Wipper Subject: [PATCH 01/15] KVM: Add API documentation for KVM_TRANSLATE2 Date: Tue, 10 Sep 2024 15:21:53 +0000 Message-ID: <20240910152207.38974-2-nikwip@amazon.de> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240910152207.38974-1-nikwip@amazon.de> References: <20240910152207.38974-1-nikwip@amazon.de> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add API documentation for the new KVM_TRANSLATE2 ioctl. Signed-off-by: Nikolas Wipper --- Documentation/virt/kvm/api.rst | 131 +++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index a4b7dc4a9dda..632dc591badf 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -6442,6 +6442,137 @@ the capability to be present. `flags` must currently be zero. +4.144 KVM_TRANSLATE2 +-------------------- + +:Capability: KVM_CAP_TRANSLATE2 +:Architectures: x86 +:Type: vcpu ioctl +:Parameters: struct kvm_translation2 (in/out) +:Returns: 0 on success, <0 on error + +KVM_TRANSLATE2 translates a guest virtual address into a guest physical one +while probing for requested access permissions and allowing for control over +whether accessed and dirty bits are set in each of the page map levels +structure. If the page walk fails, it provides detailed information explaining +the reason for the failure. + +:: + + /* for KVM_TRANSLATE2 */ + struct kvm_translation2 { + /* in */ + __u64 linear_address; + #define KVM_TRANSLATE_FLAGS_SET_ACCESSED (1 << 0) + #define KVM_TRANSLATE_FLAGS_SET_DIRTY (1 << 1) + #define KVM_TRANSLATE_FLAGS_FORCE_SET_ACCESSED (1 << 2) + __u16 flags; + #define KVM_TRANSLATE_ACCESS_WRITE (1 << 0) + #define KVM_TRANSLATE_ACCESS_USER (1 << 1) + #define KVM_TRANSLATE_ACCESS_EXEC (1 << 2) + #define KVM_TRANSLATE_ACCESS_ALL \ + (KVM_TRANSLATE_ACCESS_WRITE | \ + KVM_TRANSLATE_ACCESS_USER | \ + KVM_TRANSLATE_ACCESS_EXEC) + __u16 access; + __u8 padding[4]; + + /* out */ + __u64 physical_address; + __u8 valid; + #define KVM_TRANSLATE_FAULT_NOT_PRESENT 1 + #define KVM_TRANSLATE_FAULT_PRIVILEGE_VIOLATION 2 + #define KVM_TRANSLATE_FAULT_RESERVED_BITS 3 + #define KVM_TRANSLATE_FAULT_INVALID_GVA 4 + #define KVM_TRANSLATE_FAULT_INVALID_GPA 5 + __u16 error_code; + __u8 set_bits_succeeded; + __u8 padding2[4]; + }; + +If the page walk succeeds, `physical_address` will contain the result of the +page walk, `valid` will be set to 1 and `error_code` will not contain any +meaningful value. + +If the page walk fails, `valid` will be set to 0 and `error_code` will contain +the reason of the walk failure. `physical_address` may contain the physical +address of the page table where the page walk was aborted, depending on the +returned error code: + +.. csv-table:: + :header: "`error_code`", "`physical_address`" + + "KVM_TRANSLATE_FAULT_NOT_PRESENT", "Physical address of the page table entry without the present bit" + "KVM_TRANSLATE_FAULT_PRIVILEGE_VIOLATION", "Physical address of the page table entry where access checks failed" + "KVM_TRANSLATE_FAULT_RESERVED_BITS", "Physical address of the page table entry with reserved bits set" + "KVM_TRANSLATE_FAULT_INVALID_GPA", "Physical address that wasn't backed by host memory" + "KVM_TRANSLATE_FAULT_INVALID_GVA", "empty", + +The `flags` field can take each of these flags: + +KVM_TRANSLATE_FLAGS_SET_ACCESSED + Sets the accessed bit on each page table level on a successful page walk. + +KVM_TRANSLATE_FLAGS_SET_DIRTY + Sets the dirty bit on each page table level on a successful page walk. + +KVM_TRANSLATE_FLAGS_FORCE_SET_ACCESSED + Forces setting the accessed bit on every page table level that was walked + successfully on failed page walks. + +.. warning:: + + Setting these flags and then using the translated address may lead to a + race, if another vCPU remotely flushes the local vCPUs TLB while the + address is still in use. This can be mitigated by stalling such TLB flushes + until the memory operation is finished. + +The `access` field can take each of these flags: + +KVM_TRANSLATE_ACCESS_WRITE + The page walker will check for write access on every page table. + +KVM_TRANSLATE_ACCESS_USER + The page walker will check for user mode access on every page table. + +KVM_TRANSLATE_ACCESS_EXEC + The page walker will check for executable/fetch access on every page table. + +If none of these flags are set, read access and kernel mode permissions are +implied. + +The `error_code` field can take one of these values: + +KVM_TRANSLATE_FAULT_NOT_PRESENT + The virtual address is not mapped to any physical address. + +KVM_TRANSLATE_FAULT_PRIVILEGE_VIOLATION + One of the access checks failed during the page walk. + +KVM_TRANSLATE_FAULT_RESERVED_BITS + Reserved bits were set in a page table. + +KVM_TRANSLATE_FAULT_INVALID_GPA + One of the guest page table entries' addresses along the page walk was not + backed by a host memory. + +KVM_TRANSLATE_FAULT_INVALID_GVA + The GVA provided is not valid in the current vCPU state. For example, if on + 32-bit systems, the virtual address provided was larger than 32-bits, or on + 64-bit x86 systems, the virtual address was non-canonical. + +Regardless of the success of the page walk, `set_bits_succeeded` will contain a +boolean value indicating whether the accessed/dirty bits were set. It may be +false, if the bits were not set, because the page walk failed and +KVM_TRANSLATE_FLAGS_FORCE_SET_ACCESSED was not passed, or if there was an error +setting the bits, for example, the host memory backing the page table entry was +marked read-only. + +KVM_TRANSLATE_FLAGS_FORCE_SET_ACCESSED and KVM_TRANSLATE_FLAGS_SET_DIRTY must +never be passed without KVM_TRANSLATE_FLAGS_SET_ACCESSED. +KVM_TRANSLATE_FLAGS_SET_DIRTY must never be passed without +KVM_TRANSLATE_ACCESS_WRITE. Doing either will cause the ioctl to fail with exit +code -EINVAL. 5. The kvm_run structure ======================== From patchwork Tue Sep 10 15:21:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolas Wipper X-Patchwork-Id: 13798754 Received: from smtp-fw-33001.amazon.com (smtp-fw-33001.amazon.com [207.171.190.10]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A808F19ABC2; Tue, 10 Sep 2024 15:22:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=207.171.190.10 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725981779; cv=none; b=ZjVoIoeXYWPfHi6oPQD8SRTh1jR9EE3Ha3vtNdAYjoS/7Ri6nzErEBW4SK3+RrkRu6G9LmBoIjUGnHdMl8jFWFsZUYoAOZAlQ+DGtGHKF71Y1THadVuUeJVIzaIRZlRbEvX+wizJh5bDapNQwc7IGE5vk/nErXzjJLg9joYyktY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725981779; c=relaxed/simple; bh=yMxfmheIQpBLxXd+Jqe5Df1ZtrFux0QCDdvQ4dqCPek=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=BX11BQWVvopI2azoSssMx/Kq6IxcTeTyV+/S7j3DiYqSKv0pfTG3xMB6B/+eGO/WtQRc18Kq9q8y5X/yTg6yiAMFyHvd1/1JIkopA+wCILmWpjLgvcpBBla1bzt2lQ33ynX5RisvnoNmZMvaYnNfZ0rwqPYfpc/LBoVPbkDxAkg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de; spf=pass smtp.mailfrom=amazon.de; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b=BRmN5oRG; arc=none smtp.client-ip=207.171.190.10 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amazon.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b="BRmN5oRG" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazon201209; t=1725981778; x=1757517778; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=L+gUMvE9WBFIBh4Oxm0FXV+Z2DytGGJUGYHgLlrXem8=; b=BRmN5oRG21bNWgFzAyljmJ3VqajcZkyX5IKG42888u4blSLd1qDlJs5b 7TCNmq1gVBnwwwQJzdj6S13LCeYuOxnyyoYAUBifvPpLmIXO6AA0wlyzp dqR3C7kId49wfSVHqHn+ztUyyc73ph5PjteQsQaTDD3s+zPQskcvxGZG4 s=; X-IronPort-AV: E=Sophos;i="6.10,217,1719878400"; d="scan'208";a="367263917" Received: from iad12-co-svc-p1-lb1-vlan3.amazon.com (HELO smtpout.prod.us-east-1.prod.farcaster.email.amazon.dev) ([10.43.8.6]) by smtp-border-fw-33001.sea14.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Sep 2024 15:22:51 +0000 Received: from EX19MTAEUB001.ant.amazon.com [10.0.17.79:16832] by smtpin.naws.eu-west-1.prod.farcaster.email.amazon.dev [10.0.1.162:2525] with esmtp (Farcaster) id 85ed7a91-53a7-4f38-8884-6546c53c5910; Tue, 10 Sep 2024 15:22:47 +0000 (UTC) X-Farcaster-Flow-ID: 85ed7a91-53a7-4f38-8884-6546c53c5910 Received: from EX19D014EUC002.ant.amazon.com (10.252.51.161) by EX19MTAEUB001.ant.amazon.com (10.252.51.26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Tue, 10 Sep 2024 15:22:46 +0000 Received: from EX19MTAUEC001.ant.amazon.com (10.252.135.222) by EX19D014EUC002.ant.amazon.com (10.252.51.161) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Tue, 10 Sep 2024 15:22:46 +0000 Received: from dev-dsk-nikwip-1b-bc9ec026.eu-west-1.amazon.com (10.253.74.52) by mail-relay.amazon.com (10.252.135.200) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34 via Frontend Transport; Tue, 10 Sep 2024 15:22:44 +0000 From: Nikolas Wipper To: Paolo Bonzini , Sean Christopherson , Vitaly Kuznetsov CC: Nicolas Saenz Julienne , Alexander Graf , James Gowans , , Thomas Gleixner , "Ingo Molnar" , Borislav Petkov , Dave Hansen , , , , , , , , Nikolas Wipper Subject: [PATCH 02/15] KVM: x86/mmu: Abort page walk if permission checks fail Date: Tue, 10 Sep 2024 15:21:54 +0000 Message-ID: <20240910152207.38974-3-nikwip@amazon.de> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240910152207.38974-1-nikwip@amazon.de> References: <20240910152207.38974-1-nikwip@amazon.de> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Abort the page walk, if permission checks fail on any page table level, by moving the check to within the page walker loop. Currently, the page walker only checks for access flags after successfully walking the entire paging structure. This change is needed later to enable setting accessed bits in each page table that was successfully visited, during a page walk that ultimately failed. As a result, error codes returned by the page walker may observe a change in behaviour, specifically, the error code will be built as soon as an access violation is found, meaning that for example, if an access violation is detected on page level 4, the page walker will abort the walk without looking at level 3 and below. However, since the error code returned is built from the passed access requirements, regardless of the actual cause of the failure, it will only be different if there is an access violation in one level and a PKRU violation in a lower one. Previously the error code would include this PKRU violation, whereas now it does not, which is still in line with the behaviour specified in Intel's SDM. The exact procedure to test for violations is currently not specified in the SDM, but aborting the page walk early seems to be a reasonable implementation detail. As KVM does not read the PK bit anywhere, this only results in a different page-fault error codes for guests. Signed-off-by: Nikolas Wipper --- arch/x86/kvm/mmu/paging_tmpl.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h index ae7d39ff2d07..d9c3c78b3c14 100644 --- a/arch/x86/kvm/mmu/paging_tmpl.h +++ b/arch/x86/kvm/mmu/paging_tmpl.h @@ -422,6 +422,12 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, goto error; } + /* Convert to ACC_*_MASK flags for struct guest_walker. */ + walker->pte_access = FNAME(gpte_access)(pte_access ^ walk_nx_mask); + errcode = permission_fault(vcpu, mmu, walker->pte_access, pte_pkey, access); + if (unlikely(errcode)) + goto error; + walker->ptes[walker->level - 1] = pte; /* Convert to ACC_*_MASK flags for struct guest_walker. */ @@ -431,12 +437,6 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, pte_pkey = FNAME(gpte_pkeys)(vcpu, pte); accessed_dirty = have_ad ? pte_access & PT_GUEST_ACCESSED_MASK : 0; - /* Convert to ACC_*_MASK flags for struct guest_walker. */ - walker->pte_access = FNAME(gpte_access)(pte_access ^ walk_nx_mask); - errcode = permission_fault(vcpu, mmu, walker->pte_access, pte_pkey, access); - if (unlikely(errcode)) - goto error; - gfn = gpte_to_gfn_lvl(pte, walker->level); gfn += (addr & PT_LVL_OFFSET_MASK(walker->level)) >> PAGE_SHIFT; From patchwork Tue Sep 10 15:21:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolas Wipper X-Patchwork-Id: 13798755 Received: from smtp-fw-80009.amazon.com (smtp-fw-80009.amazon.com [99.78.197.220]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E43BD1A0B1E; Tue, 10 Sep 2024 15:23:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=99.78.197.220 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725981790; cv=none; b=jlh9WN4hQrZZ6wFGMRlBn2UMCx8rwGFkAqJH+CNapTtF7BuKZjLTC0iln1yCwNTu2W1X9tYrU+Y/lYWjcLxUuyHY3vAAUm1vcRZXtiEQtrQH0EECO7PLbFoZTonPKkfyoDxwutOL42hHrit0MEJ8evXUf5GPoMSMKq3LvpsDBS4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725981790; c=relaxed/simple; bh=itnc9gRgJy+e6+5K0E7HXZ5B4JuLftNx3P5bSoOBP7Y=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=MUYLTETpHqkoFnj6eHUlp2D/PI6f9E7Iy6/AJHQSVW6EbRGtbsLKVKVYSRf5mslJpAlH6QHqqu5bNDVsnQ2wTazpJMkloRWRn5lPgIMdhbBz+kV07evj/9f2vHVxdfk7gQyNveBZD8k3q1isIa1wOl44mSddR+dVydvydAdJw1s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de; spf=pass smtp.mailfrom=amazon.de; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b=lqhhk/nq; arc=none smtp.client-ip=99.78.197.220 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amazon.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b="lqhhk/nq" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazon201209; t=1725981789; x=1757517789; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Km2TrPXosr7uX6oYzMA+218QoXlL+9LaKCD4YvBno24=; b=lqhhk/nqiulfoDQJzCvbQHRjNTyIF7c9TfclsnWTEjph5b35oxkuKBVa al1AeL2UoZ+v9/6UPaDddgEE6w7kTPHlnV9M8OF5s+2AnKLOh2QZN6zTg L03kZYXuYHLtqW37vs8c5JxHAkn6WDN3ixLivfNtceFm2Kh1lQNDyJVyv U=; X-IronPort-AV: E=Sophos;i="6.10,217,1719878400"; d="scan'208";a="124219001" Received: from pdx4-co-svc-p1-lb2-vlan2.amazon.com (HELO smtpout.prod.us-west-2.prod.farcaster.email.amazon.dev) ([10.25.36.210]) by smtp-border-fw-80009.pdx80.corp.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Sep 2024 15:23:06 +0000 Received: from EX19MTAUWA001.ant.amazon.com [10.0.21.151:55695] by smtpin.naws.us-west-2.prod.farcaster.email.amazon.dev [10.0.52.222:2525] with esmtp (Farcaster) id 418f5ccd-c6c8-424b-bda0-10b12e0c347f; Tue, 10 Sep 2024 15:23:06 +0000 (UTC) X-Farcaster-Flow-ID: 418f5ccd-c6c8-424b-bda0-10b12e0c347f Received: from EX19D020UWA003.ant.amazon.com (10.13.138.254) by EX19MTAUWA001.ant.amazon.com (10.250.64.218) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Tue, 10 Sep 2024 15:23:05 +0000 Received: from EX19MTAUWA001.ant.amazon.com (10.250.64.204) by EX19D020UWA003.ant.amazon.com (10.13.138.254) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Tue, 10 Sep 2024 15:23:05 +0000 Received: from dev-dsk-nikwip-1b-bc9ec026.eu-west-1.amazon.com (10.253.74.52) by mail-relay.amazon.com (10.250.64.204) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34 via Frontend Transport; Tue, 10 Sep 2024 15:23:02 +0000 From: Nikolas Wipper To: Paolo Bonzini , Sean Christopherson , Vitaly Kuznetsov CC: Nicolas Saenz Julienne , Alexander Graf , James Gowans , , Thomas Gleixner , "Ingo Molnar" , Borislav Petkov , Dave Hansen , , , , , , , , Nikolas Wipper Subject: [PATCH 03/15] KVM: x86/mmu: Introduce exception flag for unmapped GPAs Date: Tue, 10 Sep 2024 15:21:55 +0000 Message-ID: <20240910152207.38974-4-nikwip@amazon.de> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240910152207.38974-1-nikwip@amazon.de> References: <20240910152207.38974-1-nikwip@amazon.de> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Introduce a flag in x86_exception which signals that a page walk failed because a page table GPA wasn't backed by a memslot. This only applies to page tables; the final physical address is not checked. This extra flag is needed, because the normal page fault error code does not contain a bit to signal this kind of fault. Used in subsequent patches to give userspace information about translation failure. Signed-off-by: Nikolas Wipper --- arch/x86/kvm/kvm_emulate.h | 2 ++ arch/x86/kvm/mmu/paging_tmpl.h | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/kvm_emulate.h b/arch/x86/kvm/kvm_emulate.h index 55a18e2f2dcd..afd8e86bc6af 100644 --- a/arch/x86/kvm/kvm_emulate.h +++ b/arch/x86/kvm/kvm_emulate.h @@ -27,6 +27,8 @@ struct x86_exception { u64 address; /* cr2 or nested page fault gpa */ u8 async_page_fault; unsigned long exit_qualification; +#define KVM_X86_UNMAPPED_PTE_GPA BIT(0) + u16 flags; }; /* diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h index d9c3c78b3c14..f6a78b7cfca1 100644 --- a/arch/x86/kvm/mmu/paging_tmpl.h +++ b/arch/x86/kvm/mmu/paging_tmpl.h @@ -339,6 +339,8 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, #endif walker->max_level = walker->level; + walker->fault.flags = 0; + /* * FIXME: on Intel processors, loads of the PDPTE registers for PAE paging * by the MOV to CR instruction are treated as reads and do not cause the @@ -393,8 +395,10 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, return 0; slot = kvm_vcpu_gfn_to_memslot(vcpu, gpa_to_gfn(real_gpa)); - if (!kvm_is_visible_memslot(slot)) + if (!kvm_is_visible_memslot(slot)) { + walker->fault.flags = KVM_X86_UNMAPPED_PTE_GPA; goto error; + } host_addr = gfn_to_hva_memslot_prot(slot, gpa_to_gfn(real_gpa), &walker->pte_writable[walker->level - 1]); From patchwork Tue Sep 10 15:21:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolas Wipper X-Patchwork-Id: 13798756 Received: from smtp-fw-9106.amazon.com (smtp-fw-9106.amazon.com [207.171.188.206]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0E8EE1925B4; Tue, 10 Sep 2024 15:23:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=207.171.188.206 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725981806; cv=none; b=jpftpejVLo5GCE5Ueq0ADyVSsQH9o5l3ippgErO52WvQecf20ayfPURvrP1qXq73xStPNTJY1WTz1iPLhnqOXWNLeyx265Man8Bdj4Dl+VcSacx6/TZy7WKgcVlDEncYU+mdYqmM5maYhSahFVO2GWs8O6bDNtY6plOvHS3ZeHQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725981806; c=relaxed/simple; bh=QE2bk34erymW2ZNrDHe69rw53PQY4qTok1UkFXnEhLQ=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=qgLoMfsQV61tH5Qaj610+NtJ5f3Ma83sXHXVIRTm4B13OuAuvNJB3LL7B/CXIdkQK+5e6EL4sBAHqym0t0KztoVnKiL1aHcCrTMYsiGB3HFPIv41C8RNOEoLpfE67/drzbY2yEZujib+ogFau599dbEc7lE1+II/hToUyAwqm4I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de; spf=pass smtp.mailfrom=amazon.de; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b=onwNz2cR; arc=none smtp.client-ip=207.171.188.206 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amazon.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b="onwNz2cR" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazon201209; t=1725981805; x=1757517805; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=lz3T3yEcwSJRvadrpSBViYV6gSG8fKxfLSa5nbTuxyw=; b=onwNz2cRBMgtvZJoje0nbsyFiSjF8l2Wmr1GnLA2+WmEQGkUb0+311SF gaJ4K1gXw5pwCKBrEEGJGZbQJFHNd4ePtGf4Q45msPOaTJyudtVqLJ+ZV 3nVkbKaFdX4q6ffNuzRwtRAO56CVtfXoqo2CNrH8lTuXNZa7pWcar6ow4 s=; X-IronPort-AV: E=Sophos;i="6.10,217,1719878400"; d="scan'208";a="758470419" Received: from pdx4-co-svc-p1-lb2-vlan2.amazon.com (HELO smtpout.prod.us-west-2.prod.farcaster.email.amazon.dev) ([10.25.36.210]) by smtp-border-fw-9106.sea19.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Sep 2024 15:23:25 +0000 Received: from EX19MTAEUA001.ant.amazon.com [10.0.43.254:25293] by smtpin.naws.eu-west-1.prod.farcaster.email.amazon.dev [10.0.16.205:2525] with esmtp (Farcaster) id 36754a66-9e06-49ef-ae03-a1478e3cf7ea; Tue, 10 Sep 2024 15:23:23 +0000 (UTC) X-Farcaster-Flow-ID: 36754a66-9e06-49ef-ae03-a1478e3cf7ea Received: from EX19D004EUA001.ant.amazon.com (10.252.50.27) by EX19MTAEUA001.ant.amazon.com (10.252.50.223) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Tue, 10 Sep 2024 15:23:23 +0000 Received: from EX19MTAUEA001.ant.amazon.com (10.252.134.203) by EX19D004EUA001.ant.amazon.com (10.252.50.27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Tue, 10 Sep 2024 15:23:22 +0000 Received: from dev-dsk-nikwip-1b-bc9ec026.eu-west-1.amazon.com (10.253.74.52) by mail-relay.amazon.com (10.252.134.102) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34 via Frontend Transport; Tue, 10 Sep 2024 15:23:21 +0000 From: Nikolas Wipper To: Paolo Bonzini , Sean Christopherson , Vitaly Kuznetsov CC: Nicolas Saenz Julienne , Alexander Graf , James Gowans , , Thomas Gleixner , "Ingo Molnar" , Borislav Petkov , Dave Hansen , , , , , , , , Nikolas Wipper Subject: [PATCH 04/15] KVM: x86/mmu: Store GPA in exception if applicable Date: Tue, 10 Sep 2024 15:21:56 +0000 Message-ID: <20240910152207.38974-5-nikwip@amazon.de> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240910152207.38974-1-nikwip@amazon.de> References: <20240910152207.38974-1-nikwip@amazon.de> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Store the GPA where the page walk failed within the walker's exception. Precisely this means, the PTE's GPA, if it couldn't be resolved or it caused an access violation, or the fully translated GPA in case the final page caused an access violation. Returning the GPA from the page walker directly is not possible, because other code within KVM relies on INVALID_GPA being returned on failure. Signed-off-by: Nikolas Wipper --- arch/x86/kvm/kvm_emulate.h | 6 ++++++ arch/x86/kvm/mmu/paging_tmpl.h | 1 + 2 files changed, 7 insertions(+) diff --git a/arch/x86/kvm/kvm_emulate.h b/arch/x86/kvm/kvm_emulate.h index afd8e86bc6af..6501ce1c76fd 100644 --- a/arch/x86/kvm/kvm_emulate.h +++ b/arch/x86/kvm/kvm_emulate.h @@ -25,6 +25,12 @@ struct x86_exception { u16 error_code; bool nested_page_fault; u64 address; /* cr2 or nested page fault gpa */ + /* + * If error_code is a page fault, this will be the address of the last + * visited page table, or the fully translated address if it caused the + * failure. Otherwise, it will not hold a meaningful value. + */ + u64 gpa_page_fault; u8 async_page_fault; unsigned long exit_qualification; #define KVM_X86_UNMAPPED_PTE_GPA BIT(0) diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h index f6a78b7cfca1..74651b097fa0 100644 --- a/arch/x86/kvm/mmu/paging_tmpl.h +++ b/arch/x86/kvm/mmu/paging_tmpl.h @@ -485,6 +485,7 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, walker->fault.vector = PF_VECTOR; walker->fault.error_code_valid = true; walker->fault.error_code = errcode; + walker->fault.gpa_page_fault = real_gpa; #if PTTYPE == PTTYPE_EPT /* From patchwork Tue Sep 10 15:21:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolas Wipper X-Patchwork-Id: 13798757 Received: from smtp-fw-9106.amazon.com (smtp-fw-9106.amazon.com [207.171.188.206]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D17E219D88C; Tue, 10 Sep 2024 15:23:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=207.171.188.206 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725981833; cv=none; b=XxoYi5BTFmzaEOypDPOeeXRXO1OSEDWTDlY8G+ViTrQP+viBZmGTilSa1J8IonTT+5tFNosOk7pssA7OEwB5zx4i23Pl2UoF6YA1bhkflfRrswCHTBK++lhiBA3xIcl4XeMnsK4HX4ckOjrDjEFgOz2nmqRY5mnkXWerXlE/LIM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725981833; c=relaxed/simple; bh=BVepAbkOeEU3slbtp/jqhBcz5M3ofT+FBHaVmTXzrPo=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=QVXWc1LH5P6w9BW1WkWvTFpXqZ2BT9agDzNqqEy8Mmy3SokPK2hRWmdw9XU9b83329QKboF8PSMQJ/5JK3aSWkQ/BJUPoqdtZ1OOW83MHwQ6MOrU+UwAbBibscPSYds4JR+NDxgbH6We8LkSCShgDppMkTG9qHWj5pQfkazDAWo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de; spf=pass smtp.mailfrom=amazon.de; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b=VAb69RGB; arc=none smtp.client-ip=207.171.188.206 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amazon.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b="VAb69RGB" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazon201209; t=1725981829; x=1757517829; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=eR/aj8npvoNsBgWmleE4bomhd/6jXremotPxYL2Sd6Y=; b=VAb69RGBgV8VUNYVnWkUuzwL2f7jAl+Mrvpq5UtBwy6n6U5oR88bnM+Z s3VRveyC1kmcZdthhBYH9qyHooorNvb94sRWzUjAqK4srtkUhVWtOQuLW Iy0pLZcuZoVDKNrGQTwwTaoZb26ew4s8LX2Mp4bQGw0MoH+e0yaUQvZRl U=; X-IronPort-AV: E=Sophos;i="6.10,217,1719878400"; d="scan'208";a="758470499" Received: from pdx4-co-svc-p1-lb2-vlan2.amazon.com (HELO smtpout.prod.us-east-1.prod.farcaster.email.amazon.dev) ([10.25.36.210]) by smtp-border-fw-9106.sea19.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Sep 2024 15:23:47 +0000 Received: from EX19MTAEUB001.ant.amazon.com [10.0.17.79:2418] by smtpin.naws.eu-west-1.prod.farcaster.email.amazon.dev [10.0.38.136:2525] with esmtp (Farcaster) id d4f45114-c17c-419b-9541-f2fc8de2c3fd; Tue, 10 Sep 2024 15:23:45 +0000 (UTC) X-Farcaster-Flow-ID: d4f45114-c17c-419b-9541-f2fc8de2c3fd Received: from EX19D014EUC002.ant.amazon.com (10.252.51.161) by EX19MTAEUB001.ant.amazon.com (10.252.51.26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Tue, 10 Sep 2024 15:23:40 +0000 Received: from EX19MTAUEC001.ant.amazon.com (10.252.135.222) by EX19D014EUC002.ant.amazon.com (10.252.51.161) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Tue, 10 Sep 2024 15:23:40 +0000 Received: from dev-dsk-nikwip-1b-bc9ec026.eu-west-1.amazon.com (10.253.74.52) by mail-relay.amazon.com (10.252.135.200) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34 via Frontend Transport; Tue, 10 Sep 2024 15:23:38 +0000 From: Nikolas Wipper To: Paolo Bonzini , Sean Christopherson , Vitaly Kuznetsov CC: Nicolas Saenz Julienne , Alexander Graf , James Gowans , , Thomas Gleixner , "Ingo Molnar" , Borislav Petkov , Dave Hansen , , , , , , , , Nikolas Wipper Subject: [PATCH 05/15] KVM: x86/mmu: Introduce flags parameter to page walker Date: Tue, 10 Sep 2024 15:21:57 +0000 Message-ID: <20240910152207.38974-6-nikwip@amazon.de> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240910152207.38974-1-nikwip@amazon.de> References: <20240910152207.38974-1-nikwip@amazon.de> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Introduce the flags parameter to walk_addr_generic() which is needed to introduce fine grained control over the accessed/dirty bits. Also forward the parameter to several of the page walker's helper functions, so it can be used in an ioctl. Setting both PWALK_SET_ACCESSED and PWALK_SET_DIRTY will continue to maintain the previous behaviour, that is, both bits are only set after a successful walk and the dirty bit is only set when write access is enabled. No functional change intended. Signed-off-by: Nikolas Wipper --- arch/x86/include/asm/kvm_host.h | 10 +++++++++- arch/x86/kvm/hyperv.c | 3 ++- arch/x86/kvm/mmu.h | 6 +++--- arch/x86/kvm/mmu/mmu.c | 4 ++-- arch/x86/kvm/mmu/paging_tmpl.h | 25 ++++++++++++++----------- arch/x86/kvm/x86.c | 33 ++++++++++++++++++++------------- 6 files changed, 50 insertions(+), 31 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 46e0a466d7fb..3acf0b069693 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -281,6 +281,14 @@ enum x86_intercept_stage; #define PFERR_PRIVATE_ACCESS BIT_ULL(49) #define PFERR_SYNTHETIC_MASK (PFERR_IMPLICIT_ACCESS | PFERR_PRIVATE_ACCESS) +#define PFERR_NESTED_GUEST_PAGE (PFERR_GUEST_PAGE_MASK | \ + PFERR_WRITE_MASK | \ + PFERR_PRESENT_MASK) + +#define PWALK_SET_ACCESSED BIT(0) +#define PWALK_SET_DIRTY BIT(1) +#define PWALK_SET_ALL (PWALK_SET_ACCESSED | PWALK_SET_DIRTY) + /* apic attention bits */ #define KVM_APIC_CHECK_VAPIC 0 /* @@ -450,7 +458,7 @@ struct kvm_mmu { void (*inject_page_fault)(struct kvm_vcpu *vcpu, struct x86_exception *fault); gpa_t (*gva_to_gpa)(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, - gpa_t gva_or_gpa, u64 access, + gpa_t gva_or_gpa, u64 access, u64 flags, struct x86_exception *exception); int (*sync_spte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, int i); diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c index 4f0a94346d00..b237231ace61 100644 --- a/arch/x86/kvm/hyperv.c +++ b/arch/x86/kvm/hyperv.c @@ -2036,7 +2036,8 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc) * read with kvm_read_guest(). */ if (!hc->fast && is_guest_mode(vcpu)) { - hc->ingpa = translate_nested_gpa(vcpu, hc->ingpa, 0, NULL); + hc->ingpa = translate_nested_gpa(vcpu, hc->ingpa, 0, + PWALK_SET_ALL, NULL); if (unlikely(hc->ingpa == INVALID_GPA)) return HV_STATUS_INVALID_HYPERCALL_INPUT; } diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h index 9dc5dd43ae7f..35030f6466b5 100644 --- a/arch/x86/kvm/mmu.h +++ b/arch/x86/kvm/mmu.h @@ -275,15 +275,15 @@ static inline void kvm_update_page_stats(struct kvm *kvm, int level, int count) } gpa_t translate_nested_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u64 access, - struct x86_exception *exception); + u64 flags, struct x86_exception *exception); static inline gpa_t kvm_translate_gpa(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, - gpa_t gpa, u64 access, + gpa_t gpa, u64 access, u64 flags, struct x86_exception *exception) { if (mmu != &vcpu->arch.nested_mmu) return gpa; - return translate_nested_gpa(vcpu, gpa, access, exception); + return translate_nested_gpa(vcpu, gpa, access, flags, exception); } #endif diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 0d94354bb2f8..50c635142bf7 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -4102,12 +4102,12 @@ void kvm_mmu_sync_prev_roots(struct kvm_vcpu *vcpu) } static gpa_t nonpaging_gva_to_gpa(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, - gpa_t vaddr, u64 access, + gpa_t vaddr, u64 access, u64 flags, struct x86_exception *exception) { if (exception) exception->error_code = 0; - return kvm_translate_gpa(vcpu, mmu, vaddr, access, exception); + return kvm_translate_gpa(vcpu, mmu, vaddr, access, flags, exception); } static bool mmio_info_in_cache(struct kvm_vcpu *vcpu, u64 addr, bool direct) diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h index 74651b097fa0..c278b83b023f 100644 --- a/arch/x86/kvm/mmu/paging_tmpl.h +++ b/arch/x86/kvm/mmu/paging_tmpl.h @@ -301,7 +301,7 @@ static inline bool FNAME(is_last_gpte)(struct kvm_mmu *mmu, */ static int FNAME(walk_addr_generic)(struct guest_walker *walker, struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, - gpa_t addr, u64 access) + gpa_t addr, u64 access, u64 flags) { int ret; pt_element_t pte; @@ -379,7 +379,8 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, walker->pte_gpa[walker->level - 1] = pte_gpa; real_gpa = kvm_translate_gpa(vcpu, mmu, gfn_to_gpa(table_gfn), - nested_access, &walker->fault); + nested_access, flags, + &walker->fault); /* * FIXME: This can happen if emulation (for of an INS/OUTS @@ -449,7 +450,8 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, gfn += pse36_gfn_delta(pte); #endif - real_gpa = kvm_translate_gpa(vcpu, mmu, gfn_to_gpa(gfn), access, &walker->fault); + real_gpa = kvm_translate_gpa(vcpu, mmu, gfn_to_gpa(gfn), access, + flags, &walker->fault); if (real_gpa == INVALID_GPA) return 0; @@ -467,8 +469,8 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, (PT_GUEST_DIRTY_SHIFT - PT_GUEST_ACCESSED_SHIFT); if (unlikely(!accessed_dirty)) { - ret = FNAME(update_accessed_dirty_bits)(vcpu, mmu, walker, - addr, write_fault); + ret = FNAME(update_accessed_dirty_bits)(vcpu, mmu, walker, addr, + write_fault); if (unlikely(ret < 0)) goto error; else if (ret) @@ -527,11 +529,11 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, return 0; } -static int FNAME(walk_addr)(struct guest_walker *walker, - struct kvm_vcpu *vcpu, gpa_t addr, u64 access) +static int FNAME(walk_addr)(struct guest_walker *walker, struct kvm_vcpu *vcpu, + gpa_t addr, u64 access, u64 flags) { return FNAME(walk_addr_generic)(walker, vcpu, vcpu->arch.mmu, addr, - access); + access, flags); } static bool @@ -793,7 +795,8 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault * The bit needs to be cleared before walking guest page tables. */ r = FNAME(walk_addr)(&walker, vcpu, fault->addr, - fault->error_code & ~PFERR_RSVD_MASK); + fault->error_code & ~PFERR_RSVD_MASK, + PWALK_SET_ALL); /* * The page is not mapped by the guest. Let the guest handle it. @@ -872,7 +875,7 @@ static gpa_t FNAME(get_level1_sp_gpa)(struct kvm_mmu_page *sp) /* Note, @addr is a GPA when gva_to_gpa() translates an L2 GPA to an L1 GPA. */ static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, - gpa_t addr, u64 access, + gpa_t addr, u64 access, u64 flags, struct x86_exception *exception) { struct guest_walker walker; @@ -884,7 +887,7 @@ static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, WARN_ON_ONCE((addr >> 32) && mmu == vcpu->arch.walk_mmu); #endif - r = FNAME(walk_addr_generic)(&walker, vcpu, mmu, addr, access); + r = FNAME(walk_addr_generic)(&walker, vcpu, mmu, addr, access, flags); if (r) { gpa = gfn_to_gpa(walker.gfn); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 15080385b8fe..32e81cd502ee 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1067,7 +1067,8 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3) * to an L1 GPA. */ real_gpa = kvm_translate_gpa(vcpu, mmu, gfn_to_gpa(pdpt_gfn), - PFERR_USER_MASK | PFERR_WRITE_MASK, NULL); + PFERR_USER_MASK | PFERR_WRITE_MASK, + PWALK_SET_ALL, NULL); if (real_gpa == INVALID_GPA) return 0; @@ -7560,7 +7561,7 @@ void kvm_get_segment(struct kvm_vcpu *vcpu, } gpa_t translate_nested_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u64 access, - struct x86_exception *exception) + u64 flags, struct x86_exception *exception) { struct kvm_mmu *mmu = vcpu->arch.mmu; gpa_t t_gpa; @@ -7569,7 +7570,7 @@ gpa_t translate_nested_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u64 access, /* NPT walks are always user-walks */ access |= PFERR_USER_MASK; - t_gpa = mmu->gva_to_gpa(vcpu, mmu, gpa, access, exception); + t_gpa = mmu->gva_to_gpa(vcpu, mmu, gpa, access, flags, exception); return t_gpa; } @@ -7580,7 +7581,8 @@ gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva, struct kvm_mmu *mmu = vcpu->arch.walk_mmu; u64 access = (kvm_x86_call(get_cpl)(vcpu) == 3) ? PFERR_USER_MASK : 0; - return mmu->gva_to_gpa(vcpu, mmu, gva, access, exception); + return mmu->gva_to_gpa(vcpu, mmu, gva, access, PWALK_SET_ALL, + exception); } EXPORT_SYMBOL_GPL(kvm_mmu_gva_to_gpa_read); @@ -7591,7 +7593,8 @@ gpa_t kvm_mmu_gva_to_gpa_write(struct kvm_vcpu *vcpu, gva_t gva, u64 access = (kvm_x86_call(get_cpl)(vcpu) == 3) ? PFERR_USER_MASK : 0; access |= PFERR_WRITE_MASK; - return mmu->gva_to_gpa(vcpu, mmu, gva, access, exception); + return mmu->gva_to_gpa(vcpu, mmu, gva, access, PWALK_SET_ALL, + exception); } EXPORT_SYMBOL_GPL(kvm_mmu_gva_to_gpa_write); @@ -7601,7 +7604,7 @@ gpa_t kvm_mmu_gva_to_gpa_system(struct kvm_vcpu *vcpu, gva_t gva, { struct kvm_mmu *mmu = vcpu->arch.walk_mmu; - return mmu->gva_to_gpa(vcpu, mmu, gva, 0, exception); + return mmu->gva_to_gpa(vcpu, mmu, gva, 0, PWALK_SET_ALL, exception); } static int kvm_read_guest_virt_helper(gva_t addr, void *val, unsigned int bytes, @@ -7613,7 +7616,8 @@ static int kvm_read_guest_virt_helper(gva_t addr, void *val, unsigned int bytes, int r = X86EMUL_CONTINUE; while (bytes) { - gpa_t gpa = mmu->gva_to_gpa(vcpu, mmu, addr, access, exception); + gpa_t gpa = mmu->gva_to_gpa(vcpu, mmu, addr, access, + PWALK_SET_ALL, exception); unsigned offset = addr & (PAGE_SIZE-1); unsigned toread = min(bytes, (unsigned)PAGE_SIZE - offset); int ret; @@ -7647,8 +7651,8 @@ static int kvm_fetch_guest_virt(struct x86_emulate_ctxt *ctxt, int ret; /* Inline kvm_read_guest_virt_helper for speed. */ - gpa_t gpa = mmu->gva_to_gpa(vcpu, mmu, addr, access|PFERR_FETCH_MASK, - exception); + gpa_t gpa = mmu->gva_to_gpa(vcpu, mmu, addr, access | PFERR_FETCH_MASK, + PWALK_SET_ALL, exception); if (unlikely(gpa == INVALID_GPA)) return X86EMUL_PROPAGATE_FAULT; @@ -7705,7 +7709,8 @@ static int kvm_write_guest_virt_helper(gva_t addr, void *val, unsigned int bytes int r = X86EMUL_CONTINUE; while (bytes) { - gpa_t gpa = mmu->gva_to_gpa(vcpu, mmu, addr, access, exception); + gpa_t gpa = mmu->gva_to_gpa(vcpu, mmu, addr, access, + PWALK_SET_ALL, exception); unsigned offset = addr & (PAGE_SIZE-1); unsigned towrite = min(bytes, (unsigned)PAGE_SIZE - offset); int ret; @@ -7817,14 +7822,15 @@ static int vcpu_mmio_gva_to_gpa(struct kvm_vcpu *vcpu, unsigned long gva, */ if (vcpu_match_mmio_gva(vcpu, gva) && (!is_paging(vcpu) || !permission_fault(vcpu, vcpu->arch.walk_mmu, - vcpu->arch.mmio_access, 0, access))) { + vcpu->arch.mmio_access, + PWALK_SET_ALL, access))) { *gpa = vcpu->arch.mmio_gfn << PAGE_SHIFT | (gva & (PAGE_SIZE - 1)); trace_vcpu_match_mmio(gva, *gpa, write, false); return 1; } - *gpa = mmu->gva_to_gpa(vcpu, mmu, gva, access, exception); + *gpa = mmu->gva_to_gpa(vcpu, mmu, gva, access, PWALK_SET_ALL, exception); if (*gpa == INVALID_GPA) return -1; @@ -13644,7 +13650,8 @@ void kvm_fixup_and_inject_pf_error(struct kvm_vcpu *vcpu, gva_t gva, u16 error_c (PFERR_WRITE_MASK | PFERR_FETCH_MASK | PFERR_USER_MASK); if (!(error_code & PFERR_PRESENT_MASK) || - mmu->gva_to_gpa(vcpu, mmu, gva, access, &fault) != INVALID_GPA) { + mmu->gva_to_gpa(vcpu, mmu, gva, access, PWALK_SET_ALL, + &fault) != INVALID_GPA) { /* * If vcpu->arch.walk_mmu->gva_to_gpa succeeded, the page * tables probably do not match the TLB. Just proceed From patchwork Tue Sep 10 15:21:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolas Wipper X-Patchwork-Id: 13798758 Received: from smtp-fw-52002.amazon.com (smtp-fw-52002.amazon.com [52.119.213.150]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BA40919D88C; Tue, 10 Sep 2024 15:24:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=52.119.213.150 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725981845; cv=none; b=dWgHc4N+dBhwnKPpt4GweX7w8hG+nBc2NiO/P1RVzo5kBcta8GKPMRi4feHDapkHWH4GsxBJNfpOgIQ/vjZSwDxMOA+09Z7jmDgszSy4wE8GJ5j1BWEbF3XM+ospKEPI/zcVo6sA4xe6EUBTNKbLIpbhbfgZ5DhG1cF64VpV3bI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725981845; c=relaxed/simple; bh=znXdsF6eiqKY2HvO6RXCANRQmaZ2fD/Ui+naRYeu3bo=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=rVdPJt9ly1xvsdJZ+TOXoyhMshZZOvIvSjjDNbcJZD+UT+PE+w5doISYhnBc8PDBqfFam5Coq8jTI+JM5R/YfeVu43aCkCGEoeIwKjnNkoxbVKDKPx5PRMKN0qdhQTYX2u8f3gxZ4VAp6yVzfNcDOw8zmjAaPEvok8AhQEZ6f9c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de; spf=pass smtp.mailfrom=amazon.de; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b=Ksa0qUrs; arc=none smtp.client-ip=52.119.213.150 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amazon.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b="Ksa0qUrs" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazon201209; t=1725981845; x=1757517845; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=U7Ctjd+6veeZS5KO0mrV/5F4c28Jr+9mluYJ7cdyklU=; b=Ksa0qUrs2ixXjwU4sSoYCa/o5uFqyt//cZkM1LkhVsKAyI1XZKkYvBmo MEHy3K1e7gWafhv4P/TyurtW3dESIBVA35xzi4RWRuWp2zThrsalF3H8C inQ/IHBSqKkSnJgzGbJ7U+qbruAMJF+VHdew7x34r2t0TUUZNXdefk0Vk w=; X-IronPort-AV: E=Sophos;i="6.10,217,1719878400"; d="scan'208";a="658004108" Received: from iad12-co-svc-p1-lb1-vlan3.amazon.com (HELO smtpout.prod.us-west-2.prod.farcaster.email.amazon.dev) ([10.43.8.6]) by smtp-border-fw-52002.iad7.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Sep 2024 15:24:01 +0000 Received: from EX19MTAEUB002.ant.amazon.com [10.0.43.254:63064] by smtpin.naws.eu-west-1.prod.farcaster.email.amazon.dev [10.0.7.67:2525] with esmtp (Farcaster) id 3e155601-fb36-42be-a9bf-a8884a254509; Tue, 10 Sep 2024 15:23:58 +0000 (UTC) X-Farcaster-Flow-ID: 3e155601-fb36-42be-a9bf-a8884a254509 Received: from EX19D014EUA004.ant.amazon.com (10.252.50.41) by EX19MTAEUB002.ant.amazon.com (10.252.51.59) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Tue, 10 Sep 2024 15:23:58 +0000 Received: from EX19MTAUEC001.ant.amazon.com (10.252.135.222) by EX19D014EUA004.ant.amazon.com (10.252.50.41) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Tue, 10 Sep 2024 15:23:58 +0000 Received: from dev-dsk-nikwip-1b-bc9ec026.eu-west-1.amazon.com (10.253.74.52) by mail-relay.amazon.com (10.252.135.200) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34 via Frontend Transport; Tue, 10 Sep 2024 15:23:56 +0000 From: Nikolas Wipper To: Paolo Bonzini , Sean Christopherson , Vitaly Kuznetsov CC: Nicolas Saenz Julienne , Alexander Graf , James Gowans , , Thomas Gleixner , "Ingo Molnar" , Borislav Petkov , Dave Hansen , , , , , , , , Nikolas Wipper Subject: [PATCH 06/15] KVM: x86/mmu: Implement PWALK_SET_ACCESSED in page walker Date: Tue, 10 Sep 2024 15:21:58 +0000 Message-ID: <20240910152207.38974-7-nikwip@amazon.de> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240910152207.38974-1-nikwip@amazon.de> References: <20240910152207.38974-1-nikwip@amazon.de> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Implement PWALK_SET_ACCESSED in the page walker. This flag allows controling whether the page walker will set the accessed bits after a successful page walk in all page table levels. If the page walk is aborted for any reason, none of the access bits are set. Signed-off-by: Nikolas Wipper --- arch/x86/kvm/mmu/paging_tmpl.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h index c278b83b023f..eed6e2c653ba 100644 --- a/arch/x86/kvm/mmu/paging_tmpl.h +++ b/arch/x86/kvm/mmu/paging_tmpl.h @@ -317,6 +317,7 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, const int write_fault = access & PFERR_WRITE_MASK; const int user_fault = access & PFERR_USER_MASK; const int fetch_fault = access & PFERR_FETCH_MASK; + const int set_accessed = flags & PWALK_SET_ACCESSED; u16 errcode = 0; gpa_t real_gpa; gfn_t gfn; @@ -468,7 +469,7 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, accessed_dirty &= pte >> (PT_GUEST_DIRTY_SHIFT - PT_GUEST_ACCESSED_SHIFT); - if (unlikely(!accessed_dirty)) { + if (unlikely(set_accessed && !accessed_dirty)) { ret = FNAME(update_accessed_dirty_bits)(vcpu, mmu, walker, addr, write_fault); if (unlikely(ret < 0)) From patchwork Tue Sep 10 15:21:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolas Wipper X-Patchwork-Id: 13798759 Received: from smtp-fw-6002.amazon.com (smtp-fw-6002.amazon.com [52.95.49.90]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 08D1119923A; Tue, 10 Sep 2024 15:24:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=52.95.49.90 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725981863; cv=none; b=Mv3vxo+W2NM6jl1SF7pBZGaboRPnTL9IZWKtZ/WQLT1QcirWTODkUzFsh2YHtVG51s7Cdz59WcWdBxq/+5z7y5tuvGKTX6vefQDbgW+8U0GJGy8YtuysPZgoYAt1IhtJY1RHyds385B7zW2uAuDt7kCE5pxd3aARkbQeAMhRsmc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725981863; c=relaxed/simple; bh=POQ8kozreKNtgbjSembbt5PYvEATBNIM8q9Rfx3n8fY=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=LHXSbcQkbxcsdwYarqCf0l7E9W4dGX5XL656bFj43ffPMRUdyLqcVyLQU4B5aETSpmtXmhlslUgNk6GWm5KYQK5v25uGokru+NV5Px+YRDfe9fNzr2+XY7PokxjcRV/rsK36ZN1Ab8OALjkwQg6Gf3SlIFvn/dWcYETtCMWVKm4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de; spf=pass smtp.mailfrom=amazon.de; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b=McST4tjY; arc=none smtp.client-ip=52.95.49.90 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amazon.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b="McST4tjY" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazon201209; t=1725981862; x=1757517862; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=3HArsw7M4ipywp4YAC24VV8yFEbuXaMw9heDyfTkF5M=; b=McST4tjY70U7io27HNx5d7mYs+NDWjmHR8ThlOB4cNENgRfYmN15laco EMNUxNfRYyqGq+oPwagw8dmGMusJB9LfJ7jec9+q4y4BGy2waBUZoe27j B3pWxIcDp6xZXIFAqu+BJbDBsOmTNWsbSp1bZtUbBf101q0EE5ooiGJGE s=; X-IronPort-AV: E=Sophos;i="6.10,217,1719878400"; d="scan'208";a="432460269" Received: from iad12-co-svc-p1-lb1-vlan3.amazon.com (HELO smtpout.prod.us-west-2.prod.farcaster.email.amazon.dev) ([10.43.8.6]) by smtp-border-fw-6002.iad6.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Sep 2024 15:24:17 +0000 Received: from EX19MTAUWC002.ant.amazon.com [10.0.21.151:47925] by smtpin.naws.us-west-2.prod.farcaster.email.amazon.dev [10.0.52.222:2525] with esmtp (Farcaster) id be656b80-426d-46ed-a1f5-9204a4d60b53; Tue, 10 Sep 2024 15:24:16 +0000 (UTC) X-Farcaster-Flow-ID: be656b80-426d-46ed-a1f5-9204a4d60b53 Received: from EX19D020UWC001.ant.amazon.com (10.13.138.157) by EX19MTAUWC002.ant.amazon.com (10.250.64.143) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Tue, 10 Sep 2024 15:24:16 +0000 Received: from EX19MTAUEA001.ant.amazon.com (10.252.134.203) by EX19D020UWC001.ant.amazon.com (10.13.138.157) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Tue, 10 Sep 2024 15:24:15 +0000 Received: from dev-dsk-nikwip-1b-bc9ec026.eu-west-1.amazon.com (10.253.74.52) by mail-relay.amazon.com (10.252.134.102) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34 via Frontend Transport; Tue, 10 Sep 2024 15:24:14 +0000 From: Nikolas Wipper To: Paolo Bonzini , Sean Christopherson , Vitaly Kuznetsov CC: Nicolas Saenz Julienne , Alexander Graf , James Gowans , , Thomas Gleixner , "Ingo Molnar" , Borislav Petkov , Dave Hansen , , , , , , , , Nikolas Wipper Subject: [PATCH 07/15] KVM: x86/mmu: Implement PWALK_SET_DIRTY in page walker Date: Tue, 10 Sep 2024 15:21:59 +0000 Message-ID: <20240910152207.38974-8-nikwip@amazon.de> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240910152207.38974-1-nikwip@amazon.de> References: <20240910152207.38974-1-nikwip@amazon.de> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Implement PWALK_SET_DIRTY in the page walker. This flag allows controlling, whether the page walker will set the dirty bit after a successful page walk. If the page walk fails for any reason, the dirty flag is not set. Signed-off-by: Nikolas Wipper --- arch/x86/kvm/mmu/paging_tmpl.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h index eed6e2c653ba..b6897f7fbf52 100644 --- a/arch/x86/kvm/mmu/paging_tmpl.h +++ b/arch/x86/kvm/mmu/paging_tmpl.h @@ -318,6 +318,7 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, const int user_fault = access & PFERR_USER_MASK; const int fetch_fault = access & PFERR_FETCH_MASK; const int set_accessed = flags & PWALK_SET_ACCESSED; + const int set_dirty = flags & PWALK_SET_DIRTY; u16 errcode = 0; gpa_t real_gpa; gfn_t gfn; @@ -471,7 +472,7 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, if (unlikely(set_accessed && !accessed_dirty)) { ret = FNAME(update_accessed_dirty_bits)(vcpu, mmu, walker, addr, - write_fault); + write_fault && set_dirty); if (unlikely(ret < 0)) goto error; else if (ret) From patchwork Tue Sep 10 15:22:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolas Wipper X-Patchwork-Id: 13798760 Received: from smtp-fw-2101.amazon.com (smtp-fw-2101.amazon.com [72.21.196.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 710681A0716; Tue, 10 Sep 2024 15:24:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=72.21.196.25 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725981885; cv=none; b=teiO/ipIqx2Yj6c/H4fmr3vzU3lHAXmjWL0X6Yga9JbSVE/nzC08bc2dNk5fau+u4J3GJIHyGHk5mb5pL1imXf4CuWZiifV38P03+5MHewknoTxxrxONiBYbF8VNeCC3qdCUp2GwOM0N069zwH4/g5ueW42gGy8OjMzgbbKrunE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725981885; c=relaxed/simple; bh=7a6wXYs7Dvqh9sEvoCjfKM7Bj1zaEgXTI4PJHU9blp0=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=QBzWLxnRCaQi3SlJs4hgCQlcZ85Lfnd9qCnGiNsMO1ssbeeOH6FDEmg89BDVD8RAOfLBYkNeHdKq7P8CrjiTgiQV0s5LRL3sq2g8R/qXTT9yxbwXlc5u0RjnUlvErYtf/JfiK9/BSQIII95LwbnBBiOTZyjcp+vLlreDWivis5o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de; spf=pass smtp.mailfrom=amazon.de; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b=XitRyemQ; arc=none smtp.client-ip=72.21.196.25 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amazon.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b="XitRyemQ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazon201209; t=1725981883; x=1757517883; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Ea1U7mANR28aq/cO/4aNKTr6fML6fTywEfVWSHI4Vxk=; b=XitRyemQQx8qE7h0w79c73PswjYefiHQwxai2fTZrsi7L/y1U1+sk2Z7 P5KPHVklf/iLHkJnPYV0kgZ36Q3THKkPKnTel/kVDkTinI/8ddjS05ULf dRlAeMVwkZ5Io5emYtgI/6Tq2No+hw5Z4DtCOY/R+pd/2GDxYLBXzhhxW s=; X-IronPort-AV: E=Sophos;i="6.10,217,1719878400"; d="scan'208";a="426771577" Received: from iad12-co-svc-p1-lb1-vlan3.amazon.com (HELO smtpout.prod.us-west-2.prod.farcaster.email.amazon.dev) ([10.43.8.6]) by smtp-border-fw-2101.iad2.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Sep 2024 15:24:39 +0000 Received: from EX19MTAUWC001.ant.amazon.com [10.0.21.151:38133] by smtpin.naws.us-west-2.prod.farcaster.email.amazon.dev [10.0.60.27:2525] with esmtp (Farcaster) id 437da87e-5527-4cc1-addb-da9ba89e99c0; Tue, 10 Sep 2024 15:24:39 +0000 (UTC) X-Farcaster-Flow-ID: 437da87e-5527-4cc1-addb-da9ba89e99c0 Received: from EX19D020UWA003.ant.amazon.com (10.13.138.254) by EX19MTAUWC001.ant.amazon.com (10.250.64.174) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Tue, 10 Sep 2024 15:24:34 +0000 Received: from EX19MTAUWA001.ant.amazon.com (10.250.64.204) by EX19D020UWA003.ant.amazon.com (10.13.138.254) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Tue, 10 Sep 2024 15:24:34 +0000 Received: from dev-dsk-nikwip-1b-bc9ec026.eu-west-1.amazon.com (10.253.74.52) by mail-relay.amazon.com (10.250.64.204) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34 via Frontend Transport; Tue, 10 Sep 2024 15:24:32 +0000 From: Nikolas Wipper To: Paolo Bonzini , Sean Christopherson , Vitaly Kuznetsov CC: Nicolas Saenz Julienne , Alexander Graf , James Gowans , , Thomas Gleixner , "Ingo Molnar" , Borislav Petkov , Dave Hansen , , , , , , , , Nikolas Wipper Subject: [PATCH 08/15] KVM: x86/mmu: Implement PWALK_FORCE_SET_ACCESSED in page walker Date: Tue, 10 Sep 2024 15:22:00 +0000 Message-ID: <20240910152207.38974-9-nikwip@amazon.de> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240910152207.38974-1-nikwip@amazon.de> References: <20240910152207.38974-1-nikwip@amazon.de> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Implement PWALK_FORCE_SET_ACCESSED in the page walker. This flag forces the page walker to set the accessed flag in all successfully visited page table levels, regardless of the outcome of the page walk. For example, if the page walk fails on level 2, the accessed bit will still be set on levels 3 and up. If the nested translations of GPAs fail, the bits will still be set. Signed-off-by: Nikolas Wipper --- arch/x86/include/asm/kvm_host.h | 1 + arch/x86/kvm/mmu/paging_tmpl.h | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 3acf0b069693..cd2c391d6a24 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -287,6 +287,7 @@ enum x86_intercept_stage; #define PWALK_SET_ACCESSED BIT(0) #define PWALK_SET_DIRTY BIT(1) +#define PWALK_FORCE_SET_ACCESSED BIT(2) #define PWALK_SET_ALL (PWALK_SET_ACCESSED | PWALK_SET_DIRTY) /* apic attention bits */ diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h index b6897f7fbf52..2cc40fd17f53 100644 --- a/arch/x86/kvm/mmu/paging_tmpl.h +++ b/arch/x86/kvm/mmu/paging_tmpl.h @@ -319,6 +319,7 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, const int fetch_fault = access & PFERR_FETCH_MASK; const int set_accessed = flags & PWALK_SET_ACCESSED; const int set_dirty = flags & PWALK_SET_DIRTY; + const int force_set = flags & PWALK_FORCE_SET_ACCESSED; u16 errcode = 0; gpa_t real_gpa; gfn_t gfn; @@ -395,7 +396,7 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, * fields. */ if (unlikely(real_gpa == INVALID_GPA)) - return 0; + goto late_exit; slot = kvm_vcpu_gfn_to_memslot(vcpu, gpa_to_gfn(real_gpa)); if (!kvm_is_visible_memslot(slot)) { @@ -455,7 +456,7 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, real_gpa = kvm_translate_gpa(vcpu, mmu, gfn_to_gpa(gfn), access, flags, &walker->fault); if (real_gpa == INVALID_GPA) - return 0; + goto late_exit; walker->gfn = real_gpa >> PAGE_SHIFT; @@ -528,6 +529,18 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, walker->fault.async_page_fault = false; trace_kvm_mmu_walker_error(walker->fault.error_code); + +late_exit: + if (force_set) { + /* + * Don't set the accessed bit for the page table that caused the + * walk to fail. + */ + ++walker->level; + FNAME(update_accessed_dirty_bits)(vcpu, mmu, walker, addr, + false); + --walker->level; + } return 0; } From patchwork Tue Sep 10 15:22:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolas Wipper X-Patchwork-Id: 13798761 Received: from smtp-fw-9106.amazon.com (smtp-fw-9106.amazon.com [207.171.188.206]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5CC641A2551; Tue, 10 Sep 2024 15:24:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=207.171.188.206 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725981897; cv=none; b=Mc7GeDe0FAqLOE7po5aAl4G05hNy8yahtmN/QwUEHWeYGTbLa6xORVx0m+6ZwUTbfpkNYuU8zO1Q44UVsF+rynIEso1feMn7GPBSgtJHehzXW7iwC9IiVQ2CAZAxRBeuS+B5yAcx164tC+RSoj73sHPZ8kJ6pLHmtWZTmd64w98= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725981897; c=relaxed/simple; bh=DKOkjI+c3qUYMLTmRQMPPaIYgXbxgKRzFDlLxE4acjM=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Nh3DlUJuEvRuhpHjNXk9ikFbr45MLor2WUJh4lrZtLBYkjAMUzDhKtwYYTwLBZs1E3LvnWKe88n+6Mm3NiVybjNcRYvGVguNctySoEm32ORCrRbkS7sTnBO84JqlRjsrAf3KDqf1lByTTNnMxfCBi+i39fqEVBr5TPbWviIz6aA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de; spf=pass smtp.mailfrom=amazon.de; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b=pRCWkV56; arc=none smtp.client-ip=207.171.188.206 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amazon.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b="pRCWkV56" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazon201209; t=1725981896; x=1757517896; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=8a5R4qdiyvNyIJoumEfbzn9XD7EbuO1bJFlMEMd4SNM=; b=pRCWkV56kCmDsRJsTsbHl4dtrHE++IqdY/ac5yNNtDxpwkDdlkj3b0N9 Ry5FvDOuE2nkMhOqglV0Jxvil0Cm36qKUQpump/k6jFwbfPSfNPFX3sIJ JMKNDT/LG2mfZMX19OFGgZuHR6l7j7Tv6/4WwfKinKz5Q6crV8uBHq08Y o=; X-IronPort-AV: E=Sophos;i="6.10,217,1719878400"; d="scan'208";a="758470951" Received: from pdx4-co-svc-p1-lb2-vlan2.amazon.com (HELO smtpout.prod.us-east-1.prod.farcaster.email.amazon.dev) ([10.25.36.210]) by smtp-border-fw-9106.sea19.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Sep 2024 15:24:54 +0000 Received: from EX19MTAEUC001.ant.amazon.com [10.0.17.79:12094] by smtpin.naws.eu-west-1.prod.farcaster.email.amazon.dev [10.0.13.80:2525] with esmtp (Farcaster) id 38291df8-0ba6-4211-80b0-303256e1086f; Tue, 10 Sep 2024 15:24:52 +0000 (UTC) X-Farcaster-Flow-ID: 38291df8-0ba6-4211-80b0-303256e1086f Received: from EX19D004EUA001.ant.amazon.com (10.252.50.27) by EX19MTAEUC001.ant.amazon.com (10.252.51.193) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Tue, 10 Sep 2024 15:24:52 +0000 Received: from EX19MTAUEA001.ant.amazon.com (10.252.134.203) by EX19D004EUA001.ant.amazon.com (10.252.50.27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Tue, 10 Sep 2024 15:24:52 +0000 Received: from dev-dsk-nikwip-1b-bc9ec026.eu-west-1.amazon.com (10.253.74.52) by mail-relay.amazon.com (10.252.134.102) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34 via Frontend Transport; Tue, 10 Sep 2024 15:24:50 +0000 From: Nikolas Wipper To: Paolo Bonzini , Sean Christopherson , Vitaly Kuznetsov CC: Nicolas Saenz Julienne , Alexander Graf , James Gowans , , Thomas Gleixner , "Ingo Molnar" , Borislav Petkov , Dave Hansen , , , , , , , , Nikolas Wipper Subject: [PATCH 09/15] KVM: x86/mmu: Introduce status parameter to page walker Date: Tue, 10 Sep 2024 15:22:01 +0000 Message-ID: <20240910152207.38974-10-nikwip@amazon.de> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240910152207.38974-1-nikwip@amazon.de> References: <20240910152207.38974-1-nikwip@amazon.de> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Introduce the status parameter to walk_addr_generic() which is used in later patches to provide the caller with information on whether setting the accessed/dirty bits succeeded. No functional change intended. Signed-off-by: Nikolas Wipper --- arch/x86/include/asm/kvm_host.h | 2 +- arch/x86/kvm/hyperv.c | 2 +- arch/x86/kvm/mmu.h | 8 +++++--- arch/x86/kvm/mmu/mmu.c | 5 +++-- arch/x86/kvm/mmu/paging_tmpl.h | 26 ++++++++++++++++---------- arch/x86/kvm/x86.c | 25 ++++++++++++++----------- 6 files changed, 40 insertions(+), 28 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index cd2c391d6a24..1c5aaf55c683 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -460,7 +460,7 @@ struct kvm_mmu { struct x86_exception *fault); gpa_t (*gva_to_gpa)(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, gpa_t gva_or_gpa, u64 access, u64 flags, - struct x86_exception *exception); + struct x86_exception *exception, u16 *status); int (*sync_spte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, int i); struct kvm_mmu_root_info root; diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c index b237231ace61..30d5b86bc306 100644 --- a/arch/x86/kvm/hyperv.c +++ b/arch/x86/kvm/hyperv.c @@ -2037,7 +2037,7 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc) */ if (!hc->fast && is_guest_mode(vcpu)) { hc->ingpa = translate_nested_gpa(vcpu, hc->ingpa, 0, - PWALK_SET_ALL, NULL); + PWALK_SET_ALL, NULL, NULL); if (unlikely(hc->ingpa == INVALID_GPA)) return HV_STATUS_INVALID_HYPERCALL_INPUT; } diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h index 35030f6466b5..272ce93f855f 100644 --- a/arch/x86/kvm/mmu.h +++ b/arch/x86/kvm/mmu.h @@ -275,15 +275,17 @@ static inline void kvm_update_page_stats(struct kvm *kvm, int level, int count) } gpa_t translate_nested_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u64 access, - u64 flags, struct x86_exception *exception); + u64 flags, struct x86_exception *exception, + u16 *status); static inline gpa_t kvm_translate_gpa(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, gpa_t gpa, u64 access, u64 flags, - struct x86_exception *exception) + struct x86_exception *exception, + u16 *status) { if (mmu != &vcpu->arch.nested_mmu) return gpa; - return translate_nested_gpa(vcpu, gpa, access, flags, exception); + return translate_nested_gpa(vcpu, gpa, access, flags, exception, status); } #endif diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 50c635142bf7..2ab0437edf54 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -4103,11 +4103,12 @@ void kvm_mmu_sync_prev_roots(struct kvm_vcpu *vcpu) static gpa_t nonpaging_gva_to_gpa(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, gpa_t vaddr, u64 access, u64 flags, - struct x86_exception *exception) + struct x86_exception *exception, u16 *status) { if (exception) exception->error_code = 0; - return kvm_translate_gpa(vcpu, mmu, vaddr, access, flags, exception); + return kvm_translate_gpa(vcpu, mmu, vaddr, access, flags, exception, + status); } static bool mmio_info_in_cache(struct kvm_vcpu *vcpu, u64 addr, bool direct) diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h index 2cc40fd17f53..985a19dda603 100644 --- a/arch/x86/kvm/mmu/paging_tmpl.h +++ b/arch/x86/kvm/mmu/paging_tmpl.h @@ -197,7 +197,8 @@ static inline unsigned FNAME(gpte_access)(u64 gpte) static int FNAME(update_accessed_dirty_bits)(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, struct guest_walker *walker, - gpa_t addr, int write_fault) + gpa_t addr, int write_fault, + u16 *status) { unsigned level, index; pt_element_t pte, orig_pte; @@ -301,7 +302,8 @@ static inline bool FNAME(is_last_gpte)(struct kvm_mmu *mmu, */ static int FNAME(walk_addr_generic)(struct guest_walker *walker, struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, - gpa_t addr, u64 access, u64 flags) + gpa_t addr, u64 access, u64 flags, + u16 *status) { int ret; pt_element_t pte; @@ -344,6 +346,9 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, walker->fault.flags = 0; + if (status) + *status = 0; + /* * FIXME: on Intel processors, loads of the PDPTE registers for PAE paging * by the MOV to CR instruction are treated as reads and do not cause the @@ -383,7 +388,7 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, real_gpa = kvm_translate_gpa(vcpu, mmu, gfn_to_gpa(table_gfn), nested_access, flags, - &walker->fault); + &walker->fault, status); /* * FIXME: This can happen if emulation (for of an INS/OUTS @@ -453,8 +458,8 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, gfn += pse36_gfn_delta(pte); #endif - real_gpa = kvm_translate_gpa(vcpu, mmu, gfn_to_gpa(gfn), access, - flags, &walker->fault); + real_gpa = kvm_translate_gpa(vcpu, mmu, gfn_to_gpa(gfn), access, flags, + &walker->fault, status); if (real_gpa == INVALID_GPA) goto late_exit; @@ -473,7 +478,8 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, if (unlikely(set_accessed && !accessed_dirty)) { ret = FNAME(update_accessed_dirty_bits)(vcpu, mmu, walker, addr, - write_fault && set_dirty); + write_fault && set_dirty, + status); if (unlikely(ret < 0)) goto error; else if (ret) @@ -538,7 +544,7 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, */ ++walker->level; FNAME(update_accessed_dirty_bits)(vcpu, mmu, walker, addr, - false); + false, status); --walker->level; } return 0; @@ -548,7 +554,7 @@ static int FNAME(walk_addr)(struct guest_walker *walker, struct kvm_vcpu *vcpu, gpa_t addr, u64 access, u64 flags) { return FNAME(walk_addr_generic)(walker, vcpu, vcpu->arch.mmu, addr, - access, flags); + access, flags, NULL); } static bool @@ -891,7 +897,7 @@ static gpa_t FNAME(get_level1_sp_gpa)(struct kvm_mmu_page *sp) /* Note, @addr is a GPA when gva_to_gpa() translates an L2 GPA to an L1 GPA. */ static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, gpa_t addr, u64 access, u64 flags, - struct x86_exception *exception) + struct x86_exception *exception, u16 *status) { struct guest_walker walker; gpa_t gpa = INVALID_GPA; @@ -902,7 +908,7 @@ static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, WARN_ON_ONCE((addr >> 32) && mmu == vcpu->arch.walk_mmu); #endif - r = FNAME(walk_addr_generic)(&walker, vcpu, mmu, addr, access, flags); + r = FNAME(walk_addr_generic)(&walker, vcpu, mmu, addr, access, flags, status); if (r) { gpa = gfn_to_gpa(walker.gfn); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 32e81cd502ee..be696b60aba6 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1068,7 +1068,7 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3) */ real_gpa = kvm_translate_gpa(vcpu, mmu, gfn_to_gpa(pdpt_gfn), PFERR_USER_MASK | PFERR_WRITE_MASK, - PWALK_SET_ALL, NULL); + PWALK_SET_ALL, NULL, NULL); if (real_gpa == INVALID_GPA) return 0; @@ -7561,7 +7561,8 @@ void kvm_get_segment(struct kvm_vcpu *vcpu, } gpa_t translate_nested_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u64 access, - u64 flags, struct x86_exception *exception) + u64 flags, struct x86_exception *exception, + u16 *status) { struct kvm_mmu *mmu = vcpu->arch.mmu; gpa_t t_gpa; @@ -7570,7 +7571,8 @@ gpa_t translate_nested_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u64 access, /* NPT walks are always user-walks */ access |= PFERR_USER_MASK; - t_gpa = mmu->gva_to_gpa(vcpu, mmu, gpa, access, flags, exception); + t_gpa = mmu->gva_to_gpa(vcpu, mmu, gpa, access, flags, exception, + status); return t_gpa; } @@ -7582,7 +7584,7 @@ gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva, u64 access = (kvm_x86_call(get_cpl)(vcpu) == 3) ? PFERR_USER_MASK : 0; return mmu->gva_to_gpa(vcpu, mmu, gva, access, PWALK_SET_ALL, - exception); + exception, NULL); } EXPORT_SYMBOL_GPL(kvm_mmu_gva_to_gpa_read); @@ -7594,7 +7596,7 @@ gpa_t kvm_mmu_gva_to_gpa_write(struct kvm_vcpu *vcpu, gva_t gva, u64 access = (kvm_x86_call(get_cpl)(vcpu) == 3) ? PFERR_USER_MASK : 0; access |= PFERR_WRITE_MASK; return mmu->gva_to_gpa(vcpu, mmu, gva, access, PWALK_SET_ALL, - exception); + exception, NULL); } EXPORT_SYMBOL_GPL(kvm_mmu_gva_to_gpa_write); @@ -7604,7 +7606,7 @@ gpa_t kvm_mmu_gva_to_gpa_system(struct kvm_vcpu *vcpu, gva_t gva, { struct kvm_mmu *mmu = vcpu->arch.walk_mmu; - return mmu->gva_to_gpa(vcpu, mmu, gva, 0, PWALK_SET_ALL, exception); + return mmu->gva_to_gpa(vcpu, mmu, gva, 0, PWALK_SET_ALL, exception, NULL); } static int kvm_read_guest_virt_helper(gva_t addr, void *val, unsigned int bytes, @@ -7617,7 +7619,7 @@ static int kvm_read_guest_virt_helper(gva_t addr, void *val, unsigned int bytes, while (bytes) { gpa_t gpa = mmu->gva_to_gpa(vcpu, mmu, addr, access, - PWALK_SET_ALL, exception); + PWALK_SET_ALL, exception, NULL); unsigned offset = addr & (PAGE_SIZE-1); unsigned toread = min(bytes, (unsigned)PAGE_SIZE - offset); int ret; @@ -7652,7 +7654,8 @@ static int kvm_fetch_guest_virt(struct x86_emulate_ctxt *ctxt, /* Inline kvm_read_guest_virt_helper for speed. */ gpa_t gpa = mmu->gva_to_gpa(vcpu, mmu, addr, access | PFERR_FETCH_MASK, - PWALK_SET_ALL, exception); + PWALK_SET_ALL, + exception, NULL); if (unlikely(gpa == INVALID_GPA)) return X86EMUL_PROPAGATE_FAULT; @@ -7710,7 +7713,7 @@ static int kvm_write_guest_virt_helper(gva_t addr, void *val, unsigned int bytes while (bytes) { gpa_t gpa = mmu->gva_to_gpa(vcpu, mmu, addr, access, - PWALK_SET_ALL, exception); + PWALK_SET_ALL, exception, NULL); unsigned offset = addr & (PAGE_SIZE-1); unsigned towrite = min(bytes, (unsigned)PAGE_SIZE - offset); int ret; @@ -7830,7 +7833,7 @@ static int vcpu_mmio_gva_to_gpa(struct kvm_vcpu *vcpu, unsigned long gva, return 1; } - *gpa = mmu->gva_to_gpa(vcpu, mmu, gva, access, PWALK_SET_ALL, exception); + *gpa = mmu->gva_to_gpa(vcpu, mmu, gva, access, PWALK_SET_ALL, exception, NULL); if (*gpa == INVALID_GPA) return -1; @@ -13651,7 +13654,7 @@ void kvm_fixup_and_inject_pf_error(struct kvm_vcpu *vcpu, gva_t gva, u16 error_c if (!(error_code & PFERR_PRESENT_MASK) || mmu->gva_to_gpa(vcpu, mmu, gva, access, PWALK_SET_ALL, - &fault) != INVALID_GPA) { + &fault, NULL) != INVALID_GPA) { /* * If vcpu->arch.walk_mmu->gva_to_gpa succeeded, the page * tables probably do not match the TLB. Just proceed From patchwork Tue Sep 10 15:22:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolas Wipper X-Patchwork-Id: 13798762 Received: from smtp-fw-80009.amazon.com (smtp-fw-80009.amazon.com [99.78.197.220]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F2008199929; Tue, 10 Sep 2024 15:25:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=99.78.197.220 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725981913; cv=none; b=BijlByHlLCH8dLRoy+BEaY5ybxXNXjtE1gxVyllWVFoYlwBNmEGTf1DBaeiBAEREGdgn+XqW0yj6XV/YG9WgyIHkS+luTPRN203KjkXMunoTiEQopJ2GGH8AKwTv6QiRjg2Zb6ICpcFwOswIXzOxr0LJB3Xf8xhPboAIKI3Hh/k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725981913; c=relaxed/simple; bh=GMykZu9zJGf4fBCWBKK4YMIS2yhYXrut9F4hJMLGt9E=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=LJa0sjrMOD6SClJ+MjncIzu0fklBVekCVNL6FP5ldAQYAjrxPNjEFqqnU4MB0Lpi34dqY8Ozyd+aK6xPakyMGv2Hz7q1n6WKe8oi+iC/VGA0FXjWfvYRgXFZYLod8rjWoU5mGutnwI1lteP5LjUwD8BiG0FszxNNJPzX5tFug30= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de; spf=pass smtp.mailfrom=amazon.de; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b=NUxEeE8E; arc=none smtp.client-ip=99.78.197.220 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amazon.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b="NUxEeE8E" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazon201209; t=1725981912; x=1757517912; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=VCZtCvHosy1tl36gR64QE1Z05bT4o2QPSCtwKVmrIoM=; b=NUxEeE8E09ltCPWkVmkmnWZTr1Hl6G+ALFusMZMcNYyPwbNHEP/LkcK4 K5722EHNuinmzC8jH9eia9JTVh+K9UGP2E/c7gh+esMLFC0/lg5MjsUVp GzyPwYssKqLAFb602WFuZTFu4PlHQfdXcgMx/lkr/RQJap6iY5wDZppGP c=; X-IronPort-AV: E=Sophos;i="6.10,217,1719878400"; d="scan'208";a="124219849" Received: from pdx4-co-svc-p1-lb2-vlan2.amazon.com (HELO smtpout.prod.us-west-2.prod.farcaster.email.amazon.dev) ([10.25.36.210]) by smtp-border-fw-80009.pdx80.corp.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Sep 2024 15:25:11 +0000 Received: from EX19MTAEUC001.ant.amazon.com [10.0.17.79:31177] by smtpin.naws.eu-west-1.prod.farcaster.email.amazon.dev [10.0.13.80:2525] with esmtp (Farcaster) id 21c9d66f-c03c-4e6f-b416-01e7a52443d5; Tue, 10 Sep 2024 15:25:10 +0000 (UTC) X-Farcaster-Flow-ID: 21c9d66f-c03c-4e6f-b416-01e7a52443d5 Received: from EX19D004EUA004.ant.amazon.com (10.252.50.183) by EX19MTAEUC001.ant.amazon.com (10.252.51.155) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Tue, 10 Sep 2024 15:25:10 +0000 Received: from EX19MTAUEC001.ant.amazon.com (10.252.135.222) by EX19D004EUA004.ant.amazon.com (10.252.50.183) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Tue, 10 Sep 2024 15:25:09 +0000 Received: from dev-dsk-nikwip-1b-bc9ec026.eu-west-1.amazon.com (10.253.74.52) by mail-relay.amazon.com (10.252.135.200) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34 via Frontend Transport; Tue, 10 Sep 2024 15:25:08 +0000 From: Nikolas Wipper To: Paolo Bonzini , Sean Christopherson , Vitaly Kuznetsov CC: Nicolas Saenz Julienne , Alexander Graf , James Gowans , , Thomas Gleixner , "Ingo Molnar" , Borislav Petkov , Dave Hansen , , , , , , , , Nikolas Wipper Subject: [PATCH 10/15] KVM: x86/mmu: Implement PWALK_STATUS_READ_ONLY_PTE_GPA in page walker Date: Tue, 10 Sep 2024 15:22:02 +0000 Message-ID: <20240910152207.38974-11-nikwip@amazon.de> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240910152207.38974-1-nikwip@amazon.de> References: <20240910152207.38974-1-nikwip@amazon.de> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Implement PWALK_STATUS_READ_ONLY_PTE_GPA in the page walker. This status flag is set when setting an accessed or dirty bit fails, because the memory of the page table entry was marked as read-only Signed-off-by: Nikolas Wipper --- arch/x86/include/asm/kvm_host.h | 2 ++ arch/x86/kvm/mmu/paging_tmpl.h | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 1c5aaf55c683..7ac1956f6f9b 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -290,6 +290,8 @@ enum x86_intercept_stage; #define PWALK_FORCE_SET_ACCESSED BIT(2) #define PWALK_SET_ALL (PWALK_SET_ACCESSED | PWALK_SET_DIRTY) +#define PWALK_STATUS_READ_ONLY_PTE_GPA BIT(0) + /* apic attention bits */ #define KVM_APIC_CHECK_VAPIC 0 /* diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h index 985a19dda603..0eefa48e0e7f 100644 --- a/arch/x86/kvm/mmu/paging_tmpl.h +++ b/arch/x86/kvm/mmu/paging_tmpl.h @@ -244,8 +244,11 @@ static int FNAME(update_accessed_dirty_bits)(struct kvm_vcpu *vcpu, * overwrite the read-only memory to set the accessed and dirty * bits. */ - if (unlikely(!walker->pte_writable[level - 1])) + if (unlikely(!walker->pte_writable[level - 1])) { + if (status) + *status |= PWALK_STATUS_READ_ONLY_PTE_GPA; continue; + } ret = __try_cmpxchg_user(ptep_user, &orig_pte, pte, fault); if (ret) From patchwork Tue Sep 10 15:22:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolas Wipper X-Patchwork-Id: 13798763 Received: from smtp-fw-52003.amazon.com (smtp-fw-52003.amazon.com [52.119.213.152]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E5FF11925B4; Tue, 10 Sep 2024 15:25:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=52.119.213.152 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725981934; cv=none; b=vCC43e28ex+AABykKcG6mk+f/kftcu7In1HWqEQkFarFADOcxGsSoSqKue5YI54xrEVXgtigMuV8hj5Zcq5sQJZjwvcqSEncHs6HiCxGj2UZPIOShYlR6KWnTbDpICXQQLVretiA2b7pfUGheTiwdXzmuHc7l0jtVOXMXyErGBo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725981934; c=relaxed/simple; bh=lwh5M10z4RNM2Da7RQPLG2d6B6aeiw/t0tqiRaPr1iw=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Aq7nhpgnKEqgaz9dbP+CtD4fyJCyiMT4azBAyukoiW+bjCz1hiLLIdWWByEUFsW2EYgYCoiupiSRcJYxoRetbi9UMnBdZREfFO6WnqhdYUqrfbcWfpWz6MefUfNxGqFScMRJkVQvROWUTDg07F5t3ErFxEG4s7+Xi6/CvTX5M/8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de; spf=pass smtp.mailfrom=amazon.de; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b=fmyPc+Sv; arc=none smtp.client-ip=52.119.213.152 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amazon.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b="fmyPc+Sv" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazon201209; t=1725981934; x=1757517934; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=LBFZ6gE4Eg8idRjndx3TROKSBGwrVfkZ4QZJ3iCcd00=; b=fmyPc+Sv42ljvz10vLDEpb99oxVcMkXNxj8slfOFAbfhiBAm6RBiu3sb Si/OOdCqj18Jt0xs1/j7x3cWfSQquVF3QcIdpuw0xkzUc/j9dy7ymU50J ZsLEcihw6TMOJduL3YJ7Xj3E9kbPyEWsgWEAebfZPeBcr/Uw304cc4cKr 8=; X-IronPort-AV: E=Sophos;i="6.10,217,1719878400"; d="scan'208";a="24631299" Received: from iad12-co-svc-p1-lb1-vlan3.amazon.com (HELO smtpout.prod.us-west-2.prod.farcaster.email.amazon.dev) ([10.43.8.6]) by smtp-border-fw-52003.iad7.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Sep 2024 15:25:30 +0000 Received: from EX19MTAUWB002.ant.amazon.com [10.0.38.20:1552] by smtpin.naws.us-west-2.prod.farcaster.email.amazon.dev [10.0.40.54:2525] with esmtp (Farcaster) id a5951997-5357-4874-bf9e-57a899457c9a; Tue, 10 Sep 2024 15:25:29 +0000 (UTC) X-Farcaster-Flow-ID: a5951997-5357-4874-bf9e-57a899457c9a Received: from EX19D020UWC002.ant.amazon.com (10.13.138.147) by EX19MTAUWB002.ant.amazon.com (10.250.64.231) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Tue, 10 Sep 2024 15:25:28 +0000 Received: from EX19MTAUWB001.ant.amazon.com (10.250.64.248) by EX19D020UWC002.ant.amazon.com (10.13.138.147) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Tue, 10 Sep 2024 15:25:28 +0000 Received: from dev-dsk-nikwip-1b-bc9ec026.eu-west-1.amazon.com (10.253.74.52) by mail-relay.amazon.com (10.250.64.254) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34 via Frontend Transport; Tue, 10 Sep 2024 15:25:26 +0000 From: Nikolas Wipper To: Paolo Bonzini , Sean Christopherson , Vitaly Kuznetsov CC: Nicolas Saenz Julienne , Alexander Graf , James Gowans , , Thomas Gleixner , "Ingo Molnar" , Borislav Petkov , Dave Hansen , , , , , , , , Nikolas Wipper Subject: [PATCH 11/15] KVM: x86: Introduce generic gva to gpa translation function Date: Tue, 10 Sep 2024 15:22:03 +0000 Message-ID: <20240910152207.38974-12-nikwip@amazon.de> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240910152207.38974-1-nikwip@amazon.de> References: <20240910152207.38974-1-nikwip@amazon.de> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Introduce a function to translate gvas to gpas with the ability to control set_bit_mode, access mode and flags, as well as receive status codes. Signed-off-by: Nikolas Wipper --- arch/x86/include/asm/kvm_host.h | 3 +++ arch/x86/kvm/x86.c | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 7ac1956f6f9b..ae05e917d7ea 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -2160,6 +2160,9 @@ static inline bool kvm_mmu_unprotect_gfn_and_retry(struct kvm_vcpu *vcpu, void kvm_mmu_free_roots(struct kvm *kvm, struct kvm_mmu *mmu, ulong roots_to_free); void kvm_mmu_free_guest_mode_roots(struct kvm *kvm, struct kvm_mmu *mmu); +gpa_t kvm_mmu_gva_to_gpa(struct kvm_vcpu *vcpu, gva_t gva, u64 access, + u64 flags, struct x86_exception *exception, + u16 *status); gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva, struct x86_exception *exception); gpa_t kvm_mmu_gva_to_gpa_write(struct kvm_vcpu *vcpu, gva_t gva, diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index be696b60aba6..27fc71aaa1e4 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -7577,6 +7577,17 @@ gpa_t translate_nested_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u64 access, return t_gpa; } +gpa_t kvm_mmu_gva_to_gpa(struct kvm_vcpu *vcpu, gva_t gva, u64 access, + u64 flags, struct x86_exception *exception, + u16 *status) +{ + struct kvm_mmu *mmu = vcpu->arch.walk_mmu; + + return mmu->gva_to_gpa(vcpu, mmu, gva, access, flags, exception, + status); +} +EXPORT_SYMBOL_GPL(kvm_mmu_gva_to_gpa); + gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva, struct x86_exception *exception) { From patchwork Tue Sep 10 15:22:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolas Wipper X-Patchwork-Id: 13798764 Received: from smtp-fw-80008.amazon.com (smtp-fw-80008.amazon.com [99.78.197.219]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 346BB19ABBB; Tue, 10 Sep 2024 15:25:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=99.78.197.219 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725981958; cv=none; b=Let1by3GakUuI/aZvckDlA50mpX5MxJl5cZEoB0h/oITS8Fisg2anokVI0vRKI5JuGmI9YQxFHxLh0eAYGssUSF0T0QBi43VtyWPDtW4EM5x0YAKE8YGr8NllIIzMQ091VijxO85hyY3fhnQniVHqDS82lqJmGFFBt+Nz+fShVs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725981958; c=relaxed/simple; bh=9hr/0kawES/adepKkQ9yHHYMngxIVaVfaZIR1M8p5u0=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=uuFND5G1DTSHM3iYUNSr0q0KKz3WRnkagimTOzn2+BnD7vpvWt8JG7SjpYaEyiFPEJ0jU+qTjo9I8IYe6/Ju77XdUeqykRyrmDrbQH+BkzmZJs3WuAnmrtjHOp2OSLEbbgUFO92z449+ZNeh0gHcYQuKjbbp8GFhDQ9tZuQ1MFw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de; spf=pass smtp.mailfrom=amazon.de; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b=EO7w9DT+; arc=none smtp.client-ip=99.78.197.219 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amazon.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b="EO7w9DT+" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazon201209; t=1725981957; x=1757517957; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=FHvBgv0Npw60N9xHTv3fpyMvYJu/4r16iS7NVuI/vEA=; b=EO7w9DT+4/auSp7v7nsiCLqBKiphLJMGCi7IcockpSDp7gwb1V0zxl34 kWQG7PKLaDKyx+fGt1CAEbNdVo00D1ifxKt5O9R6mL122h1zAABB2hY/+ /EjRgZv2f2mrbBWrVQS62wqbcrUgGqwghJc70Ng8btBFZqg0zpt5KqJna E=; X-IronPort-AV: E=Sophos;i="6.10,217,1719878400"; d="scan'208";a="124582879" Received: from pdx4-co-svc-p1-lb2-vlan3.amazon.com (HELO smtpout.prod.us-west-2.prod.farcaster.email.amazon.dev) ([10.25.36.214]) by smtp-border-fw-80008.pdx80.corp.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Sep 2024 15:25:55 +0000 Received: from EX19MTAUWA002.ant.amazon.com [10.0.38.20:62383] by smtpin.naws.us-west-2.prod.farcaster.email.amazon.dev [10.0.52.222:2525] with esmtp (Farcaster) id ed13ad4c-99ab-45f6-a219-529a4081f79b; Tue, 10 Sep 2024 15:25:54 +0000 (UTC) X-Farcaster-Flow-ID: ed13ad4c-99ab-45f6-a219-529a4081f79b Received: from EX19D020UWC002.ant.amazon.com (10.13.138.147) by EX19MTAUWA002.ant.amazon.com (10.250.64.202) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Tue, 10 Sep 2024 15:25:47 +0000 Received: from EX19MTAUWC001.ant.amazon.com (10.250.64.145) by EX19D020UWC002.ant.amazon.com (10.13.138.147) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Tue, 10 Sep 2024 15:25:47 +0000 Received: from dev-dsk-nikwip-1b-bc9ec026.eu-west-1.amazon.com (10.253.74.52) by mail-relay.amazon.com (10.250.64.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34 via Frontend Transport; Tue, 10 Sep 2024 15:25:44 +0000 From: Nikolas Wipper To: Paolo Bonzini , Sean Christopherson , Vitaly Kuznetsov CC: Nicolas Saenz Julienne , Alexander Graf , James Gowans , , Thomas Gleixner , "Ingo Molnar" , Borislav Petkov , Dave Hansen , , , , , , , , Nikolas Wipper Subject: [PATCH 12/15] KVM: Introduce KVM_TRANSLATE2 Date: Tue, 10 Sep 2024 15:22:04 +0000 Message-ID: <20240910152207.38974-13-nikwip@amazon.de> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240910152207.38974-1-nikwip@amazon.de> References: <20240910152207.38974-1-nikwip@amazon.de> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Introduce a new ioctl that extends the functionality of KVM_TRANSLATE. It allows the caller to specify an access mode that must be upheld throughout the entire page walk. Additionally, it provides control over whether the accessed/dirty bits in the page table should be set at all, and whether they should be set if the walk fails. Lastly, if the page walk fails, it returns the exact error code which caused the failure. KVM_TRANSLATE lacks information about executability of the translated page and doesn't provide control over the accessed/dirty page table bits at all. Because it lacks any sort of input flags, it cannot simply be expanded without breaking backwards compatibility. Additionally, in the x86 implementation the 'writable' and 'usermode' are currently hardcoded to 1 and 0 respectively, which is behaviour that might be relied upon. The ioctl will be implemented for x86 in following commits. Signed-off-by: Nikolas Wipper --- include/linux/kvm_host.h | 4 ++++ include/uapi/linux/kvm.h | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index b23c6d48392f..c78017fd2907 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -84,6 +84,10 @@ #define KVM_MAX_NR_ADDRESS_SPACES 1 #endif +#define KVM_TRANSLATE_FLAGS_ALL \ + (KVM_TRANSLATE_FLAGS_SET_ACCESSED | \ + KVM_TRANSLATE_FLAGS_SET_DIRTY | \ + KVM_TRANSLATE_FLAGS_FORCE_SET_ACCESSED) /* * For the normal pfn, the highest 12 bits should be zero, * so we can mask bit 62 ~ bit 52 to indicate the error pfn, diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 637efc055145..602323e734cc 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -512,6 +512,37 @@ struct kvm_translation { __u8 pad[5]; }; +/* for KVM_TRANSLATE2 */ +struct kvm_translation2 { + /* in */ + __u64 linear_address; +#define KVM_TRANSLATE_FLAGS_SET_ACCESSED (1 << 0) +#define KVM_TRANSLATE_FLAGS_SET_DIRTY (1 << 1) +#define KVM_TRANSLATE_FLAGS_FORCE_SET_ACCESSED (1 << 2) + __u16 flags; +#define KVM_TRANSLATE_ACCESS_WRITE (1 << 0) +#define KVM_TRANSLATE_ACCESS_USER (1 << 1) +#define KVM_TRANSLATE_ACCESS_EXEC (1 << 2) +#define KVM_TRANSLATE_ACCESS_ALL \ + (KVM_TRANSLATE_ACCESS_WRITE | \ + KVM_TRANSLATE_ACCESS_USER | \ + KVM_TRANSLATE_ACCESS_EXEC) + __u16 access; + __u8 padding[4]; + + /* out */ + __u64 physical_address; + __u8 valid; +#define KVM_TRANSLATE_FAULT_NOT_PRESENT 1 +#define KVM_TRANSLATE_FAULT_PRIVILEGE_VIOLATION 2 +#define KVM_TRANSLATE_FAULT_RESERVED_BITS 3 +#define KVM_TRANSLATE_FAULT_INVALID_GVA 4 +#define KVM_TRANSLATE_FAULT_INVALID_GPA 5 + __u16 error_code; + __u8 set_bits_succeeded; + __u8 padding2[4]; +}; + /* for KVM_INTERRUPT */ struct kvm_interrupt { /* in */ @@ -933,6 +964,7 @@ struct kvm_enable_cap { #define KVM_CAP_PRE_FAULT_MEMORY 236 #define KVM_CAP_X86_APIC_BUS_CYCLES_NS 237 #define KVM_CAP_X86_GUEST_MODE 238 +#define KVM_CAP_TRANSLATE2 239 struct kvm_irq_routing_irqchip { __u32 irqchip; @@ -1269,6 +1301,7 @@ struct kvm_vfio_spapr_tce { #define KVM_SET_SREGS _IOW(KVMIO, 0x84, struct kvm_sregs) #define KVM_TRANSLATE _IOWR(KVMIO, 0x85, struct kvm_translation) #define KVM_INTERRUPT _IOW(KVMIO, 0x86, struct kvm_interrupt) +#define KVM_TRANSLATE2 _IOWR(KVMIO, 0x87, struct kvm_translation2) #define KVM_GET_MSRS _IOWR(KVMIO, 0x88, struct kvm_msrs) #define KVM_SET_MSRS _IOW(KVMIO, 0x89, struct kvm_msrs) #define KVM_SET_CPUID _IOW(KVMIO, 0x8a, struct kvm_cpuid) From patchwork Tue Sep 10 15:22:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolas Wipper X-Patchwork-Id: 13798792 Received: from smtp-fw-6002.amazon.com (smtp-fw-6002.amazon.com [52.95.49.90]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0962819AD81; Tue, 10 Sep 2024 15:26:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=52.95.49.90 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725981972; cv=none; b=YyjULrgjz0s/rJrzFfkJTWA5wuBYNTbGUWpzp+hr3JPkVLQPmgjE6vgFHJt8X34+0pzclWABiI9b8XgP07Wl1EZrrUxiTjfIM8Emfjc9rGVRHdxl04+Gwit9GjPitXU7h8Wux2oFUZKkUflVGjhqzITHrlnzI7qT+gZvc27Go/Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725981972; c=relaxed/simple; bh=++HidJlPLgLwaU/8+cLxxidpjLOQ5iKZF0hGZox10tc=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=NpBRFKmYfv9Vy67Rv/IPZgL7G9DyXMkGugBWovm8+WI8WYiIjN6j6a0VeEMqEHQCIgirTPrlGIFhc9pVuLzFJAZ7Re97Y2lHYVATK/5y2/lzQjr2C4vnOUyoUromjhbkF40eINAl1OKZesv/pEQx2wf+wYl4W+Nk4hwhMbNgTp0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de; spf=pass smtp.mailfrom=amazon.de; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b=u9duiKmX; arc=none smtp.client-ip=52.95.49.90 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amazon.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b="u9duiKmX" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazon201209; t=1725981971; x=1757517971; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=qyhv+EAHgrh/iCvCQUdCsSUgOa9xa1Wd76nhgoQDloY=; b=u9duiKmX9pqi7g76xsw1uex/8eLRjCIQExkQ61YVv10C8vPtLateKtV7 JzDr5Y5pj/EqIYyJ4fXbysWZJwEMgKKKyXBwgityWjWtHoSJG5rhpllgw M6oal1X7MYuwXeZHg4YT+XCtOjAZhPZEMc/ErDv3nswmSeM/GEE4WvHTA 0=; X-IronPort-AV: E=Sophos;i="6.10,217,1719878400"; d="scan'208";a="432460735" Received: from iad12-co-svc-p1-lb1-vlan3.amazon.com (HELO smtpout.prod.us-west-2.prod.farcaster.email.amazon.dev) ([10.43.8.6]) by smtp-border-fw-6002.iad6.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Sep 2024 15:26:08 +0000 Received: from EX19MTAUWB001.ant.amazon.com [10.0.21.151:10936] by smtpin.naws.us-west-2.prod.farcaster.email.amazon.dev [10.0.38.253:2525] with esmtp (Farcaster) id c98c2613-8b3f-4de2-87d9-65fcddd7723f; Tue, 10 Sep 2024 15:26:06 +0000 (UTC) X-Farcaster-Flow-ID: c98c2613-8b3f-4de2-87d9-65fcddd7723f Received: from EX19D020UWC004.ant.amazon.com (10.13.138.149) by EX19MTAUWB001.ant.amazon.com (10.250.64.248) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Tue, 10 Sep 2024 15:26:06 +0000 Received: from EX19MTAUWA001.ant.amazon.com (10.250.64.204) by EX19D020UWC004.ant.amazon.com (10.13.138.149) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Tue, 10 Sep 2024 15:26:06 +0000 Received: from dev-dsk-nikwip-1b-bc9ec026.eu-west-1.amazon.com (10.253.74.52) by mail-relay.amazon.com (10.250.64.204) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34 via Frontend Transport; Tue, 10 Sep 2024 15:26:03 +0000 From: Nikolas Wipper To: Paolo Bonzini , Sean Christopherson , Vitaly Kuznetsov CC: Nicolas Saenz Julienne , Alexander Graf , James Gowans , , Thomas Gleixner , "Ingo Molnar" , Borislav Petkov , Dave Hansen , , , , , , , , Nikolas Wipper Subject: [PATCH 13/15] KVM: Add KVM_TRANSLATE2 stub Date: Tue, 10 Sep 2024 15:22:05 +0000 Message-ID: <20240910152207.38974-14-nikwip@amazon.de> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240910152207.38974-1-nikwip@amazon.de> References: <20240910152207.38974-1-nikwip@amazon.de> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add stub function for the KVM_TRANSLATE2 ioctl, as well as generic parameter verification. In a later commit, the ioctl will be properly implemented for x86. Signed-off-by: Nikolas Wipper --- include/linux/kvm_host.h | 2 ++ virt/kvm/kvm_main.c | 41 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index c78017fd2907..de6557794735 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -1492,6 +1492,8 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu); int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu, struct kvm_translation *tr); +int kvm_arch_vcpu_ioctl_translate2(struct kvm_vcpu *vcpu, + struct kvm_translation2 *tr); int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs); int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs); diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index d51357fd28d7..c129dc0b0485 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -4442,6 +4442,32 @@ static int kvm_vcpu_pre_fault_memory(struct kvm_vcpu *vcpu, } #endif +int __weak kvm_arch_vcpu_ioctl_translate2(struct kvm_vcpu *vcpu, + struct kvm_translation2 *tr) +{ + return -EINVAL; +} + +static int kvm_vcpu_ioctl_translate2(struct kvm_vcpu *vcpu, + struct kvm_translation2 *tr) +{ + /* Don't allow FORCE_SET_ACCESSED and SET_BITS without SET_ACCESSED */ + if (!(tr->flags & KVM_TRANSLATE_FLAGS_SET_ACCESSED) && + (tr->flags & KVM_TRANSLATE_FLAGS_FORCE_SET_ACCESSED || + tr->flags & KVM_TRANSLATE_FLAGS_SET_DIRTY)) + return -EINVAL; + + if (tr->flags & KVM_TRANSLATE_FLAGS_SET_DIRTY && + !(tr->access & KVM_TRANSLATE_ACCESS_WRITE)) + return -EINVAL; + + if (tr->flags & ~KVM_TRANSLATE_FLAGS_ALL || + tr->access & ~KVM_TRANSLATE_ACCESS_ALL) + return -EINVAL; + + return kvm_arch_vcpu_ioctl_translate2(vcpu, tr); +} + static long kvm_vcpu_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { @@ -4585,6 +4611,21 @@ static long kvm_vcpu_ioctl(struct file *filp, r = 0; break; } + case KVM_TRANSLATE2: { + struct kvm_translation2 tr; + + r = -EFAULT; + if (copy_from_user(&tr, argp, sizeof(tr))) + goto out; + r = kvm_vcpu_ioctl_translate2(vcpu, &tr); + if (r) + goto out; + r = -EFAULT; + if (copy_to_user(argp, &tr, sizeof(tr))) + goto out; + r = 0; + break; + } case KVM_SET_GUEST_DEBUG: { struct kvm_guest_debug dbg; From patchwork Tue Sep 10 15:22:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolas Wipper X-Patchwork-Id: 13798793 Received: from smtp-fw-9102.amazon.com (smtp-fw-9102.amazon.com [207.171.184.29]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C6ADB196434; Tue, 10 Sep 2024 15:26:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=207.171.184.29 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725981996; cv=none; b=h3l/TfqenPhbMvH8k/FhFvTHgoH/7l81Unh+WRFHySjDxRGhGVOh7ZpMHWX4I5cNaIEmyOc1IFgzFMt2wOUiqu0keEYzsIZVrIKribS42/7KELUi1rgUWl1JWVCKQxRDNrr9cAhuXHjGqcZkFgfWVI1dGsOkqzMVMXK85sP0E+Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725981996; c=relaxed/simple; bh=P1+qeKj1jWxQHOBUtyutYQVE5fRKcoSoqDE+RShE8+U=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=HRATGVVUksHn3zmuYlNJAJ0WTxst8Ui5DLIVZvCq20F6SXaAaN2vgAYKfC8L37N3c97zI1SXyg3GOCXGFbq6y8rmEkDsD1TTJ9tLVL1Ra2jk+nlLNg6nLSwn6Eld1m8tY2905OXD+wBGUvNxU1hil6jkI1np2wcugT6dm86z8U8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de; spf=pass smtp.mailfrom=amazon.de; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b=U5ph+NPr; arc=none smtp.client-ip=207.171.184.29 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amazon.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b="U5ph+NPr" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazon201209; t=1725981995; x=1757517995; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=hQ6xRuASXpOta6yp55hPSDQn+GPR+RFHRqTzI9yNfP0=; b=U5ph+NPrIc2zYgg1+f1J/W+CGgYoHBawkeA0bqaa5JQ7cjR8PawrgUmx otabuRlXV9gvHr68rW10KVKepO9EnhBH+LVjtT7wCn0OVLMUVk/uNZQgz UseLUhSxlWrlP2g4xRULo8ye8cf1DtgdxAYMclj62o5j6gYMXNylDDhQN A=; X-IronPort-AV: E=Sophos;i="6.10,217,1719878400"; d="scan'208";a="452528207" Received: from pdx4-co-svc-p1-lb2-vlan3.amazon.com (HELO smtpout.prod.us-east-1.prod.farcaster.email.amazon.dev) ([10.25.36.214]) by smtp-border-fw-9102.sea19.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Sep 2024 15:26:27 +0000 Received: from EX19MTAEUC001.ant.amazon.com [10.0.10.100:21666] by smtpin.naws.eu-west-1.prod.farcaster.email.amazon.dev [10.0.39.168:2525] with esmtp (Farcaster) id dd915001-a97f-4234-a16e-6bb0e9589d81; Tue, 10 Sep 2024 15:26:26 +0000 (UTC) X-Farcaster-Flow-ID: dd915001-a97f-4234-a16e-6bb0e9589d81 Received: from EX19D004EUA004.ant.amazon.com (10.252.50.183) by EX19MTAEUC001.ant.amazon.com (10.252.51.155) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Tue, 10 Sep 2024 15:26:24 +0000 Received: from EX19MTAUEB001.ant.amazon.com (10.252.135.35) by EX19D004EUA004.ant.amazon.com (10.252.50.183) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Tue, 10 Sep 2024 15:26:23 +0000 Received: from dev-dsk-nikwip-1b-bc9ec026.eu-west-1.amazon.com (10.253.74.52) by mail-relay.amazon.com (10.252.135.35) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34 via Frontend Transport; Tue, 10 Sep 2024 15:26:22 +0000 From: Nikolas Wipper To: Paolo Bonzini , Sean Christopherson , Vitaly Kuznetsov CC: Nicolas Saenz Julienne , Alexander Graf , James Gowans , , Thomas Gleixner , "Ingo Molnar" , Borislav Petkov , Dave Hansen , , , , , , , , Nikolas Wipper Subject: [PATCH 14/15] KVM: x86: Implement KVM_TRANSLATE2 Date: Tue, 10 Sep 2024 15:22:06 +0000 Message-ID: <20240910152207.38974-15-nikwip@amazon.de> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240910152207.38974-1-nikwip@amazon.de> References: <20240910152207.38974-1-nikwip@amazon.de> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Implement KVM_TRANSLATE2 for x86 using the default KVM page walker. Signed-off-by: Nikolas Wipper --- arch/x86/kvm/x86.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 27fc71aaa1e4..3bcbad958324 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4683,6 +4683,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_IRQFD_RESAMPLE: case KVM_CAP_MEMORY_FAULT_INFO: case KVM_CAP_X86_GUEST_MODE: + case KVM_CAP_TRANSLATE2: r = 1; break; case KVM_CAP_PRE_FAULT_MEMORY: @@ -12156,6 +12157,81 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu, return 0; } +/* + * Translate a guest virtual address to a guest physical address. + */ +int kvm_arch_vcpu_ioctl_translate2(struct kvm_vcpu *vcpu, + struct kvm_translation2 *tr) +{ + int idx, set_bit_mode = 0, access = 0; + struct x86_exception exception = { }; + gva_t vaddr = tr->linear_address; + u16 status = 0; + gpa_t gpa; + + if (tr->flags & KVM_TRANSLATE_FLAGS_SET_ACCESSED) + set_bit_mode |= PWALK_SET_ACCESSED; + if (tr->flags & KVM_TRANSLATE_FLAGS_SET_DIRTY) + set_bit_mode |= PWALK_SET_DIRTY; + if (tr->flags & KVM_TRANSLATE_FLAGS_FORCE_SET_ACCESSED) + set_bit_mode |= PWALK_FORCE_SET_ACCESSED; + + if (tr->access & KVM_TRANSLATE_ACCESS_WRITE) + access |= PFERR_WRITE_MASK; + if (tr->access & KVM_TRANSLATE_ACCESS_USER) + access |= PFERR_USER_MASK; + if (tr->access & KVM_TRANSLATE_ACCESS_EXEC) + access |= PFERR_FETCH_MASK; + + vcpu_load(vcpu); + + idx = srcu_read_lock(&vcpu->kvm->srcu); + + /* Even with PAE virtual addresses are still 32-bit */ + if (is_64_bit_mode(vcpu) ? is_noncanonical_address(vaddr, vcpu) : + tr->linear_address >> 32) { + tr->valid = false; + tr->error_code = KVM_TRANSLATE_FAULT_INVALID_GVA; + goto exit; + } + + gpa = kvm_mmu_gva_to_gpa(vcpu, vaddr, access, set_bit_mode, &exception, + &status); + + tr->physical_address = exception.error_code_valid ? exception.gpa_page_fault : gpa; + tr->valid = !exception.error_code_valid; + + /* + * Order is important here: + * - If there are access restrictions those will always be set in the + * error_code + * - If a PTE GPA is unmapped, the present bit in error_code may not + * have been set already + */ + if (exception.flags & KVM_X86_UNMAPPED_PTE_GPA) + tr->error_code = KVM_TRANSLATE_FAULT_INVALID_GPA; + else if (!(exception.error_code & PFERR_PRESENT_MASK)) + tr->error_code = KVM_TRANSLATE_FAULT_NOT_PRESENT; + else if (exception.error_code & PFERR_RSVD_MASK) + tr->error_code = KVM_TRANSLATE_FAULT_RESERVED_BITS; + else if (exception.error_code & (PFERR_USER_MASK | PFERR_WRITE_MASK | + PFERR_FETCH_MASK)) + tr->error_code = KVM_TRANSLATE_FAULT_PRIVILEGE_VIOLATION; + + /* + * exceptions.flags and thus tr->set_bits_succeeded have meaning + * regardless of the success of the page walk. + */ + tr->set_bits_succeeded = tr->flags && + !(status & PWALK_STATUS_READ_ONLY_PTE_GPA); + +exit: + srcu_read_unlock(&vcpu->kvm->srcu, idx); + + vcpu_put(vcpu); + return 0; +} + int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) { struct fxregs_state *fxsave; From patchwork Tue Sep 10 15:22:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nikolas Wipper X-Patchwork-Id: 13798794 Received: from smtp-fw-6001.amazon.com (smtp-fw-6001.amazon.com [52.95.48.154]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D54E919ABB6; Tue, 10 Sep 2024 15:26:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=52.95.48.154 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725982022; cv=none; b=R3wbnWUL81BwAY3jvGgAeamhSHYmjR2HIyM8LgBmt32zOl0YOAyjURN2YKv0oNg9Eus7AH6OXLM19pQVjOx8gP6M6oBAo1SCLyethY3fXEz9vJf987I8UiOd/FFeM6DNtAlwKtFHGFgd56KK3KwhPAELbxw/owL7kDr9aAu/W9Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725982022; c=relaxed/simple; bh=9cKjl9ygprSgUGbTu9ou8VxGIYHVdp/M2hZ72Ih7JLQ=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=hH0tXPNdOeB85+ywSiEdjWVOvAyL2eqSLPkBu8yAJM8AYqMfn3uFBhoogQ0JC6fxlnT+qNkJKlKPurXHP64HSG3aWUd2YxU8gXaHdt3rdVCZp2+rFAkcyH7/BmUcoEREkQqWopfLtUSASABrwiEaf/TLSRJ/EcdzCIf8EVszeqQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de; spf=pass smtp.mailfrom=amazon.de; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b=TJV73I0G; arc=none smtp.client-ip=52.95.48.154 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amazon.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b="TJV73I0G" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazon201209; t=1725982021; x=1757518021; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=9cKjl9ygprSgUGbTu9ou8VxGIYHVdp/M2hZ72Ih7JLQ=; b=TJV73I0GBfGkLuPTE4hHaboHrbBDasOLYNmBzZEqMMC86wJF0RZ9+Q/N rNYY23kAbr57xHORC4RsIBNwQsmydXYVNfMgKSr7Xd6c3OMekvas8ZDt5 5KVR0JmDt013iL/GMN3fYy3S7+upHHRa24GM7X0sr57D9ZRFcbmiO2p3n U=; X-IronPort-AV: E=Sophos;i="6.10,217,1719878400"; d="scan'208";a="422886989" Received: from iad12-co-svc-p1-lb1-vlan2.amazon.com (HELO smtpout.prod.us-west-2.prod.farcaster.email.amazon.dev) ([10.43.8.2]) by smtp-border-fw-6001.iad6.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Sep 2024 15:26:50 +0000 Received: from EX19MTAUWA002.ant.amazon.com [10.0.38.20:61190] by smtpin.naws.us-west-2.prod.farcaster.email.amazon.dev [10.0.23.84:2525] with esmtp (Farcaster) id dd07028c-4466-4584-b915-58f08c541f19; Tue, 10 Sep 2024 15:26:49 +0000 (UTC) X-Farcaster-Flow-ID: dd07028c-4466-4584-b915-58f08c541f19 Received: from EX19D020UWA002.ant.amazon.com (10.13.138.222) by EX19MTAUWA002.ant.amazon.com (10.250.64.202) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Tue, 10 Sep 2024 15:26:41 +0000 Received: from EX19MTAUEA001.ant.amazon.com (10.252.134.203) by EX19D020UWA002.ant.amazon.com (10.13.138.222) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Tue, 10 Sep 2024 15:26:41 +0000 Received: from dev-dsk-nikwip-1b-bc9ec026.eu-west-1.amazon.com (10.253.74.52) by mail-relay.amazon.com (10.252.134.102) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34 via Frontend Transport; Tue, 10 Sep 2024 15:26:39 +0000 From: Nikolas Wipper To: Paolo Bonzini , Sean Christopherson , Vitaly Kuznetsov CC: Nicolas Saenz Julienne , Alexander Graf , James Gowans , , Thomas Gleixner , "Ingo Molnar" , Borislav Petkov , Dave Hansen , , , , , , , , Nikolas Wipper Subject: [PATCH 15/15] KVM: selftests: Add test for KVM_TRANSLATE2 Date: Tue, 10 Sep 2024 15:22:07 +0000 Message-ID: <20240910152207.38974-16-nikwip@amazon.de> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240910152207.38974-1-nikwip@amazon.de> References: <20240910152207.38974-1-nikwip@amazon.de> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add selftest for KVM_TRANSLATE2. There are four different subtests. A basic translate test that checks whether access permissions are handled correctly. A set bits test, that checks whether the accessed and dirty bits are set correctly. An errors test, that checks negative cases of the flags. And a fuzzy test on random guest page tables. The tests currently use x86 specific paging code, so generalising them for more platforms is hard. Once other architectures implement KVM_TRANSLATE2 they need to be split into arch specific and agnostic parts. Signed-off-by: Nikolas Wipper --- tools/testing/selftests/kvm/Makefile | 1 + .../selftests/kvm/x86_64/kvm_translate2.c | 310 ++++++++++++++++++ 2 files changed, 311 insertions(+) create mode 100644 tools/testing/selftests/kvm/x86_64/kvm_translate2.c diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile index 45cb70c048bb..5bb2db679658 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -81,6 +81,7 @@ TEST_GEN_PROGS_x86_64 += x86_64/hyperv_svm_test TEST_GEN_PROGS_x86_64 += x86_64/hyperv_tlb_flush TEST_GEN_PROGS_x86_64 += x86_64/kvm_clock_test TEST_GEN_PROGS_x86_64 += x86_64/kvm_pv_test +TEST_GEN_PROGS_x86_64 += x86_64/kvm_translate2 TEST_GEN_PROGS_x86_64 += x86_64/monitor_mwait_test TEST_GEN_PROGS_x86_64 += x86_64/nested_exceptions_test TEST_GEN_PROGS_x86_64 += x86_64/platform_info_test diff --git a/tools/testing/selftests/kvm/x86_64/kvm_translate2.c b/tools/testing/selftests/kvm/x86_64/kvm_translate2.c new file mode 100644 index 000000000000..607af6376243 --- /dev/null +++ b/tools/testing/selftests/kvm/x86_64/kvm_translate2.c @@ -0,0 +1,310 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Test for x86 KVM_TRANSLATE2 + * + * Copyright © 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * This work is licensed under the terms of the GNU GPL, version 2. + * + */ +#include +#include +#include +#include +#include + +#include "test_util.h" +#include "kvm_util.h" +#include "processor.h" + +#define CHECK_ACCESSED_BIT(pte, set, start) \ + ({ \ + for (int _i = start; _i <= PG_LEVEL_512G; _i++) { \ + if (set) \ + TEST_ASSERT( \ + (*pte[_i] & PTE_ACCESSED_MASK) != 0, \ + "Page not marked accessed on level %i", \ + _i); \ + else \ + TEST_ASSERT( \ + (*pte[_i] & PTE_ACCESSED_MASK) == 0, \ + "Page marked accessed on level %i", \ + _i); \ + } \ + }) + +#define CHECK_DIRTY_BIT(pte, set) \ + ({ \ + if (set) \ + TEST_ASSERT((*pte[PG_LEVEL_4K] & PTE_DIRTY_MASK) != 0, \ + "Page not marked dirty"); \ + else \ + TEST_ASSERT((*pte[PG_LEVEL_4K] & PTE_DIRTY_MASK) == 0, \ + "Page marked dirty"); \ + }) + +enum point_of_failure { + pof_none, + pof_ioctl, + pof_page_walk, + pof_no_failure, +}; + +struct kvm_translation2 kvm_translate2(struct kvm_vcpu *vcpu, uint64_t vaddr, + int flags, int access, + enum point_of_failure pof) +{ + struct kvm_translation2 tr = { .linear_address = vaddr, + .flags = flags, + .access = access }; + + int res = ioctl(vcpu->fd, KVM_TRANSLATE2, &tr); + + if (pof == pof_none) + return tr; + + if (pof == pof_ioctl) { + TEST_ASSERT(res == -1, "ioctl didn't fail"); + return tr; + } + + TEST_ASSERT(res != -1, "ioctl failed"); + TEST_ASSERT((pof != pof_page_walk) == tr.valid, + "Page walk fail with code %u", tr.error_code); + + return tr; +} + +void test_translate(struct kvm_vm *vm, struct kvm_vcpu *vcpu, int index, + uint64_t *pte[PG_LEVEL_NUM], vm_vaddr_t vaddr) +{ + struct kvm_translation2 translation; + int access = index; + + printf("%s - write: %u, user: %u, exec: %u ...\t", + __func__, + (access & KVM_TRANSLATE_ACCESS_WRITE) >> 0, + (access & KVM_TRANSLATE_ACCESS_USER) >> 1, + (access & KVM_TRANSLATE_ACCESS_EXEC) >> 2); + + uint64_t mask = PTE_WRITABLE_MASK | PTE_USER_MASK | PTE_NX_MASK; + uint64_t new_value = 0; + + if (access & KVM_TRANSLATE_ACCESS_WRITE) + new_value |= PTE_WRITABLE_MASK; + if (access & KVM_TRANSLATE_ACCESS_USER) + new_value |= PTE_USER_MASK; + if (!(access & KVM_TRANSLATE_ACCESS_EXEC)) + new_value |= PTE_NX_MASK; + + for (int i = PG_LEVEL_4K; i <= PG_LEVEL_512G; i++) + *pte[i] = (*pte[i] & ~mask) | new_value; + + translation = kvm_translate2(vcpu, vaddr, 0, access, pof_no_failure); + + TEST_ASSERT_EQ(*pte[PG_LEVEL_4K] & GENMASK(51, 12), + translation.physical_address); + + /* Check configurations that have extra access requirements */ + for (int i = 0; i < 8; i++) { + int case_access = i; + + if ((case_access | access) <= access) + continue; + + translation = kvm_translate2(vcpu, vaddr, 0, case_access, + pof_page_walk); + TEST_ASSERT_EQ(translation.error_code, + KVM_TRANSLATE_FAULT_PRIVILEGE_VIOLATION); + } + + /* Clear accessed bits */ + for (int i = PG_LEVEL_4K; i <= PG_LEVEL_512G; i++) + *pte[i] &= ~PTE_ACCESSED_MASK; + + printf("[ok]\n"); +} + +void test_set_bits(struct kvm_vm *vm, struct kvm_vcpu *vcpu, + uint64_t *pte[PG_LEVEL_NUM], vm_vaddr_t vaddr) +{ + printf("%s ...\t", __func__); + + /* Sanity checks */ + CHECK_ACCESSED_BIT(pte, false, PG_LEVEL_4K); + CHECK_DIRTY_BIT(pte, false); + + kvm_translate2(vcpu, vaddr, 0, 0, pof_no_failure); + + CHECK_ACCESSED_BIT(pte, false, PG_LEVEL_4K); + CHECK_DIRTY_BIT(pte, false); + + kvm_translate2(vcpu, vaddr, KVM_TRANSLATE_FLAGS_SET_ACCESSED, 0, + pof_no_failure); + + CHECK_ACCESSED_BIT(pte, true, PG_LEVEL_4K); + CHECK_DIRTY_BIT(pte, false); + + kvm_translate2(vcpu, vaddr, + KVM_TRANSLATE_FLAGS_SET_ACCESSED | KVM_TRANSLATE_FLAGS_SET_DIRTY, + KVM_TRANSLATE_ACCESS_WRITE, pof_no_failure); + + CHECK_ACCESSED_BIT(pte, true, PG_LEVEL_4K); + CHECK_DIRTY_BIT(pte, true); + + printf("[ok]\n"); +} + +void test_errors(struct kvm_vm *vm, struct kvm_vcpu *vcpu, + uint64_t *pte[PG_LEVEL_NUM], vm_vaddr_t vaddr) +{ + struct kvm_translation2 tr; + + printf("%s ...\t", __func__); + + /* Set an unsupported access bit */ + kvm_translate2(vcpu, vaddr, 0, (1 << 3), pof_ioctl); + kvm_translate2(vcpu, vaddr, KVM_TRANSLATE_FLAGS_SET_DIRTY, 0, pof_ioctl); + kvm_translate2(vcpu, vaddr, KVM_TRANSLATE_FLAGS_FORCE_SET_ACCESSED, 0, + pof_ioctl); + + /* Try to translate a non-canonical address */ + tr = kvm_translate2(vcpu, 0b101ull << 60, 0, 0, pof_page_walk); + TEST_ASSERT_EQ(tr.error_code, KVM_TRANSLATE_FAULT_INVALID_GVA); + + uint64_t old_pte = *pte[PG_LEVEL_2M]; + + *pte[PG_LEVEL_2M] |= (1ull << 51); /* Set a reserved bit */ + + tr = kvm_translate2(vcpu, vaddr, 0, 0, pof_page_walk); + TEST_ASSERT_EQ(tr.error_code, KVM_TRANSLATE_FAULT_RESERVED_BITS); + + *pte[PG_LEVEL_2M] &= ~(1ull << 51); + + /* Create a GPA that's definitely not mapped */ + *pte[PG_LEVEL_2M] |= GENMASK(35, 13); + + tr = kvm_translate2(vcpu, vaddr, 0, 0, pof_page_walk); + TEST_ASSERT_EQ(tr.error_code, KVM_TRANSLATE_FAULT_INVALID_GPA); + + *pte[PG_LEVEL_2M] = old_pte; + + /* Clear accessed bits */ + for (int i = PG_LEVEL_4K; i <= PG_LEVEL_512G; i++) + *pte[i] &= ~PTE_ACCESSED_MASK; + + /* Try translating a non-present page */ + *pte[PG_LEVEL_4K] &= ~PTE_PRESENT_MASK; + + tr = kvm_translate2( + vcpu, vaddr, + KVM_TRANSLATE_FLAGS_SET_ACCESSED | + KVM_TRANSLATE_FLAGS_FORCE_SET_ACCESSED, 0, + pof_page_walk); + TEST_ASSERT_EQ(tr.error_code, KVM_TRANSLATE_FAULT_NOT_PRESENT); + CHECK_ACCESSED_BIT(pte, true, PG_LEVEL_2M); + + *pte[PG_LEVEL_4K] |= PTE_PRESENT_MASK; + + /* + * Try setting accessed/dirty bits on a PTE that is in read-only memory + */ + vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS, 0x80000000, 1, 4, + KVM_MEM_READONLY); + + uint64_t *addr = addr_gpa2hva(vm, 0x80000000); + uint64_t *base = addr_gpa2hva(vm, *pte[PG_LEVEL_2M] & GENMASK(51, 12)); + + /* Copy the entire page table */ + for (int i = 0; i < 0x200; i += 1) + addr[i] = (base[i] & ~PTE_ACCESSED_MASK) | PTE_PRESENT_MASK; + + uint64_t old_2m = *pte[PG_LEVEL_2M]; + *pte[PG_LEVEL_2M] &= ~GENMASK(51, 12); + *pte[PG_LEVEL_2M] |= 0x80000000; + + tr = kvm_translate2(vcpu, vaddr, + KVM_TRANSLATE_FLAGS_SET_ACCESSED | + KVM_TRANSLATE_FLAGS_SET_DIRTY | + KVM_TRANSLATE_FLAGS_FORCE_SET_ACCESSED, + KVM_TRANSLATE_ACCESS_WRITE, pof_no_failure); + + TEST_ASSERT(!tr.set_bits_succeeded, "Page not read-only"); + + *pte[PG_LEVEL_2M] = old_2m; + + printf("[ok]\n"); +} + +/* Test page walker stability, by trying to translate with garbage PTEs */ +void test_fuzz(struct kvm_vm *vm, struct kvm_vcpu *vcpu, + uint64_t *pte[PG_LEVEL_NUM], vm_vaddr_t vaddr) +{ + printf("%s ...\t", __func__); + + /* Test gPTEs that point to random addresses */ + for (int level = PG_LEVEL_4K; level < PG_LEVEL_NUM; level++) { + for (int i = 0; i < 10000; i++) { + uint64_t random_address = random() % GENMASK(29, 0) << 12; + *pte[level] = (*pte[level] & ~GENMASK(51, 12)) | random_address; + + kvm_translate2(vcpu, vaddr, + KVM_TRANSLATE_FLAGS_SET_ACCESSED | + KVM_TRANSLATE_FLAGS_SET_DIRTY | + KVM_TRANSLATE_FLAGS_FORCE_SET_ACCESSED, + 0, pof_none); + } + } + + /* Test gPTEs with completely random values */ + for (int level = PG_LEVEL_4K; level < PG_LEVEL_NUM; level++) { + for (int i = 0; i < 10000; i++) { + *pte[level] = random(); + + kvm_translate2(vcpu, vaddr, + KVM_TRANSLATE_FLAGS_SET_ACCESSED | + KVM_TRANSLATE_FLAGS_SET_DIRTY | + KVM_TRANSLATE_FLAGS_FORCE_SET_ACCESSED, + 0, pof_none); + } + } + + printf("[ok]\n"); +} + +int main(int argc, char *argv[]) +{ + uint64_t *pte[PG_LEVEL_NUM]; + struct kvm_vcpu *vcpu; + struct kvm_sregs regs; + struct kvm_vm *vm; + vm_vaddr_t vaddr; + int page_level; + + TEST_REQUIRE(kvm_has_cap(KVM_CAP_TRANSLATE2)); + + vm = vm_create_with_one_vcpu(&vcpu, NULL); + + vaddr = __vm_vaddr_alloc_page(vm, MEM_REGION_TEST_DATA); + + for (page_level = PG_LEVEL_512G; page_level > PG_LEVEL_NONE; + page_level--) { + pte[page_level] = __vm_get_page_table_entry(vm, vaddr, &page_level); + } + + /* Enable WP bit in cr0, so kernel accesses uphold write protection */ + vcpu_ioctl(vcpu, KVM_GET_SREGS, ®s); + regs.cr0 |= 1 << 16; + vcpu_ioctl(vcpu, KVM_SET_SREGS, ®s); + + for (int index = 0; index < 8; index++) + test_translate(vm, vcpu, index, pte, vaddr); + + test_set_bits(vm, vcpu, pte, vaddr); + test_errors(vm, vcpu, pte, vaddr); + test_fuzz(vm, vcpu, pte, vaddr); + + kvm_vm_free(vm); + + return 0; +}