summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorDave Voutila <dv@cvs.openbsd.org>2023-02-06 20:33:35 +0000
committerDave Voutila <dv@cvs.openbsd.org>2023-02-06 20:33:35 +0000
commitf81e1b3cfd5f3d2971ef2bc7f05ebc4150fccb38 (patch)
tree7588de7b7760edca37084ef2fb269ebb264f4d85 /usr.sbin
parent221037d53324be84dc7db804a7fe698ab5886812 (diff)
vmd(8): scan pci bus to determine bootorder strings.
vmd's SeaBIOS bootorder strings had hardcoded pci device ids, so if a user added a network interface the bootorder strings didn't line up with reality. Using vmctl(8) to boot from a cdrom (-B cdrom) would fail, for instance, if attaching both a nic and a disk as well. This change scans the pci devices and finds the first of each type to construct viable bootorder strings. ok jan@
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/vmd/fw_cfg.c22
-rw-r--r--usr.sbin/vmd/pci.c20
-rw-r--r--usr.sbin/vmd/pci.h3
-rw-r--r--usr.sbin/vmd/vm.c20
4 files changed, 49 insertions, 16 deletions
diff --git a/usr.sbin/vmd/fw_cfg.c b/usr.sbin/vmd/fw_cfg.c
index ed4386b7c9c..b875082b6fe 100644
--- a/usr.sbin/vmd/fw_cfg.c
+++ b/usr.sbin/vmd/fw_cfg.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fw_cfg.c,v 1.6 2022/12/26 23:50:20 dv Exp $ */
+/* $OpenBSD: fw_cfg.c,v 1.7 2023/02/06 20:33:34 dv Exp $ */
/*
* Copyright (c) 2018 Claudio Jeker <claudio@openbsd.org>
*
@@ -18,12 +18,14 @@
#include <sys/uio.h>
#include <machine/biosvar.h> /* bios_memmap_t */
#include <machine/vmmvar.h>
+#include <dev/pv/virtioreg.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "atomicio.h"
+#include "pci.h"
#include "vmd.h"
#include "vmm.h"
#include "fw_cfg.h"
@@ -72,9 +74,11 @@ static void fw_cfg_file_dir(void);
void
fw_cfg_init(struct vmop_create_params *vmc)
{
- const char *bootorder = NULL;
unsigned int sd = 0;
size_t i, e820_len = 0;
+ char bootorder[64];
+ const char *bootfmt;
+ int bootidx = -1;
/* Define e820 memory ranges. */
memset(&e820, 0, sizeof(e820));
@@ -96,18 +100,24 @@ fw_cfg_init(struct vmop_create_params *vmc)
switch (vmc->vmc_bootdevice) {
case VMBOOTDEV_DISK:
- bootorder = "/pci@i0cf8/*@3\nHALT";
+ bootidx = pci_find_first_device(PCI_PRODUCT_VIRTIO_BLOCK);
+ bootfmt = "/pci@i0cf8/*@%d\nHALT";
break;
case VMBOOTDEV_CDROM:
- bootorder = "/pci@i0cf8/*@4/*@0/*@0,40000100\nHALT";
+ bootidx = pci_find_first_device(PCI_PRODUCT_VIRTIO_SCSI);
+ bootfmt = "/pci@i0cf8/*@%d/*@0/*@0,40000100\nHALT";
break;
case VMBOOTDEV_NET:
/* XXX not yet */
- bootorder = "HALT";
+ bootidx = pci_find_first_device(PCI_PRODUCT_VIRTIO_NETWORK);
+ bootfmt = "HALT";
break;
}
- if (bootorder)
+ if (bootidx > -1) {
+ snprintf(bootorder, sizeof(bootorder), bootfmt, bootidx);
+ log_debug("%s: bootorder: %s", __func__, bootorder);
fw_cfg_add_file("bootorder", bootorder, strlen(bootorder) + 1);
+ }
}
int
diff --git a/usr.sbin/vmd/pci.c b/usr.sbin/vmd/pci.c
index c1cd8154663..5309449b339 100644
--- a/usr.sbin/vmd/pci.c
+++ b/usr.sbin/vmd/pci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pci.c,v 1.30 2023/01/28 14:40:53 dv Exp $ */
+/* $OpenBSD: pci.c,v 1.31 2023/02/06 20:33:34 dv Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
@@ -437,3 +437,21 @@ pci_restore(int fd)
}
return (0);
}
+
+/*
+ * Find the first PCI device based on PCI Subsystem ID
+ * (e.g. PCI_PRODUCT_VIRTIO_BLOCK).
+ *
+ * Returns the PCI device id of the first matching device, if found.
+ * Otherwise, returns -1.
+ */
+int
+pci_find_first_device(uint16_t subsys_id)
+{
+ int i;
+
+ for (i = 0; i < pci.pci_dev_ct; i++)
+ if (pci.pci_devices[i].pd_subsys_id == subsys_id)
+ return (i);
+ return (-1);
+}
diff --git a/usr.sbin/vmd/pci.h b/usr.sbin/vmd/pci.h
index ed6ba534536..73b54437bed 100644
--- a/usr.sbin/vmd/pci.h
+++ b/usr.sbin/vmd/pci.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pci.h,v 1.9 2021/06/16 16:55:02 dv Exp $ */
+/* $OpenBSD: pci.h,v 1.10 2023/02/06 20:33:34 dv Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
@@ -92,6 +92,7 @@ struct pci {
struct pci_dev pci_devices[PCI_CONFIG_MAX_DEV];
};
+int pci_find_first_device(uint16_t);
void pci_handle_address_reg(struct vm_run_params *);
void pci_handle_data_reg(struct vm_run_params *);
uint8_t pci_handle_io(struct vm_run_params *);
diff --git a/usr.sbin/vmd/vm.c b/usr.sbin/vmd/vm.c
index bf8b0b958f5..5b9a1831f5b 100644
--- a/usr.sbin/vmd/vm.c
+++ b/usr.sbin/vmd/vm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm.c,v 1.82 2023/01/28 14:40:53 dv Exp $ */
+/* $OpenBSD: vm.c,v 1.83 2023/02/06 20:33:34 dv Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
@@ -1106,13 +1106,6 @@ init_emulated_hw(struct vmop_create_params *vmc, int child_cdrom,
for (i = COM1_DATA; i <= COM1_SCR; i++)
ioports_map[i] = vcpu_exit_com;
- /* Init QEMU fw_cfg interface */
- fw_cfg_init(vmc);
- ioports_map[FW_CFG_IO_SELECT] = vcpu_exit_fw_cfg;
- ioports_map[FW_CFG_IO_DATA] = vcpu_exit_fw_cfg;
- ioports_map[FW_CFG_IO_DMA_ADDR_HIGH] = vcpu_exit_fw_cfg_dma;
- ioports_map[FW_CFG_IO_DMA_ADDR_LOW] = vcpu_exit_fw_cfg_dma;
-
/* Initialize PCI */
for (i = VM_PCI_IO_BAR_BASE; i <= VM_PCI_IO_BAR_END; i++)
ioports_map[i] = vcpu_exit_pci;
@@ -1126,7 +1119,18 @@ init_emulated_hw(struct vmop_create_params *vmc, int child_cdrom,
/* Initialize virtio devices */
virtio_init(current_vm, child_cdrom, child_disks, child_taps);
+
+ /*
+ * Init QEMU fw_cfg interface. Must be done last for pci hardware
+ * detection.
+ */
+ fw_cfg_init(vmc);
+ ioports_map[FW_CFG_IO_SELECT] = vcpu_exit_fw_cfg;
+ ioports_map[FW_CFG_IO_DATA] = vcpu_exit_fw_cfg;
+ ioports_map[FW_CFG_IO_DMA_ADDR_HIGH] = vcpu_exit_fw_cfg_dma;
+ ioports_map[FW_CFG_IO_DMA_ADDR_LOW] = vcpu_exit_fw_cfg_dma;
}
+
/*
* restore_emulated_hw
*