tree: https://github.com/0day-ci/linux/commits/UPDATE-20210827-103812/Colin-Xu/vfio-pci-Add-OpRegion-2-0-Extended-VBT-support/20210813-101440 head: 52452f6e09eab566a6b475b09d9c2f7ce211c0b9 commit: 52452f6e09eab566a6b475b09d9c2f7ce211c0b9 vfio/pci: Add OpRegion 2.0 Extended VBT support. date: 3 days ago config: i386-randconfig-s001-20210830 (attached as .config) compiler: gcc-9 (Debian 9.3.0-22) 9.3.0 reproduce: # apt-get install sparse # sparse version: v0.6.3-348-gf0e6938b-dirty # https://github.com/0day-ci/linux/commit/52452f6e09eab566a6b475b09d9c2f7ce211c0b9 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review UPDATE-20210827-103812/Colin-Xu/vfio-pci-Add-OpRegion-2-0-Extended-VBT-support/20210813-101440 git checkout 52452f6e09eab566a6b475b09d9c2f7ce211c0b9 # save the attached .config to linux build tree make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=i386 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot sparse warnings: (new ones prefixed by >>) >> drivers/vfio/pci/vfio_pci_igd.c:158:69: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __le16 [usertype] @@ got int @@ drivers/vfio/pci/vfio_pci_igd.c:158:69: sparse: expected restricted __le16 [usertype] drivers/vfio/pci/vfio_pci_igd.c:158:69: sparse: got int >> drivers/vfio/pci/vfio_pci_igd.c:160:66: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __le64 [usertype] @@ got int @@ drivers/vfio/pci/vfio_pci_igd.c:160:66: sparse: expected restricted __le64 [usertype] drivers/vfio/pci/vfio_pci_igd.c:160:66: sparse: got int drivers/vfio/pci/vfio_pci_igd.c:232:21: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned short [addressable] [usertype] val @@ got restricted __le16 [usertype] @@ drivers/vfio/pci/vfio_pci_igd.c:232:21: sparse: expected unsigned short [addressable] [usertype] val drivers/vfio/pci/vfio_pci_igd.c:232:21: sparse: got restricted __le16 [usertype] drivers/vfio/pci/vfio_pci_igd.c:247:21: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned int [addressable] [usertype] val @@ got restricted __le32 [usertype] @@ drivers/vfio/pci/vfio_pci_igd.c:247:21: sparse: expected unsigned int [addressable] [usertype] val drivers/vfio/pci/vfio_pci_igd.c:247:21: sparse: got restricted __le32 [usertype] drivers/vfio/pci/vfio_pci_igd.c:262:21: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned short [addressable] [usertype] val @@ got restricted __le16 [usertype] @@ drivers/vfio/pci/vfio_pci_igd.c:262:21: sparse: expected unsigned short [addressable] [usertype] val drivers/vfio/pci/vfio_pci_igd.c:262:21: sparse: got restricted __le16 [usertype] vim +158 drivers/vfio/pci/vfio_pci_igd.c 61 62 static int vfio_pci_igd_opregion_init(struct vfio_pci_device *vdev) 63 { 64 __le32 *dwordp = (__le32 *)(vdev->vconfig + OPREGION_PCI_ADDR); 65 u32 addr, size, rvds = 0; 66 void *base, *opregionvbt; 67 int ret; 68 u16 version; 69 u64 rvda = 0; 70 71 ret = pci_read_config_dword(vdev->pdev, OPREGION_PCI_ADDR, &addr); 72 if (ret) 73 return ret; 74 75 if (!addr || !(~addr)) 76 return -ENODEV; 77 78 base = memremap(addr, OPREGION_SIZE, MEMREMAP_WB); 79 if (!base) 80 return -ENOMEM; 81 82 if (memcmp(base, OPREGION_SIGNATURE, 16)) { 83 memunmap(base); 84 return -EINVAL; 85 } 86 87 size = le32_to_cpu(*(__le32 *)(base + 16)); 88 if (!size) { 89 memunmap(base); 90 return -EINVAL; 91 } 92 93 size *= 1024; /* In KB */ 94 95 /* 96 * OpRegion and VBT: 97 * When VBT data doesn't exceed 6KB, it's stored in Mailbox #4. 98 * When VBT data exceeds 6KB size, Mailbox #4 is no longer large enough 99 * to hold the VBT data, the Extended VBT region is introduced since 100 * OpRegion 2.0 to hold the VBT data. Since OpRegion 2.0, RVDA/RVDS are 101 * introduced to define the extended VBT data location and size. 102 * OpRegion 2.0: RVDA defines the absolute physical address of the 103 * extended VBT data, RVDS defines the VBT data size. 104 * OpRegion 2.1 and above: RVDA defines the relative address of the 105 * extended VBT data to OpRegion base, RVDS defines the VBT data size. 106 * 107 * Due to the RVDA difference in OpRegion VBT (also the only diff between 108 * 2.0 and 2.1), while for OpRegion 2.1 and above it's possible to map 109 * a contigious memory to expose OpRegion and VBT r/w via the vfio 110 * region, for OpRegion 2.0 shadow and amendment mechanism is used to 111 * expose OpRegion and VBT r/w properly. So that from r/w ops view, only 112 * OpRegion 2.1 is exposed regardless underneath Region is 2.0 or 2.1. 113 */ 114 version = le16_to_cpu(*(__le16 *)(base + OPREGION_VERSION)); 115 116 if (version >= 0x0200) { 117 rvda = le64_to_cpu(*(__le64 *)(base + OPREGION_RVDA)); 118 rvds = le32_to_cpu(*(__le32 *)(base + OPREGION_RVDS)); 119 120 /* The extended VBT must follows OpRegion for OpRegion 2.1+ */ 121 if (rvda != size && version > 0x0200) { 122 memunmap(base); 123 pci_err(vdev->pdev, 124 "Extended VBT does not follow opregion on version 0x%04x\n", 125 version); 126 return -EINVAL; 127 } 128 129 /* The extended VBT is valid only when RVDA/RVDS are non-zero. */ 130 if (rvda && rvds) { 131 size += rvds; 132 } 133 } 134 135 if (size != OPREGION_SIZE) { 136 /* Allocate memory for OpRegion and extended VBT for 2.0 */ 137 if (rvda && rvds && version == 0x0200) { 138 void *vbt_base; 139 140 vbt_base = memremap(rvda, rvds, MEMREMAP_WB); 141 if (!vbt_base) { 142 memunmap(base); 143 return -ENOMEM; 144 } 145 146 opregionvbt = kzalloc(size, GFP_KERNEL); 147 if (!opregionvbt) { 148 memunmap(base); 149 memunmap(vbt_base); 150 return -ENOMEM; 151 } 152 153 /* Stitch VBT after OpRegion noncontigious */ 154 memcpy(opregionvbt, base, OPREGION_SIZE); 155 memcpy(opregionvbt + OPREGION_SIZE, vbt_base, rvds); 156 157 /* Patch OpRegion 2.0 to 2.1 */ > 158 *(__le16 *)(opregionvbt + OPREGION_VERSION) = 0x0201; 159 /* Patch RVDA to relative address after OpRegion */ > 160 *(__le64 *)(opregionvbt + OPREGION_RVDA) = OPREGION_SIZE; 161 162 memunmap(vbt_base); 163 memunmap(base); 164 165 /* Register shadow instead of map as vfio_region */ 166 base = opregionvbt; 167 /* Remap OpRegion + extended VBT for 2.1+ */ 168 } else { 169 memunmap(base); 170 base = memremap(addr, size, MEMREMAP_WB); 171 if (!base) 172 return -ENOMEM; 173 } 174 } 175 176 ret = vfio_pci_register_dev_region(vdev, 177 PCI_VENDOR_ID_INTEL | VFIO_REGION_TYPE_PCI_VENDOR_TYPE, 178 VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION, 179 &vfio_pci_igd_regops, size, VFIO_REGION_INFO_FLAG_READ, base); 180 if (ret) { 181 if (is_ioremap_addr(base)) 182 memunmap(base); 183 else 184 kfree(base); 185 return ret; 186 } 187 188 /* Fill vconfig with the hw value and virtualize register */ 189 *dwordp = cpu_to_le32(addr); 190 memset(vdev->pci_config_map + OPREGION_PCI_ADDR, 191 PCI_CAP_ID_INVALID_VIRT, 4); 192 193 return ret; 194 } 195 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org