diff options
-rw-r--r-- | drivers/gpu/drm/i915/gvt/kvmgt.c | 51 |
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 | ||
736 | static 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 | |||
736 | static ssize_t intel_vgpu_read(struct mdev_device *mdev, char __user *buf, | 755 | static 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))) |