From cc753fbe1ac47560e1517e3e11fb0c8a3c95eef5 Mon Sep 17 00:00:00 2001 From: Hang Yuan Date: Fri, 22 Dec 2017 18:06:31 +0800 Subject: drm/i915/gvt: validate gfn before set shadow page entry GVT may receive partial write on one guest PTE update. Validate gfn not to translate incomplete gfn. This avoids some unnecessary error messages incurred by the incomplete gfn translating. Also fix the bug that the whole PPGTT shadow page update is aborted on any invalid gfn entry. gfn validation relys on hypervisor's help. Add one MPT module function to provide the function. Signed-off-by: Hang Yuan Reviewed-by: Zhi Wang Signed-off-by: Zhenyu Wang Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/gvt/kvmgt.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers/gpu/drm/i915/gvt/kvmgt.c') diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index 45bab5a6290b..eb92572056c3 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -1570,6 +1570,21 @@ static unsigned long kvmgt_virt_to_pfn(void *addr) return PFN_DOWN(__pa(addr)); } +static bool kvmgt_is_valid_gfn(unsigned long handle, unsigned long gfn) +{ + struct kvmgt_guest_info *info; + struct kvm *kvm; + + if (!handle_valid(handle)) + return false; + + info = (struct kvmgt_guest_info *)handle; + kvm = info->kvm; + + return kvm_is_visible_gfn(kvm, gfn); + +} + struct intel_gvt_mpt kvmgt_mpt = { .host_init = kvmgt_host_init, .host_exit = kvmgt_host_exit, @@ -1585,6 +1600,7 @@ struct intel_gvt_mpt kvmgt_mpt = { .set_opregion = kvmgt_set_opregion, .get_vfio_device = kvmgt_get_vfio_device, .put_vfio_device = kvmgt_put_vfio_device, + .is_valid_gfn = kvmgt_is_valid_gfn, }; EXPORT_SYMBOL_GPL(kvmgt_mpt); -- cgit v1.2.1 From d480b28a41a628e356dbacfa1c9f6d05b9baf838 Mon Sep 17 00:00:00 2001 From: Changbin Du Date: Tue, 30 Jan 2018 13:51:31 +0800 Subject: drm/i915/gvt: Fix aperture read/write emulation when enable x-no-mmap=on When add 'x-no-mmap=on' for vfio-pci option, aperture access in guest is emulated. But the vgpu_aperture_rw() function take wrong offset when do memcpy, since vgpu->gm.aperture_va is not the base of entire aperture. This mistake cause GPU command in guest get lost and so the seqno is not updated in engine HWSP. This patch fix this, and it also move the emulation code to kvmgt. Because only vfio need to emulate it. Put aperture rw to MMIO emulation path breaks assumptions in xengt. v2: Remove PAGE_ALIGN for size (zhenyu) Fixes: f090a00df9ec ("drm/i915/gvt: Add emulation for BAR2 (aperture) with normal file RW approach") Signed-off-by: Changbin Du Signed-off-by: Zhi Wang Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/gvt/kvmgt.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915/gvt/kvmgt.c') diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index eb92572056c3..801a3375c7b4 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -651,6 +651,39 @@ static int intel_vgpu_bar_rw(struct intel_vgpu *vgpu, int bar, uint64_t off, return ret; } +static inline bool intel_vgpu_in_aperture(struct intel_vgpu *vgpu, uint64_t off) +{ + return off >= vgpu_aperture_offset(vgpu) && + off < vgpu_aperture_offset(vgpu) + vgpu_aperture_sz(vgpu); +} + +static int intel_vgpu_aperture_rw(struct intel_vgpu *vgpu, uint64_t off, + void *buf, unsigned long count, bool is_write) +{ + void *aperture_va; + + if (!intel_vgpu_in_aperture(vgpu, off) || + !intel_vgpu_in_aperture(vgpu, off + count)) { + gvt_vgpu_err("Invalid aperture offset %llu\n", off); + return -EINVAL; + } + + aperture_va = io_mapping_map_wc(&vgpu->gvt->dev_priv->ggtt.iomap, + ALIGN_DOWN(off, PAGE_SIZE), + count + offset_in_page(off)); + if (!aperture_va) + return -EIO; + + if (is_write) + memcpy(aperture_va + offset_in_page(off), buf, count); + else + memcpy(buf, aperture_va + offset_in_page(off), count); + + io_mapping_unmap(aperture_va); + + return 0; +} + static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char *buf, size_t count, loff_t *ppos, bool is_write) { @@ -679,8 +712,7 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char *buf, buf, count, is_write); break; case VFIO_PCI_BAR2_REGION_INDEX: - ret = intel_vgpu_bar_rw(vgpu, PCI_BASE_ADDRESS_2, pos, - buf, count, is_write); + ret = intel_vgpu_aperture_rw(vgpu, pos, buf, count, is_write); break; case VFIO_PCI_BAR1_REGION_INDEX: case VFIO_PCI_BAR3_REGION_INDEX: -- cgit v1.2.1