Skip to content

Commit ba193f6

Browse files
sean-jcbonzini
authored andcommitted
drm/i915/gvt: Don't rely on KVM's gfn_to_pfn() to query possible 2M GTT
Now that gvt_pin_guest_page() explicitly verifies the pinned PFN is a transparent hugepage page, don't use KVM's gfn_to_pfn() to pre-check if a 2MiB GTT entry is possible and instead just try to map the GFN with a 2MiB entry. Using KVM to query pfn that is ultimately managed through VFIO is odd, and KVM's gfn_to_pfn() is not intended for non-KVM consumption; it's exported only because of KVM vendor modules (x86 and PPC). Open code the check on 2MiB support instead of keeping is_2MB_gtt_possible() around for a single line of code. Move the call to intel_gvt_dma_map_guest_page() for a 4KiB entry into its case statement, i.e. fork the common path into the 4KiB and 2MiB "direct" shadow paths. Keeping the call in the "common" path is arguably more in the spirit of "one change per patch", but retaining the local "page_size" variable is silly, i.e. the call site will be changed either way, and jumping around the no-longer-common code is more subtle and rather odd, i.e. would just need to be immediately cleaned up. Drop the error message from gvt_pin_guest_page() when KVMGT attempts to shadow a 2MiB guest page that isn't backed by a compatible hugepage in the host. Dropping the pre-check on a THP makes it much more likely that the "error" will be encountered in normal operation. Reviewed-by: Yan Zhao <yan.y.zhao@intel.com> Tested-by: Yan Zhao <yan.y.zhao@intel.com> Tested-by: Yongwei Ma <yongwei.ma@intel.com> Reviewed-by: Zhi Wang <zhi.a.wang@intel.com> Link: https://lore.kernel.org/r/20230729013535.1070024-9-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 241f0aa commit ba193f6

2 files changed

Lines changed: 8 additions & 42 deletions

File tree

drivers/gpu/drm/i915/gvt/gtt.c

Lines changed: 8 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,36 +1145,6 @@ static inline void ppgtt_generate_shadow_entry(struct intel_gvt_gtt_entry *se,
11451145
ops->set_pfn(se, s->shadow_page.mfn);
11461146
}
11471147

1148-
/*
1149-
* Check if can do 2M page
1150-
* @vgpu: target vgpu
1151-
* @entry: target pfn's gtt entry
1152-
*
1153-
* Return 1 if 2MB huge gtt shadowing is possible, 0 if miscondition,
1154-
* negative if found err.
1155-
*/
1156-
static int is_2MB_gtt_possible(struct intel_vgpu *vgpu,
1157-
struct intel_gvt_gtt_entry *entry)
1158-
{
1159-
const struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops;
1160-
kvm_pfn_t pfn;
1161-
int ret;
1162-
1163-
if (!HAS_PAGE_SIZES(vgpu->gvt->gt->i915, I915_GTT_PAGE_SIZE_2M))
1164-
return 0;
1165-
1166-
pfn = gfn_to_pfn(vgpu->vfio_device.kvm, ops->get_pfn(entry));
1167-
if (is_error_noslot_pfn(pfn))
1168-
return -EINVAL;
1169-
1170-
if (!pfn_valid(pfn))
1171-
return -EINVAL;
1172-
1173-
ret = PageTransHuge(pfn_to_page(pfn));
1174-
kvm_release_pfn_clean(pfn);
1175-
return ret;
1176-
}
1177-
11781148
static int split_2MB_gtt_entry(struct intel_vgpu *vgpu,
11791149
struct intel_vgpu_ppgtt_spt *spt, unsigned long index,
11801150
struct intel_gvt_gtt_entry *se)
@@ -1268,7 +1238,7 @@ static int ppgtt_populate_shadow_entry(struct intel_vgpu *vgpu,
12681238
{
12691239
const struct intel_gvt_gtt_pte_ops *pte_ops = vgpu->gvt->gtt.pte_ops;
12701240
struct intel_gvt_gtt_entry se = *ge;
1271-
unsigned long gfn, page_size = PAGE_SIZE;
1241+
unsigned long gfn;
12721242
dma_addr_t dma_addr;
12731243
int ret;
12741244

@@ -1280,6 +1250,9 @@ static int ppgtt_populate_shadow_entry(struct intel_vgpu *vgpu,
12801250
switch (ge->type) {
12811251
case GTT_TYPE_PPGTT_PTE_4K_ENTRY:
12821252
gvt_vdbg_mm("shadow 4K gtt entry\n");
1253+
ret = intel_gvt_dma_map_guest_page(vgpu, gfn, PAGE_SIZE, &dma_addr);
1254+
if (ret)
1255+
return -ENXIO;
12831256
break;
12841257
case GTT_TYPE_PPGTT_PTE_64K_ENTRY:
12851258
gvt_vdbg_mm("shadow 64K gtt entry\n");
@@ -1291,12 +1264,10 @@ static int ppgtt_populate_shadow_entry(struct intel_vgpu *vgpu,
12911264
return split_64KB_gtt_entry(vgpu, spt, index, &se);
12921265
case GTT_TYPE_PPGTT_PTE_2M_ENTRY:
12931266
gvt_vdbg_mm("shadow 2M gtt entry\n");
1294-
ret = is_2MB_gtt_possible(vgpu, ge);
1295-
if (ret == 0)
1267+
if (!HAS_PAGE_SIZES(vgpu->gvt->gt->i915, I915_GTT_PAGE_SIZE_2M) ||
1268+
intel_gvt_dma_map_guest_page(vgpu, gfn,
1269+
I915_GTT_PAGE_SIZE_2M, &dma_addr))
12961270
return split_2MB_gtt_entry(vgpu, spt, index, &se);
1297-
else if (ret < 0)
1298-
return ret;
1299-
page_size = I915_GTT_PAGE_SIZE_2M;
13001271
break;
13011272
case GTT_TYPE_PPGTT_PTE_1G_ENTRY:
13021273
gvt_vgpu_err("GVT doesn't support 1GB entry\n");
@@ -1306,11 +1277,7 @@ static int ppgtt_populate_shadow_entry(struct intel_vgpu *vgpu,
13061277
return -EINVAL;
13071278
}
13081279

1309-
/* direct shadow */
1310-
ret = intel_gvt_dma_map_guest_page(vgpu, gfn, page_size, &dma_addr);
1311-
if (ret)
1312-
return -ENXIO;
1313-
1280+
/* Successfully shadowed a 4K or 2M page (without splitting). */
13141281
pte_ops->set_pfn(&se, dma_addr >> PAGE_SHIFT);
13151282
ppgtt_set_shadow_entry(spt, &se, index);
13161283
return 0;

drivers/gpu/drm/i915/gvt/kvmgt.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,6 @@ static int gvt_pin_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
162162
if (npage == 0)
163163
base_page = cur_page;
164164
else if (page_to_pfn(base_page) + npage != page_to_pfn(cur_page)) {
165-
gvt_vgpu_err("The pages are not continuous\n");
166165
ret = -EINVAL;
167166
npage++;
168167
goto err;

0 commit comments

Comments
 (0)