* [PATCH v8 0/8] Add Qemu to SeaBIOS LCHS interface
@ 2019-10-16 16:41 Sam Eiderman
2019-10-16 16:41 ` [PATCH v8 1/8] block: Refactor macros - fix tabbing Sam Eiderman
` (10 more replies)
0 siblings, 11 replies; 18+ messages in thread
From: Sam Eiderman @ 2019-10-16 16:41 UTC (permalink / raw)
To: qemu-devel
Cc: arbel.moshe, karl.heubaum, kevin, kraxel, kwolf, liran.alon,
qemu-block, sameid, seabios, lersek, philmd, jsnow
v1:
Non-standard logical geometries break under QEMU.
A virtual disk which contains an operating system which depends on
logical geometries (consistent values being reported from BIOS INT13
AH=08) will most likely break under QEMU/SeaBIOS if it has non-standard
logical geometries - for example 56 SPT (sectors per track).
No matter what QEMU will guess - SeaBIOS, for large enough disks - will
use LBA translation, which will report 63 SPT instead.
In addition we can not enforce SeaBIOS to rely on phyiscal geometries at
all. A virtio-blk-pci virtual disk with 255 phyiscal heads can not
report more than 16 physical heads when moved to an IDE controller, the
ATA spec allows a maximum of 16 heads - this is an artifact of
virtualization.
By supplying the logical geometies directly we are able to support such
"exotic" disks.
We will use fw_cfg to do just that.
v2:
Fix missing parenthesis check in
"hd-geo-test: Add tests for lchs override"
v3:
* Rename fw_cfg key to "bios-geometry".
* Remove "extendible" interface.
* Add cpu_to_le32 fix as Laszlo suggested or big endian hosts
* Fix last qtest commit - automatic docker tester for some reason does not have qemu-img set
v4:
* Change fw_cfg interface from mixed textual/binary to textual only
v5:
* Fix line > 80 chars in tests/hd-geo-test.c
v6:
* Small fixes for issues pointed by Max
* (&conf->conf)->lcyls to conf->conf.lcyls and so on
* Remove scsi_unrealize from everything other than scsi-hd
* Add proper include to sysemu.h
* scsi_device_unrealize() after scsi_device_purge_requests()
v7:
* Adapted last commit (tests) to changes in qtest
v8:
* Fixed BE issue with tests by using qfw_cfg_get_file() instead of
read_fw_cfg_file(), thanks Laszlo.
* Removed incorrect comment in 7/8.
Sam Eiderman (8):
block: Refactor macros - fix tabbing
block: Support providing LCHS from user
bootdevice: Add interface to gather LCHS
scsi: Propagate unrealize() callback to scsi-hd
bootdevice: Gather LCHS from all relevant devices
bootdevice: Refactor get_boot_devices_list
bootdevice: FW_CFG interface for LCHS values
hd-geo-test: Add tests for lchs override
bootdevice.c | 147 +++++++++--
hw/block/virtio-blk.c | 6 +
hw/ide/qdev.c | 7 +-
hw/nvram/fw_cfg.c | 14 +-
hw/scsi/scsi-bus.c | 16 ++
hw/scsi/scsi-disk.c | 12 +
include/hw/block/block.h | 22 +-
include/hw/scsi/scsi.h | 1 +
include/sysemu/sysemu.h | 4 +
tests/Makefile.include | 2 +-
tests/hd-geo-test.c | 551 +++++++++++++++++++++++++++++++++++++++
11 files changed, 741 insertions(+), 41 deletions(-)
--
2.23.0.700.g56cf767bdb-goog
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v8 1/8] block: Refactor macros - fix tabbing
2019-10-16 16:41 [PATCH v8 0/8] Add Qemu to SeaBIOS LCHS interface Sam Eiderman
@ 2019-10-16 16:41 ` Sam Eiderman
2019-10-16 16:41 ` [PATCH v8 1/1] hd-geo-test: Add tests for lchs override Sam Eiderman
` (9 subsequent siblings)
10 siblings, 0 replies; 18+ messages in thread
From: Sam Eiderman @ 2019-10-16 16:41 UTC (permalink / raw)
To: qemu-devel
Cc: arbel.moshe, karl.heubaum, kevin, kraxel, kwolf, liran.alon,
qemu-block, sameid, seabios, lersek, philmd, jsnow, Sam Eiderman
From: Sam Eiderman <shmuel.eiderman@oracle.com>
Fixing tabbing in block related macros.
Reviewed-by: Karl Heubaum <karl.heubaum@oracle.com>
Reviewed-by: Arbel Moshe <arbel.moshe@oracle.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Sam Eiderman <shmuel.eiderman@oracle.com>
Signed-off-by: Sam Eiderman <sameid@google.com>
---
hw/ide/qdev.c | 2 +-
include/hw/block/block.h | 16 ++++++++--------
2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 6fba6b62b8..6dd219944f 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -290,7 +290,7 @@ static void ide_drive_realize(IDEDevice *dev, Error **errp)
DEFINE_BLOCK_PROPERTIES(IDEDrive, dev.conf), \
DEFINE_BLOCK_ERROR_PROPERTIES(IDEDrive, dev.conf), \
DEFINE_PROP_STRING("ver", IDEDrive, dev.version), \
- DEFINE_PROP_UINT64("wwn", IDEDrive, dev.wwn, 0), \
+ DEFINE_PROP_UINT64("wwn", IDEDrive, dev.wwn, 0), \
DEFINE_PROP_STRING("serial", IDEDrive, dev.serial),\
DEFINE_PROP_STRING("model", IDEDrive, dev.model)
diff --git a/include/hw/block/block.h b/include/hw/block/block.h
index 607539057a..fd55a30bca 100644
--- a/include/hw/block/block.h
+++ b/include/hw/block/block.h
@@ -50,21 +50,21 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
_conf.logical_block_size), \
DEFINE_PROP_BLOCKSIZE("physical_block_size", _state, \
_conf.physical_block_size), \
- DEFINE_PROP_UINT16("min_io_size", _state, _conf.min_io_size, 0), \
+ DEFINE_PROP_UINT16("min_io_size", _state, _conf.min_io_size, 0), \
DEFINE_PROP_UINT32("opt_io_size", _state, _conf.opt_io_size, 0), \
- DEFINE_PROP_UINT32("discard_granularity", _state, \
- _conf.discard_granularity, -1), \
- DEFINE_PROP_ON_OFF_AUTO("write-cache", _state, _conf.wce, \
- ON_OFF_AUTO_AUTO), \
+ DEFINE_PROP_UINT32("discard_granularity", _state, \
+ _conf.discard_granularity, -1), \
+ DEFINE_PROP_ON_OFF_AUTO("write-cache", _state, _conf.wce, \
+ ON_OFF_AUTO_AUTO), \
DEFINE_PROP_BOOL("share-rw", _state, _conf.share_rw, false)
#define DEFINE_BLOCK_PROPERTIES(_state, _conf) \
DEFINE_PROP_DRIVE("drive", _state, _conf.blk), \
DEFINE_BLOCK_PROPERTIES_BASE(_state, _conf)
-#define DEFINE_BLOCK_CHS_PROPERTIES(_state, _conf) \
- DEFINE_PROP_UINT32("cyls", _state, _conf.cyls, 0), \
- DEFINE_PROP_UINT32("heads", _state, _conf.heads, 0), \
+#define DEFINE_BLOCK_CHS_PROPERTIES(_state, _conf) \
+ DEFINE_PROP_UINT32("cyls", _state, _conf.cyls, 0), \
+ DEFINE_PROP_UINT32("heads", _state, _conf.heads, 0), \
DEFINE_PROP_UINT32("secs", _state, _conf.secs, 0)
#define DEFINE_BLOCK_ERROR_PROPERTIES(_state, _conf) \
--
2.23.0.700.g56cf767bdb-goog
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v8 1/1] hd-geo-test: Add tests for lchs override
2019-10-16 16:41 [PATCH v8 0/8] Add Qemu to SeaBIOS LCHS interface Sam Eiderman
2019-10-16 16:41 ` [PATCH v8 1/8] block: Refactor macros - fix tabbing Sam Eiderman
@ 2019-10-16 16:41 ` Sam Eiderman
2019-10-16 16:41 ` [PATCH v8 2/8] block: Support providing LCHS from user Sam Eiderman
` (8 subsequent siblings)
10 siblings, 0 replies; 18+ messages in thread
From: Sam Eiderman @ 2019-10-16 16:41 UTC (permalink / raw)
To: qemu-devel
Cc: arbel.moshe, karl.heubaum, kevin, kraxel, kwolf, liran.alon,
qemu-block, sameid, seabios, lersek, philmd, jsnow, Sam Eiderman
From: Sam Eiderman <shmuel.eiderman@oracle.com>
Add QTest tests to check the logical geometry override option.
The tests in hd-geo-test are out of date - they only test IDE and do not
test interesting MBRs.
Creating qcow2 disks with specific size and MBR layout is currently
unused - we only use a default empty MBR.
Reviewed-by: Karl Heubaum <karl.heubaum@oracle.com>
Reviewed-by: Arbel Moshe <arbel.moshe@oracle.com>
Signed-off-by: Sam Eiderman <shmuel.eiderman@oracle.com>
Signed-off-by: Sam Eiderman <sameid@google.com>
---
tests/Makefile.include | 2 +-
tests/hd-geo-test.c | 551 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 552 insertions(+), 1 deletion(-)
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 3543451ed3..6941ae7c77 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -780,7 +780,7 @@ tests/ide-test$(EXESUF): tests/ide-test.o $(libqos-pc-obj-y)
tests/ahci-test$(EXESUF): tests/ahci-test.o $(libqos-pc-obj-y) qemu-img$(EXESUF)
tests/ipmi-kcs-test$(EXESUF): tests/ipmi-kcs-test.o
tests/ipmi-bt-test$(EXESUF): tests/ipmi-bt-test.o
-tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o
+tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o $(libqos-obj-y)
tests/boot-order-test$(EXESUF): tests/boot-order-test.o $(libqos-obj-y)
tests/boot-serial-test$(EXESUF): tests/boot-serial-test.o $(libqos-obj-y)
tests/bios-tables-test$(EXESUF): tests/bios-tables-test.o \
diff --git a/tests/hd-geo-test.c b/tests/hd-geo-test.c
index 62eb624726..7e86c5416c 100644
--- a/tests/hd-geo-test.c
+++ b/tests/hd-geo-test.c
@@ -17,7 +17,12 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
+#include "qemu/bswap.h"
+#include "qapi/qmp/qlist.h"
#include "libqtest.h"
+#include "libqos/fw_cfg.h"
+#include "libqos/libqos.h"
+#include "standard-headers/linux/qemu_fw_cfg.h"
#define ARGV_SIZE 256
@@ -388,6 +393,537 @@ static void test_ide_drive_cd_0(void)
qtest_quit(qts);
}
+typedef struct {
+ bool active;
+ uint32_t head;
+ uint32_t sector;
+ uint32_t cyl;
+ uint32_t end_head;
+ uint32_t end_sector;
+ uint32_t end_cyl;
+ uint32_t start_sect;
+ uint32_t nr_sects;
+} MBRpartitions[4];
+
+static MBRpartitions empty_mbr = { {false, 0, 0, 0, 0, 0, 0, 0, 0},
+ {false, 0, 0, 0, 0, 0, 0, 0, 0},
+ {false, 0, 0, 0, 0, 0, 0, 0, 0},
+ {false, 0, 0, 0, 0, 0, 0, 0, 0} };
+
+static char *create_qcow2_with_mbr(MBRpartitions mbr, uint64_t sectors)
+{
+ const char *template = "/tmp/qtest.XXXXXX";
+ char *raw_path = strdup(template);
+ char *qcow2_path = strdup(template);
+ char cmd[100 + 2 * PATH_MAX];
+ uint8_t buf[512];
+ int i, ret, fd, offset;
+ uint64_t qcow2_size = sectors * 512;
+ uint8_t status, parttype, head, sector, cyl;
+ char *qemu_img_path;
+ char *qemu_img_abs_path;
+
+ offset = 0xbe;
+
+ for (i = 0; i < 4; i++) {
+ status = mbr[i].active ? 0x80 : 0x00;
+ g_assert(mbr[i].head < 256);
+ g_assert(mbr[i].sector < 64);
+ g_assert(mbr[i].cyl < 1024);
+ head = mbr[i].head;
+ sector = mbr[i].sector + ((mbr[i].cyl & 0x300) >> 2);
+ cyl = mbr[i].cyl & 0xff;
+
+ buf[offset + 0x0] = status;
+ buf[offset + 0x1] = head;
+ buf[offset + 0x2] = sector;
+ buf[offset + 0x3] = cyl;
+
+ parttype = 0;
+ g_assert(mbr[i].end_head < 256);
+ g_assert(mbr[i].end_sector < 64);
+ g_assert(mbr[i].end_cyl < 1024);
+ head = mbr[i].end_head;
+ sector = mbr[i].end_sector + ((mbr[i].end_cyl & 0x300) >> 2);
+ cyl = mbr[i].end_cyl & 0xff;
+
+ buf[offset + 0x4] = parttype;
+ buf[offset + 0x5] = head;
+ buf[offset + 0x6] = sector;
+ buf[offset + 0x7] = cyl;
+
+ (*(uint32_t *)&buf[offset + 0x8]) = cpu_to_le32(mbr[i].start_sect);
+ (*(uint32_t *)&buf[offset + 0xc]) = cpu_to_le32(mbr[i].nr_sects);
+
+ offset += 0x10;
+ }
+
+ fd = mkstemp(raw_path);
+ g_assert(fd);
+ close(fd);
+
+ fd = open(raw_path, O_WRONLY);
+ g_assert(fd >= 0);
+ ret = write(fd, buf, sizeof(buf));
+ g_assert(ret == sizeof(buf));
+ close(fd);
+
+ fd = mkstemp(qcow2_path);
+ g_assert(fd);
+ close(fd);
+
+ qemu_img_path = getenv("QTEST_QEMU_IMG");
+ g_assert(qemu_img_path);
+ qemu_img_abs_path = realpath(qemu_img_path, NULL);
+ g_assert(qemu_img_abs_path);
+
+ ret = snprintf(cmd, sizeof(cmd),
+ "%s convert -f raw -O qcow2 %s %s > /dev/null",
+ qemu_img_abs_path,
+ raw_path, qcow2_path);
+ g_assert((0 < ret) && (ret <= sizeof(cmd)));
+ ret = system(cmd);
+ g_assert(ret == 0);
+
+ ret = snprintf(cmd, sizeof(cmd),
+ "%s resize %s %" PRIu64 " > /dev/null",
+ qemu_img_abs_path,
+ qcow2_path, qcow2_size);
+ g_assert((0 < ret) && (ret <= sizeof(cmd)));
+ ret = system(cmd);
+ g_assert(ret == 0);
+
+ free(qemu_img_abs_path);
+
+ unlink(raw_path);
+ free(raw_path);
+
+ return qcow2_path;
+}
+
+#define BIOS_GEOMETRY_MAX_SIZE 10000
+
+typedef struct {
+ uint32_t c;
+ uint32_t h;
+ uint32_t s;
+} CHS;
+
+typedef struct {
+ const char *dev_path;
+ CHS chs;
+} CHSResult;
+
+static void read_bootdevices(QFWCFG *fw_cfg, CHSResult expected[])
+{
+ char *buf = g_malloc0(BIOS_GEOMETRY_MAX_SIZE);
+ char *cur;
+ GList *results = NULL, *cur_result;
+ CHSResult *r;
+ int i;
+ int res;
+ bool found;
+
+ qfw_cfg_get_file(fw_cfg, "bios-geometry", buf, BIOS_GEOMETRY_MAX_SIZE);
+
+ for (cur = buf; *cur; cur++) {
+ if (*cur == '\n') {
+ *cur = '\0';
+ }
+ }
+ cur = buf;
+
+ while (strlen(cur)) {
+
+ r = g_malloc0(sizeof(*r));
+ r->dev_path = g_malloc0(strlen(cur) + 1);
+ res = sscanf(cur, "%s %" PRIu32 " %" PRIu32 " %" PRIu32,
+ (char *)r->dev_path,
+ &(r->chs.c), &(r->chs.h), &(r->chs.s));
+
+ g_assert(res == 4);
+
+ results = g_list_prepend(results, r);
+
+ cur += strlen(cur) + 1;
+ }
+
+ i = 0;
+
+ while (expected[i].dev_path) {
+ found = false;
+ cur_result = results;
+ while (cur_result) {
+ r = cur_result->data;
+ if (!strcmp(r->dev_path, expected[i].dev_path) &&
+ !memcmp(&(r->chs), &(expected[i].chs), sizeof(r->chs))) {
+ found = true;
+ break;
+ }
+ cur_result = g_list_next(cur_result);
+ }
+ g_assert(found);
+ g_free((char *)((CHSResult *)cur_result->data)->dev_path);
+ g_free(cur_result->data);
+ results = g_list_delete_link(results, cur_result);
+ i++;
+ }
+
+ g_assert(results == NULL);
+
+ g_free(buf);
+}
+
+#define MAX_DRIVES 30
+
+typedef struct {
+ char **argv;
+ int argc;
+ char **drives;
+ int n_drives;
+ int n_scsi_disks;
+ int n_scsi_controllers;
+ int n_virtio_disks;
+} TestArgs;
+
+static TestArgs *create_args(void)
+{
+ TestArgs *args = g_malloc0(sizeof(*args));
+ args->argv = g_new0(char *, ARGV_SIZE);
+ args->argc = append_arg(args->argc, args->argv,
+ ARGV_SIZE, g_strdup("-nodefaults"));
+ args->drives = g_new0(char *, MAX_DRIVES);
+ return args;
+}
+
+static void add_drive_with_mbr(TestArgs *args,
+ MBRpartitions mbr, uint64_t sectors)
+{
+ char *img_file_name;
+ char part[300];
+ int ret;
+
+ g_assert(args->n_drives < MAX_DRIVES);
+
+ img_file_name = create_qcow2_with_mbr(mbr, sectors);
+
+ args->drives[args->n_drives] = img_file_name;
+ ret = snprintf(part, sizeof(part),
+ "-drive file=%s,if=none,format=qcow2,id=disk%d",
+ img_file_name, args->n_drives);
+ g_assert((0 < ret) && (ret <= sizeof(part)));
+ args->argc = append_arg(args->argc, args->argv, ARGV_SIZE, g_strdup(part));
+ args->n_drives++;
+}
+
+static void add_ide_disk(TestArgs *args,
+ int drive_idx, int bus, int unit, int c, int h, int s)
+{
+ char part[300];
+ int ret;
+
+ ret = snprintf(part, sizeof(part),
+ "-device ide-hd,drive=disk%d,bus=ide.%d,unit=%d,"
+ "lcyls=%d,lheads=%d,lsecs=%d",
+ drive_idx, bus, unit, c, h, s);
+ g_assert((0 < ret) && (ret <= sizeof(part)));
+ args->argc = append_arg(args->argc, args->argv, ARGV_SIZE, g_strdup(part));
+}
+
+static void add_scsi_controller(TestArgs *args,
+ const char *type,
+ const char *bus,
+ int addr)
+{
+ char part[300];
+ int ret;
+
+ ret = snprintf(part, sizeof(part),
+ "-device %s,id=scsi%d,bus=%s,addr=%d",
+ type, args->n_scsi_controllers, bus, addr);
+ g_assert((0 < ret) && (ret <= sizeof(part)));
+ args->argc = append_arg(args->argc, args->argv, ARGV_SIZE, g_strdup(part));
+ args->n_scsi_controllers++;
+}
+
+static void add_scsi_disk(TestArgs *args,
+ int drive_idx, int bus,
+ int channel, int scsi_id, int lun,
+ int c, int h, int s)
+{
+ char part[300];
+ int ret;
+
+ ret = snprintf(part, sizeof(part),
+ "-device scsi-hd,id=scsi-disk%d,drive=disk%d,"
+ "bus=scsi%d.0,"
+ "channel=%d,scsi-id=%d,lun=%d,"
+ "lcyls=%d,lheads=%d,lsecs=%d",
+ args->n_scsi_disks, drive_idx, bus, channel, scsi_id, lun,
+ c, h, s);
+ g_assert((0 < ret) && (ret <= sizeof(part)));
+ args->argc = append_arg(args->argc, args->argv, ARGV_SIZE, g_strdup(part));
+ args->n_scsi_disks++;
+}
+
+static void add_virtio_disk(TestArgs *args,
+ int drive_idx, const char *bus, int addr,
+ int c, int h, int s)
+{
+ char part[300];
+ int ret;
+
+ ret = snprintf(part, sizeof(part),
+ "-device virtio-blk-pci,id=virtio-disk%d,"
+ "drive=disk%d,bus=%s,addr=%d,"
+ "lcyls=%d,lheads=%d,lsecs=%d",
+ args->n_virtio_disks, drive_idx, bus, addr, c, h, s);
+ g_assert((0 < ret) && (ret <= sizeof(part)));
+ args->argc = append_arg(args->argc, args->argv, ARGV_SIZE, g_strdup(part));
+ args->n_virtio_disks++;
+}
+
+static void test_override(TestArgs *args, CHSResult expected[])
+{
+ QTestState *qts;
+ char *joined_args;
+ QFWCFG *fw_cfg;
+ int i;
+
+ joined_args = g_strjoinv(" ", args->argv);
+
+ qts = qtest_init(joined_args);
+ fw_cfg = pc_fw_cfg_init(qts);
+
+ read_bootdevices(fw_cfg, expected);
+
+ g_free(joined_args);
+ qtest_quit(qts);
+
+ g_free(fw_cfg);
+
+ for (i = 0; i < args->n_drives; i++) {
+ unlink(args->drives[i]);
+ free(args->drives[i]);
+ }
+ g_free(args->drives);
+ g_strfreev(args->argv);
+ g_free(args);
+}
+
+static void test_override_ide(void)
+{
+ TestArgs *args = create_args();
+ CHSResult expected[] = {
+ {"/pci@i0cf8/ide@1,1/drive@0/disk@0", {10000, 120, 30} },
+ {"/pci@i0cf8/ide@1,1/drive@0/disk@1", {9000, 120, 30} },
+ {"/pci@i0cf8/ide@1,1/drive@1/disk@0", {0, 1, 1} },
+ {"/pci@i0cf8/ide@1,1/drive@1/disk@1", {1, 0, 0} },
+ {NULL, {0, 0, 0} }
+ };
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_ide_disk(args, 0, 0, 0, 10000, 120, 30);
+ add_ide_disk(args, 1, 0, 1, 9000, 120, 30);
+ add_ide_disk(args, 2, 1, 0, 0, 1, 1);
+ add_ide_disk(args, 3, 1, 1, 1, 0, 0);
+ test_override(args, expected);
+}
+
+static void test_override_scsi(void)
+{
+ TestArgs *args = create_args();
+ CHSResult expected[] = {
+ {"/pci@i0cf8/scsi@3/channel@0/disk@0,0", {10000, 120, 30} },
+ {"/pci@i0cf8/scsi@3/channel@0/disk@1,0", {9000, 120, 30} },
+ {"/pci@i0cf8/scsi@3/channel@0/disk@2,0", {1, 0, 0} },
+ {"/pci@i0cf8/scsi@3/channel@0/disk@3,0", {0, 1, 0} },
+ {NULL, {0, 0, 0} }
+ };
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_scsi_controller(args, "lsi53c895a", "pci.0", 3);
+ add_scsi_disk(args, 0, 0, 0, 0, 0, 10000, 120, 30);
+ add_scsi_disk(args, 1, 0, 0, 1, 0, 9000, 120, 30);
+ add_scsi_disk(args, 2, 0, 0, 2, 0, 1, 0, 0);
+ add_scsi_disk(args, 3, 0, 0, 3, 0, 0, 1, 0);
+ test_override(args, expected);
+}
+
+static void test_override_scsi_2_controllers(void)
+{
+ TestArgs *args = create_args();
+ CHSResult expected[] = {
+ {"/pci@i0cf8/scsi@3/channel@0/disk@0,0", {10000, 120, 30} },
+ {"/pci@i0cf8/scsi@3/channel@0/disk@1,0", {9000, 120, 30} },
+ {"/pci@i0cf8/scsi@4/channel@0/disk@0,1", {1, 0, 0} },
+ {"/pci@i0cf8/scsi@4/channel@0/disk@1,2", {0, 1, 0} },
+ {NULL, {0, 0, 0} }
+ };
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_scsi_controller(args, "lsi53c895a", "pci.0", 3);
+ add_scsi_controller(args, "virtio-scsi-pci", "pci.0", 4);
+ add_scsi_disk(args, 0, 0, 0, 0, 0, 10000, 120, 30);
+ add_scsi_disk(args, 1, 0, 0, 1, 0, 9000, 120, 30);
+ add_scsi_disk(args, 2, 1, 0, 0, 1, 1, 0, 0);
+ add_scsi_disk(args, 3, 1, 0, 1, 2, 0, 1, 0);
+ test_override(args, expected);
+}
+
+static void test_override_virtio_blk(void)
+{
+ TestArgs *args = create_args();
+ CHSResult expected[] = {
+ {"/pci@i0cf8/scsi@3/disk@0,0", {10000, 120, 30} },
+ {"/pci@i0cf8/scsi@4/disk@0,0", {9000, 120, 30} },
+ {NULL, {0, 0, 0} }
+ };
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_virtio_disk(args, 0, "pci.0", 3, 10000, 120, 30);
+ add_virtio_disk(args, 1, "pci.0", 4, 9000, 120, 30);
+ test_override(args, expected);
+}
+
+static void test_override_zero_chs(void)
+{
+ TestArgs *args = create_args();
+ CHSResult expected[] = {
+ {NULL, {0, 0, 0} }
+ };
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_ide_disk(args, 0, 1, 1, 0, 0, 0);
+ test_override(args, expected);
+}
+
+static void test_override_scsi_hot_unplug(void)
+{
+ QTestState *qts;
+ char *joined_args;
+ QFWCFG *fw_cfg;
+ QDict *response;
+ int i;
+ TestArgs *args = create_args();
+ CHSResult expected[] = {
+ {"/pci@i0cf8/scsi@2/channel@0/disk@0,0", {10000, 120, 30} },
+ {"/pci@i0cf8/scsi@2/channel@0/disk@1,0", {20, 20, 20} },
+ {NULL, {0, 0, 0} }
+ };
+ CHSResult expected2[] = {
+ {"/pci@i0cf8/scsi@2/channel@0/disk@1,0", {20, 20, 20} },
+ {NULL, {0, 0, 0} }
+ };
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_scsi_controller(args, "virtio-scsi-pci", "pci.0", 2);
+ add_scsi_disk(args, 0, 0, 0, 0, 0, 10000, 120, 30);
+ add_scsi_disk(args, 1, 0, 0, 1, 0, 20, 20, 20);
+
+ joined_args = g_strjoinv(" ", args->argv);
+
+ qts = qtest_init(joined_args);
+ fw_cfg = pc_fw_cfg_init(qts);
+
+ read_bootdevices(fw_cfg, expected);
+
+ /* unplug device an restart */
+ response = qtest_qmp(qts,
+ "{ 'execute': 'device_del',"
+ " 'arguments': {'id': 'scsi-disk0' }}");
+ g_assert(response);
+ g_assert(!qdict_haskey(response, "error"));
+ qobject_unref(response);
+ response = qtest_qmp(qts,
+ "{ 'execute': 'system_reset', 'arguments': { }}");
+ g_assert(response);
+ g_assert(!qdict_haskey(response, "error"));
+ qobject_unref(response);
+
+ qtest_qmp_eventwait(qts, "RESET");
+
+ read_bootdevices(fw_cfg, expected2);
+
+ g_free(joined_args);
+ qtest_quit(qts);
+
+ g_free(fw_cfg);
+
+ for (i = 0; i < args->n_drives; i++) {
+ unlink(args->drives[i]);
+ free(args->drives[i]);
+ }
+ g_free(args->drives);
+ g_strfreev(args->argv);
+ g_free(args);
+}
+
+static void test_override_virtio_hot_unplug(void)
+{
+ QTestState *qts;
+ char *joined_args;
+ QFWCFG *fw_cfg;
+ QDict *response;
+ int i;
+ TestArgs *args = create_args();
+ CHSResult expected[] = {
+ {"/pci@i0cf8/scsi@2/disk@0,0", {10000, 120, 30} },
+ {"/pci@i0cf8/scsi@3/disk@0,0", {20, 20, 20} },
+ {NULL, {0, 0, 0} }
+ };
+ CHSResult expected2[] = {
+ {"/pci@i0cf8/scsi@3/disk@0,0", {20, 20, 20} },
+ {NULL, {0, 0, 0} }
+ };
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_virtio_disk(args, 0, "pci.0", 2, 10000, 120, 30);
+ add_virtio_disk(args, 1, "pci.0", 3, 20, 20, 20);
+
+ joined_args = g_strjoinv(" ", args->argv);
+
+ qts = qtest_init(joined_args);
+ fw_cfg = pc_fw_cfg_init(qts);
+
+ read_bootdevices(fw_cfg, expected);
+
+ /* unplug device an restart */
+ response = qtest_qmp(qts,
+ "{ 'execute': 'device_del',"
+ " 'arguments': {'id': 'virtio-disk0' }}");
+ g_assert(response);
+ g_assert(!qdict_haskey(response, "error"));
+ qobject_unref(response);
+ response = qtest_qmp(qts,
+ "{ 'execute': 'system_reset', 'arguments': { }}");
+ g_assert(response);
+ g_assert(!qdict_haskey(response, "error"));
+ qobject_unref(response);
+
+ qtest_qmp_eventwait(qts, "RESET");
+
+ read_bootdevices(fw_cfg, expected2);
+
+ g_free(joined_args);
+ qtest_quit(qts);
+
+ g_free(fw_cfg);
+
+ for (i = 0; i < args->n_drives; i++) {
+ unlink(args->drives[i]);
+ free(args->drives[i]);
+ }
+ g_free(args->drives);
+ g_strfreev(args->argv);
+ g_free(args);
+}
+
int main(int argc, char **argv)
{
Backend i;
@@ -413,6 +949,21 @@ int main(int argc, char **argv)
qtest_add_func("hd-geo/ide/device/mbr/chs", test_ide_device_mbr_chs);
qtest_add_func("hd-geo/ide/device/user/chs", test_ide_device_user_chs);
qtest_add_func("hd-geo/ide/device/user/chst", test_ide_device_user_chst);
+ if (have_qemu_img()) {
+ qtest_add_func("hd-geo/override/ide", test_override_ide);
+ qtest_add_func("hd-geo/override/scsi", test_override_scsi);
+ qtest_add_func("hd-geo/override/scsi_2_controllers",
+ test_override_scsi_2_controllers);
+ qtest_add_func("hd-geo/override/virtio_blk", test_override_virtio_blk);
+ qtest_add_func("hd-geo/override/zero_chs", test_override_zero_chs);
+ qtest_add_func("hd-geo/override/scsi_hot_unplug",
+ test_override_scsi_hot_unplug);
+ qtest_add_func("hd-geo/override/virtio_hot_unplug",
+ test_override_virtio_hot_unplug);
+ } else {
+ g_test_message("QTEST_QEMU_IMG not set or qemu-img missing; "
+ "skipping hd-geo/override/* tests");
+ }
ret = g_test_run();
--
2.23.0.700.g56cf767bdb-goog
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v8 2/8] block: Support providing LCHS from user
2019-10-16 16:41 [PATCH v8 0/8] Add Qemu to SeaBIOS LCHS interface Sam Eiderman
2019-10-16 16:41 ` [PATCH v8 1/8] block: Refactor macros - fix tabbing Sam Eiderman
2019-10-16 16:41 ` [PATCH v8 1/1] hd-geo-test: Add tests for lchs override Sam Eiderman
@ 2019-10-16 16:41 ` Sam Eiderman
2019-10-22 10:20 ` Philippe Mathieu-Daudé
2019-10-16 16:41 ` [PATCH v8 3/8] bootdevice: Add interface to gather LCHS Sam Eiderman
` (7 subsequent siblings)
10 siblings, 1 reply; 18+ messages in thread
From: Sam Eiderman @ 2019-10-16 16:41 UTC (permalink / raw)
To: qemu-devel
Cc: arbel.moshe, karl.heubaum, kevin, kraxel, kwolf, liran.alon,
qemu-block, sameid, seabios, lersek, philmd, jsnow, Sam Eiderman
From: Sam Eiderman <shmuel.eiderman@oracle.com>
Add logical geometry variables to BlockConf.
A user can now supply "lcyls", "lheads" & "lsecs" for any HD device
that supports CHS ("cyls", "heads", "secs").
These devices include:
* ide-hd
* scsi-hd
* virtio-blk-pci
In future commits we will use the provided LCHS and pass it to the BIOS
through fw_cfg to be supplied using INT13 routines.
Reviewed-by: Karl Heubaum <karl.heubaum@oracle.com>
Reviewed-by: Arbel Moshe <arbel.moshe@oracle.com>
Signed-off-by: Sam Eiderman <shmuel.eiderman@oracle.com>
Signed-off-by: Sam Eiderman <sameid@google.com>
---
include/hw/block/block.h | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/include/hw/block/block.h b/include/hw/block/block.h
index fd55a30bca..d7246f3862 100644
--- a/include/hw/block/block.h
+++ b/include/hw/block/block.h
@@ -26,6 +26,7 @@ typedef struct BlockConf {
uint32_t discard_granularity;
/* geometry, not all devices use this */
uint32_t cyls, heads, secs;
+ uint32_t lcyls, lheads, lsecs;
OnOffAuto wce;
bool share_rw;
BlockdevOnError rerror;
@@ -65,7 +66,10 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
#define DEFINE_BLOCK_CHS_PROPERTIES(_state, _conf) \
DEFINE_PROP_UINT32("cyls", _state, _conf.cyls, 0), \
DEFINE_PROP_UINT32("heads", _state, _conf.heads, 0), \
- DEFINE_PROP_UINT32("secs", _state, _conf.secs, 0)
+ DEFINE_PROP_UINT32("secs", _state, _conf.secs, 0), \
+ DEFINE_PROP_UINT32("lcyls", _state, _conf.lcyls, 0), \
+ DEFINE_PROP_UINT32("lheads", _state, _conf.lheads, 0), \
+ DEFINE_PROP_UINT32("lsecs", _state, _conf.lsecs, 0)
#define DEFINE_BLOCK_ERROR_PROPERTIES(_state, _conf) \
DEFINE_PROP_BLOCKDEV_ON_ERROR("rerror", _state, _conf.rerror, \
--
2.23.0.700.g56cf767bdb-goog
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v8 3/8] bootdevice: Add interface to gather LCHS
2019-10-16 16:41 [PATCH v8 0/8] Add Qemu to SeaBIOS LCHS interface Sam Eiderman
` (2 preceding siblings ...)
2019-10-16 16:41 ` [PATCH v8 2/8] block: Support providing LCHS from user Sam Eiderman
@ 2019-10-16 16:41 ` Sam Eiderman
2019-10-22 10:22 ` Philippe Mathieu-Daudé
2019-10-16 16:41 ` [PATCH v8 4/8] scsi: Propagate unrealize() callback to scsi-hd Sam Eiderman
` (6 subsequent siblings)
10 siblings, 1 reply; 18+ messages in thread
From: Sam Eiderman @ 2019-10-16 16:41 UTC (permalink / raw)
To: qemu-devel
Cc: arbel.moshe, karl.heubaum, kevin, kraxel, kwolf, liran.alon,
qemu-block, sameid, seabios, lersek, philmd, jsnow, Sam Eiderman
From: Sam Eiderman <shmuel.eiderman@oracle.com>
Add an interface to provide direct logical CHS values for boot devices.
We will use this interface in the next commits.
Reviewed-by: Karl Heubaum <karl.heubaum@oracle.com>
Reviewed-by: Arbel Moshe <arbel.moshe@oracle.com>
Signed-off-by: Sam Eiderman <shmuel.eiderman@oracle.com>
Signed-off-by: Sam Eiderman <sameid@google.com>
---
bootdevice.c | 55 +++++++++++++++++++++++++++++++++++++++++
include/sysemu/sysemu.h | 3 +++
2 files changed, 58 insertions(+)
diff --git a/bootdevice.c b/bootdevice.c
index 1d225202f9..bc5e1c2de4 100644
--- a/bootdevice.c
+++ b/bootdevice.c
@@ -343,3 +343,58 @@ void device_add_bootindex_property(Object *obj, int32_t *bootindex,
/* initialize devices' bootindex property to -1 */
object_property_set_int(obj, -1, name, NULL);
}
+
+typedef struct FWLCHSEntry FWLCHSEntry;
+
+struct FWLCHSEntry {
+ QTAILQ_ENTRY(FWLCHSEntry) link;
+ DeviceState *dev;
+ char *suffix;
+ uint32_t lcyls;
+ uint32_t lheads;
+ uint32_t lsecs;
+};
+
+static QTAILQ_HEAD(, FWLCHSEntry) fw_lchs =
+ QTAILQ_HEAD_INITIALIZER(fw_lchs);
+
+void add_boot_device_lchs(DeviceState *dev, const char *suffix,
+ uint32_t lcyls, uint32_t lheads, uint32_t lsecs)
+{
+ FWLCHSEntry *node;
+
+ if (!lcyls && !lheads && !lsecs) {
+ return;
+ }
+
+ assert(dev != NULL || suffix != NULL);
+
+ node = g_malloc0(sizeof(FWLCHSEntry));
+ node->suffix = g_strdup(suffix);
+ node->dev = dev;
+ node->lcyls = lcyls;
+ node->lheads = lheads;
+ node->lsecs = lsecs;
+
+ QTAILQ_INSERT_TAIL(&fw_lchs, node, link);
+}
+
+void del_boot_device_lchs(DeviceState *dev, const char *suffix)
+{
+ FWLCHSEntry *i;
+
+ if (dev == NULL) {
+ return;
+ }
+
+ QTAILQ_FOREACH(i, &fw_lchs, link) {
+ if ((!suffix || !g_strcmp0(i->suffix, suffix)) &&
+ i->dev == dev) {
+ QTAILQ_REMOVE(&fw_lchs, i, link);
+ g_free(i->suffix);
+ g_free(i);
+
+ break;
+ }
+ }
+}
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 44f18eb739..5bc5c79cbc 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -103,6 +103,9 @@ void device_add_bootindex_property(Object *obj, int32_t *bootindex,
DeviceState *dev, Error **errp);
void restore_boot_order(void *opaque);
void validate_bootdevices(const char *devices, Error **errp);
+void add_boot_device_lchs(DeviceState *dev, const char *suffix,
+ uint32_t lcyls, uint32_t lheads, uint32_t lsecs);
+void del_boot_device_lchs(DeviceState *dev, const char *suffix);
/* handler to set the boot_device order for a specific type of MachineClass */
typedef void QEMUBootSetHandler(void *opaque, const char *boot_order,
--
2.23.0.700.g56cf767bdb-goog
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v8 4/8] scsi: Propagate unrealize() callback to scsi-hd
2019-10-16 16:41 [PATCH v8 0/8] Add Qemu to SeaBIOS LCHS interface Sam Eiderman
` (3 preceding siblings ...)
2019-10-16 16:41 ` [PATCH v8 3/8] bootdevice: Add interface to gather LCHS Sam Eiderman
@ 2019-10-16 16:41 ` Sam Eiderman
2019-10-22 10:23 ` Philippe Mathieu-Daudé
2019-10-16 16:41 ` [PATCH v8 5/8] bootdevice: Gather LCHS from all relevant devices Sam Eiderman
` (5 subsequent siblings)
10 siblings, 1 reply; 18+ messages in thread
From: Sam Eiderman @ 2019-10-16 16:41 UTC (permalink / raw)
To: qemu-devel
Cc: arbel.moshe, karl.heubaum, kevin, kraxel, kwolf, liran.alon,
qemu-block, sameid, seabios, lersek, philmd, jsnow, Sam Eiderman
From: Sam Eiderman <shmuel.eiderman@oracle.com>
We will need to add LCHS removal logic to scsi-hd's unrealize() in the
next commit.
Reviewed-by: Karl Heubaum <karl.heubaum@oracle.com>
Reviewed-by: Arbel Moshe <arbel.moshe@oracle.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Sam Eiderman <shmuel.eiderman@oracle.com>
Signed-off-by: Sam Eiderman <sameid@google.com>
---
hw/scsi/scsi-bus.c | 16 ++++++++++++++++
include/hw/scsi/scsi.h | 1 +
2 files changed, 17 insertions(+)
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index bccb7cc4c6..359d50d6d0 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -59,6 +59,14 @@ static void scsi_device_realize(SCSIDevice *s, Error **errp)
}
}
+static void scsi_device_unrealize(SCSIDevice *s, Error **errp)
+{
+ SCSIDeviceClass *sc = SCSI_DEVICE_GET_CLASS(s);
+ if (sc->unrealize) {
+ sc->unrealize(s, errp);
+ }
+}
+
int scsi_bus_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf,
void *hba_private)
{
@@ -217,12 +225,20 @@ static void scsi_qdev_realize(DeviceState *qdev, Error **errp)
static void scsi_qdev_unrealize(DeviceState *qdev, Error **errp)
{
SCSIDevice *dev = SCSI_DEVICE(qdev);
+ Error *local_err = NULL;
if (dev->vmsentry) {
qemu_del_vm_change_state_handler(dev->vmsentry);
}
scsi_device_purge_requests(dev, SENSE_CODE(NO_SENSE));
+
+ scsi_device_unrealize(dev, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
blockdev_mark_auto_del(dev->conf.blk);
}
diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
index d77a92361b..332ef602f4 100644
--- a/include/hw/scsi/scsi.h
+++ b/include/hw/scsi/scsi.h
@@ -59,6 +59,7 @@ struct SCSIRequest {
typedef struct SCSIDeviceClass {
DeviceClass parent_class;
void (*realize)(SCSIDevice *dev, Error **errp);
+ void (*unrealize)(SCSIDevice *dev, Error **errp);
int (*parse_cdb)(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf,
void *hba_private);
SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun,
--
2.23.0.700.g56cf767bdb-goog
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v8 5/8] bootdevice: Gather LCHS from all relevant devices
2019-10-16 16:41 [PATCH v8 0/8] Add Qemu to SeaBIOS LCHS interface Sam Eiderman
` (4 preceding siblings ...)
2019-10-16 16:41 ` [PATCH v8 4/8] scsi: Propagate unrealize() callback to scsi-hd Sam Eiderman
@ 2019-10-16 16:41 ` Sam Eiderman
2019-10-22 10:30 ` Philippe Mathieu-Daudé
2019-10-16 16:41 ` [PATCH v8 6/8] bootdevice: Refactor get_boot_devices_list Sam Eiderman
` (4 subsequent siblings)
10 siblings, 1 reply; 18+ messages in thread
From: Sam Eiderman @ 2019-10-16 16:41 UTC (permalink / raw)
To: qemu-devel
Cc: arbel.moshe, karl.heubaum, kevin, kraxel, kwolf, liran.alon,
qemu-block, sameid, seabios, lersek, philmd, jsnow, Sam Eiderman
From: Sam Eiderman <shmuel.eiderman@oracle.com>
Relevant devices are:
* ide-hd (and ide-cd, ide-drive)
* scsi-hd (and scsi-cd, scsi-disk, scsi-block)
* virtio-blk-pci
We do not call del_boot_device_lchs() for ide-* since we don't need to -
IDE block devices do not support unplugging.
Reviewed-by: Karl Heubaum <karl.heubaum@oracle.com>
Reviewed-by: Arbel Moshe <arbel.moshe@oracle.com>
Signed-off-by: Sam Eiderman <shmuel.eiderman@oracle.com>
Signed-off-by: Sam Eiderman <sameid@google.com>
---
hw/block/virtio-blk.c | 6 ++++++
hw/ide/qdev.c | 5 +++++
hw/scsi/scsi-disk.c | 12 ++++++++++++
3 files changed, 23 insertions(+)
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index ed2ddebd2b..c56e905f80 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -1200,6 +1200,11 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
blk_set_guest_block_size(s->blk, s->conf.conf.logical_block_size);
blk_iostatus_enable(s->blk);
+
+ add_boot_device_lchs(dev, "/disk@0,0",
+ conf->conf.lcyls,
+ conf->conf.lheads,
+ conf->conf.lsecs);
}
static void virtio_blk_device_unrealize(DeviceState *dev, Error **errp)
@@ -1207,6 +1212,7 @@ static void virtio_blk_device_unrealize(DeviceState *dev, Error **errp)
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
VirtIOBlock *s = VIRTIO_BLK(dev);
+ del_boot_device_lchs(dev, "/disk@0,0");
virtio_blk_data_plane_destroy(s->dataplane);
s->dataplane = NULL;
qemu_del_vm_change_state_handler(s->change);
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 6dd219944f..2ffd387a73 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -220,6 +220,11 @@ static void ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind, Error **errp)
add_boot_device_path(dev->conf.bootindex, &dev->qdev,
dev->unit ? "/disk@1" : "/disk@0");
+
+ add_boot_device_lchs(&dev->qdev, dev->unit ? "/disk@1" : "/disk@0",
+ dev->conf.lcyls,
+ dev->conf.lheads,
+ dev->conf.lsecs);
}
static void ide_dev_get_bootindex(Object *obj, Visitor *v, const char *name,
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 68b1675fd9..07fb5ebdf1 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -35,6 +35,7 @@
#include "hw/block/block.h"
#include "hw/qdev-properties.h"
#include "sysemu/dma.h"
+#include "sysemu/sysemu.h"
#include "qemu/cutils.h"
#include "trace.h"
@@ -2414,6 +2415,16 @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
blk_set_guest_block_size(s->qdev.conf.blk, s->qdev.blocksize);
blk_iostatus_enable(s->qdev.conf.blk);
+
+ add_boot_device_lchs(&dev->qdev, NULL,
+ dev->conf.lcyls,
+ dev->conf.lheads,
+ dev->conf.lsecs);
+}
+
+static void scsi_unrealize(SCSIDevice *dev, Error **errp)
+{
+ del_boot_device_lchs(&dev->qdev, NULL);
}
static void scsi_hd_realize(SCSIDevice *dev, Error **errp)
@@ -3018,6 +3029,7 @@ static void scsi_hd_class_initfn(ObjectClass *klass, void *data)
SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
sc->realize = scsi_hd_realize;
+ sc->unrealize = scsi_unrealize;
sc->alloc_req = scsi_new_request;
sc->unit_attention_reported = scsi_disk_unit_attention_reported;
dc->desc = "virtual SCSI disk";
--
2.23.0.700.g56cf767bdb-goog
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v8 6/8] bootdevice: Refactor get_boot_devices_list
2019-10-16 16:41 [PATCH v8 0/8] Add Qemu to SeaBIOS LCHS interface Sam Eiderman
` (5 preceding siblings ...)
2019-10-16 16:41 ` [PATCH v8 5/8] bootdevice: Gather LCHS from all relevant devices Sam Eiderman
@ 2019-10-16 16:41 ` Sam Eiderman
2019-10-22 10:32 ` Philippe Mathieu-Daudé
2019-10-16 16:41 ` [PATCH v8 7/8] bootdevice: FW_CFG interface for LCHS values Sam Eiderman
` (3 subsequent siblings)
10 siblings, 1 reply; 18+ messages in thread
From: Sam Eiderman @ 2019-10-16 16:41 UTC (permalink / raw)
To: qemu-devel
Cc: arbel.moshe, karl.heubaum, kevin, kraxel, kwolf, liran.alon,
qemu-block, sameid, seabios, lersek, philmd, jsnow, Sam Eiderman
From: Sam Eiderman <shmuel.eiderman@oracle.com>
Move device name construction to a separate function.
We will reuse this function in the following commit to pass logical CHS
parameters through fw_cfg much like we currently pass bootindex.
Reviewed-by: Karl Heubaum <karl.heubaum@oracle.com>
Reviewed-by: Arbel Moshe <arbel.moshe@oracle.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Sam Eiderman <shmuel.eiderman@oracle.com>
Signed-off-by: Sam Eiderman <sameid@google.com>
---
bootdevice.c | 61 +++++++++++++++++++++++++++++-----------------------
1 file changed, 34 insertions(+), 27 deletions(-)
diff --git a/bootdevice.c b/bootdevice.c
index bc5e1c2de4..2cf6b37c57 100644
--- a/bootdevice.c
+++ b/bootdevice.c
@@ -202,6 +202,39 @@ DeviceState *get_boot_device(uint32_t position)
return res;
}
+static char *get_boot_device_path(DeviceState *dev, bool ignore_suffixes,
+ const char *suffix)
+{
+ char *devpath = NULL, *s = NULL, *d, *bootpath;
+
+ if (dev) {
+ devpath = qdev_get_fw_dev_path(dev);
+ assert(devpath);
+ }
+
+ if (!ignore_suffixes) {
+ if (dev) {
+ d = qdev_get_own_fw_dev_path_from_handler(dev->parent_bus, dev);
+ if (d) {
+ assert(!suffix);
+ s = d;
+ } else {
+ s = g_strdup(suffix);
+ }
+ } else {
+ s = g_strdup(suffix);
+ }
+ }
+
+ bootpath = g_strdup_printf("%s%s",
+ devpath ? devpath : "",
+ s ? s : "");
+ g_free(devpath);
+ g_free(s);
+
+ return bootpath;
+}
+
/*
* This function returns null terminated string that consist of new line
* separated device paths.
@@ -218,36 +251,10 @@ char *get_boot_devices_list(size_t *size)
bool ignore_suffixes = mc->ignore_boot_device_suffixes;
QTAILQ_FOREACH(i, &fw_boot_order, link) {
- char *devpath = NULL, *suffix = NULL;
char *bootpath;
- char *d;
size_t len;
- if (i->dev) {
- devpath = qdev_get_fw_dev_path(i->dev);
- assert(devpath);
- }
-
- if (!ignore_suffixes) {
- if (i->dev) {
- d = qdev_get_own_fw_dev_path_from_handler(i->dev->parent_bus,
- i->dev);
- if (d) {
- assert(!i->suffix);
- suffix = d;
- } else {
- suffix = g_strdup(i->suffix);
- }
- } else {
- suffix = g_strdup(i->suffix);
- }
- }
-
- bootpath = g_strdup_printf("%s%s",
- devpath ? devpath : "",
- suffix ? suffix : "");
- g_free(devpath);
- g_free(suffix);
+ bootpath = get_boot_device_path(i->dev, ignore_suffixes, i->suffix);
if (total) {
list[total-1] = '\n';
--
2.23.0.700.g56cf767bdb-goog
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v8 7/8] bootdevice: FW_CFG interface for LCHS values
2019-10-16 16:41 [PATCH v8 0/8] Add Qemu to SeaBIOS LCHS interface Sam Eiderman
` (6 preceding siblings ...)
2019-10-16 16:41 ` [PATCH v8 6/8] bootdevice: Refactor get_boot_devices_list Sam Eiderman
@ 2019-10-16 16:41 ` Sam Eiderman
2019-10-22 10:35 ` Philippe Mathieu-Daudé
2019-10-16 16:41 ` [PATCH v8 8/8] hd-geo-test: Add tests for lchs override Sam Eiderman
` (2 subsequent siblings)
10 siblings, 1 reply; 18+ messages in thread
From: Sam Eiderman @ 2019-10-16 16:41 UTC (permalink / raw)
To: qemu-devel
Cc: arbel.moshe, karl.heubaum, kevin, kraxel, kwolf, liran.alon,
qemu-block, sameid, seabios, lersek, philmd, jsnow, Sam Eiderman
From: Sam Eiderman <shmuel.eiderman@oracle.com>
Using fw_cfg, supply logical CHS values directly from QEMU to the BIOS.
Non-standard logical geometries break under QEMU.
A virtual disk which contains an operating system which depends on
logical geometries (consistent values being reported from BIOS INT13
AH=08) will most likely break under QEMU/SeaBIOS if it has non-standard
logical geometries - for example 56 SPT (sectors per track).
No matter what QEMU will report - SeaBIOS, for large enough disks - will
use LBA translation, which will report 63 SPT instead.
In addition we cannot force SeaBIOS to rely on physical geometries at
all. A virtio-blk-pci virtual disk with 255 phyiscal heads cannot
report more than 16 physical heads when moved to an IDE controller,
since the ATA spec allows a maximum of 16 heads - this is an artifact of
virtualization.
By supplying the logical geometries directly we are able to support such
"exotic" disks.
We serialize this information in a similar way to the "bootorder"
interface.
The new fw_cfg entry is "bios-geometry".
Reviewed-by: Karl Heubaum <karl.heubaum@oracle.com>
Reviewed-by: Arbel Moshe <arbel.moshe@oracle.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Sam Eiderman <shmuel.eiderman@oracle.com>
Signed-off-by: Sam Eiderman <sameid@google.com>
---
bootdevice.c | 31 +++++++++++++++++++++++++++++++
hw/nvram/fw_cfg.c | 14 +++++++++++---
include/sysemu/sysemu.h | 1 +
3 files changed, 43 insertions(+), 3 deletions(-)
diff --git a/bootdevice.c b/bootdevice.c
index 2cf6b37c57..03aaffcc8d 100644
--- a/bootdevice.c
+++ b/bootdevice.c
@@ -405,3 +405,34 @@ void del_boot_device_lchs(DeviceState *dev, const char *suffix)
}
}
}
+
+char *get_boot_devices_lchs_list(size_t *size)
+{
+ FWLCHSEntry *i;
+ size_t total = 0;
+ char *list = NULL;
+
+ QTAILQ_FOREACH(i, &fw_lchs, link) {
+ char *bootpath;
+ char *chs_string;
+ size_t len;
+
+ bootpath = get_boot_device_path(i->dev, false, i->suffix);
+ chs_string = g_strdup_printf("%s %" PRIu32 " %" PRIu32 " %" PRIu32,
+ bootpath, i->lcyls, i->lheads, i->lsecs);
+
+ if (total) {
+ list[total - 1] = '\n';
+ }
+ len = strlen(chs_string) + 1;
+ list = g_realloc(list, total + len);
+ memcpy(&list[total], chs_string, len);
+ total += len;
+ g_free(chs_string);
+ g_free(bootpath);
+ }
+
+ *size = total;
+
+ return list;
+}
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index 7dc3ac378e..18aff658c0 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -920,13 +920,21 @@ void *fw_cfg_modify_file(FWCfgState *s, const char *filename,
static void fw_cfg_machine_reset(void *opaque)
{
+ MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
+ FWCfgState *s = opaque;
void *ptr;
size_t len;
- FWCfgState *s = opaque;
- char *bootindex = get_boot_devices_list(&len);
+ char *buf;
- ptr = fw_cfg_modify_file(s, "bootorder", (uint8_t *)bootindex, len);
+ buf = get_boot_devices_list(&len);
+ ptr = fw_cfg_modify_file(s, "bootorder", (uint8_t *)buf, len);
g_free(ptr);
+
+ if (!mc->legacy_fw_cfg_order) {
+ buf = get_boot_devices_lchs_list(&len);
+ ptr = fw_cfg_modify_file(s, "bios-geometry", (uint8_t *)buf, len);
+ g_free(ptr);
+ }
}
static void fw_cfg_machine_ready(struct Notifier *n, void *data)
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 5bc5c79cbc..80c57fdc4e 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -106,6 +106,7 @@ void validate_bootdevices(const char *devices, Error **errp);
void add_boot_device_lchs(DeviceState *dev, const char *suffix,
uint32_t lcyls, uint32_t lheads, uint32_t lsecs);
void del_boot_device_lchs(DeviceState *dev, const char *suffix);
+char *get_boot_devices_lchs_list(size_t *size);
/* handler to set the boot_device order for a specific type of MachineClass */
typedef void QEMUBootSetHandler(void *opaque, const char *boot_order,
--
2.23.0.700.g56cf767bdb-goog
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v8 8/8] hd-geo-test: Add tests for lchs override
2019-10-16 16:41 [PATCH v8 0/8] Add Qemu to SeaBIOS LCHS interface Sam Eiderman
` (7 preceding siblings ...)
2019-10-16 16:41 ` [PATCH v8 7/8] bootdevice: FW_CFG interface for LCHS values Sam Eiderman
@ 2019-10-16 16:41 ` Sam Eiderman
2019-10-16 20:13 ` [PATCH v8 0/8] Add Qemu to SeaBIOS LCHS interface no-reply
2019-10-21 21:02 ` John Snow
10 siblings, 0 replies; 18+ messages in thread
From: Sam Eiderman @ 2019-10-16 16:41 UTC (permalink / raw)
To: qemu-devel
Cc: arbel.moshe, karl.heubaum, kevin, kraxel, kwolf, liran.alon,
qemu-block, sameid, seabios, lersek, philmd, jsnow, Sam Eiderman
From: Sam Eiderman <shmuel.eiderman@oracle.com>
Add QTest tests to check the logical geometry override option.
The tests in hd-geo-test are out of date - they only test IDE and do not
test interesting MBRs.
Creating qcow2 disks with specific size and MBR layout is currently
unused - we only use a default empty MBR.
Reviewed-by: Karl Heubaum <karl.heubaum@oracle.com>
Reviewed-by: Arbel Moshe <arbel.moshe@oracle.com>
Signed-off-by: Sam Eiderman <shmuel.eiderman@oracle.com>
Signed-off-by: Sam Eiderman <sameid@google.com>
---
tests/Makefile.include | 2 +-
tests/hd-geo-test.c | 551 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 552 insertions(+), 1 deletion(-)
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 3543451ed3..6941ae7c77 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -780,7 +780,7 @@ tests/ide-test$(EXESUF): tests/ide-test.o $(libqos-pc-obj-y)
tests/ahci-test$(EXESUF): tests/ahci-test.o $(libqos-pc-obj-y) qemu-img$(EXESUF)
tests/ipmi-kcs-test$(EXESUF): tests/ipmi-kcs-test.o
tests/ipmi-bt-test$(EXESUF): tests/ipmi-bt-test.o
-tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o
+tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o $(libqos-obj-y)
tests/boot-order-test$(EXESUF): tests/boot-order-test.o $(libqos-obj-y)
tests/boot-serial-test$(EXESUF): tests/boot-serial-test.o $(libqos-obj-y)
tests/bios-tables-test$(EXESUF): tests/bios-tables-test.o \
diff --git a/tests/hd-geo-test.c b/tests/hd-geo-test.c
index 62eb624726..7e86c5416c 100644
--- a/tests/hd-geo-test.c
+++ b/tests/hd-geo-test.c
@@ -17,7 +17,12 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
+#include "qemu/bswap.h"
+#include "qapi/qmp/qlist.h"
#include "libqtest.h"
+#include "libqos/fw_cfg.h"
+#include "libqos/libqos.h"
+#include "standard-headers/linux/qemu_fw_cfg.h"
#define ARGV_SIZE 256
@@ -388,6 +393,537 @@ static void test_ide_drive_cd_0(void)
qtest_quit(qts);
}
+typedef struct {
+ bool active;
+ uint32_t head;
+ uint32_t sector;
+ uint32_t cyl;
+ uint32_t end_head;
+ uint32_t end_sector;
+ uint32_t end_cyl;
+ uint32_t start_sect;
+ uint32_t nr_sects;
+} MBRpartitions[4];
+
+static MBRpartitions empty_mbr = { {false, 0, 0, 0, 0, 0, 0, 0, 0},
+ {false, 0, 0, 0, 0, 0, 0, 0, 0},
+ {false, 0, 0, 0, 0, 0, 0, 0, 0},
+ {false, 0, 0, 0, 0, 0, 0, 0, 0} };
+
+static char *create_qcow2_with_mbr(MBRpartitions mbr, uint64_t sectors)
+{
+ const char *template = "/tmp/qtest.XXXXXX";
+ char *raw_path = strdup(template);
+ char *qcow2_path = strdup(template);
+ char cmd[100 + 2 * PATH_MAX];
+ uint8_t buf[512];
+ int i, ret, fd, offset;
+ uint64_t qcow2_size = sectors * 512;
+ uint8_t status, parttype, head, sector, cyl;
+ char *qemu_img_path;
+ char *qemu_img_abs_path;
+
+ offset = 0xbe;
+
+ for (i = 0; i < 4; i++) {
+ status = mbr[i].active ? 0x80 : 0x00;
+ g_assert(mbr[i].head < 256);
+ g_assert(mbr[i].sector < 64);
+ g_assert(mbr[i].cyl < 1024);
+ head = mbr[i].head;
+ sector = mbr[i].sector + ((mbr[i].cyl & 0x300) >> 2);
+ cyl = mbr[i].cyl & 0xff;
+
+ buf[offset + 0x0] = status;
+ buf[offset + 0x1] = head;
+ buf[offset + 0x2] = sector;
+ buf[offset + 0x3] = cyl;
+
+ parttype = 0;
+ g_assert(mbr[i].end_head < 256);
+ g_assert(mbr[i].end_sector < 64);
+ g_assert(mbr[i].end_cyl < 1024);
+ head = mbr[i].end_head;
+ sector = mbr[i].end_sector + ((mbr[i].end_cyl & 0x300) >> 2);
+ cyl = mbr[i].end_cyl & 0xff;
+
+ buf[offset + 0x4] = parttype;
+ buf[offset + 0x5] = head;
+ buf[offset + 0x6] = sector;
+ buf[offset + 0x7] = cyl;
+
+ (*(uint32_t *)&buf[offset + 0x8]) = cpu_to_le32(mbr[i].start_sect);
+ (*(uint32_t *)&buf[offset + 0xc]) = cpu_to_le32(mbr[i].nr_sects);
+
+ offset += 0x10;
+ }
+
+ fd = mkstemp(raw_path);
+ g_assert(fd);
+ close(fd);
+
+ fd = open(raw_path, O_WRONLY);
+ g_assert(fd >= 0);
+ ret = write(fd, buf, sizeof(buf));
+ g_assert(ret == sizeof(buf));
+ close(fd);
+
+ fd = mkstemp(qcow2_path);
+ g_assert(fd);
+ close(fd);
+
+ qemu_img_path = getenv("QTEST_QEMU_IMG");
+ g_assert(qemu_img_path);
+ qemu_img_abs_path = realpath(qemu_img_path, NULL);
+ g_assert(qemu_img_abs_path);
+
+ ret = snprintf(cmd, sizeof(cmd),
+ "%s convert -f raw -O qcow2 %s %s > /dev/null",
+ qemu_img_abs_path,
+ raw_path, qcow2_path);
+ g_assert((0 < ret) && (ret <= sizeof(cmd)));
+ ret = system(cmd);
+ g_assert(ret == 0);
+
+ ret = snprintf(cmd, sizeof(cmd),
+ "%s resize %s %" PRIu64 " > /dev/null",
+ qemu_img_abs_path,
+ qcow2_path, qcow2_size);
+ g_assert((0 < ret) && (ret <= sizeof(cmd)));
+ ret = system(cmd);
+ g_assert(ret == 0);
+
+ free(qemu_img_abs_path);
+
+ unlink(raw_path);
+ free(raw_path);
+
+ return qcow2_path;
+}
+
+#define BIOS_GEOMETRY_MAX_SIZE 10000
+
+typedef struct {
+ uint32_t c;
+ uint32_t h;
+ uint32_t s;
+} CHS;
+
+typedef struct {
+ const char *dev_path;
+ CHS chs;
+} CHSResult;
+
+static void read_bootdevices(QFWCFG *fw_cfg, CHSResult expected[])
+{
+ char *buf = g_malloc0(BIOS_GEOMETRY_MAX_SIZE);
+ char *cur;
+ GList *results = NULL, *cur_result;
+ CHSResult *r;
+ int i;
+ int res;
+ bool found;
+
+ qfw_cfg_get_file(fw_cfg, "bios-geometry", buf, BIOS_GEOMETRY_MAX_SIZE);
+
+ for (cur = buf; *cur; cur++) {
+ if (*cur == '\n') {
+ *cur = '\0';
+ }
+ }
+ cur = buf;
+
+ while (strlen(cur)) {
+
+ r = g_malloc0(sizeof(*r));
+ r->dev_path = g_malloc0(strlen(cur) + 1);
+ res = sscanf(cur, "%s %" PRIu32 " %" PRIu32 " %" PRIu32,
+ (char *)r->dev_path,
+ &(r->chs.c), &(r->chs.h), &(r->chs.s));
+
+ g_assert(res == 4);
+
+ results = g_list_prepend(results, r);
+
+ cur += strlen(cur) + 1;
+ }
+
+ i = 0;
+
+ while (expected[i].dev_path) {
+ found = false;
+ cur_result = results;
+ while (cur_result) {
+ r = cur_result->data;
+ if (!strcmp(r->dev_path, expected[i].dev_path) &&
+ !memcmp(&(r->chs), &(expected[i].chs), sizeof(r->chs))) {
+ found = true;
+ break;
+ }
+ cur_result = g_list_next(cur_result);
+ }
+ g_assert(found);
+ g_free((char *)((CHSResult *)cur_result->data)->dev_path);
+ g_free(cur_result->data);
+ results = g_list_delete_link(results, cur_result);
+ i++;
+ }
+
+ g_assert(results == NULL);
+
+ g_free(buf);
+}
+
+#define MAX_DRIVES 30
+
+typedef struct {
+ char **argv;
+ int argc;
+ char **drives;
+ int n_drives;
+ int n_scsi_disks;
+ int n_scsi_controllers;
+ int n_virtio_disks;
+} TestArgs;
+
+static TestArgs *create_args(void)
+{
+ TestArgs *args = g_malloc0(sizeof(*args));
+ args->argv = g_new0(char *, ARGV_SIZE);
+ args->argc = append_arg(args->argc, args->argv,
+ ARGV_SIZE, g_strdup("-nodefaults"));
+ args->drives = g_new0(char *, MAX_DRIVES);
+ return args;
+}
+
+static void add_drive_with_mbr(TestArgs *args,
+ MBRpartitions mbr, uint64_t sectors)
+{
+ char *img_file_name;
+ char part[300];
+ int ret;
+
+ g_assert(args->n_drives < MAX_DRIVES);
+
+ img_file_name = create_qcow2_with_mbr(mbr, sectors);
+
+ args->drives[args->n_drives] = img_file_name;
+ ret = snprintf(part, sizeof(part),
+ "-drive file=%s,if=none,format=qcow2,id=disk%d",
+ img_file_name, args->n_drives);
+ g_assert((0 < ret) && (ret <= sizeof(part)));
+ args->argc = append_arg(args->argc, args->argv, ARGV_SIZE, g_strdup(part));
+ args->n_drives++;
+}
+
+static void add_ide_disk(TestArgs *args,
+ int drive_idx, int bus, int unit, int c, int h, int s)
+{
+ char part[300];
+ int ret;
+
+ ret = snprintf(part, sizeof(part),
+ "-device ide-hd,drive=disk%d,bus=ide.%d,unit=%d,"
+ "lcyls=%d,lheads=%d,lsecs=%d",
+ drive_idx, bus, unit, c, h, s);
+ g_assert((0 < ret) && (ret <= sizeof(part)));
+ args->argc = append_arg(args->argc, args->argv, ARGV_SIZE, g_strdup(part));
+}
+
+static void add_scsi_controller(TestArgs *args,
+ const char *type,
+ const char *bus,
+ int addr)
+{
+ char part[300];
+ int ret;
+
+ ret = snprintf(part, sizeof(part),
+ "-device %s,id=scsi%d,bus=%s,addr=%d",
+ type, args->n_scsi_controllers, bus, addr);
+ g_assert((0 < ret) && (ret <= sizeof(part)));
+ args->argc = append_arg(args->argc, args->argv, ARGV_SIZE, g_strdup(part));
+ args->n_scsi_controllers++;
+}
+
+static void add_scsi_disk(TestArgs *args,
+ int drive_idx, int bus,
+ int channel, int scsi_id, int lun,
+ int c, int h, int s)
+{
+ char part[300];
+ int ret;
+
+ ret = snprintf(part, sizeof(part),
+ "-device scsi-hd,id=scsi-disk%d,drive=disk%d,"
+ "bus=scsi%d.0,"
+ "channel=%d,scsi-id=%d,lun=%d,"
+ "lcyls=%d,lheads=%d,lsecs=%d",
+ args->n_scsi_disks, drive_idx, bus, channel, scsi_id, lun,
+ c, h, s);
+ g_assert((0 < ret) && (ret <= sizeof(part)));
+ args->argc = append_arg(args->argc, args->argv, ARGV_SIZE, g_strdup(part));
+ args->n_scsi_disks++;
+}
+
+static void add_virtio_disk(TestArgs *args,
+ int drive_idx, const char *bus, int addr,
+ int c, int h, int s)
+{
+ char part[300];
+ int ret;
+
+ ret = snprintf(part, sizeof(part),
+ "-device virtio-blk-pci,id=virtio-disk%d,"
+ "drive=disk%d,bus=%s,addr=%d,"
+ "lcyls=%d,lheads=%d,lsecs=%d",
+ args->n_virtio_disks, drive_idx, bus, addr, c, h, s);
+ g_assert((0 < ret) && (ret <= sizeof(part)));
+ args->argc = append_arg(args->argc, args->argv, ARGV_SIZE, g_strdup(part));
+ args->n_virtio_disks++;
+}
+
+static void test_override(TestArgs *args, CHSResult expected[])
+{
+ QTestState *qts;
+ char *joined_args;
+ QFWCFG *fw_cfg;
+ int i;
+
+ joined_args = g_strjoinv(" ", args->argv);
+
+ qts = qtest_init(joined_args);
+ fw_cfg = pc_fw_cfg_init(qts);
+
+ read_bootdevices(fw_cfg, expected);
+
+ g_free(joined_args);
+ qtest_quit(qts);
+
+ g_free(fw_cfg);
+
+ for (i = 0; i < args->n_drives; i++) {
+ unlink(args->drives[i]);
+ free(args->drives[i]);
+ }
+ g_free(args->drives);
+ g_strfreev(args->argv);
+ g_free(args);
+}
+
+static void test_override_ide(void)
+{
+ TestArgs *args = create_args();
+ CHSResult expected[] = {
+ {"/pci@i0cf8/ide@1,1/drive@0/disk@0", {10000, 120, 30} },
+ {"/pci@i0cf8/ide@1,1/drive@0/disk@1", {9000, 120, 30} },
+ {"/pci@i0cf8/ide@1,1/drive@1/disk@0", {0, 1, 1} },
+ {"/pci@i0cf8/ide@1,1/drive@1/disk@1", {1, 0, 0} },
+ {NULL, {0, 0, 0} }
+ };
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_ide_disk(args, 0, 0, 0, 10000, 120, 30);
+ add_ide_disk(args, 1, 0, 1, 9000, 120, 30);
+ add_ide_disk(args, 2, 1, 0, 0, 1, 1);
+ add_ide_disk(args, 3, 1, 1, 1, 0, 0);
+ test_override(args, expected);
+}
+
+static void test_override_scsi(void)
+{
+ TestArgs *args = create_args();
+ CHSResult expected[] = {
+ {"/pci@i0cf8/scsi@3/channel@0/disk@0,0", {10000, 120, 30} },
+ {"/pci@i0cf8/scsi@3/channel@0/disk@1,0", {9000, 120, 30} },
+ {"/pci@i0cf8/scsi@3/channel@0/disk@2,0", {1, 0, 0} },
+ {"/pci@i0cf8/scsi@3/channel@0/disk@3,0", {0, 1, 0} },
+ {NULL, {0, 0, 0} }
+ };
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_scsi_controller(args, "lsi53c895a", "pci.0", 3);
+ add_scsi_disk(args, 0, 0, 0, 0, 0, 10000, 120, 30);
+ add_scsi_disk(args, 1, 0, 0, 1, 0, 9000, 120, 30);
+ add_scsi_disk(args, 2, 0, 0, 2, 0, 1, 0, 0);
+ add_scsi_disk(args, 3, 0, 0, 3, 0, 0, 1, 0);
+ test_override(args, expected);
+}
+
+static void test_override_scsi_2_controllers(void)
+{
+ TestArgs *args = create_args();
+ CHSResult expected[] = {
+ {"/pci@i0cf8/scsi@3/channel@0/disk@0,0", {10000, 120, 30} },
+ {"/pci@i0cf8/scsi@3/channel@0/disk@1,0", {9000, 120, 30} },
+ {"/pci@i0cf8/scsi@4/channel@0/disk@0,1", {1, 0, 0} },
+ {"/pci@i0cf8/scsi@4/channel@0/disk@1,2", {0, 1, 0} },
+ {NULL, {0, 0, 0} }
+ };
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_scsi_controller(args, "lsi53c895a", "pci.0", 3);
+ add_scsi_controller(args, "virtio-scsi-pci", "pci.0", 4);
+ add_scsi_disk(args, 0, 0, 0, 0, 0, 10000, 120, 30);
+ add_scsi_disk(args, 1, 0, 0, 1, 0, 9000, 120, 30);
+ add_scsi_disk(args, 2, 1, 0, 0, 1, 1, 0, 0);
+ add_scsi_disk(args, 3, 1, 0, 1, 2, 0, 1, 0);
+ test_override(args, expected);
+}
+
+static void test_override_virtio_blk(void)
+{
+ TestArgs *args = create_args();
+ CHSResult expected[] = {
+ {"/pci@i0cf8/scsi@3/disk@0,0", {10000, 120, 30} },
+ {"/pci@i0cf8/scsi@4/disk@0,0", {9000, 120, 30} },
+ {NULL, {0, 0, 0} }
+ };
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_virtio_disk(args, 0, "pci.0", 3, 10000, 120, 30);
+ add_virtio_disk(args, 1, "pci.0", 4, 9000, 120, 30);
+ test_override(args, expected);
+}
+
+static void test_override_zero_chs(void)
+{
+ TestArgs *args = create_args();
+ CHSResult expected[] = {
+ {NULL, {0, 0, 0} }
+ };
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_ide_disk(args, 0, 1, 1, 0, 0, 0);
+ test_override(args, expected);
+}
+
+static void test_override_scsi_hot_unplug(void)
+{
+ QTestState *qts;
+ char *joined_args;
+ QFWCFG *fw_cfg;
+ QDict *response;
+ int i;
+ TestArgs *args = create_args();
+ CHSResult expected[] = {
+ {"/pci@i0cf8/scsi@2/channel@0/disk@0,0", {10000, 120, 30} },
+ {"/pci@i0cf8/scsi@2/channel@0/disk@1,0", {20, 20, 20} },
+ {NULL, {0, 0, 0} }
+ };
+ CHSResult expected2[] = {
+ {"/pci@i0cf8/scsi@2/channel@0/disk@1,0", {20, 20, 20} },
+ {NULL, {0, 0, 0} }
+ };
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_scsi_controller(args, "virtio-scsi-pci", "pci.0", 2);
+ add_scsi_disk(args, 0, 0, 0, 0, 0, 10000, 120, 30);
+ add_scsi_disk(args, 1, 0, 0, 1, 0, 20, 20, 20);
+
+ joined_args = g_strjoinv(" ", args->argv);
+
+ qts = qtest_init(joined_args);
+ fw_cfg = pc_fw_cfg_init(qts);
+
+ read_bootdevices(fw_cfg, expected);
+
+ /* unplug device an restart */
+ response = qtest_qmp(qts,
+ "{ 'execute': 'device_del',"
+ " 'arguments': {'id': 'scsi-disk0' }}");
+ g_assert(response);
+ g_assert(!qdict_haskey(response, "error"));
+ qobject_unref(response);
+ response = qtest_qmp(qts,
+ "{ 'execute': 'system_reset', 'arguments': { }}");
+ g_assert(response);
+ g_assert(!qdict_haskey(response, "error"));
+ qobject_unref(response);
+
+ qtest_qmp_eventwait(qts, "RESET");
+
+ read_bootdevices(fw_cfg, expected2);
+
+ g_free(joined_args);
+ qtest_quit(qts);
+
+ g_free(fw_cfg);
+
+ for (i = 0; i < args->n_drives; i++) {
+ unlink(args->drives[i]);
+ free(args->drives[i]);
+ }
+ g_free(args->drives);
+ g_strfreev(args->argv);
+ g_free(args);
+}
+
+static void test_override_virtio_hot_unplug(void)
+{
+ QTestState *qts;
+ char *joined_args;
+ QFWCFG *fw_cfg;
+ QDict *response;
+ int i;
+ TestArgs *args = create_args();
+ CHSResult expected[] = {
+ {"/pci@i0cf8/scsi@2/disk@0,0", {10000, 120, 30} },
+ {"/pci@i0cf8/scsi@3/disk@0,0", {20, 20, 20} },
+ {NULL, {0, 0, 0} }
+ };
+ CHSResult expected2[] = {
+ {"/pci@i0cf8/scsi@3/disk@0,0", {20, 20, 20} },
+ {NULL, {0, 0, 0} }
+ };
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_drive_with_mbr(args, empty_mbr, 1);
+ add_virtio_disk(args, 0, "pci.0", 2, 10000, 120, 30);
+ add_virtio_disk(args, 1, "pci.0", 3, 20, 20, 20);
+
+ joined_args = g_strjoinv(" ", args->argv);
+
+ qts = qtest_init(joined_args);
+ fw_cfg = pc_fw_cfg_init(qts);
+
+ read_bootdevices(fw_cfg, expected);
+
+ /* unplug device an restart */
+ response = qtest_qmp(qts,
+ "{ 'execute': 'device_del',"
+ " 'arguments': {'id': 'virtio-disk0' }}");
+ g_assert(response);
+ g_assert(!qdict_haskey(response, "error"));
+ qobject_unref(response);
+ response = qtest_qmp(qts,
+ "{ 'execute': 'system_reset', 'arguments': { }}");
+ g_assert(response);
+ g_assert(!qdict_haskey(response, "error"));
+ qobject_unref(response);
+
+ qtest_qmp_eventwait(qts, "RESET");
+
+ read_bootdevices(fw_cfg, expected2);
+
+ g_free(joined_args);
+ qtest_quit(qts);
+
+ g_free(fw_cfg);
+
+ for (i = 0; i < args->n_drives; i++) {
+ unlink(args->drives[i]);
+ free(args->drives[i]);
+ }
+ g_free(args->drives);
+ g_strfreev(args->argv);
+ g_free(args);
+}
+
int main(int argc, char **argv)
{
Backend i;
@@ -413,6 +949,21 @@ int main(int argc, char **argv)
qtest_add_func("hd-geo/ide/device/mbr/chs", test_ide_device_mbr_chs);
qtest_add_func("hd-geo/ide/device/user/chs", test_ide_device_user_chs);
qtest_add_func("hd-geo/ide/device/user/chst", test_ide_device_user_chst);
+ if (have_qemu_img()) {
+ qtest_add_func("hd-geo/override/ide", test_override_ide);
+ qtest_add_func("hd-geo/override/scsi", test_override_scsi);
+ qtest_add_func("hd-geo/override/scsi_2_controllers",
+ test_override_scsi_2_controllers);
+ qtest_add_func("hd-geo/override/virtio_blk", test_override_virtio_blk);
+ qtest_add_func("hd-geo/override/zero_chs", test_override_zero_chs);
+ qtest_add_func("hd-geo/override/scsi_hot_unplug",
+ test_override_scsi_hot_unplug);
+ qtest_add_func("hd-geo/override/virtio_hot_unplug",
+ test_override_virtio_hot_unplug);
+ } else {
+ g_test_message("QTEST_QEMU_IMG not set or qemu-img missing; "
+ "skipping hd-geo/override/* tests");
+ }
ret = g_test_run();
--
2.23.0.700.g56cf767bdb-goog
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH v8 0/8] Add Qemu to SeaBIOS LCHS interface
2019-10-16 16:41 [PATCH v8 0/8] Add Qemu to SeaBIOS LCHS interface Sam Eiderman
` (8 preceding siblings ...)
2019-10-16 16:41 ` [PATCH v8 8/8] hd-geo-test: Add tests for lchs override Sam Eiderman
@ 2019-10-16 20:13 ` no-reply
2019-10-21 21:02 ` John Snow
10 siblings, 0 replies; 18+ messages in thread
From: no-reply @ 2019-10-16 20:13 UTC (permalink / raw)
To: sameid
Cc: kwolf, qemu-block, arbel.moshe, philmd, seabios, qemu-devel,
jsnow, kevin, liran.alon, kraxel, sameid, lersek, karl.heubaum
Patchew URL: https://patchew.org/QEMU/20191016164145.115898-1-sameid@google.com/
Hi,
This series seems to have some coding style problems. See output below for
more information:
Subject: [PATCH v8 0/8] Add Qemu to SeaBIOS LCHS interface
Type: series
Message-id: 20191016164145.115898-1-sameid@google.com
=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===
Switched to a new branch 'test'
c45edbb bootdevice: FW_CFG interface for LCHS values
729ce76 bootdevice: Refactor get_boot_devices_list
46853bd bootdevice: Gather LCHS from all relevant devices
4f9e597 scsi: Propagate unrealize() callback to scsi-hd
50179a7 bootdevice: Add interface to gather LCHS
968cf33 block: Support providing LCHS from user
ccb1747 hd-geo-test: Add tests for lchs override
538dbd3 block: Refactor macros - fix tabbing
=== OUTPUT BEGIN ===
1/8 Checking commit 538dbd328a6b (block: Refactor macros - fix tabbing)
ERROR: Macros with complex values should be enclosed in parenthesis
#57: FILE: include/hw/block/block.h:65:
+#define DEFINE_BLOCK_CHS_PROPERTIES(_state, _conf) \
+ DEFINE_PROP_UINT32("cyls", _state, _conf.cyls, 0), \
+ DEFINE_PROP_UINT32("heads", _state, _conf.heads, 0), \
DEFINE_PROP_UINT32("secs", _state, _conf.secs, 0)
total: 1 errors, 0 warnings, 37 lines checked
Patch 1/8 has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
2/8 Checking commit ccb1747f11c5 (hd-geo-test: Add tests for lchs override)
WARNING: Block comments use a leading /* on a separate line
#606: FILE: tests/hd-geo-test.c:965:
+ "skipping hd-geo/override/* tests");
total: 0 errors, 1 warnings, 578 lines checked
Patch 2/8 has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
3/8 Checking commit 968cf330ecbc (block: Support providing LCHS from user)
4/8 Checking commit 50179a7c4473 (bootdevice: Add interface to gather LCHS)
5/8 Checking commit 4f9e597a32b8 (scsi: Propagate unrealize() callback to scsi-hd)
6/8 Checking commit 46853bd0b7bf (bootdevice: Gather LCHS from all relevant devices)
7/8 Checking commit 729ce765a499 (bootdevice: Refactor get_boot_devices_list)
8/8 Checking commit c45edbb64fde (bootdevice: FW_CFG interface for LCHS values)
=== OUTPUT END ===
Test command exited with code: 1
The full log is available at
http://patchew.org/logs/20191016164145.115898-1-sameid@google.com/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-devel@redhat.com
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v8 0/8] Add Qemu to SeaBIOS LCHS interface
2019-10-16 16:41 [PATCH v8 0/8] Add Qemu to SeaBIOS LCHS interface Sam Eiderman
` (9 preceding siblings ...)
2019-10-16 20:13 ` [PATCH v8 0/8] Add Qemu to SeaBIOS LCHS interface no-reply
@ 2019-10-21 21:02 ` John Snow
10 siblings, 0 replies; 18+ messages in thread
From: John Snow @ 2019-10-21 21:02 UTC (permalink / raw)
To: Sam Eiderman, qemu-devel
Cc: kwolf, qemu-block, arbel.moshe, philmd, seabios, kevin,
liran.alon, kraxel, lersek, karl.heubaum
On 10/16/19 12:41 PM, Sam Eiderman wrote:
>
> v1:
>
> Non-standard logical geometries break under QEMU.
>
> A virtual disk which contains an operating system which depends on
> logical geometries (consistent values being reported from BIOS INT13
> AH=08) will most likely break under QEMU/SeaBIOS if it has non-standard
> logical geometries - for example 56 SPT (sectors per track).
> No matter what QEMU will guess - SeaBIOS, for large enough disks - will
> use LBA translation, which will report 63 SPT instead.
>
> In addition we can not enforce SeaBIOS to rely on phyiscal geometries at
> all. A virtio-blk-pci virtual disk with 255 phyiscal heads can not
> report more than 16 physical heads when moved to an IDE controller, the
> ATA spec allows a maximum of 16 heads - this is an artifact of
> virtualization.
>
> By supplying the logical geometies directly we are able to support such
> "exotic" disks.
>
> We will use fw_cfg to do just that.
>
> v2:
>
> Fix missing parenthesis check in
> "hd-geo-test: Add tests for lchs override"
>
> v3:
>
> * Rename fw_cfg key to "bios-geometry".
> * Remove "extendible" interface.
> * Add cpu_to_le32 fix as Laszlo suggested or big endian hosts
> * Fix last qtest commit - automatic docker tester for some reason does not have qemu-img set
>
> v4:
>
> * Change fw_cfg interface from mixed textual/binary to textual only
>
> v5:
>
> * Fix line > 80 chars in tests/hd-geo-test.c
>
> v6:
>
> * Small fixes for issues pointed by Max
> * (&conf->conf)->lcyls to conf->conf.lcyls and so on
> * Remove scsi_unrealize from everything other than scsi-hd
> * Add proper include to sysemu.h
> * scsi_device_unrealize() after scsi_device_purge_requests()
>
> v7:
>
> * Adapted last commit (tests) to changes in qtest
>
> v8:
>
> * Fixed BE issue with tests by using qfw_cfg_get_file() instead of
> read_fw_cfg_file(), thanks Laszlo.
> * Removed incorrect comment in 7/8.
>
> Sam Eiderman (8):
> block: Refactor macros - fix tabbing
> block: Support providing LCHS from user
> bootdevice: Add interface to gather LCHS
> scsi: Propagate unrealize() callback to scsi-hd
> bootdevice: Gather LCHS from all relevant devices
> bootdevice: Refactor get_boot_devices_list
> bootdevice: FW_CFG interface for LCHS values
> hd-geo-test: Add tests for lchs override
>
> bootdevice.c | 147 +++++++++--
> hw/block/virtio-blk.c | 6 +
> hw/ide/qdev.c | 7 +-
> hw/nvram/fw_cfg.c | 14 +-
> hw/scsi/scsi-bus.c | 16 ++
> hw/scsi/scsi-disk.c | 12 +
> include/hw/block/block.h | 22 +-
> include/hw/scsi/scsi.h | 1 +
> include/sysemu/sysemu.h | 4 +
> tests/Makefile.include | 2 +-
> tests/hd-geo-test.c | 551 +++++++++++++++++++++++++++++++++++++++
> 11 files changed, 741 insertions(+), 41 deletions(-)
>
Thanks, applied to my IDE tree:
https://github.com/jnsnow/qemu/commits/ide
https://github.com/jnsnow/qemu.git
--js
(Philippe, you have a few days to check that I didn't snub your reviews
if you want to look ...!)
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v8 2/8] block: Support providing LCHS from user
2019-10-16 16:41 ` [PATCH v8 2/8] block: Support providing LCHS from user Sam Eiderman
@ 2019-10-22 10:20 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 18+ messages in thread
From: Philippe Mathieu-Daudé @ 2019-10-22 10:20 UTC (permalink / raw)
To: Sam Eiderman, qemu-devel
Cc: kwolf, qemu-block, arbel.moshe, jsnow, seabios, kevin,
liran.alon, kraxel, Sam Eiderman, lersek, karl.heubaum
On 10/16/19 6:41 PM, Sam Eiderman wrote:
> From: Sam Eiderman <shmuel.eiderman@oracle.com>
>
> Add logical geometry variables to BlockConf.
>
> A user can now supply "lcyls", "lheads" & "lsecs" for any HD device
> that supports CHS ("cyls", "heads", "secs").
>
> These devices include:
> * ide-hd
> * scsi-hd
> * virtio-blk-pci
>
> In future commits we will use the provided LCHS and pass it to the BIOS
> through fw_cfg to be supplied using INT13 routines.
>
> Reviewed-by: Karl Heubaum <karl.heubaum@oracle.com>
> Reviewed-by: Arbel Moshe <arbel.moshe@oracle.com>
> Signed-off-by: Sam Eiderman <shmuel.eiderman@oracle.com>
> Signed-off-by: Sam Eiderman <sameid@google.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
> ---
> include/hw/block/block.h | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/include/hw/block/block.h b/include/hw/block/block.h
> index fd55a30bca..d7246f3862 100644
> --- a/include/hw/block/block.h
> +++ b/include/hw/block/block.h
> @@ -26,6 +26,7 @@ typedef struct BlockConf {
> uint32_t discard_granularity;
> /* geometry, not all devices use this */
> uint32_t cyls, heads, secs;
> + uint32_t lcyls, lheads, lsecs;
> OnOffAuto wce;
> bool share_rw;
> BlockdevOnError rerror;
> @@ -65,7 +66,10 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
> #define DEFINE_BLOCK_CHS_PROPERTIES(_state, _conf) \
> DEFINE_PROP_UINT32("cyls", _state, _conf.cyls, 0), \
> DEFINE_PROP_UINT32("heads", _state, _conf.heads, 0), \
> - DEFINE_PROP_UINT32("secs", _state, _conf.secs, 0)
> + DEFINE_PROP_UINT32("secs", _state, _conf.secs, 0), \
> + DEFINE_PROP_UINT32("lcyls", _state, _conf.lcyls, 0), \
> + DEFINE_PROP_UINT32("lheads", _state, _conf.lheads, 0), \
> + DEFINE_PROP_UINT32("lsecs", _state, _conf.lsecs, 0)
>
> #define DEFINE_BLOCK_ERROR_PROPERTIES(_state, _conf) \
> DEFINE_PROP_BLOCKDEV_ON_ERROR("rerror", _state, _conf.rerror, \
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v8 3/8] bootdevice: Add interface to gather LCHS
2019-10-16 16:41 ` [PATCH v8 3/8] bootdevice: Add interface to gather LCHS Sam Eiderman
@ 2019-10-22 10:22 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 18+ messages in thread
From: Philippe Mathieu-Daudé @ 2019-10-22 10:22 UTC (permalink / raw)
To: Sam Eiderman, qemu-devel
Cc: kwolf, qemu-block, arbel.moshe, jsnow, seabios, kevin,
liran.alon, kraxel, Sam Eiderman, lersek, karl.heubaum
On 10/16/19 6:41 PM, Sam Eiderman wrote:
> From: Sam Eiderman <shmuel.eiderman@oracle.com>
>
> Add an interface to provide direct logical CHS values for boot devices.
> We will use this interface in the next commits.
>
> Reviewed-by: Karl Heubaum <karl.heubaum@oracle.com>
> Reviewed-by: Arbel Moshe <arbel.moshe@oracle.com>
> Signed-off-by: Sam Eiderman <shmuel.eiderman@oracle.com>
> Signed-off-by: Sam Eiderman <sameid@google.com>
> ---
> bootdevice.c | 55 +++++++++++++++++++++++++++++++++++++++++
> include/sysemu/sysemu.h | 3 +++
> 2 files changed, 58 insertions(+)
>
> diff --git a/bootdevice.c b/bootdevice.c
> index 1d225202f9..bc5e1c2de4 100644
> --- a/bootdevice.c
> +++ b/bootdevice.c
> @@ -343,3 +343,58 @@ void device_add_bootindex_property(Object *obj, int32_t *bootindex,
> /* initialize devices' bootindex property to -1 */
> object_property_set_int(obj, -1, name, NULL);
> }
> +
> +typedef struct FWLCHSEntry FWLCHSEntry;
> +
> +struct FWLCHSEntry {
> + QTAILQ_ENTRY(FWLCHSEntry) link;
> + DeviceState *dev;
> + char *suffix;
> + uint32_t lcyls;
> + uint32_t lheads;
> + uint32_t lsecs;
> +};
> +
> +static QTAILQ_HEAD(, FWLCHSEntry) fw_lchs =
> + QTAILQ_HEAD_INITIALIZER(fw_lchs);
> +
> +void add_boot_device_lchs(DeviceState *dev, const char *suffix,
> + uint32_t lcyls, uint32_t lheads, uint32_t lsecs)
> +{
> + FWLCHSEntry *node;
> +
> + if (!lcyls && !lheads && !lsecs) {
> + return;
> + }
> +
> + assert(dev != NULL || suffix != NULL);
> +
> + node = g_malloc0(sizeof(FWLCHSEntry));
> + node->suffix = g_strdup(suffix);
> + node->dev = dev;
> + node->lcyls = lcyls;
> + node->lheads = lheads;
> + node->lsecs = lsecs;
> +
> + QTAILQ_INSERT_TAIL(&fw_lchs, node, link);
> +}
> +
> +void del_boot_device_lchs(DeviceState *dev, const char *suffix)
> +{
> + FWLCHSEntry *i;
> +
> + if (dev == NULL) {
> + return;
> + }
> +
> + QTAILQ_FOREACH(i, &fw_lchs, link) {
> + if ((!suffix || !g_strcmp0(i->suffix, suffix)) &&
> + i->dev == dev) {
> + QTAILQ_REMOVE(&fw_lchs, i, link);
> + g_free(i->suffix);
> + g_free(i);
> +
> + break;
> + }
> + }
> +}
> diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
> index 44f18eb739..5bc5c79cbc 100644
> --- a/include/sysemu/sysemu.h
> +++ b/include/sysemu/sysemu.h
> @@ -103,6 +103,9 @@ void device_add_bootindex_property(Object *obj, int32_t *bootindex,
> DeviceState *dev, Error **errp);
> void restore_boot_order(void *opaque);
> void validate_bootdevices(const char *devices, Error **errp);
> +void add_boot_device_lchs(DeviceState *dev, const char *suffix,
> + uint32_t lcyls, uint32_t lheads, uint32_t lsecs);
> +void del_boot_device_lchs(DeviceState *dev, const char *suffix);
>
> /* handler to set the boot_device order for a specific type of MachineClass */
> typedef void QEMUBootSetHandler(void *opaque, const char *boot_order,
>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v8 4/8] scsi: Propagate unrealize() callback to scsi-hd
2019-10-16 16:41 ` [PATCH v8 4/8] scsi: Propagate unrealize() callback to scsi-hd Sam Eiderman
@ 2019-10-22 10:23 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 18+ messages in thread
From: Philippe Mathieu-Daudé @ 2019-10-22 10:23 UTC (permalink / raw)
To: Sam Eiderman, qemu-devel
Cc: kwolf, qemu-block, arbel.moshe, jsnow, seabios, kevin,
liran.alon, kraxel, Sam Eiderman, lersek, karl.heubaum
On 10/16/19 6:41 PM, Sam Eiderman wrote:
> From: Sam Eiderman <shmuel.eiderman@oracle.com>
>
> We will need to add LCHS removal logic to scsi-hd's unrealize() in the
> next commit.
>
> Reviewed-by: Karl Heubaum <karl.heubaum@oracle.com>
> Reviewed-by: Arbel Moshe <arbel.moshe@oracle.com>
> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
> Signed-off-by: Sam Eiderman <shmuel.eiderman@oracle.com>
> Signed-off-by: Sam Eiderman <sameid@google.com>
> ---
> hw/scsi/scsi-bus.c | 16 ++++++++++++++++
> include/hw/scsi/scsi.h | 1 +
> 2 files changed, 17 insertions(+)
>
> diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
> index bccb7cc4c6..359d50d6d0 100644
> --- a/hw/scsi/scsi-bus.c
> +++ b/hw/scsi/scsi-bus.c
> @@ -59,6 +59,14 @@ static void scsi_device_realize(SCSIDevice *s, Error **errp)
> }
> }
>
> +static void scsi_device_unrealize(SCSIDevice *s, Error **errp)
> +{
> + SCSIDeviceClass *sc = SCSI_DEVICE_GET_CLASS(s);
> + if (sc->unrealize) {
> + sc->unrealize(s, errp);
> + }
> +}
> +
> int scsi_bus_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf,
> void *hba_private)
> {
> @@ -217,12 +225,20 @@ static void scsi_qdev_realize(DeviceState *qdev, Error **errp)
> static void scsi_qdev_unrealize(DeviceState *qdev, Error **errp)
> {
> SCSIDevice *dev = SCSI_DEVICE(qdev);
> + Error *local_err = NULL;
>
> if (dev->vmsentry) {
> qemu_del_vm_change_state_handler(dev->vmsentry);
> }
>
> scsi_device_purge_requests(dev, SENSE_CODE(NO_SENSE));
> +
> + scsi_device_unrealize(dev, &local_err);
> + if (local_err) {
> + error_propagate(errp, local_err);
> + return;
> + }
> +
> blockdev_mark_auto_del(dev->conf.blk);
> }
>
> diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
> index d77a92361b..332ef602f4 100644
> --- a/include/hw/scsi/scsi.h
> +++ b/include/hw/scsi/scsi.h
> @@ -59,6 +59,7 @@ struct SCSIRequest {
> typedef struct SCSIDeviceClass {
> DeviceClass parent_class;
> void (*realize)(SCSIDevice *dev, Error **errp);
> + void (*unrealize)(SCSIDevice *dev, Error **errp);
> int (*parse_cdb)(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf,
> void *hba_private);
> SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun,
>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v8 5/8] bootdevice: Gather LCHS from all relevant devices
2019-10-16 16:41 ` [PATCH v8 5/8] bootdevice: Gather LCHS from all relevant devices Sam Eiderman
@ 2019-10-22 10:30 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 18+ messages in thread
From: Philippe Mathieu-Daudé @ 2019-10-22 10:30 UTC (permalink / raw)
To: Sam Eiderman, qemu-devel
Cc: kwolf, qemu-block, arbel.moshe, jsnow, seabios, kevin,
liran.alon, kraxel, Sam Eiderman, lersek, karl.heubaum
On 10/16/19 6:41 PM, Sam Eiderman wrote:
> From: Sam Eiderman <shmuel.eiderman@oracle.com>
>
> Relevant devices are:
> * ide-hd (and ide-cd, ide-drive)
> * scsi-hd (and scsi-cd, scsi-disk, scsi-block)
> * virtio-blk-pci
>
> We do not call del_boot_device_lchs() for ide-* since we don't need to -
> IDE block devices do not support unplugging.
>
> Reviewed-by: Karl Heubaum <karl.heubaum@oracle.com>
> Reviewed-by: Arbel Moshe <arbel.moshe@oracle.com>
> Signed-off-by: Sam Eiderman <shmuel.eiderman@oracle.com>
> Signed-off-by: Sam Eiderman <sameid@google.com>
> ---
> hw/block/virtio-blk.c | 6 ++++++
> hw/ide/qdev.c | 5 +++++
> hw/scsi/scsi-disk.c | 12 ++++++++++++
> 3 files changed, 23 insertions(+)
>
> diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
> index ed2ddebd2b..c56e905f80 100644
> --- a/hw/block/virtio-blk.c
> +++ b/hw/block/virtio-blk.c
> @@ -1200,6 +1200,11 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
> blk_set_guest_block_size(s->blk, s->conf.conf.logical_block_size);
>
> blk_iostatus_enable(s->blk);
> +
> + add_boot_device_lchs(dev, "/disk@0,0",
> + conf->conf.lcyls,
> + conf->conf.lheads,
> + conf->conf.lsecs);
> }
>
> static void virtio_blk_device_unrealize(DeviceState *dev, Error **errp)
> @@ -1207,6 +1212,7 @@ static void virtio_blk_device_unrealize(DeviceState *dev, Error **errp)
> VirtIODevice *vdev = VIRTIO_DEVICE(dev);
> VirtIOBlock *s = VIRTIO_BLK(dev);
>
> + del_boot_device_lchs(dev, "/disk@0,0");
> virtio_blk_data_plane_destroy(s->dataplane);
> s->dataplane = NULL;
> qemu_del_vm_change_state_handler(s->change);
> diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
> index 6dd219944f..2ffd387a73 100644
> --- a/hw/ide/qdev.c
> +++ b/hw/ide/qdev.c
> @@ -220,6 +220,11 @@ static void ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind, Error **errp)
>
> add_boot_device_path(dev->conf.bootindex, &dev->qdev,
> dev->unit ? "/disk@1" : "/disk@0");
> +
> + add_boot_device_lchs(&dev->qdev, dev->unit ? "/disk@1" : "/disk@0",
> + dev->conf.lcyls,
> + dev->conf.lheads,
> + dev->conf.lsecs);
> }
>
> static void ide_dev_get_bootindex(Object *obj, Visitor *v, const char *name,
> diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
> index 68b1675fd9..07fb5ebdf1 100644
> --- a/hw/scsi/scsi-disk.c
> +++ b/hw/scsi/scsi-disk.c
> @@ -35,6 +35,7 @@
> #include "hw/block/block.h"
> #include "hw/qdev-properties.h"
> #include "sysemu/dma.h"
> +#include "sysemu/sysemu.h"
> #include "qemu/cutils.h"
> #include "trace.h"
>
> @@ -2414,6 +2415,16 @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
> blk_set_guest_block_size(s->qdev.conf.blk, s->qdev.blocksize);
>
> blk_iostatus_enable(s->qdev.conf.blk);
> +
> + add_boot_device_lchs(&dev->qdev, NULL,
> + dev->conf.lcyls,
> + dev->conf.lheads,
> + dev->conf.lsecs);
> +}
> +
> +static void scsi_unrealize(SCSIDevice *dev, Error **errp)
> +{
> + del_boot_device_lchs(&dev->qdev, NULL);
> }
>
> static void scsi_hd_realize(SCSIDevice *dev, Error **errp)
> @@ -3018,6 +3029,7 @@ static void scsi_hd_class_initfn(ObjectClass *klass, void *data)
> SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
>
> sc->realize = scsi_hd_realize;
> + sc->unrealize = scsi_unrealize;
> sc->alloc_req = scsi_new_request;
> sc->unit_attention_reported = scsi_disk_unit_attention_reported;
> dc->desc = "virtual SCSI disk";
>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v8 6/8] bootdevice: Refactor get_boot_devices_list
2019-10-16 16:41 ` [PATCH v8 6/8] bootdevice: Refactor get_boot_devices_list Sam Eiderman
@ 2019-10-22 10:32 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 18+ messages in thread
From: Philippe Mathieu-Daudé @ 2019-10-22 10:32 UTC (permalink / raw)
To: Sam Eiderman, qemu-devel
Cc: kwolf, qemu-block, arbel.moshe, jsnow, seabios, kevin,
liran.alon, kraxel, Sam Eiderman, lersek, karl.heubaum
On 10/16/19 6:41 PM, Sam Eiderman wrote:
> From: Sam Eiderman <shmuel.eiderman@oracle.com>
>
> Move device name construction to a separate function.
>
> We will reuse this function in the following commit to pass logical CHS
> parameters through fw_cfg much like we currently pass bootindex.
>
> Reviewed-by: Karl Heubaum <karl.heubaum@oracle.com>
> Reviewed-by: Arbel Moshe <arbel.moshe@oracle.com>
> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
> Signed-off-by: Sam Eiderman <shmuel.eiderman@oracle.com>
> Signed-off-by: Sam Eiderman <sameid@google.com>
> ---
> bootdevice.c | 61 +++++++++++++++++++++++++++++-----------------------
> 1 file changed, 34 insertions(+), 27 deletions(-)
>
> diff --git a/bootdevice.c b/bootdevice.c
> index bc5e1c2de4..2cf6b37c57 100644
> --- a/bootdevice.c
> +++ b/bootdevice.c
> @@ -202,6 +202,39 @@ DeviceState *get_boot_device(uint32_t position)
> return res;
> }
>
> +static char *get_boot_device_path(DeviceState *dev, bool ignore_suffixes,
> + const char *suffix)
> +{
> + char *devpath = NULL, *s = NULL, *d, *bootpath;
> +
> + if (dev) {
> + devpath = qdev_get_fw_dev_path(dev);
> + assert(devpath);
> + }
> +
> + if (!ignore_suffixes) {
> + if (dev) {
> + d = qdev_get_own_fw_dev_path_from_handler(dev->parent_bus, dev);
> + if (d) {
> + assert(!suffix);
> + s = d;
> + } else {
> + s = g_strdup(suffix);
> + }
> + } else {
> + s = g_strdup(suffix);
> + }
> + }
> +
> + bootpath = g_strdup_printf("%s%s",
> + devpath ? devpath : "",
> + s ? s : "");
> + g_free(devpath);
> + g_free(s);
> +
> + return bootpath;
> +}
> +
> /*
> * This function returns null terminated string that consist of new line
> * separated device paths.
> @@ -218,36 +251,10 @@ char *get_boot_devices_list(size_t *size)
> bool ignore_suffixes = mc->ignore_boot_device_suffixes;
>
> QTAILQ_FOREACH(i, &fw_boot_order, link) {
> - char *devpath = NULL, *suffix = NULL;
> char *bootpath;
> - char *d;
> size_t len;
>
> - if (i->dev) {
> - devpath = qdev_get_fw_dev_path(i->dev);
> - assert(devpath);
> - }
> -
> - if (!ignore_suffixes) {
> - if (i->dev) {
> - d = qdev_get_own_fw_dev_path_from_handler(i->dev->parent_bus,
> - i->dev);
> - if (d) {
> - assert(!i->suffix);
> - suffix = d;
> - } else {
> - suffix = g_strdup(i->suffix);
> - }
> - } else {
> - suffix = g_strdup(i->suffix);
> - }
> - }
> -
> - bootpath = g_strdup_printf("%s%s",
> - devpath ? devpath : "",
> - suffix ? suffix : "");
> - g_free(devpath);
> - g_free(suffix);
> + bootpath = get_boot_device_path(i->dev, ignore_suffixes, i->suffix);
>
> if (total) {
> list[total-1] = '\n';
>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v8 7/8] bootdevice: FW_CFG interface for LCHS values
2019-10-16 16:41 ` [PATCH v8 7/8] bootdevice: FW_CFG interface for LCHS values Sam Eiderman
@ 2019-10-22 10:35 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 18+ messages in thread
From: Philippe Mathieu-Daudé @ 2019-10-22 10:35 UTC (permalink / raw)
To: Sam Eiderman, qemu-devel
Cc: kwolf, qemu-block, arbel.moshe, jsnow, seabios, kevin,
liran.alon, kraxel, Sam Eiderman, lersek, karl.heubaum
On 10/16/19 6:41 PM, Sam Eiderman wrote:
> From: Sam Eiderman <shmuel.eiderman@oracle.com>
>
> Using fw_cfg, supply logical CHS values directly from QEMU to the BIOS.
>
> Non-standard logical geometries break under QEMU.
>
> A virtual disk which contains an operating system which depends on
> logical geometries (consistent values being reported from BIOS INT13
> AH=08) will most likely break under QEMU/SeaBIOS if it has non-standard
> logical geometries - for example 56 SPT (sectors per track).
> No matter what QEMU will report - SeaBIOS, for large enough disks - will
> use LBA translation, which will report 63 SPT instead.
>
> In addition we cannot force SeaBIOS to rely on physical geometries at
> all. A virtio-blk-pci virtual disk with 255 phyiscal heads cannot
> report more than 16 physical heads when moved to an IDE controller,
> since the ATA spec allows a maximum of 16 heads - this is an artifact of
> virtualization.
>
> By supplying the logical geometries directly we are able to support such
> "exotic" disks.
>
> We serialize this information in a similar way to the "bootorder"
> interface.
> The new fw_cfg entry is "bios-geometry".
>
> Reviewed-by: Karl Heubaum <karl.heubaum@oracle.com>
> Reviewed-by: Arbel Moshe <arbel.moshe@oracle.com>
> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
> Signed-off-by: Sam Eiderman <shmuel.eiderman@oracle.com>
> Signed-off-by: Sam Eiderman <sameid@google.com>
> ---
> bootdevice.c | 31 +++++++++++++++++++++++++++++++
> hw/nvram/fw_cfg.c | 14 +++++++++++---
> include/sysemu/sysemu.h | 1 +
> 3 files changed, 43 insertions(+), 3 deletions(-)
>
> diff --git a/bootdevice.c b/bootdevice.c
> index 2cf6b37c57..03aaffcc8d 100644
> --- a/bootdevice.c
> +++ b/bootdevice.c
> @@ -405,3 +405,34 @@ void del_boot_device_lchs(DeviceState *dev, const char *suffix)
> }
> }
> }
> +
> +char *get_boot_devices_lchs_list(size_t *size)
> +{
> + FWLCHSEntry *i;
> + size_t total = 0;
> + char *list = NULL;
> +
> + QTAILQ_FOREACH(i, &fw_lchs, link) {
> + char *bootpath;
> + char *chs_string;
> + size_t len;
> +
> + bootpath = get_boot_device_path(i->dev, false, i->suffix);
> + chs_string = g_strdup_printf("%s %" PRIu32 " %" PRIu32 " %" PRIu32,
> + bootpath, i->lcyls, i->lheads, i->lsecs);
> +
> + if (total) {
> + list[total - 1] = '\n';
> + }
> + len = strlen(chs_string) + 1;
> + list = g_realloc(list, total + len);
> + memcpy(&list[total], chs_string, len);
> + total += len;
> + g_free(chs_string);
> + g_free(bootpath);
> + }
> +
Hmm maybe assert(size != NULL) or if(size) {
> + *size = total;
} or simply document "@size must not be NULL" in the declaration.
Can be a follow-up cleaning patch.
Regardless:
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
> +
> + return list;
> +}
> diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
> index 7dc3ac378e..18aff658c0 100644
> --- a/hw/nvram/fw_cfg.c
> +++ b/hw/nvram/fw_cfg.c
> @@ -920,13 +920,21 @@ void *fw_cfg_modify_file(FWCfgState *s, const char *filename,
>
> static void fw_cfg_machine_reset(void *opaque)
> {
> + MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
> + FWCfgState *s = opaque;
> void *ptr;
> size_t len;
> - FWCfgState *s = opaque;
> - char *bootindex = get_boot_devices_list(&len);
> + char *buf;
>
> - ptr = fw_cfg_modify_file(s, "bootorder", (uint8_t *)bootindex, len);
> + buf = get_boot_devices_list(&len);
> + ptr = fw_cfg_modify_file(s, "bootorder", (uint8_t *)buf, len);
> g_free(ptr);
> +
> + if (!mc->legacy_fw_cfg_order) {
> + buf = get_boot_devices_lchs_list(&len);
> + ptr = fw_cfg_modify_file(s, "bios-geometry", (uint8_t *)buf, len);
> + g_free(ptr);
> + }
> }
>
> static void fw_cfg_machine_ready(struct Notifier *n, void *data)
> diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
> index 5bc5c79cbc..80c57fdc4e 100644
> --- a/include/sysemu/sysemu.h
> +++ b/include/sysemu/sysemu.h
> @@ -106,6 +106,7 @@ void validate_bootdevices(const char *devices, Error **errp);
> void add_boot_device_lchs(DeviceState *dev, const char *suffix,
> uint32_t lcyls, uint32_t lheads, uint32_t lsecs);
> void del_boot_device_lchs(DeviceState *dev, const char *suffix);
> +char *get_boot_devices_lchs_list(size_t *size);
>
> /* handler to set the boot_device order for a specific type of MachineClass */
> typedef void QEMUBootSetHandler(void *opaque, const char *boot_order,
>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2019-10-22 10:36 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-16 16:41 [PATCH v8 0/8] Add Qemu to SeaBIOS LCHS interface Sam Eiderman
2019-10-16 16:41 ` [PATCH v8 1/8] block: Refactor macros - fix tabbing Sam Eiderman
2019-10-16 16:41 ` [PATCH v8 1/1] hd-geo-test: Add tests for lchs override Sam Eiderman
2019-10-16 16:41 ` [PATCH v8 2/8] block: Support providing LCHS from user Sam Eiderman
2019-10-22 10:20 ` Philippe Mathieu-Daudé
2019-10-16 16:41 ` [PATCH v8 3/8] bootdevice: Add interface to gather LCHS Sam Eiderman
2019-10-22 10:22 ` Philippe Mathieu-Daudé
2019-10-16 16:41 ` [PATCH v8 4/8] scsi: Propagate unrealize() callback to scsi-hd Sam Eiderman
2019-10-22 10:23 ` Philippe Mathieu-Daudé
2019-10-16 16:41 ` [PATCH v8 5/8] bootdevice: Gather LCHS from all relevant devices Sam Eiderman
2019-10-22 10:30 ` Philippe Mathieu-Daudé
2019-10-16 16:41 ` [PATCH v8 6/8] bootdevice: Refactor get_boot_devices_list Sam Eiderman
2019-10-22 10:32 ` Philippe Mathieu-Daudé
2019-10-16 16:41 ` [PATCH v8 7/8] bootdevice: FW_CFG interface for LCHS values Sam Eiderman
2019-10-22 10:35 ` Philippe Mathieu-Daudé
2019-10-16 16:41 ` [PATCH v8 8/8] hd-geo-test: Add tests for lchs override Sam Eiderman
2019-10-16 20:13 ` [PATCH v8 0/8] Add Qemu to SeaBIOS LCHS interface no-reply
2019-10-21 21:02 ` John Snow
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.