scsi: hide MODE SELECT block size change behind a quirk
This is a dangerous operation in that the block size is not protected by a lock, but it can be written concurrently if you have a multi-queue virtio-scsi HBA. Put it behind a quirk that is only enabled by the Q800 machine, since the MODE SELECT feature was added for A/UX. Cc: qemu-stable@nongnu.org Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Paolo Bonzini committed
Aug 26, 2026 at 19:53 UTC
0f410adf6b0dead1f09938054da639954bda3bc1
3 files changed
+13
-2
hw/m68k/q800.c
+2
@@ -710,12 +710,14 @@ static void q800_init(Object *obj)
710
711
static GlobalProperty hw_compat_q800[] = {
712
{ "scsi-hd", "quirk_mode_page_vendor_specific_apple", "on" },
713
+ { "scsi-hd", "quirk_mode_page_set_block_size", "on" },
714
{ "scsi-hd", "vendor", " SEAGATE" },
715
{ "scsi-hd", "product", " ST225N" },
716
{ "scsi-hd", "ver", "1.0 " },
717
{ "scsi-cd", "quirk_mode_page_apple_vendor", "on" },
718
{ "scsi-cd", "quirk_mode_sense_rom_use_dbd", "on" },
719
{ "scsi-cd", "quirk_mode_page_vendor_specific_apple", "on" },
720
+ { "scsi-cd", "quirk_mode_page_set_block_size", "on" },
721
{ "scsi-cd", "quirk_mode_page_truncated", "on" },
722
{ "scsi-cd", "vendor", "MATSHITA" },
723
{ "scsi-cd", "product", "CD-ROM CR-8005" },
hw/scsi/scsi-disk.c
+10
-2
@@ -1673,8 +1673,12 @@ static void scsi_disk_emulate_mode_select(SCSIDiskReq *r, uint8_t *inbuf)
1673
goto invalid_param;
1674
}
1675
1676
- /* Allow changing the block size */
1677
- if (bd_len) {
1676
+ /*
1677
+ * Allow changing the block size only if the quirk is enabled for it.
1678
+ * Writing s->qdev.blocksize is not thread safe!
1679
+ */
1680
+ if (bd_len && (s->quirks &
1681
+ (1 << SCSI_DISK_QUIRK_MODE_PAGE_SET_BLOCK_SIZE))) {
1682
bs = p[5] << 16 | p[6] << 8 | p[7];
1683
1684
/*
@@ -3247,6 +3251,8 @@ static const Property scsi_hd_properties[] = {
3251
DEFINE_PROP_BIT("quirk_mode_page_vendor_specific_apple", SCSIDiskState,
3252
quirks, SCSI_DISK_QUIRK_MODE_PAGE_VENDOR_SPECIFIC_APPLE,
3253
0),
3254
+ DEFINE_PROP_BIT("quirk_mode_page_set_block_size", SCSIDiskState,
3255
+ quirks, SCSI_DISK_QUIRK_MODE_PAGE_SET_BLOCK_SIZE, 0),
3256
DEFINE_BLOCK_CHS_PROPERTIES(SCSIDiskState, qdev.conf),
3257
};
3258
@@ -3352,6 +3358,8 @@ static const Property scsi_cd_properties[] = {
3358
0),
3359
DEFINE_PROP_BIT("quirk_mode_page_truncated", SCSIDiskState, quirks,
3360
SCSI_DISK_QUIRK_MODE_PAGE_TRUNCATED, 0),
3361
+ DEFINE_PROP_BIT("quirk_mode_page_set_block_size", SCSIDiskState,
3362
+ quirks, SCSI_DISK_QUIRK_MODE_PAGE_SET_BLOCK_SIZE, 0),
3363
};
3364
3365
static void scsi_cd_class_initfn(ObjectClass *klass, const void *data)
include/hw/scsi/scsi.h
+1
@@ -262,5 +262,6 @@ bool scsi_generic_pr_state_preempt(SCSIDevice *s, Error **errp);
262
#define SCSI_DISK_QUIRK_MODE_SENSE_ROM_USE_DBD 1
263
#define SCSI_DISK_QUIRK_MODE_PAGE_VENDOR_SPECIFIC_APPLE 2
264
#define SCSI_DISK_QUIRK_MODE_PAGE_TRUNCATED 3
265
+#define SCSI_DISK_QUIRK_MODE_PAGE_SET_BLOCK_SIZE 4
266
267
#endif