Patch "drm/i915/gvt: Fix incorrect PCI BARs reporting" has been added to the 4.13-stable tree
This is a note to let you know that I've just added the patch titled
drm/i915/gvt: Fix incorrect PCI BARs reporting
to the 4.13-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
drm-i915-gvt-fix-incorrect-pci-bars-reporting.patch
and it can be found in the queue-4.13 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
7b4dc3c0da0d66e7b20a826c537d41bb73e4df54Mon Sep 17 00:00:00 2001
From: Changbin Du <[email protected]>
Date: Fri, 18 Aug 2017 17:49:58 +0800
Subject: drm/i915/gvt: Fix incorrect PCI BARs reporting
From: Changbin Du <[email protected]>
commit 7b4dc3c0da0d66e7b20a826c537d41bb73e4df54 upstream.
Looking at our virtual PCI device, we can see surprising Region 4 and Region 5.
00:10.0 VGA compatible controller: Intel Corporation Sky Lake Integrated Graphics (rev 06) (prog-if 00 [VGA controller])
....
Region 0: Memory at 140000000 (64-bit, non-prefetchable) [size=16M]
Region 2: Memory at 180000000 (64-bit, prefetchable) [size=1G]
Region 4: Memory at <ignored> (32-bit, non-prefetchable)
Region 5: Memory at <ignored> (32-bit, non-prefetchable)
Expansion ROM at febd6000 [disabled] [size=2K]
The fact is that we only implemented BAR0 and BAR2. Surprising Region 4 and Region 5 are shown because we report their size as 0xffffffff. They should report size 0 instead.
BTW, the physical GPU has a PIO BAR. GVTg hasn't implemented PIO access, so we ignored this BAR for vGPU device.
v2: fix BAR size value calculation.
--- drivers/gpu/drm/i915/gvt/cfg_space.c | 113 ++++++++++++++--------------------- 1 file changed, 48 insertions(+), 65 deletions(-)
drivers/gpu/drm/i915/gvt/cfg_space.c +48 -65
@@ -197,78 +197,65 @@ static int emulate_pci_command_write(strstatic int emulate_pci_bar_write (struct intel_vgpu *vgpu,unsigned int offset,void *p_data,unsigned int bytes) { -unsigned int bar_index = - (rounddown (offset,8 ) %PCI_BASE_ADDRESS_0 ) /8 ;u32 new = *(u32 *)(p_data);bool lo =IS_ALIGNED (offset,8 );u64 size;int ret =0 ;bool mmio_enabled =vgpu_cfg_space (vgpu)[PCI_COMMAND ] &PCI_COMMAND_MEMORY ; +struct intel_vgpu_pci_bar *bars = vgpu->cfg_space.bar; -if (WARN_ON (bar_index >=INTEL_GVT_PCI_BAR_MAX )) -return -EINVAL ; - +/* +* Power-up software can determine how much address +* space the device requires by writing a value of +* all 1's to the register and then reading the value +* back. The device will return 0's in all don't-care +* address bits. +*/ if (new ==0xffffffff ) { -/* -* Power-up software can determine how much address -* space the device requires by writing a value of -* all 1's to the register and then reading the value -* back. The device will return 0's in all don't-care -* address bits. -*/ - size = vgpu->cfg_space.bar[bar_index].size; -if (lo) { - new =rounddown (new, size); - }else { -u32 val =vgpu_cfg_space (vgpu)[rounddown (offset,8 )]; -/* for 32bit mode bar it returns all-0 in upper 32 -* bit, for 64bit mode bar it will calculate the -* size with lower 32bit and return the corresponding -* value +switch (offset) { +case PCI_BASE_ADDRESS_0 : +case PCI_BASE_ADDRESS_1 : + size = ~(bars[INTEL_GVT_PCI_BAR_GTTMMIO ].size -1 ); +intel_vgpu_write_pci_bar (vgpu, offset, + size >> (lo ?0 :32 ), lo); +/* +* Untrap the BAR, since guest hasn't configured a +* valid GPA */ -if (val &PCI_BASE_ADDRESS_MEM_TYPE_64 ) - new &= (~(size-1 )) >>32 ; -else - new =0 ; - } -/* -* Unmapp & untrap the BAR, since guest hasn't configured a -* valid GPA -*/ -switch (bar_index) { -case INTEL_GVT_PCI_BAR_GTTMMIO : ret =trap_gttmmio (vgpu, false);break ; -case INTEL_GVT_PCI_BAR_APERTURE : +case PCI_BASE_ADDRESS_2 : +case PCI_BASE_ADDRESS_3 : + size = ~(bars[INTEL_GVT_PCI_BAR_APERTURE ].size -1 ); +intel_vgpu_write_pci_bar (vgpu, offset, + size >> (lo ?0 :32 ), lo); ret =map_aperture (vgpu, false);break ; +default : +/* Unimplemented BARs */ +intel_vgpu_write_pci_bar (vgpu, offset,0x0 , false); } -intel_vgpu_write_pci_bar (vgpu, offset, new, lo); }else { -/* -* Unmapp & untrap the old BAR first, since guest has -* re-configured the BAR -*/ -switch (bar_index) { -case INTEL_GVT_PCI_BAR_GTTMMIO : - ret =trap_gttmmio (vgpu, false); +switch (offset) { +case PCI_BASE_ADDRESS_0 : +case PCI_BASE_ADDRESS_1 : +/* +* Untrap the old BAR first, since guest has +* re-configured the BAR +*/ +trap_gttmmio (vgpu, false); +intel_vgpu_write_pci_bar (vgpu, offset, new, lo); + ret =trap_gttmmio (vgpu, mmio_enabled);break ; -case INTEL_GVT_PCI_BAR_APERTURE : - ret =map_aperture (vgpu, false); +case PCI_BASE_ADDRESS_2 : +case PCI_BASE_ADDRESS_3 : +map_aperture (vgpu, false); +intel_vgpu_write_pci_bar (vgpu, offset, new, lo); + ret =map_aperture (vgpu, mmio_enabled);break ; - } -intel_vgpu_write_pci_bar (vgpu, offset, new, lo); -/* Track the new BAR */ -if (mmio_enabled) { -switch (bar_index) { -case INTEL_GVT_PCI_BAR_GTTMMIO : - ret =trap_gttmmio (vgpu, true); -break ; -case INTEL_GVT_PCI_BAR_APERTURE : - ret =map_aperture (vgpu, true); -break ; - } +default : +intel_vgpu_write_pci_bar (vgpu, offset, new, lo); } }return ret;
@@ -299,10 +286,7 @@ int intel_vgpu_emulate_cfg_write(struct }switch (rounddown (offset,4 )) { -case PCI_BASE_ADDRESS_0 : -case PCI_BASE_ADDRESS_1 : -case PCI_BASE_ADDRESS_2 : -case PCI_BASE_ADDRESS_3 : + case PCI_BASE_ADDRESS_0 ... PCI_BASE_ADDRESS_5:if (WARN_ON (!IS_ALIGNED (offset,4 )))return -EINVAL ;return emulate_pci_bar_write (vgpu, offset, p_data, bytes);
@@ -344,7 +328,6 @@ void intel_vgpu_init_cfg_space(struct instruct intel_gvt *gvt = vgpu->gvt;const struct intel_gvt_device_info *info = &gvt->device_info;u16 *gmch_ctl; -int i;memcpy (vgpu_cfg_space (vgpu), gvt->firmware.cfg_space, info->cfg_space_size);
@@ -371,13 +354,13 @@ void intel_vgpu_init_cfg_space(struct in*/ memset (vgpu_cfg_space (vgpu) +PCI_BASE_ADDRESS_1 ,0 ,4 );memset (vgpu_cfg_space (vgpu) +PCI_BASE_ADDRESS_3 ,0 ,4 ); +memset (vgpu_cfg_space (vgpu) +PCI_BASE_ADDRESS_4 ,0 ,8 );memset (vgpu_cfg_space (vgpu) +INTEL_GVT_PCI_OPREGION ,0 ,4 ); -for (i =0 ; i <INTEL_GVT_MAX_BAR_NUM ; i++) { - vgpu->cfg_space.bar[i].size =pci_resource_len ( - gvt->dev_priv->drm.pdev, i *2 ); - vgpu->cfg_space.bar[i].tracked = false; - } + vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_GTTMMIO ].size = +pci_resource_len (gvt->dev_priv->drm.pdev,0 ); + vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_APERTURE ].size = +pci_resource_len (gvt->dev_priv->drm.pdev,2 ); }/**
Patches currently in stable-queue which might be from [email protected] are
queue-4.13/drm-i915-gvt-fix-incorrect-pci-bars-reporting.patch