drivers/vfio/pci/vfio_pci_igd.c:158:69: sparse: sparse: incorrect type in assignment (different base types)

From: kernel test robot
Date: Mon Aug 30 2021 - 07:57:40 EST


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 <lkp@xxxxxxxxx>


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@xxxxxxxxxxxx

Attachment: .config.gz
Description: application/gzip