[PATCH 6.6.y v2 3/4] s390/vfio_ccw: Calculate idal length based on idaw type
Eric Farman <[email protected]>
| Newsgroups | org.kernel.vger.stable |
|---|---|
| Message-ID | <[email protected]> |
Sashiko pointed out that get_guest_idal() unconditionally calculates the length of the IDAL presuming everything is a Format-2 IDAW. The output of vfio-ccw is always Format-2, but the input can be either Format-1 (31-bit addresses) or Format-2 (64-bit addresses). As a result, the size of the guest IDAL may be incorrect and should be trimmed down. Reported-by: sashiko-bot <[email protected]> Link: https://lore.kernel.org/r/[email protected]/ Fixes: 1b676fe3d9d3 ("vfio/ccw: handle a guest Format-1 IDAL") Cc: [email protected] Reviewed-by: Matthew Rosato <[email protected]> Signed-off-by: Eric Farman <[email protected]> Signed-off-by: Christian Borntraeger <[email protected]> (cherry picked from commit 4f6fdc6e1a7fbfa36b945af33c65a417948feac0) [[email protected]: resolved merge conflict] Signed-off-by: Eric Farman <[email protected]> --- drivers/s390/cio/vfio_ccw_cp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/s390/cio/vfio_ccw_cp.c b/drivers/s390/cio/vfio_ccw_cp.c index 22bbdfa7076b..bbc57a60e27c 100644 --- a/drivers/s390/cio/vfio_ccw_cp.c +++ b/drivers/s390/cio/vfio_ccw_cp.c @@ -233,6 +233,7 @@ static void convert_ccw0_to_ccw1(struct ccw1 *source, unsigned long len) } #define idal_is_2k(_cp) (!(_cp)->orb.cmd.c64 || (_cp)->orb.cmd.i2k) +#define get_idaw_size(_cp) ((_cp)->orb.cmd.c64 ? sizeof(u64) : sizeof(u32)) /* * Helpers to operate ccwchain. @@ -522,7 +523,7 @@ static unsigned long *get_guest_idal(struct ccw1 *ccw, unsigned long *idaws; unsigned int *idaws_f1; u64 first_idaw; - int idal_len = idaw_nr * sizeof(*idaws); + int idal_len = idaw_nr * get_idaw_size(cp); int idaw_size = idal_is_2k(cp) ? PAGE_SIZE / 2 : PAGE_SIZE; int idaw_mask = ~(idaw_size - 1); int i, ret; @@ -587,7 +588,7 @@ static int ccw_count_idaws(struct ccw1 *ccw, struct vfio_device *vdev = &container_of(cp, struct vfio_ccw_private, cp)->vdev; u64 iova; - int size = cp->orb.cmd.c64 ? sizeof(u64) : sizeof(u32); + int size = get_idaw_size(cp); int ret; int bytes = 1; -- 2.55.0