Received: by 2002:a05:7412:5112:b0:fa:6e18:a558 with SMTP id fm18csp190946rdb; Mon, 22 Jan 2024 17:06:35 -0800 (PST) X-Google-Smtp-Source: AGHT+IG3MgjtyC0bzCDq2+oEKq8QZPs1feFceCLw2D3NpkplEhi7gHUSNmPBWmZAgQ6MVF/f/qg+ X-Received: by 2002:a05:620a:560f:b0:783:4613:2bec with SMTP id vu15-20020a05620a560f00b0078346132becmr6928931qkn.101.1705971994776; Mon, 22 Jan 2024 17:06:34 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1705971994; cv=pass; d=google.com; s=arc-20160816; b=x2hpQFkxg+SUIoZGFow1XMKE74MTn66CyqnSUqt3gxG5rfnKQvui6bNfRRJpwoCKmR 5eAxzVrQJbSZ/qCWiwjvuBfCRD24p3OJbOQdr3687o/+prb2CU2cFvpVHa1JfdAGlSUr vVyhst/K+2in7AOMBgwiAzvagDU21Vtf+FkdIoMgqIh3RiOdgfjAiTGgxg+66sEAnktm 8h9DtJD4D/OpBAg+Cf726vgxpUzSnlkS6LRVyzlp3yBdw4aHRf2dkB8rSXqjhywCLdK5 OD9WzaG9BgKfva9CSUWdryUvr54cyA4/HeTFYrBvYaWg5K/8tdqA71ROemZiYqHnYVgm jYQg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=R3ccLsSrD/coUXen2o4abDchyQnK3m0aTsMzyovhWEM=; fh=Itbyk7CEvizIrzGEESCqq3I2tZgG1kc/GkVOa3S7Hsg=; b=DxD/Ez9aLmK90grZkvwu83haSqoZmJoV5oji/eh1A03/RYFTpWGNh7pyRwC6pV8t+w gx5aoH7eMRsFdt0ZLwwyJWlZkGFoY/p4+SzDtwVexuwsNOq/r6kp9n/geOZXLg8t395O yK5TnzybBDJIV3r9flLtL0UgrKzp8UtbomavSeR6cqWAHddwUO4UrLL+YU1Hpw6A/7xX AIx6E5qfjc1HFGSQrSYY8e5Im4Kh/IKHTI0bW+w1UP761m69zlM1jVM9CqMViSQbjCxU id6q4XqUQdir9X2WxseZRbb9AgMCQecgnPPv6qfc/WTpIosb8tq7R1HVREcQdQK6rY72 j1lA== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b="SL/GUP1G"; arc=pass (i=1 spf=pass spfdomain=intel.com dkim=pass dkdomain=intel.com dmarc=pass fromdomain=intel.com); spf=pass (google.com: domain of linux-kernel+bounces-34460-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-34460-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id v15-20020a05620a0a8f00b0078337e502f8si6821778qkg.688.2024.01.22.17.06.34 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Jan 2024 17:06:34 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-34460-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b="SL/GUP1G"; arc=pass (i=1 spf=pass spfdomain=intel.com dkim=pass dkdomain=intel.com dmarc=pass fromdomain=intel.com); spf=pass (google.com: domain of linux-kernel+bounces-34460-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-34460-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 7A3051C26130 for ; Tue, 23 Jan 2024 01:06:34 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id C7677153500; Tue, 23 Jan 2024 00:22:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="SL/GUP1G" Received: from mgamail.intel.com (mgamail.intel.com [134.134.136.65]) (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 E05D6151CC1; Tue, 23 Jan 2024 00:22:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=134.134.136.65 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1705969368; cv=none; b=NuPPFlW66iz3GnhbPS1No8PPOdKErALsLNrUyrvFlbYhLXyO96xCrPV7m3ZC/75+rGa2yz1kCuunOqphSer+GB0nnnxlMkapVXasK0yGRXaqN7a6lvQH+q1ejnnC06qrSnLftZMFDvKKB14LhecA05SAXB2wxFRwJ3ncn3KRgZU= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1705969368; c=relaxed/simple; bh=UuGG+E/cBBOlFOuGRHBHh8cTWAmu4YzcsHsZq3wM5To=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=P6xNJ9aQ3b+X2/PzRF9YPEILIvEF+CmJcYUkVu9XtTtxK72btusYb4JhONfSpqDS+0dnwZeGsoGiHyD+iALcn30XjkL2lmlLGAwgICwiwjM7eaoTv0bUPcS0BFYhxKZfMlW65eg+t40nLon0WmNFqRlc9ZShzrHTOOfCeLO1P3Q= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=SL/GUP1G; arc=none smtp.client-ip=134.134.136.65 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1705969366; x=1737505366; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=UuGG+E/cBBOlFOuGRHBHh8cTWAmu4YzcsHsZq3wM5To=; b=SL/GUP1GSV7XaATdgiHxZfWn8tqh9uhVcLWXG3gk2iDsIwzf+FVMsi5k DJzCYMwto4YW4kUN2CmvN7MHDVYTNGB/pxZ/9HvRGHezskZGNBbg11cWv wd+wW09JWyGSRyOIoS7km0K5lBgZSCUWGUE352pUBgSxwWodE4t5KlwVp LdDwWfVQOwO7lADbh383EmRjPqm6fltlLmuansJGzL54rtsSGaVzWcYtO A+mPA1MWtMvQ9SSz1WrdgfS4sV2uOOFzdhWLbmIwEkZSwTSYd+qrWtF+C O//ey1PDB4kO5RKPcwc2L6/EAToUPiK1tcBSsyB5GOGAFIUGEMPgJZXoS g==; X-IronPort-AV: E=McAfee;i="6600,9927,10961"; a="405125703" X-IronPort-AV: E=Sophos;i="6.05,212,1701158400"; d="scan'208";a="405125703" Received: from fmviesa001.fm.intel.com ([10.60.135.141]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Jan 2024 16:22:41 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.05,212,1701158400"; d="scan'208";a="27825668" Received: from ls.sc.intel.com (HELO localhost) ([172.25.112.31]) by smtpauth.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Jan 2024 16:22:41 -0800 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 , Kai Huang , chen.bo@intel.com, hang.yuan@intel.com, tina.zhang@intel.com Subject: [PATCH v7 12/13] KVM: x86/mmu: Make kvm fault handler aware of large page of private memslot Date: Mon, 22 Jan 2024 16:22:27 -0800 Message-Id: <9b2b24606fc5c80402c8565e2213dec3b6a20cc7.1705965958.git.isaku.yamahata@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Isaku Yamahata struct kvm_page_fault.req_level is the page level which takes care of the faulted-in page size. For now its calculation is only for the conventional kvm memslot by host_pfn_mapping_level() that traverses page table. However, host_pfn_mapping_level() cannot be used for private kvm memslot because private pages of private kvm memlost aren't mapped into user virtual address space. Instead, page order is given when getting pfn. Remember it in struct kvm_page_fault and use it. Signed-off-by: Isaku Yamahata --- arch/x86/kvm/mmu/mmu.c | 34 +++++++++++++++++---------------- arch/x86/kvm/mmu/mmu_internal.h | 12 +++++++++++- arch/x86/kvm/mmu/tdp_mmu.c | 2 +- 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index a9e7a3d2d362..c7c816c969a9 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -3154,10 +3154,10 @@ static int host_pfn_mapping_level(struct kvm *kvm, gfn_t gfn, static int __kvm_mmu_max_mapping_level(struct kvm *kvm, const struct kvm_memory_slot *slot, - gfn_t gfn, int max_level, bool is_private) + gfn_t gfn, int max_level, int host_level, + bool is_private) { struct kvm_lpage_info *linfo; - int host_level; max_level = min(max_level, max_huge_page_level); for ( ; max_level > PG_LEVEL_4K; max_level--) { @@ -3166,24 +3166,23 @@ static int __kvm_mmu_max_mapping_level(struct kvm *kvm, break; } - if (is_private) - return max_level; - if (max_level == PG_LEVEL_4K) return PG_LEVEL_4K; - host_level = host_pfn_mapping_level(kvm, gfn, slot); + if (!is_private) { + WARN_ON_ONCE(host_level != PG_LEVEL_NONE); + host_level = host_pfn_mapping_level(kvm, gfn, slot); + } + WARN_ON_ONCE(host_level == PG_LEVEL_NONE); return min(host_level, max_level); } int kvm_mmu_max_mapping_level(struct kvm *kvm, const struct kvm_memory_slot *slot, gfn_t gfn, - int max_level) + int max_level, bool faultin_private) { - bool is_private = kvm_slot_can_be_private(slot) && - kvm_mem_is_private(kvm, gfn); - - return __kvm_mmu_max_mapping_level(kvm, slot, gfn, max_level, is_private); + return __kvm_mmu_max_mapping_level(kvm, slot, gfn, max_level, + PG_LEVEL_NONE, faultin_private); } void kvm_mmu_hugepage_adjust(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault) @@ -3208,7 +3207,8 @@ void kvm_mmu_hugepage_adjust(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault */ fault->req_level = __kvm_mmu_max_mapping_level(vcpu->kvm, slot, fault->gfn, fault->max_level, - fault->is_private); + fault->host_level, + kvm_is_faultin_private(fault)); if (fault->req_level == PG_LEVEL_4K || fault->huge_page_disallowed) return; @@ -4332,6 +4332,7 @@ static int kvm_faultin_pfn_private(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault) { int max_order, r; + u8 max_level; if (!kvm_slot_can_be_private(fault->slot)) { kvm_mmu_prepare_memory_fault_exit(vcpu, fault); @@ -4345,8 +4346,9 @@ static int kvm_faultin_pfn_private(struct kvm_vcpu *vcpu, return r; } - fault->max_level = min(kvm_max_level_for_order(max_order), - fault->max_level); + max_level = kvm_max_level_for_order(max_order); + fault->host_level = max_level; + fault->max_level = min(max_level, fault->max_level); fault->map_writable = !(fault->slot->flags & KVM_MEM_READONLY); return RET_PF_CONTINUE; @@ -4396,7 +4398,7 @@ static int __kvm_faultin_pfn(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault return -EFAULT; } - if (fault->is_private) + if (kvm_is_faultin_private(fault)) return kvm_faultin_pfn_private(vcpu, fault); async = false; @@ -6805,7 +6807,7 @@ static bool kvm_mmu_zap_collapsible_spte(struct kvm *kvm, */ if (sp->role.direct && sp->role.level < kvm_mmu_max_mapping_level(kvm, slot, sp->gfn, - PG_LEVEL_NUM)) { + PG_LEVEL_NUM, false)) { kvm_zap_one_rmap_spte(kvm, rmap_head, sptep); if (kvm_available_flush_remote_tlbs_range()) diff --git a/arch/x86/kvm/mmu/mmu_internal.h b/arch/x86/kvm/mmu/mmu_internal.h index cc0a95e554b5..1e6bf3875779 100644 --- a/arch/x86/kvm/mmu/mmu_internal.h +++ b/arch/x86/kvm/mmu/mmu_internal.h @@ -358,6 +358,9 @@ struct kvm_page_fault { * is changing its own translation in the guest page tables. */ bool write_fault_to_shadow_pgtable; + + /* valid only for private memslot && private gfn */ + enum pg_level host_level; }; int kvm_tdp_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault); @@ -452,7 +455,7 @@ static inline int kvm_mmu_do_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, int kvm_mmu_max_mapping_level(struct kvm *kvm, const struct kvm_memory_slot *slot, gfn_t gfn, - int max_level); + int max_level, bool faultin_private); void kvm_mmu_hugepage_adjust(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault); void disallowed_hugepage_adjust(struct kvm_page_fault *fault, u64 spte, int cur_level); @@ -470,4 +473,11 @@ static inline bool kvm_hugepage_test_mixed(struct kvm_memory_slot *slot, gfn_t g } #endif +static inline bool kvm_is_faultin_private(const struct kvm_page_fault *fault) +{ + if (IS_ENABLED(CONFIG_KVM_GENERIC_PRIVATE_MEM)) + return fault->is_private && kvm_slot_can_be_private(fault->slot); + return false; +} + #endif /* __KVM_X86_MMU_INTERNAL_H */ diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c index bd9ec77e7933..42c8cf1abdf8 100644 --- a/arch/x86/kvm/mmu/tdp_mmu.c +++ b/arch/x86/kvm/mmu/tdp_mmu.c @@ -2183,7 +2183,7 @@ static void zap_collapsible_spte_range(struct kvm *kvm, continue; max_mapping_level = kvm_mmu_max_mapping_level(kvm, slot, - iter.gfn, PG_LEVEL_NUM); + iter.gfn, PG_LEVEL_NUM, false); if (max_mapping_level < iter.level) continue; -- 2.25.1