diff options
Diffstat (limited to 'drivers/gpu/drm/i915/gvt/mmio.c')
-rw-r--r-- | drivers/gpu/drm/i915/gvt/mmio.c | 47 |
1 files changed, 45 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/gvt/mmio.c b/drivers/gpu/drm/i915/gvt/mmio.c index 980ec8906b1e..1e1310f50289 100644 --- a/drivers/gpu/drm/i915/gvt/mmio.c +++ b/drivers/gpu/drm/i915/gvt/mmio.c @@ -45,8 +45,7 @@ */ int intel_vgpu_gpa_to_mmio_offset(struct intel_vgpu *vgpu, u64 gpa) { - u64 gttmmio_gpa = *(u64 *)(vgpu_cfg_space(vgpu) + PCI_BASE_ADDRESS_0) & - ~GENMASK(3, 0); + u64 gttmmio_gpa = intel_vgpu_get_bar_gpa(vgpu, PCI_BASE_ADDRESS_0); return gpa - gttmmio_gpa; } @@ -57,6 +56,38 @@ int intel_vgpu_gpa_to_mmio_offset(struct intel_vgpu *vgpu, u64 gpa) (reg >= gvt->device_info.gtt_start_offset \ && reg < gvt->device_info.gtt_start_offset + gvt_ggtt_sz(gvt)) +static bool vgpu_gpa_is_aperture(struct intel_vgpu *vgpu, uint64_t gpa) +{ + u64 aperture_gpa = intel_vgpu_get_bar_gpa(vgpu, PCI_BASE_ADDRESS_2); + u64 aperture_sz = vgpu_aperture_sz(vgpu); + + return gpa >= aperture_gpa && gpa < aperture_gpa + aperture_sz; +} + +static int vgpu_aperture_rw(struct intel_vgpu *vgpu, uint64_t gpa, + void *pdata, unsigned int size, bool is_read) +{ + u64 aperture_gpa = intel_vgpu_get_bar_gpa(vgpu, PCI_BASE_ADDRESS_2); + u64 offset = gpa - aperture_gpa; + + if (!vgpu_gpa_is_aperture(vgpu, gpa + size - 1)) { + gvt_vgpu_err("Aperture rw out of range, offset %llx, size %d\n", + offset, size); + return -EINVAL; + } + + if (!vgpu->gm.aperture_va) { + gvt_vgpu_err("BAR is not enabled\n"); + return -ENXIO; + } + + if (is_read) + memcpy(pdata, vgpu->gm.aperture_va + offset, size); + else + memcpy(vgpu->gm.aperture_va + offset, pdata, size); + return 0; +} + static void failsafe_emulate_mmio_rw(struct intel_vgpu *vgpu, uint64_t pa, void *p_data, unsigned int bytes, bool read) { @@ -133,6 +164,12 @@ int intel_vgpu_emulate_mmio_read(struct intel_vgpu *vgpu, uint64_t pa, } mutex_lock(&gvt->lock); + if (vgpu_gpa_is_aperture(vgpu, pa)) { + ret = vgpu_aperture_rw(vgpu, pa, p_data, bytes, true); + mutex_unlock(&gvt->lock); + return ret; + } + if (atomic_read(&vgpu->gtt.n_write_protected_guest_page)) { struct intel_vgpu_guest_page *gp; @@ -224,6 +261,12 @@ int intel_vgpu_emulate_mmio_write(struct intel_vgpu *vgpu, uint64_t pa, mutex_lock(&gvt->lock); + if (vgpu_gpa_is_aperture(vgpu, pa)) { + ret = vgpu_aperture_rw(vgpu, pa, p_data, bytes, false); + mutex_unlock(&gvt->lock); + return ret; + } + if (atomic_read(&vgpu->gtt.n_write_protected_guest_page)) { struct intel_vgpu_guest_page *gp; |