Received: by 2002:a05:6358:e9c4:b0:b2:91dc:71ab with SMTP id hc4csp4124098rwb; Sun, 7 Aug 2022 15:45:05 -0700 (PDT) X-Google-Smtp-Source: AA6agR71/bo18THqOcrwtHAnf9Qw9QJsyffbTR+/pEsCQXAB33mtYCiT4cMe8QB1nsEJrWdkn8Kz X-Received: by 2002:a17:90a:714b:b0:1f2:21e9:b089 with SMTP id g11-20020a17090a714b00b001f221e9b089mr26808735pjs.241.1659912304907; Sun, 07 Aug 2022 15:45:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1659912304; cv=none; d=google.com; s=arc-20160816; b=AnLN/0PRapFyXQb1+NzdiAtpQ4t6seqyBXBWon3/1bVtqSWEcRXVMA64UvDnc7pKij ttRH8YfKIWpkF9SqyPbQk7AhOdWJW/JvrWPG/a2/no09wGrUFI07QEvQ6DY14nEYQCnL y9Fp1fQDv64jJ1ZNioYyj61gTlzo+QJeBStX0rmuns922/nUHZaugVjBVhWQU+ZaWinO N+Fa89hsl3bliM3O7jtI/QB7ukRn48ptK+q2RVN58qoexrsgp9EmCkNEkm5rIoLzPAbQ G+A27CoB5dlWsIf4xfsIpXbkrTWRWM21iuuSw6TRIF7WYGnAVmlEWQ1YaHkwTDi7oSXK j2HA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=b7AQl1ni5KVX3L1xp7uf5sJUyBb5z6pLJgmt2/8FX7g=; b=dmr1p6+V0GFhClX8t6GCLZpKNo9og41r713ZlgxMUEI/b92yZNX+c62IKHHIEGhL14 UfNeO1jpd5ROCh+lArDOovJPEt3tkUMj6NO9rfyarno9vxXBqJ02XY1P2vOsOFTdpaby KZYomyR32vFycFnD9LZtOVEvTbuvJyrN0Gy89SBPuEn8EJIGxb5+CUxr6AxWwOPhG7ab 2DtKF/W1LWhAC07uzrP21VXYI4t636+QRk8livldMRkP+FYUUJl93VWCUwBk8/RU66wH rvaXml5FXjdHTDbC2Sg/PxlkkRhD/VDq2UW6/suZeWlj5q5Fpn4iwnXu/v4ZMkYqjCCR /S9Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=HytzFknp; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id h15-20020a63210f000000b0041c4d61263esi8892344pgh.137.2022.08.07.15.44.51; Sun, 07 Aug 2022 15:45:04 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=HytzFknp; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241877AbiHGWch (ORCPT + 99 others); Sun, 7 Aug 2022 18:32:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35142 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241766AbiHGWbk (ORCPT ); Sun, 7 Aug 2022 18:31:40 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2EDB318367; Sun, 7 Aug 2022 15:18:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1659910732; x=1691446732; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=/ak/GZpX2iOgkbhao08i+WoO/ngVEvNdqD8iJNRSVFE=; b=HytzFknpEKyoZrbuNAPsf5t2cGLKoI+LeavGR16Y4Qys4Gf6vanf7tM8 W38qmlmm41InkVEXMFX1y5w0QtnJDvkKjjEopRBxVy0CmavRqcABaJ/Bp EuA8Assu5L76LHNlNO8cWp4WbG5tw7EAmE92tdtWOE4QDcDKAgcBJIciX pbfZPNlMjVUCUO6GfZzA9h42ajHlUU7mb2donQhDVgELVSSmPWlCDfKnp uFOVd9YaO8gn5ErUXQTco18Q1UrrpMb4uMC0t75BeEPA2fVKHWuLYhF11 +RStuks6N2lSrjN+xAZRBeiQpoLqxqwx6JUI4COYYt3SCC6hTBJeWt7v6 Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10432"; a="270852840" X-IronPort-AV: E=Sophos;i="5.93,221,1654585200"; d="scan'208";a="270852840" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Aug 2022 15:18:51 -0700 X-IronPort-AV: E=Sophos;i="5.93,221,1654585200"; d="scan'208";a="632642335" Received: from ls.sc.intel.com (HELO localhost) ([143.183.96.54]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Aug 2022 15:18:51 -0700 From: isaku.yamahata@intel.com To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org Cc: isaku.yamahata@intel.com, isaku.yamahata@gmail.com, Paolo Bonzini , erdemaktas@google.com, Sean Christopherson , Sagi Shahar Subject: [RFC PATCH 10/13] KVM: MMU: Pass desired page level in err code for page fault handler Date: Sun, 7 Aug 2022 15:18:43 -0700 Message-Id: <6bddb15cc5913c27330faead819d68b69c84d0a0.1659854957.git.isaku.yamahata@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-5.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Xiaoyao Li For TDX, EPT violation can happen when TDG.MEM.PAGE.ACCEPT. And TDG.MEM.PAGE.ACCEPT contains the desired accept page level of TD guest. 1. KVM can map it with 4KB page while TD guest wants to accept 2MB page. TD geust will get TDX_PAGE_SIZE_MISMATCH and it should try to accept 4KB size. 2. KVM can map it with 2MB page while TD guest wants to accept 4KB page. KVM needs to honor it because a) there is no way to tell guest KVM maps it as 2MB size. And b) guest accepts it in 4KB size since guest knows some other 4KB page in the same 2MB range will be used as shared page. For case 2, it need to pass desired page level to MMU's page_fault_handler. Use bit 29:31 of kvm PF error code for this purpose. Signed-off-by: Xiaoyao Li --- arch/x86/include/asm/kvm_host.h | 2 ++ arch/x86/kvm/vmx/common.h | 2 +- arch/x86/kvm/vmx/tdx.c | 9 +++++++-- arch/x86/kvm/vmx/tdx.h | 19 ------------------- arch/x86/kvm/vmx/tdx_arch.h | 19 +++++++++++++++++++ arch/x86/kvm/vmx/vmx.c | 2 +- 6 files changed, 30 insertions(+), 23 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index c01bde832de2..a6bfcabcbbd7 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -273,6 +273,8 @@ enum x86_intercept_stage; PFERR_WRITE_MASK | \ PFERR_PRESENT_MASK) +#define PFERR_LEVEL(err_code) (((err_code) & PFERR_LEVEL_MASK) >> PFERR_LEVEL_START_BIT) + /* apic attention bits */ #define KVM_APIC_CHECK_VAPIC 0 /* diff --git a/arch/x86/kvm/vmx/common.h b/arch/x86/kvm/vmx/common.h index f512eaa458a2..0835ea975250 100644 --- a/arch/x86/kvm/vmx/common.h +++ b/arch/x86/kvm/vmx/common.h @@ -99,7 +99,7 @@ static inline int __vmx_handle_ept_violation(struct kvm_vcpu *vcpu, gpa_t gpa, error_code |= (exit_qualification & EPT_VIOLATION_GVA_TRANSLATED) != 0 ? PFERR_GUEST_FINAL_MASK : PFERR_GUEST_PAGE_MASK; - if (err_page_level > 0) + if (err_page_level > PG_LEVEL_NONE) error_code |= (err_page_level << PFERR_LEVEL_START_BIT) & PFERR_LEVEL_MASK; return kvm_mmu_page_fault(vcpu, gpa, error_code, NULL, 0); diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c index 2fdf3aa70c57..e4e193b1a758 100644 --- a/arch/x86/kvm/vmx/tdx.c +++ b/arch/x86/kvm/vmx/tdx.c @@ -1803,7 +1803,7 @@ static int tdx_handle_ept_violation(struct kvm_vcpu *vcpu) #define TDX_SEPT_VIOLATION_EXIT_QUAL EPT_VIOLATION_ACC_WRITE exit_qual = TDX_SEPT_VIOLATION_EXIT_QUAL; } else { - exit_qual = tdexit_exit_qual(vcpu);; + exit_qual = tdexit_exit_qual(vcpu); if (exit_qual & EPT_VIOLATION_ACC_INSTR) { pr_warn("kvm: TDX instr fetch to shared GPA = 0x%lx @ RIP = 0x%lx\n", tdexit_gpa(vcpu), kvm_rip_read(vcpu)); @@ -2303,6 +2303,7 @@ static int tdx_init_mem_region(struct kvm *kvm, struct kvm_tdx_cmd *cmd) struct kvm_tdx_init_mem_region region; struct kvm_vcpu *vcpu; struct page *page; + u64 error_code; kvm_pfn_t pfn; int idx, ret = 0; @@ -2356,7 +2357,11 @@ static int tdx_init_mem_region(struct kvm *kvm, struct kvm_tdx_cmd *cmd) kvm_tdx->source_pa = pfn_to_hpa(page_to_pfn(page)) | (cmd->flags & KVM_TDX_MEASURE_MEMORY_REGION); - pfn = kvm_mmu_map_tdp_page(vcpu, region.gpa, TDX_SEPT_PFERR, + /* TODO: large page support. */ + error_code = TDX_SEPT_PFERR; + error_code |= (PG_LEVEL_4K << PFERR_LEVEL_START_BIT) & + PFERR_LEVEL_MASK; + pfn = kvm_mmu_map_tdp_page(vcpu, region.gpa, error_code, PG_LEVEL_4K); if (is_error_noslot_pfn(pfn) || kvm->vm_bugged) ret = -EFAULT; diff --git a/arch/x86/kvm/vmx/tdx.h b/arch/x86/kvm/vmx/tdx.h index 3400563a2254..8284cce0d385 100644 --- a/arch/x86/kvm/vmx/tdx.h +++ b/arch/x86/kvm/vmx/tdx.h @@ -79,25 +79,6 @@ union tdx_exit_reason { u64 full; }; -union tdx_ext_exit_qualification { - struct { - u64 type : 4; - u64 reserved0 : 28; - u64 req_sept_level : 3; - u64 err_sept_level : 3; - u64 err_sept_state : 8; - u64 err_sept_is_leaf : 1; - u64 reserved1 : 17; - }; - u64 full; -}; - -enum tdx_ext_exit_qualification_type { - EXT_EXIT_QUAL_NONE, - EXT_EXIT_QUAL_ACCEPT, - NUM_EXT_EXIT_QUAL, -}; - struct vcpu_tdx { struct kvm_vcpu vcpu; diff --git a/arch/x86/kvm/vmx/tdx_arch.h b/arch/x86/kvm/vmx/tdx_arch.h index 94258056d742..fbf334bc18c9 100644 --- a/arch/x86/kvm/vmx/tdx_arch.h +++ b/arch/x86/kvm/vmx/tdx_arch.h @@ -154,4 +154,23 @@ struct td_params { #define TDX_MIN_TSC_FREQUENCY_KHZ (100 * 1000) #define TDX_MAX_TSC_FREQUENCY_KHZ (10 * 1000 * 1000) +union tdx_ext_exit_qualification { + struct { + u64 type : 4; + u64 reserved0 : 28; + u64 req_sept_level : 3; + u64 err_sept_level : 3; + u64 err_sept_state : 8; + u64 err_sept_is_leaf : 1; + u64 reserved1 : 17; + }; + u64 full; +}; + +enum tdx_ext_exit_qualification_type { + EXT_EXIT_QUAL_NONE = 0, + EXT_EXIT_QUAL_ACCEPT, + NUM_EXT_EXIT_QUAL, +}; + #endif /* __KVM_X86_TDX_ARCH_H */ diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 6ba3eded55a7..bb493ce80fa9 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -5646,7 +5646,7 @@ static int handle_ept_violation(struct kvm_vcpu *vcpu) if (unlikely(allow_smaller_maxphyaddr && kvm_vcpu_is_illegal_gpa(vcpu, gpa))) return kvm_emulate_instruction(vcpu, 0); - return __vmx_handle_ept_violation(vcpu, gpa, exit_qualification, 0); + return __vmx_handle_ept_violation(vcpu, gpa, exit_qualification, PG_LEVEL_NONE); } static int handle_ept_misconfig(struct kvm_vcpu *vcpu) -- 2.25.1