Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp17107959ybl; Wed, 1 Jan 2020 22:11:02 -0800 (PST) X-Google-Smtp-Source: APXvYqxYL6h1soJJQNepxqbf9GdNMWPiyRT74fHBYikP5NFW8wu1zowVo8+2RzwAXspOKz6bi4io X-Received: by 2002:a05:6830:4b9:: with SMTP id l25mr92180578otd.266.1577945462059; Wed, 01 Jan 2020 22:11:02 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1577945462; cv=none; d=google.com; s=arc-20160816; b=IwpQ54NY83jWGDd30aKFDJDPAToMfKOQNX6qzcehsBjS6XgtxW5voDkwW3EBEAURGf Vjw3y/Kx/sJG8S7tlLjznT8UrlrAuVprh/6PUHSF698TcbNY0fq2P2Y+02ohRjDZUq7O re1q3wbCCTwMc3rW/meFS2szMyoIg0scSDvPmqENnHLNKOY/Zb+WV1X5nplw2cxgOj+A Biufjg+FX38NJNfEW1llZxOtovcxU2L5KpGjDfXAbrrHElA4mZeGcWi83u5g1oDPR7/0 KeP63a3HxspdLmOCIFyGu6v7owjei1W3QHVPakH7pGjZEgIXhVSO4flxB/rgV+zSxTm5 uNFA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=8Mr/f9kZz604GmLnNmw8lEGFj/yA7FUE2gh5Mci3noo=; b=PVwp2IeGZ30qS4cffnMhqWEm9fyfkDHa+iHW6Bgh/6wRIIX/cuYR9u4EZPEGdomhNo MDo2UfCCAnvmMu5nSZEh0YCrNnmG3v0rwzqnDzpknXQZzyfagnUK0r0JDTiItHy8vNWX n2s55zlvf3CjHx909O3bPOLJ6EGEOWNo4kihayllgeYf4WCP74Xs5gD1XYdHo5YxiJ5s Xf/7FbZHbXCBMR0jaoiSAPUPwangpt/aNgZCN4DomnhD9XQg8NEcSJ1PjN8j2QTh3Iiq t1UrS3twSwNTpehr07DQDGNFWo/Ru+6e1aoQiGWW4BURMxC7gAKS32kdLU2kyaNsFBge PaoQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 3si1239334oip.263.2020.01.01.22.10.50; Wed, 01 Jan 2020 22:11:02 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727816AbgABGJ4 (ORCPT + 99 others); Thu, 2 Jan 2020 01:09:56 -0500 Received: from mga07.intel.com ([134.134.136.100]:3905 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727722AbgABGJe (ORCPT ); Thu, 2 Jan 2020 01:09:34 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 01 Jan 2020 22:09:34 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,385,1571727600"; d="scan'208";a="224706763" Received: from local-michael-cet-test.sh.intel.com ([10.239.159.128]) by fmsmga001.fm.intel.com with ESMTP; 01 Jan 2020 22:09:32 -0800 From: Yang Weijiang To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, pbonzini@redhat.com, jmattson@google.com, sean.j.christopherson@intel.com Cc: yu.c.zhang@linux.intel.com, alazar@bitdefender.com, edwin.zhai@intel.com, Yang Weijiang Subject: [RESEND PATCH v10 07/10] mmu: spp: Enable Lazy mode SPP protection Date: Thu, 2 Jan 2020 14:13:16 +0800 Message-Id: <20200102061319.10077-8-weijiang.yang@intel.com> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20200102061319.10077-1-weijiang.yang@intel.com> References: <20200102061319.10077-1-weijiang.yang@intel.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org To deal with SPP protected 4KB pages within hugepage(2MB,1GB etc), the hugepage entry is first zapped when set subpage permission, then in tdp_page_fault(), it checks whether the gfn should be mapped to PT_PAGE_TABLE_LEVEL or PT_DIRECTORY_LEVEL level depending on gfn inclusion of SPP protected page range. Suggested-by: Paolo Bonzini Signed-off-by: Yang Weijiang --- arch/x86/kvm/mmu/mmu.c | 20 ++++++++++++++++++++ arch/x86/kvm/mmu/spp.c | 43 ++++++++++++++++++++++++++++++++++++++++++ arch/x86/kvm/mmu/spp.h | 2 ++ 3 files changed, 65 insertions(+) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index c41791ebee65..aada0a3552b2 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -3246,6 +3246,7 @@ static int direct_pte_prefetch_many(struct kvm_vcpu *vcpu, unsigned access = sp->role.access; int i, ret; gfn_t gfn; + u32 *wp_bitmap; gfn = kvm_mmu_page_get_gfn(sp, start - sp->spt); slot = gfn_to_memslot_dirty_bitmap(vcpu, gfn, access & ACC_WRITE_MASK); @@ -3259,6 +3260,13 @@ static int direct_pte_prefetch_many(struct kvm_vcpu *vcpu, for (i = 0; i < ret; i++, gfn++, start++) { mmu_set_spte(vcpu, start, access, 0, sp->role.level, gfn, page_to_pfn(pages[i]), true, true); + if (vcpu->kvm->arch.spp_active) { + wp_bitmap = gfn_to_subpage_wp_info(slot, gfn); + if (wp_bitmap && *wp_bitmap != FULL_SPP_ACCESS) + kvm_spp_mark_protection(vcpu->kvm, + gfn, + *wp_bitmap); + } put_page(pages[i]); } @@ -3372,6 +3380,15 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t gpa, int write, map_writable); direct_pte_prefetch(vcpu, it.sptep); ++vcpu->stat.pf_fixed; + if (level == PT_PAGE_TABLE_LEVEL) { + int ret; + u32 access; + + ret = kvm_spp_get_permission(vcpu->kvm, gfn, 1, &access); + if (ret == 1 && access != FULL_SPP_ACCESS) + kvm_spp_mark_protection(vcpu->kvm, gfn, access); + } + return ret; } @@ -4338,6 +4355,9 @@ static int tdp_page_fault(struct kvm_vcpu *vcpu, gva_t gpa, u32 error_code, if (level > PT_DIRECTORY_LEVEL && !check_hugepage_cache_consistency(vcpu, gfn, level)) level = PT_DIRECTORY_LEVEL; + + check_spp_protection(vcpu, gfn, &force_pt_level, &level); + gfn &= ~(KVM_PAGES_PER_HPAGE(level) - 1); } diff --git a/arch/x86/kvm/mmu/spp.c b/arch/x86/kvm/mmu/spp.c index 3ec434140967..f63541b42385 100644 --- a/arch/x86/kvm/mmu/spp.c +++ b/arch/x86/kvm/mmu/spp.c @@ -571,6 +571,49 @@ inline u64 construct_spptp(unsigned long root_hpa) } EXPORT_SYMBOL_GPL(construct_spptp); +static bool is_spp_protected(struct kvm_memory_slot *slot, gfn_t gfn, int level) +{ + int page_num = KVM_PAGES_PER_HPAGE(level); + u32 *access; + gfn_t gfn_max; + + gfn &= ~(page_num - 1); + gfn_max = gfn + page_num - 1; + for (; gfn <= gfn_max; gfn++) { + access = gfn_to_subpage_wp_info(slot, gfn); + if (access && *access != FULL_SPP_ACCESS) + return true; + } + return false; +} + +bool check_spp_protection(struct kvm_vcpu *vcpu, gfn_t gfn, + bool *force_pt_level, int *level) +{ + struct kvm *kvm = vcpu->kvm; + struct kvm_memory_slot *slot; + bool protected; + int old_level = *level; + + if (!kvm->arch.spp_active) + return false; + + slot = gfn_to_memslot(kvm, gfn); + + if (!slot) + return false; + protected = is_spp_protected(slot, gfn, PT_DIRECTORY_LEVEL); + + if (protected) { + *level = PT_PAGE_TABLE_LEVEL; + *force_pt_level = true; + } else if (*level == PT_PDPE_LEVEL && + is_spp_protected(slot, gfn, PT_PDPE_LEVEL)) + *level = PT_DIRECTORY_LEVEL; + + return (old_level != *level); +} + int kvm_vm_ioctl_get_subpages(struct kvm *kvm, u64 gfn, u32 npages, diff --git a/arch/x86/kvm/mmu/spp.h b/arch/x86/kvm/mmu/spp.h index 5ffe06d2cd6f..0baf0f9ac135 100644 --- a/arch/x86/kvm/mmu/spp.h +++ b/arch/x86/kvm/mmu/spp.h @@ -13,6 +13,8 @@ int kvm_spp_mark_protection(struct kvm *kvm, u64 gfn, u32 access); bool is_spp_spte(struct kvm_mmu_page *sp); void restore_spp_bit(u64 *spte); bool was_spp_armed(u64 spte); +bool check_spp_protection(struct kvm_vcpu *vcpu, gfn_t gfn, + bool *force_pt_level, int *level); u64 construct_spptp(unsigned long root_hpa); int kvm_vm_ioctl_get_subpages(struct kvm *kvm, u64 gfn, -- 2.17.2