Re: [PATCH v4] drivers: gpio: add virtio-gpio guest driver

From: kernel test robot
Date: Thu Jun 17 2021 - 02:36:17 EST


Hi "Enrico,

I love your patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on v5.13-rc6 next-20210616]
[cannot apply to linux/master gpio/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url: https://github.com/0day-ci/linux/commits/Enrico-Weigelt-metux-IT-consult/drivers-gpio-add-virtio-gpio-guest-driver/20210617-023610
base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 6b00bc639f1f2beeff3595e1bab9faaa51d23b01
config: i386-randconfig-s032-20210617 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce:
# apt-get install sparse
# sparse version: v0.6.3-341-g8af24329-dirty
# https://github.com/0day-ci/linux/commit/8df8c3f8af32ee316ad10d20fc9d75f6e5afae9c
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Enrico-Weigelt-metux-IT-consult/drivers-gpio-add-virtio-gpio-guest-driver/20210617-023610
git checkout 8df8c3f8af32ee316ad10d20fc9d75f6e5afae9c
# save the attached .config to linux build tree
make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' W=1 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/gpio/gpio-virtio.c:119:13: sparse: sparse: incorrect type in assignment (different base types) @@ expected int [assigned] ret @@ got restricted __le32 [usertype] value @@
drivers/gpio/gpio-virtio.c:119:13: sparse: expected int [assigned] ret
drivers/gpio/gpio-virtio.c:119:13: sparse: got restricted __le32 [usertype] value
>> drivers/gpio/gpio-virtio.c:197:19: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __le16 [usertype] type @@ got unsigned short [usertype] @@
drivers/gpio/gpio-virtio.c:197:19: sparse: expected restricted __le16 [usertype] type
drivers/gpio/gpio-virtio.c:197:19: sparse: got unsigned short [usertype]
>> drivers/gpio/gpio-virtio.c:198:19: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __le16 [usertype] pin @@ got unsigned short [usertype] @@
drivers/gpio/gpio-virtio.c:198:19: sparse: expected restricted __le16 [usertype] pin
drivers/gpio/gpio-virtio.c:198:19: sparse: got unsigned short [usertype]
>> drivers/gpio/gpio-virtio.c:199:19: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __le32 [usertype] value @@ got unsigned int [usertype] @@
drivers/gpio/gpio-virtio.c:199:19: sparse: expected restricted __le32 [usertype] value
drivers/gpio/gpio-virtio.c:199:19: sparse: got unsigned int [usertype]
>> drivers/gpio/gpio-virtio.c:204:44: sparse: sparse: incorrect type in argument 2 (different base types) @@ expected int event @@ got restricted __le16 [usertype] type @@
drivers/gpio/gpio-virtio.c:204:44: sparse: expected int event
drivers/gpio/gpio-virtio.c:204:44: sparse: got restricted __le16 [usertype] type
>> drivers/gpio/gpio-virtio.c:204:54: sparse: sparse: incorrect type in argument 3 (different base types) @@ expected int pin @@ got restricted __le16 [usertype] pin @@
drivers/gpio/gpio-virtio.c:204:54: sparse: expected int pin
drivers/gpio/gpio-virtio.c:204:54: sparse: got restricted __le16 [usertype] pin
>> drivers/gpio/gpio-virtio.c:204:63: sparse: sparse: incorrect type in argument 4 (different base types) @@ expected int value @@ got restricted __le32 [usertype] value @@
drivers/gpio/gpio-virtio.c:204:63: sparse: expected int value
drivers/gpio/gpio-virtio.c:204:63: sparse: got restricted __le32 [usertype] value
>> drivers/gpio/gpio-virtio.c:207:38: sparse: sparse: restricted __le16 degrades to integer
drivers/gpio/gpio-virtio.c:201:19: sparse: sparse: restricted __le16 degrades to integer
>> drivers/gpio/gpio-virtio.c:286:9: sparse: sparse: no generic selection for 'unsigned short virtio_cread_v'
>> drivers/gpio/gpio-virtio.c:286:9: sparse: sparse: incompatible types in comparison expression (different base types):
>> drivers/gpio/gpio-virtio.c:286:9: sparse: bad type *
>> drivers/gpio/gpio-virtio.c:286:9: sparse: unsigned short *
>> drivers/gpio/gpio-virtio.c:286:9: sparse: sparse: no generic selection for 'unsigned short [addressable] virtio_cread_v'
>> drivers/gpio/gpio-virtio.c:288:9: sparse: sparse: no generic selection for 'unsigned int virtio_cread_v'
drivers/gpio/gpio-virtio.c:288:9: sparse: sparse: incompatible types in comparison expression (different base types):
drivers/gpio/gpio-virtio.c:288:9: sparse: bad type *
>> drivers/gpio/gpio-virtio.c:288:9: sparse: unsigned int *
>> drivers/gpio/gpio-virtio.c:288:9: sparse: sparse: no generic selection for 'unsigned int [addressable] virtio_cread_v'

vim +119 drivers/gpio/gpio-virtio.c

100
101 static int virtio_gpio_rpc(struct virtio_gpio_priv *priv, int type,
102 int pin, int value)
103 {
104 int ret;
105 struct virtio_gpio_msg *buf = kzalloc(MSG_BUF_SZ, GFP_KERNEL);
106
107 if (!buf)
108 return -ENOMEM;
109
110 mutex_lock(&priv->rpc_mutex);
111 virtio_gpio_prepare_inbuf(priv);
112 clear_event(priv, type);
113
114 ret = virtio_gpio_xmit(priv, type, pin, value, buf);
115 if (ret)
116 goto out;
117
118 wait_event_interruptible(priv->waitq, check_event(priv, type));
> 119 ret = priv->last.value;
120
121 out:
122 mutex_unlock(&priv->rpc_mutex);
123 kfree(buf);
124 return ret;
125 }
126
127 static int virtio_gpio_direction_input(struct gpio_chip *gc,
128 unsigned int pin)
129 {
130 return virtio_gpio_rpc(gpiochip_get_data(gc),
131 VIRTIO_GPIO_MSG_CPU_DIRECTION_INPUT,
132 pin, 0);
133 }
134
135 static int virtio_gpio_direction_output(struct gpio_chip *gc,
136 unsigned int pin, int value)
137 {
138 return virtio_gpio_rpc(gpiochip_get_data(gc),
139 VIRTIO_GPIO_MSG_CPU_DIRECTION_OUTPUT,
140 pin, value);
141 }
142
143 static int virtio_gpio_get_direction(struct gpio_chip *gc, unsigned int pin)
144 {
145 return virtio_gpio_rpc(gpiochip_get_data(gc),
146 VIRTIO_GPIO_MSG_CPU_GET_DIRECTION,
147 pin, 0);
148 }
149
150 static void virtio_gpio_set(struct gpio_chip *gc,
151 unsigned int pin, int value)
152 {
153 virtio_gpio_rpc(gpiochip_get_data(gc),
154 VIRTIO_GPIO_MSG_CPU_SET_LEVEL, pin, value);
155 }
156
157 static int virtio_gpio_get(struct gpio_chip *gc,
158 unsigned int pin)
159 {
160 return virtio_gpio_rpc(gpiochip_get_data(gc),
161 VIRTIO_GPIO_MSG_CPU_GET_LEVEL, pin, 0);
162 }
163
164 static int virtio_gpio_request(struct gpio_chip *gc,
165 unsigned int pin)
166 {
167 return virtio_gpio_rpc(gpiochip_get_data(gc),
168 VIRTIO_GPIO_MSG_CPU_REQUEST, pin, 0);
169 }
170
171 static void virtio_gpio_signal(struct virtio_gpio_priv *priv, int event,
172 int pin, int value)
173 {
174 int mapped_irq = irq_find_mapping(priv->gc.irq.domain, pin);
175
176 if ((pin < priv->num_gpios) && test_bit(pin, priv->irq_mask))
177 generic_handle_irq(mapped_irq);
178 }
179
180 static void virtio_gpio_data_rx(struct virtqueue *vq)
181 {
182 struct virtio_gpio_priv *priv = vq->vdev->priv;
183 void *data;
184 unsigned int len;
185 struct virtio_gpio_msg *ev;
186
187 data = virtqueue_get_buf(priv->vq_rx, &len);
188 if (!data || !len) {
189 dev_warn(&vq->vdev->dev, "RX received no data ! %d\n", len);
190 return;
191 }
192
193 ev = data;
194
195 memcpy(&priv->last, data, MSG_BUF_SZ);
196
> 197 ev->type = le16_to_cpu(ev->type);
> 198 ev->pin = le16_to_cpu(ev->pin);
> 199 ev->value = le32_to_cpu(ev->value);
200
> 201 switch (ev->type) {
202 case VIRTIO_GPIO_MSG_DEVICE_LEVEL:
203 virtio_gpio_prepare_inbuf(priv);
> 204 virtio_gpio_signal(priv, ev->type, ev->pin, ev->value);
205 break;
206 default:
> 207 wakeup_event(priv, ev->type & ~VIRTIO_GPIO_MSG_REPLY);
208 break;
209 }
210
211 wake_up_all(&priv->waitq);
212
213 devm_kfree(&priv->vdev->dev, data);
214 }
215
216 static int virtio_gpio_alloc_vq(struct virtio_gpio_priv *priv)
217 {
218 struct virtqueue *vqs[2];
219 vq_callback_t *cbs[] = {
220 NULL,
221 virtio_gpio_data_rx,
222 };
223 static const char * const names[] = { "in", "out", };
224 int ret;
225
226 ret = virtio_find_vqs(priv->vdev, 2, vqs, cbs, names, NULL);
227 if (ret) {
228 dev_err(&priv->vdev->dev, "failed to alloc vqs: %d\n", ret);
229 return ret;
230 }
231
232 priv->vq_rx = vqs[0];
233 priv->vq_tx = vqs[1];
234
235 ret = virtio_gpio_prepare_inbuf(priv);
236 if (ret) {
237 dev_err(&priv->vdev->dev, "preparing inbuf failed\n");
238 return ret;
239 }
240
241 virtqueue_enable_cb(priv->vq_rx);
242 virtio_device_ready(priv->vdev);
243
244 return 0;
245 }
246
247 static void virtio_gpio_irq_unmask(struct irq_data *irq)
248 {
249 int hwirq = irqd_to_hwirq(irq);
250 struct virtio_gpio_priv *priv
251 = gpiochip_get_data(irq_data_get_irq_chip_data(irq));
252 if (hwirq < CONFIG_VIRTIO_GPIO_MAX_IRQ)
253 set_bit(hwirq, priv->irq_mask);
254 }
255
256 static void virtio_gpio_irq_mask(struct irq_data *irq)
257 {
258 int hwirq = irqd_to_hwirq(irq);
259 struct virtio_gpio_priv *priv
260 = gpiochip_get_data(irq_data_get_irq_chip_data(irq));
261 if (hwirq < CONFIG_VIRTIO_GPIO_MAX_IRQ)
262 clear_bit(hwirq, priv->irq_mask);
263 }
264
265 static int virtio_gpio_probe(struct virtio_device *vdev)
266 {
267 struct virtio_gpio_priv *priv;
268 struct virtio_gpio_config cf = {};
269 char *name_buffer;
270 const char **gpio_names = NULL;
271 struct device *dev = &vdev->dev;
272 struct gpio_irq_chip *girq;
273
274 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
275 if (!priv)
276 return -ENOMEM;
277
278 priv->name = devm_kzalloc(dev, sizeof(cf.name)+1, GFP_KERNEL);
279 if (!priv->name)
280 return -ENOMEM;
281
282 spin_lock_init(&priv->vq_lock);
283 mutex_init(&priv->rpc_mutex);
284
285 virtio_cread_le(vdev, struct virtio_gpio_config, version, &cf.version);
> 286 virtio_cread_le(vdev, struct virtio_gpio_config, num_gpios,
287 &cf.num_gpios);
> 288 virtio_cread_le(vdev, struct virtio_gpio_config, names_size,
289 &cf.names_size);
290 virtio_cread_bytes(vdev, offsetof(struct virtio_gpio_config, name),
291 priv->name, sizeof(cf.name));
292
293 if (cf.version != 1) {
294 dev_err(dev, "unsupported interface version %d\n", cf.version);
295 return -EINVAL;
296 }
297
298 priv->num_gpios = cf.num_gpios;
299
300 if (cf.names_size) {
301 char *bufwalk;
302 int idx = 0;
303
304 name_buffer = devm_kzalloc(&vdev->dev, cf.names_size,
305 GFP_KERNEL)+1;
306 virtio_cread_bytes(vdev, sizeof(struct virtio_gpio_config),
307 name_buffer, cf.names_size);
308 name_buffer[cf.names_size] = 0;
309
310 gpio_names = devm_kcalloc(dev, priv->num_gpios, sizeof(char *),
311 GFP_KERNEL);
312 bufwalk = name_buffer;
313
314 while (idx < priv->num_gpios &&
315 bufwalk < (name_buffer+cf.names_size)) {
316 gpio_names[idx] = (strlen(bufwalk) ? bufwalk : NULL);
317 bufwalk += strlen(bufwalk)+1;
318 idx++;
319 }
320 }
321
322 priv->vdev = vdev;
323 vdev->priv = priv;
324
325 priv->gc.owner = THIS_MODULE;
326 priv->gc.parent = dev;
327 priv->gc.label = (priv->name[0] ? priv->name
328 : dev_name(dev));
329 priv->gc.ngpio = priv->num_gpios;
330 priv->gc.names = gpio_names;
331 priv->gc.base = -1;
332 priv->gc.request = virtio_gpio_request;
333 priv->gc.direction_input = virtio_gpio_direction_input;
334 priv->gc.direction_output = virtio_gpio_direction_output;
335 priv->gc.get_direction = virtio_gpio_get_direction;
336 priv->gc.get = virtio_gpio_get;
337 priv->gc.set = virtio_gpio_set;
338 priv->gc.can_sleep = true;
339
340 priv->irq_chip.name = "virtio-gpio-irq";
341 priv->irq_chip.irq_mask = virtio_gpio_irq_mask;
342 priv->irq_chip.irq_unmask = virtio_gpio_irq_unmask;
343
344 girq = &priv->gc.irq;
345
346 priv->gc.irq.chip = &priv->irq_chip;
347 priv->gc.irq.num_parents = 1;
348 priv->gc.irq.default_type = IRQ_TYPE_NONE;
349 priv->gc.irq.handler = handle_simple_irq;
350 priv->gc.irq.parents = &priv->irq_parents;
351 priv->irq_parents = 0;
352
353 init_waitqueue_head(&priv->waitq);
354
355 priv->reply_wait = 0;
356
357 virtio_gpio_alloc_vq(priv);
358
359 return devm_gpiochip_add_data(dev, &priv->gc, priv);
360 }
361

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@xxxxxxxxxxxx

Attachment: .config.gz
Description: application/gzip