diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2022-08-08 09:57:37 -0700 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2022-08-08 09:57:37 -0700 |
commit | 8a1337e60400ef54432e063164faf5043a55555d (patch) | |
tree | b41a8db1f3e8d035e45f76d85a2292eba26cc388 /hw | |
parent | 0b86b4e0dabbef15ba8d50e13bfecc582df70653 (diff) | |
parent | f6a5f380627ab2af384bf2f2940d29386dea11ff (diff) |
Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging
* Fix and tests for -readconfig
* Fixes for changeable block size
# -----BEGIN PGP SIGNATURE-----
#
# iQFIBAABCAAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmLxB6wUHHBib256aW5p
# QHJlZGhhdC5jb20ACgkQv/vSX3jHroMbgQgAmj38xh/KurUvjAwlki9OF+jIXem/
# r7eHtc6wG/dGN7CyL+EK08c2GfPIphhii3JGfLT3P/xHvHRVgYow2AELNvYSG85M
# SBQGfDsHLoKvY6Wni3AolECvtGycXkd30RtrzqdTT8iZyIhTTsikEG2hSgE+Z6Yy
# 9XGPHN9puTkkD5HYnDV1+T4+yc28F8UTVob3fv9b7LMH7mSYz7UN5Tw4zB7DjOL1
# JNTuYqW9JN1X1vIYKxYw9Y5Jb3qNjnl8y6if8bPuvrLRw94sd0ax23yEQHwtgcUj
# cYGcvZ2/X0SQg4AHTsqGJCuffKNDfHhmmA7w0Xb2DEvBvoveYOaDp3dKZQ==
# =L9FI
# -----END PGP SIGNATURE-----
# gpg: Signature made Mon 08 Aug 2022 05:55:08 AM PDT
# gpg: using RSA key F13338574B662389866C7682BFFBD25F78C7AE83
# gpg: issuer "pbonzini@redhat.com"
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [undefined]
# gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [undefined]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg: There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1
# Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83
* tag 'for-upstream' of https://gitlab.com/bonzini/qemu:
tests/qtest: add scenario for -readconfig handling
vl: remove dead code in parse_memory_options()
vl: fix [memory] section with -readconfig
scsi-disk: ensure block size is non-zero and changes limited to bits 8-15
scsi-disk: fix overflow when block size is not a multiple of BDRV_SECTOR_SIZE
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/scsi/scsi-disk.c | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index f5cdb9ad4b..efee6739f9 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -1591,7 +1591,7 @@ static void scsi_disk_emulate_mode_select(SCSIDiskReq *r, uint8_t *inbuf) int cmd = r->req.cmd.buf[0]; int len = r->req.cmd.xfer; int hdr_len = (cmd == MODE_SELECT ? 4 : 8); - int bd_len; + int bd_len, bs; int pass; if ((r->req.cmd.buf[1] & 0x11) != 0x10) { @@ -1617,9 +1617,19 @@ static void scsi_disk_emulate_mode_select(SCSIDiskReq *r, uint8_t *inbuf) } /* Allow changing the block size */ - if (bd_len && p[6] != (s->qdev.blocksize >> 8)) { - s->qdev.blocksize = p[6] << 8; - trace_scsi_disk_mode_select_set_blocksize(s->qdev.blocksize); + if (bd_len) { + bs = p[5] << 16 | p[6] << 8 | p[7]; + + /* + * Since the existing code only checks/updates bits 8-15 of the block + * size, restrict ourselves to the same requirement for now to ensure + * that a block size set by a block descriptor and then read back by + * a subsequent SCSI command will be the same + */ + if (bs && !(bs & ~0xff00) && bs != s->qdev.blocksize) { + s->qdev.blocksize = bs; + trace_scsi_disk_mode_select_set_blocksize(s->qdev.blocksize); + } } len -= bd_len; @@ -1849,7 +1859,7 @@ static void scsi_disk_emulate_write_same(SCSIDiskReq *r, uint8_t *inbuf) uint32_t nb_sectors = scsi_data_cdb_xfer(r->req.cmd.buf); WriteSameCBData *data; uint8_t *buf; - int i; + int i, l; /* Fail if PBDATA=1 or LBDATA=1 or ANCHOR=1. */ if (nb_sectors == 0 || (req->cmd.buf[1] & 0x16)) { @@ -1891,8 +1901,9 @@ static void scsi_disk_emulate_write_same(SCSIDiskReq *r, uint8_t *inbuf) data->iov.iov_len); qemu_iovec_init_external(&data->qiov, &data->iov, 1); - for (i = 0; i < data->iov.iov_len; i += s->qdev.blocksize) { - memcpy(&buf[i], inbuf, s->qdev.blocksize); + for (i = 0; i < data->iov.iov_len; i += l) { + l = MIN(s->qdev.blocksize, data->iov.iov_len - i); + memcpy(&buf[i], inbuf, l); } scsi_req_ref(&r->req); |