Skip to content

Commit ebcff9d

Browse files
arndbmstsirkin
authored andcommitted
vduse: avoid adding implicit padding
The vduse_iova_range_v2 and vduse_iotlb_entry_v2 structures are both defined in a way that adds implicit padding and is incompatible between i386 and x86_64 userspace because of the different structure alignment requirements. Building the header with -Wpadded shows these new warnings: vduse.h:305:1: error: padding struct size to alignment boundary with 4 bytes [-Werror=padded] vduse.h:374:1: error: padding struct size to alignment boundary with 4 bytes [-Werror=padded] Change the amount of padding in these two structures to align them to 64 bit words and avoid those problems. Since the v1 vduse_iotlb_entry already has an inconsistent size, do not attempt to reuse the structure but rather list the members indiviudally, with a fixed amount of padding. Fixes: 079212f ("vduse: add vq group asid support") Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Message-Id: <20260202224835.559538-1-arnd@kernel.org>
1 parent 5145b27 commit ebcff9d

2 files changed

Lines changed: 21 additions & 28 deletions

File tree

drivers/vdpa/vdpa_user/vduse_dev.c

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1301,7 +1301,7 @@ static int vduse_dev_iotlb_entry(struct vduse_dev *dev,
13011301
int r = -EINVAL;
13021302
struct vhost_iotlb_map *map;
13031303

1304-
if (entry->v1.start > entry->v1.last || entry->asid >= dev->nas)
1304+
if (entry->start > entry->last || entry->asid >= dev->nas)
13051305
return -EINVAL;
13061306

13071307
asid = array_index_nospec(entry->asid, dev->nas);
@@ -1312,18 +1312,18 @@ static int vduse_dev_iotlb_entry(struct vduse_dev *dev,
13121312

13131313
spin_lock(&dev->as[asid].domain->iotlb_lock);
13141314
map = vhost_iotlb_itree_first(dev->as[asid].domain->iotlb,
1315-
entry->v1.start, entry->v1.last);
1315+
entry->start, entry->last);
13161316
if (map) {
13171317
if (f) {
13181318
const struct vdpa_map_file *map_file;
13191319

13201320
map_file = (struct vdpa_map_file *)map->opaque;
1321-
entry->v1.offset = map_file->offset;
1321+
entry->offset = map_file->offset;
13221322
*f = get_file(map_file->file);
13231323
}
1324-
entry->v1.start = map->start;
1325-
entry->v1.last = map->last;
1326-
entry->v1.perm = map->perm;
1324+
entry->start = map->start;
1325+
entry->last = map->last;
1326+
entry->perm = map->perm;
13271327
if (capability) {
13281328
*capability = 0;
13291329

@@ -1363,14 +1363,8 @@ static long vduse_dev_ioctl(struct file *file, unsigned int cmd,
13631363
break;
13641364

13651365
ret = -EFAULT;
1366-
if (cmd == VDUSE_IOTLB_GET_FD2) {
1367-
if (copy_from_user(&entry, argp, sizeof(entry)))
1368-
break;
1369-
} else {
1370-
if (copy_from_user(&entry.v1, argp,
1371-
sizeof(entry.v1)))
1372-
break;
1373-
}
1366+
if (copy_from_user(&entry, argp, _IOC_SIZE(cmd)))
1367+
break;
13741368

13751369
ret = -EINVAL;
13761370
if (!is_mem_zero((const char *)entry.reserved,
@@ -1385,19 +1379,13 @@ static long vduse_dev_ioctl(struct file *file, unsigned int cmd,
13851379
if (!f)
13861380
break;
13871381

1388-
if (cmd == VDUSE_IOTLB_GET_FD2)
1389-
ret = copy_to_user(argp, &entry,
1390-
sizeof(entry));
1391-
else
1392-
ret = copy_to_user(argp, &entry.v1,
1393-
sizeof(entry.v1));
1394-
1382+
ret = copy_to_user(argp, &entry, _IOC_SIZE(cmd));
13951383
if (ret) {
13961384
ret = -EFAULT;
13971385
fput(f);
13981386
break;
13991387
}
1400-
ret = receive_fd(f, NULL, perm_to_file_flags(entry.v1.perm));
1388+
ret = receive_fd(f, NULL, perm_to_file_flags(entry.perm));
14011389
fput(f);
14021390
break;
14031391
}
@@ -1603,16 +1591,16 @@ static long vduse_dev_ioctl(struct file *file, unsigned int cmd,
16031591
} else if (info.asid >= dev->nas)
16041592
break;
16051593

1606-
entry.v1.start = info.start;
1607-
entry.v1.last = info.last;
1594+
entry.start = info.start;
1595+
entry.last = info.last;
16081596
entry.asid = info.asid;
16091597
ret = vduse_dev_iotlb_entry(dev, &entry, NULL,
16101598
&info.capability);
16111599
if (ret < 0)
16121600
break;
16131601

1614-
info.start = entry.v1.start;
1615-
info.last = entry.v1.last;
1602+
info.start = entry.start;
1603+
info.last = entry.last;
16161604
info.asid = entry.asid;
16171605

16181606
ret = -EFAULT;

include/uapi/linux/vduse.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,9 +293,13 @@ struct vduse_iova_info {
293293
* Structure used by VDUSE_IOTLB_GET_FD2 ioctl to find an overlapped IOVA region.
294294
*/
295295
struct vduse_iotlb_entry_v2 {
296-
struct vduse_iotlb_entry v1;
296+
__u64 offset;
297+
__u64 start;
298+
__u64 last;
299+
__u8 perm;
300+
__u8 padding[7];
297301
__u32 asid;
298-
__u32 reserved[12];
302+
__u32 reserved[11];
299303
};
300304

301305
/*
@@ -365,6 +369,7 @@ struct vduse_iova_range_v2 {
365369
__u64 start;
366370
__u64 last;
367371
__u32 asid;
372+
__u32 padding;
368373
};
369374

370375
/**

0 commit comments

Comments
 (0)