diff options
author | Jason J. Herne <jjherne@linux.vnet.ibm.com> | 2017-07-21 03:14:36 +0200 |
---|---|---|
committer | Cornelia Huck <cohuck@redhat.com> | 2017-07-24 09:54:37 +0200 |
commit | c389377c01bf2d6e2a178e86aef8535931bfbd75 (patch) | |
tree | 0d8a78e41190e41a9d38ca16b114b351abaea7ae /drivers/s390/cio/vfio_ccw_cp.c | |
parent | 97ca7bfc19605bc08e9183441b8b8545e84032d6 (diff) | |
download | linux-c389377c01bf2d6e2a178e86aef8535931bfbd75.tar.gz linux-c389377c01bf2d6e2a178e86aef8535931bfbd75.tar.bz2 linux-c389377c01bf2d6e2a178e86aef8535931bfbd75.zip |
vfio: ccw: fix bad ptr math for TIC cda translation
When we are translating channel data addresses from guest to host
address space for TIC instructions we are getting incorrect
addresses because of a pointer arithmetic error.
We currently calculate the offset of the TIC's cda from the start
of the channel program chain (ccw->cda - ccw_head). We then add
that to the address of the ccw chain in host memory (iter->ch_ccw).
The problem is that iter->ch_ccw is a pointer to struct ccw1 so
when we increment it we are actually incrementing by the size of
struct ccw1 which is 8 bytes. The intent was to increment by
n-bytes, not n*8.
The fix: cast iter->ch_ccw to char* so it will be incremented by
n*1.
Reviewed-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
Signed-off-by: Jason J. Herne <jjherne@linux.vnet.ibm.com>
Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
Message-Id: <20170721011436.76112-1-bjsdjshi@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Diffstat (limited to 'drivers/s390/cio/vfio_ccw_cp.c')
-rw-r--r-- | drivers/s390/cio/vfio_ccw_cp.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/s390/cio/vfio_ccw_cp.c b/drivers/s390/cio/vfio_ccw_cp.c index ba6ac83a6c25..5ccfdc80d0ec 100644 --- a/drivers/s390/cio/vfio_ccw_cp.c +++ b/drivers/s390/cio/vfio_ccw_cp.c @@ -481,7 +481,7 @@ static int ccwchain_fetch_tic(struct ccwchain *chain, ccw_tail = ccw_head + (iter->ch_len - 1) * sizeof(struct ccw1); if ((ccw_head <= ccw->cda) && (ccw->cda <= ccw_tail)) { - ccw->cda = (__u32) (addr_t) (iter->ch_ccw + + ccw->cda = (__u32) (addr_t) (((char *)iter->ch_ccw) + (ccw->cda - ccw_head)); return 0; } |