mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Yan Zhao <yan.y.zhao@intel.com>
To: Sean Christopherson <seanjc@google.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
	Zhenyu Wang <zhenyuw@linux.intel.com>,
	Zhi Wang <zhi.a.wang@intel.com>, <kvm@vger.kernel.org>,
	<intel-gvt-dev@lists.freedesktop.org>,
	<intel-gfx@lists.freedesktop.org>, <linux-kernel@vger.kernel.org>,
	Ben Gardon <bgardon@google.com>
Subject: Re: [PATCH v2 04/27] drm/i915/gvt: Incorporate KVM memslot info into check for 2MiB GTT entry
Date: Tue, 14 Mar 2023 11:09:20 +0800	[thread overview]
Message-ID: <ZA/lYL7dsv7xBA01@yzhao56-desk.sh.intel.com> (raw)
In-Reply-To: <20230311002258.852397-5-seanjc@google.com>

On Fri, Mar 10, 2023 at 04:22:35PM -0800, Sean Christopherson wrote:
> Honor KVM's max allowed page size when determining whether or not a 2MiB
> GTT shadow page can be created for the guest.  Querying KVM's max allowed
> size is somewhat odd as there's no strict requirement that KVM's memslots
> and VFIO's mappings are configured with the same gfn=>hva mapping, but
> the check will be accurate if userspace wants to have a functional guest,
> and at the very least checking KVM's memslots guarantees that the entire
> 2MiB range has been exposed to the guest.
>
hi Sean,
I remember in our last discussion, the conclusion was that
we can safely just use VFIO ABI (which is intel_gvt_dma_map_guest_page()
introduced in patch 7) to check max mapping size. [1][2]

"Though checking kvm_page_track_max_mapping_level() is also fine, it makes DMA
mapping size unnecessarily smaller."
This is especially true when the guest page is page tracked by kvm internally
for nested VMs, but is not page tracked by kvmgt as ppgtt page table pages.
kvmgt is ok to map those pages as huge when 4k is returned in
kvm_page_track_max_mapping_level() for this reason. 


"I'm totally fine if KVMGT's ABI is that VFIO is the source of truth for mappings
and permissions, and that the only requirement for KVM memslots is that GTT page
tables need to be visible in KVM's memslots.  But if that's the ABI, then
intel_gvt_is_valid_gfn() should be probing VFIO, not KVM (commit cc753fbe1ac4
("drm/i915/gvt: validate gfn before set shadow page entry").

In other words, pick either VFIO or KVM.  Checking that X is valid according to
KVM and then mapping X through VFIO is confusing and makes assumptions about how
userspace configures KVM and VFIO.  It works because QEMU always configures KVM
and VFIO as expected, but IMO it's unnecessarily fragile and again confusing for
unaware readers because the code is technically flawed.
"

[1] https://lore.kernel.org/all/Y7Y+759IN2DH5h3h@yzhao56-desk.sh.intel.com/
[2] https://lore.kernel.org/all/Y7cLkLUMCy+XLRwm@google.com/

> Note, KVM may also restrict the mapping size for reasons that aren't
> relevant to KVMGT, e.g. for KVM's iTLB multi-hit workaround or if the gfn
> is write-tracked (KVM's write-tracking only handles writes from vCPUs).
> However, such scenarios are unlikely to occur with a well-behaved guest,
> and at worst will result in sub-optimal performance.

As being confirmed in [3], there's no risk of iTLB multi-hit even for
not-well-behaved guests if page tables for DMA mappings in IOMMU page tables
are in a separated set of tables from EPT/NPT (which is the by default
condition currently).

[3] https://lore.kernel.org/all/Y7%2FFZpizEyIaL+Su@yzhao56-desk.sh.intel.com/

So, I'm fine with exporting this kvm_page_track_max_mapping_level()
interface, but I don't think KVMGT is a user of it. 
> 
> Fixes: b901b252b6cf ("drm/i915/gvt: Add 2M huge gtt support")
> Signed-off-by: Yan Zhao <yan.y.zhao@intel.com>
> Signed-off-by: Sean Christopherson <seanjc@google.com>
> ---
>  arch/x86/include/asm/kvm_page_track.h |  2 ++
>  arch/x86/kvm/mmu/page_track.c         | 18 ++++++++++++++++++
>  drivers/gpu/drm/i915/gvt/gtt.c        | 10 +++++++++-
>  3 files changed, 29 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/x86/include/asm/kvm_page_track.h b/arch/x86/include/asm/kvm_page_track.h
> index eb186bc57f6a..3f72c7a172fc 100644
> --- a/arch/x86/include/asm/kvm_page_track.h
> +++ b/arch/x86/include/asm/kvm_page_track.h
> @@ -51,6 +51,8 @@ void kvm_page_track_cleanup(struct kvm *kvm);
>  
>  bool kvm_page_track_write_tracking_enabled(struct kvm *kvm);
>  int kvm_page_track_write_tracking_alloc(struct kvm_memory_slot *slot);
> +enum pg_level kvm_page_track_max_mapping_level(struct kvm *kvm, gfn_t gfn,
> +					       enum pg_level max_level);
>  
>  void kvm_page_track_free_memslot(struct kvm_memory_slot *slot);
>  int kvm_page_track_create_memslot(struct kvm *kvm,
> diff --git a/arch/x86/kvm/mmu/page_track.c b/arch/x86/kvm/mmu/page_track.c
> index 0a2ac438d647..e739dcc3375c 100644
> --- a/arch/x86/kvm/mmu/page_track.c
> +++ b/arch/x86/kvm/mmu/page_track.c
> @@ -301,3 +301,21 @@ void kvm_page_track_flush_slot(struct kvm *kvm, struct kvm_memory_slot *slot)
>  			n->track_flush_slot(kvm, slot, n);
>  	srcu_read_unlock(&head->track_srcu, idx);
>  }
> +
> +enum pg_level kvm_page_track_max_mapping_level(struct kvm *kvm, gfn_t gfn,
> +					       enum pg_level max_level)
> +{
> +	struct kvm_memory_slot *slot;
> +	int idx;
> +
> +	idx = srcu_read_lock(&kvm->srcu);
> +	slot = gfn_to_memslot(kvm, gfn);
> +	if (!slot || slot->flags & KVM_MEMSLOT_INVALID)
> +		max_level = PG_LEVEL_4K;
> +	else
> +		max_level = kvm_mmu_max_slot_mapping_level(slot, gfn, max_level);
> +	srcu_read_unlock(&kvm->srcu, idx);
> +
> +	return max_level;
> +}
> +EXPORT_SYMBOL_GPL(kvm_page_track_max_mapping_level);
> diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c
> index f30922c55a0c..d59c7ab9d224 100644
> --- a/drivers/gpu/drm/i915/gvt/gtt.c
> +++ b/drivers/gpu/drm/i915/gvt/gtt.c
> @@ -1157,14 +1157,22 @@ static int is_2MB_gtt_possible(struct intel_vgpu *vgpu,
>  	struct intel_gvt_gtt_entry *entry)
>  {
>  	const struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops;
> +	unsigned long gfn = ops->get_pfn(entry);
>  	kvm_pfn_t pfn;
> +	int max_level;
>  
>  	if (!HAS_PAGE_SIZES(vgpu->gvt->gt->i915, I915_GTT_PAGE_SIZE_2M))
>  		return 0;
>  
>  	if (!test_bit(INTEL_VGPU_STATUS_ATTACHED, vgpu->status))
>  		return -EINVAL;
> -	pfn = gfn_to_pfn(vgpu->vfio_device.kvm, ops->get_pfn(entry));
> +
> +	max_level = kvm_page_track_max_mapping_level(vgpu->vfio_device.kvm,
> +						     gfn, PG_LEVEL_2M);
> +	if (max_level < PG_LEVEL_2M)
> +		return 0;
> +
> +	pfn = gfn_to_pfn(vgpu->vfio_device.kvm, gfn);
>  	if (is_error_noslot_pfn(pfn))
>  		return -EINVAL;
>  
> -- 
> 2.40.0.rc1.284.g88254d51c5-goog
> 

  reply	other threads:[~2023-03-14  3:34 UTC|newest]

Thread overview: 79+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-11  0:22 [PATCH v2 00/27] drm/i915/gvt: KVM: KVMGT fixes and page-track cleanups Sean Christopherson
2023-03-11  0:22 ` [PATCH v2 01/27] drm/i915/gvt: Verify pfn is "valid" before dereferencing "struct page" Sean Christopherson
2023-03-13 15:37   ` Wang, Wei W
2023-03-15 18:13     ` [Intel-gfx] " Andrzej Hajda
2023-03-15 19:23       ` Sean Christopherson
2023-03-17  4:20   ` Yan Zhao
2023-03-11  0:22 ` [PATCH v2 02/27] KVM: x86/mmu: Factor out helper to get max mapping size of a memslot Sean Christopherson
2023-03-13 15:37   ` Wang, Wei W
2023-03-11  0:22 ` [PATCH v2 03/27] drm/i915/gvt: remove interface intel_gvt_is_valid_gfn Sean Christopherson
2023-03-17  4:26   ` Yan Zhao
2023-03-11  0:22 ` [PATCH v2 04/27] drm/i915/gvt: Incorporate KVM memslot info into check for 2MiB GTT entry Sean Christopherson
2023-03-14  3:09   ` Yan Zhao [this message]
2023-03-14 17:13     ` Sean Christopherson
2023-03-11  0:22 ` [PATCH v2 05/27] drm/i915/gvt: Verify VFIO-pinned page is THP when shadowing 2M gtt entry Sean Christopherson
2023-03-17  5:33   ` Yan Zhao
2023-05-04 20:41     ` Sean Christopherson
2023-05-06  6:35       ` Yan Zhao
2023-05-06 10:57         ` Yan Zhao
2023-05-08 14:05           ` Sean Christopherson
2023-03-11  0:22 ` [PATCH v2 06/27] drm/i915/gvt: Put the page reference obtained by KVM's gfn_to_pfn() Sean Christopherson
2023-03-17  6:18   ` Yan Zhao
2023-03-11  0:22 ` [PATCH v2 07/27] drm/i915/gvt: Don't rely on KVM's gfn_to_pfn() to query possible 2M GTT Sean Christopherson
2023-03-17  5:37   ` Yan Zhao
2023-03-11  0:22 ` [PATCH v2 08/27] drm/i915/gvt: Use an "unsigned long" to iterate over memslot gfns Sean Christopherson
2023-03-17  6:19   ` Yan Zhao
2023-03-11  0:22 ` [PATCH v2 09/27] drm/i915/gvt: Drop unused helper intel_vgpu_reset_gtt() Sean Christopherson
2023-03-17  6:20   ` Yan Zhao
2023-03-11  0:22 ` [PATCH v2 10/27] drm/i915/gvt: Protect gfn hash table with vgpu_lock Sean Christopherson
2023-03-17  6:21   ` Yan Zhao
2023-03-11  0:22 ` [PATCH v2 11/27] KVM: x86/mmu: Don't rely on page-track mechanism to flush on memslot change Sean Christopherson
2023-03-15  1:08   ` Yan Zhao
2023-03-15 15:32     ` Sean Christopherson
2023-03-11  0:22 ` [PATCH v2 12/27] KVM: x86/mmu: Don't bounce through page-track mechanism for guest PTEs Sean Christopherson
2023-03-17  6:37   ` Yan Zhao
2023-03-11  0:22 ` [PATCH v2 13/27] KVM: drm/i915/gvt: Drop @vcpu from KVM's ->track_write() hook Sean Christopherson
2023-03-17  7:28   ` Yan Zhao
2023-03-11  0:22 ` [PATCH v2 14/27] KVM: x86: Reject memslot MOVE operations if KVMGT is attached Sean Christopherson
2023-03-15  8:03   ` Yan Zhao
2023-03-15 15:43     ` Sean Christopherson
2023-03-16  9:27       ` Yan Zhao
2023-03-17  7:29   ` Yan Zhao
2023-03-11  0:22 ` [PATCH v2 15/27] drm/i915/gvt: Don't bother removing write-protection on to-be-deleted slot Sean Christopherson
2023-03-17  7:30   ` Yan Zhao
2023-03-11  0:22 ` [PATCH v2 16/27] KVM: x86: Add a new page-track hook to handle memslot deletion Sean Christopherson
2023-03-17  7:43   ` Yan Zhao
2023-03-17 16:20     ` Sean Christopherson
2023-03-11  0:22 ` [PATCH v2 17/27] drm/i915/gvt: switch from ->track_flush_slot() to ->track_remove_region() Sean Christopherson
2023-03-17  7:45   ` Yan Zhao
2023-03-11  0:22 ` [PATCH v2 18/27] KVM: x86: Remove the unused page-track hook track_flush_slot() Sean Christopherson
2023-03-11  0:22 ` [PATCH v2 19/27] KVM: x86/mmu: Move KVM-only page-track declarations to internal header Sean Christopherson
2023-03-15  8:44   ` Yan Zhao
2023-03-15 15:13     ` Sean Christopherson
2023-03-16  9:19       ` Yan Zhao
2023-03-11  0:22 ` [PATCH v2 20/27] KVM: x86/mmu: Use page-track notifiers iff there are external users Sean Christopherson
2023-03-15  9:34   ` Yan Zhao
2023-03-15 16:21     ` Sean Christopherson
2023-03-16  9:29       ` Yan Zhao
2023-03-15 10:36   ` Yan Zhao
2023-03-15 16:54     ` Sean Christopherson
2023-05-04 19:54       ` Sean Christopherson
2023-05-06  1:08         ` Yan Zhao
2023-03-11  0:22 ` [PATCH v2 21/27] KVM: x86/mmu: Drop infrastructure for multiple page-track modes Sean Christopherson
2023-03-11  0:22 ` [PATCH v2 22/27] KVM: x86/mmu: Rename page-track APIs to reflect the new reality Sean Christopherson
2023-03-11  0:22 ` [PATCH v2 23/27] KVM: x86/mmu: Assert that correct locks are held for page write-tracking Sean Christopherson
2023-03-17  7:55   ` Yan Zhao
2023-03-11  0:22 ` [PATCH v2 24/27] KVM: x86/mmu: Bug the VM if write-tracking is used but not enabled Sean Christopherson
2023-03-11  0:22 ` [PATCH v2 25/27] KVM: x86/mmu: Drop @slot param from exported/external page-track APIs Sean Christopherson
2023-03-17  8:28   ` Yan Zhao
2023-03-23  8:50     ` Yan Zhao
2023-05-03 23:16       ` Sean Christopherson
2023-05-04  2:17         ` Yan Zhao
2023-05-08  1:15           ` Yan Zhao
2023-05-11 22:39             ` Sean Christopherson
2023-05-12  2:58               ` Yan Zhao
2023-03-11  0:22 ` [PATCH v2 26/27] KVM: x86/mmu: Handle KVM bookkeeping in page-track APIs, not callers Sean Christopherson
2023-03-17  8:52   ` Yan Zhao
2023-03-11  0:22 ` [PATCH v2 27/27] drm/i915/gvt: Drop final dependencies on KVM internal details Sean Christopherson
2023-03-17  8:58   ` Yan Zhao
2023-03-13  9:58 ` [PATCH v2 00/27] drm/i915/gvt: KVM: KVMGT fixes and page-track cleanups Yan Zhao

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZA/lYL7dsv7xBA01@yzhao56-desk.sh.intel.com \
    --to=yan.y.zhao@intel.com \
    --cc=bgardon@google.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=intel-gvt-dev@lists.freedesktop.org \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=seanjc@google.com \
    --cc=zhenyuw@linux.intel.com \
    --cc=zhi.a.wang@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®