aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/gvt/kvmgt.c51
1 files changed, 49 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 909499b73d03..021f722e2481 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -733,6 +733,25 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char *buf,
733 return ret == 0 ? count : ret; 733 return ret == 0 ? count : ret;
734} 734}
735 735
736static bool gtt_entry(struct mdev_device *mdev, loff_t *ppos)
737{
738 struct intel_vgpu *vgpu = mdev_get_drvdata(mdev);
739 unsigned int index = VFIO_PCI_OFFSET_TO_INDEX(*ppos);
740 struct intel_gvt *gvt = vgpu->gvt;
741 int offset;
742
743 /* Only allow MMIO GGTT entry access */
744 if (index != PCI_BASE_ADDRESS_0)
745 return false;
746
747 offset = (u64)(*ppos & VFIO_PCI_OFFSET_MASK) -
748 intel_vgpu_get_bar_gpa(vgpu, PCI_BASE_ADDRESS_0);
749
750 return (offset >= gvt->device_info.gtt_start_offset &&
751 offset < gvt->device_info.gtt_start_offset + gvt_ggtt_sz(gvt)) ?
752 true : false;
753}
754
736static ssize_t intel_vgpu_read(struct mdev_device *mdev, char __user *buf, 755static ssize_t intel_vgpu_read(struct mdev_device *mdev, char __user *buf,
737 size_t count, loff_t *ppos) 756 size_t count, loff_t *ppos)
738{ 757{
@@ -742,7 +761,21 @@ static ssize_t intel_vgpu_read(struct mdev_device *mdev, char __user *buf,
742 while (count) { 761 while (count) {
743 size_t filled; 762 size_t filled;
744 763
745 if (count >= 4 && !(*ppos % 4)) { 764 /* Only support GGTT entry 8 bytes read */
765 if (count >= 8 && !(*ppos % 8) &&
766 gtt_entry(mdev, ppos)) {
767 u64 val;
768
769 ret = intel_vgpu_rw(mdev, (char *)&val, sizeof(val),
770 ppos, false);
771 if (ret <= 0)
772 goto read_err;
773
774 if (copy_to_user(buf, &val, sizeof(val)))
775 goto read_err;
776
777 filled = 8;
778 } else if (count >= 4 && !(*ppos % 4)) {
746 u32 val; 779 u32 val;
747 780
748 ret = intel_vgpu_rw(mdev, (char *)&val, sizeof(val), 781 ret = intel_vgpu_rw(mdev, (char *)&val, sizeof(val),
@@ -802,7 +835,21 @@ static ssize_t intel_vgpu_write(struct mdev_device *mdev,
802 while (count) { 835 while (count) {
803 size_t filled; 836 size_t filled;
804 837
805 if (count >= 4 && !(*ppos % 4)) { 838 /* Only support GGTT entry 8 bytes write */
839 if (count >= 8 && !(*ppos % 8) &&
840 gtt_entry(mdev, ppos)) {
841 u64 val;
842
843 if (copy_from_user(&val, buf, sizeof(val)))
844 goto write_err;
845
846 ret = intel_vgpu_rw(mdev, (char *)&val, sizeof(val),
847 ppos, true);
848 if (ret <= 0)
849 goto write_err;
850
851 filled = 8;
852 } else if (count >= 4 && !(*ppos % 4)) {
806 u32 val; 853 u32 val;
807 854
808 if (copy_from_user(&val, buf, sizeof(val))) 855 if (copy_from_user(&val, buf, sizeof(val)))