git: a862ee32ca8b - stable/14 - bhyve: Move legacy PCI interrupt handling under amd64/
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 11 Oct 2023 13:25:15 UTC
The branch stable/14 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=a862ee32ca8bf2e0db6c749ae6e403216c95fe75 commit a862ee32ca8bf2e0db6c749ae6e403216c95fe75 Author: Mark Johnston <markj@FreeBSD.org> AuthorDate: 2023-10-04 16:25:19 +0000 Commit: Mark Johnston <markj@FreeBSD.org> CommitDate: 2023-10-11 13:22:05 +0000 bhyve: Move legacy PCI interrupt handling under amd64/ Specifically, move IO-APIC, LPC and PIRQ routing code under amd64/. Use ifdefs to conditionally compile related code in other files. In particular, legacy PCI interrupt handling is now compiled only on amd64. This is not too invasive, but suggestions for a more modular approach would be appreciated. I am not sure why qemu fwcfg handling is tied to LPC, and I suspect it should be decoupled. In this commit I just apply an ifdef hammer, but we will eventually want fwcfg on arm64 as well. No functional change intended. Reviewed by: corvink, jhb MFC after: 1 week Sponsored by: Innovate UK Differential Revision: https://reviews.freebsd.org/D40739 (cherry picked from commit 55c13f6e7a412cc4bd0ea3fc183cd7c5c2348f01) --- usr.sbin/bhyve/Makefile | 3 --- usr.sbin/bhyve/amd64/Makefile.inc | 3 +++ usr.sbin/bhyve/{ => amd64}/ioapic.c | 0 usr.sbin/bhyve/{ => amd64}/ioapic.h | 0 usr.sbin/bhyve/{ => amd64}/pci_irq.c | 0 usr.sbin/bhyve/{ => amd64}/pci_irq.h | 0 usr.sbin/bhyve/{ => amd64}/pci_lpc.c | 0 usr.sbin/bhyve/{ => amd64}/pci_lpc.h | 0 usr.sbin/bhyve/bhyverun.c | 16 ++++++++++++---- usr.sbin/bhyve/pci_emul.c | 36 +++++++++++++++++++++++++++++------- usr.sbin/bhyve/pci_emul.h | 27 +++++++++++++++------------ usr.sbin/bhyve/qemu_fwcfg.c | 18 ++++++++++++++++-- usr.sbin/bhyve/virtio.h | 2 ++ 13 files changed, 77 insertions(+), 28 deletions(-) diff --git a/usr.sbin/bhyve/Makefile b/usr.sbin/bhyve/Makefile index 0ec6ad73e2a2..5aaf0d4ea2a0 100644 --- a/usr.sbin/bhyve/Makefile +++ b/usr.sbin/bhyve/Makefile @@ -31,7 +31,6 @@ SRCS= \ gdb.c \ hda_codec.c \ inout.c \ - ioapic.c \ iov.c \ mem.c \ mevent.c \ @@ -40,8 +39,6 @@ SRCS= \ pci_emul.c \ pci_fbuf.c \ pci_hostbridge.c \ - pci_irq.c \ - pci_lpc.c \ pci_nvme.c \ pci_passthru.c \ pci_virtio_9p.c \ diff --git a/usr.sbin/bhyve/amd64/Makefile.inc b/usr.sbin/bhyve/amd64/Makefile.inc index 862aeddb16e0..76813891b0a0 100644 --- a/usr.sbin/bhyve/amd64/Makefile.inc +++ b/usr.sbin/bhyve/amd64/Makefile.inc @@ -2,12 +2,15 @@ SRCS+= \ atkbdc.c \ e820.c \ fwctl.c \ + ioapic.c \ kernemu_dev.c \ mptbl.c \ pci_ahci.c \ pci_e82545.c \ pci_gvt-d.c \ pci_hda.c \ + pci_irq.c \ + pci_lpc.c \ pci_uart.c \ pci_xhci.c \ pctestdev.c \ diff --git a/usr.sbin/bhyve/ioapic.c b/usr.sbin/bhyve/amd64/ioapic.c similarity index 100% rename from usr.sbin/bhyve/ioapic.c rename to usr.sbin/bhyve/amd64/ioapic.c diff --git a/usr.sbin/bhyve/ioapic.h b/usr.sbin/bhyve/amd64/ioapic.h similarity index 100% rename from usr.sbin/bhyve/ioapic.h rename to usr.sbin/bhyve/amd64/ioapic.h diff --git a/usr.sbin/bhyve/pci_irq.c b/usr.sbin/bhyve/amd64/pci_irq.c similarity index 100% rename from usr.sbin/bhyve/pci_irq.c rename to usr.sbin/bhyve/amd64/pci_irq.c diff --git a/usr.sbin/bhyve/pci_irq.h b/usr.sbin/bhyve/amd64/pci_irq.h similarity index 100% rename from usr.sbin/bhyve/pci_irq.h rename to usr.sbin/bhyve/amd64/pci_irq.h diff --git a/usr.sbin/bhyve/pci_lpc.c b/usr.sbin/bhyve/amd64/pci_lpc.c similarity index 100% rename from usr.sbin/bhyve/pci_lpc.c rename to usr.sbin/bhyve/amd64/pci_lpc.c diff --git a/usr.sbin/bhyve/pci_lpc.h b/usr.sbin/bhyve/amd64/pci_lpc.h similarity index 100% rename from usr.sbin/bhyve/pci_lpc.h rename to usr.sbin/bhyve/amd64/pci_lpc.h diff --git a/usr.sbin/bhyve/bhyverun.c b/usr.sbin/bhyve/bhyverun.c index 2c32e2a56fbb..b8e59d3b0fc0 100644 --- a/usr.sbin/bhyve/bhyverun.c +++ b/usr.sbin/bhyve/bhyverun.c @@ -85,8 +85,8 @@ #include "amd64/fwctl.h" #endif #include "gdb.h" -#include "ioapic.h" #ifdef __amd64__ +#include "amd64/ioapic.h" #include "amd64/kernemu_dev.h" #endif #include "mem.h" @@ -95,8 +95,10 @@ #include "amd64/mptbl.h" #endif #include "pci_emul.h" -#include "pci_irq.h" -#include "pci_lpc.h" +#ifdef __amd64__ +#include "amd64/pci_irq.h" +#include "amd64/pci_lpc.h" +#endif #include "qemu_fwcfg.h" #include "smbiostbl.h" #ifdef BHYVE_SNAPSHOT @@ -634,8 +636,10 @@ do_open(const char *vmname) reinit = romboot = false; +#ifdef __amd64__ if (lpc_bootrom()) romboot = true; +#endif error = vm_create(vmname); if (error) { @@ -851,6 +855,7 @@ main(int argc, char *argv[]) case 'K': set_config_value("keyboard.layout", optarg); break; +#ifdef __amd64__ case 'l': if (strncmp(optarg, "help", strlen(optarg)) == 0) { lpc_print_supported_devices(); @@ -860,6 +865,7 @@ main(int argc, char *argv[]) "configuration '%s'", optarg); } break; +#endif #ifdef BHYVE_SNAPSHOT case 'r': restore_file = optarg; @@ -1033,9 +1039,9 @@ main(int argc, char *argv[]) init_bootrom(ctx); #ifdef __amd64__ atkbdc_init(ctx); -#endif pci_irq_init(ctx); ioapic_init(ctx); +#endif #ifdef __amd64__ rtc_init(ctx); @@ -1081,6 +1087,7 @@ main(int argc, char *argv[]) init_gdb(ctx); +#ifdef __amd64__ if (lpc_bootrom()) { if (vm_set_capability(bsp, VM_CAP_UNRESTRICTED_GUEST, 1)) { fprintf(stderr, "ROM boot failed: unrestricted guest " @@ -1090,6 +1097,7 @@ main(int argc, char *argv[]) error = vcpu_reset(bsp); assert(error == 0); } +#endif /* * Add all vCPUs. diff --git a/usr.sbin/bhyve/pci_emul.c b/usr.sbin/bhyve/pci_emul.c index 5fb25dbfe9c7..6b2e46ce917d 100644 --- a/usr.sbin/bhyve/pci_emul.c +++ b/usr.sbin/bhyve/pci_emul.c @@ -52,11 +52,15 @@ #include "config.h" #include "debug.h" #include "inout.h" -#include "ioapic.h" +#ifdef __amd64__ +#include "amd64/ioapic.h" +#endif #include "mem.h" #include "pci_emul.h" -#include "pci_irq.h" -#include "pci_lpc.h" +#ifdef __amd64__ +#include "amd64/pci_irq.h" +#include "amd64/pci_lpc.h" +#endif #include "pci_passthru.h" #include "qemu_fwcfg.h" @@ -143,9 +147,12 @@ SYSRES_MEM(PCI_EMUL_ECFG_BASE, PCI_EMUL_ECFG_SIZE); #define PCI_EMUL_MEMLIMIT32 PCI_EMUL_ECFG_BASE #define PCI_EMUL_MEMSIZE64 (32*GB) -static struct pci_devemu *pci_emul_finddev(const char *name); +#ifdef __amd64__ static void pci_lintr_route(struct pci_devinst *pi); static void pci_lintr_update(struct pci_devinst *pi); +#endif + +static struct pci_devemu *pci_emul_finddev(const char *name); static void pci_cfgrw(int in, int bus, int slot, int func, int coff, int bytes, uint32_t *val); @@ -1061,11 +1068,13 @@ pci_emul_init(struct vmctx *ctx, struct pci_devemu *pde, int bus, int slot, pdi->pi_bus = bus; pdi->pi_slot = slot; pdi->pi_func = func; +#ifdef __amd64__ pthread_mutex_init(&pdi->pi_lintr.lock, NULL); pdi->pi_lintr.pin = 0; pdi->pi_lintr.state = IDLE; pdi->pi_lintr.pirq_pin = 0; pdi->pi_lintr.ioapic_irq = 0; +#endif pdi->pi_d = pde; snprintf(pdi->pi_name, PI_NAMESZ, "%s@pci.%d.%d.%d", pde->pe_emu, bus, slot, func); @@ -1203,7 +1212,9 @@ msixcap_cfgwrite(struct pci_devinst *pi, int capoff, int offset, pi->pi_msix.enabled = val & PCIM_MSIXCTRL_MSIX_ENABLE; pi->pi_msix.function_mask = val & PCIM_MSIXCTRL_FUNCTION_MASK; +#ifdef __amd64__ pci_lintr_update(pi); +#endif } CFGWRITE(pi, offset, val, bytes); @@ -1245,7 +1256,9 @@ msicap_cfgwrite(struct pci_devinst *pi, int capoff, int offset, } else { pi->pi_msi.maxmsgnum = 0; } +#ifdef __amd64__ pci_lintr_update(pi); +#endif } static void @@ -1538,6 +1551,7 @@ init_pci(struct vmctx *ctx) bi->memlimit64 = pci_emul_membase64; } +#ifdef __amd64__ /* * PCI backends are initialized before routing INTx interrupts * so that LPC devices are able to reserve ISA IRQs before @@ -1558,6 +1572,7 @@ init_pci(struct vmctx *ctx) } } lpc_pirq_routed(); +#endif if ((error = init_bootorder()) != 0) { warnx("%s: Unable to init bootorder", __func__); @@ -1601,6 +1616,7 @@ init_pci(struct vmctx *ctx) return (0); } +#ifdef __amd64__ static void pci_apic_prt_entry(int bus __unused, int slot, int pin, int pirq_pin __unused, int ioapic_irq, void *arg __unused) @@ -1633,6 +1649,7 @@ pci_pirq_prt_entry(int bus __unused, int slot, int pin, int pirq_pin, dsdt_line(" },"); free(name); } +#endif /* * A bhyve virtual machine has a flat PCI hierarchy with a root port @@ -1644,7 +1661,7 @@ pci_bus_write_dsdt(int bus) struct businfo *bi; struct slotinfo *si; struct pci_devinst *pi; - int count, func, slot; + int func, slot; /* * If there are no devices on this 'bus' then just return. @@ -1747,8 +1764,8 @@ pci_bus_write_dsdt(int bus) dsdt_line(" ,, , AddressRangeMemory, TypeStatic)"); dsdt_line(" })"); - count = pci_count_lintr(bus); - if (count != 0) { +#ifdef __amd64__ + if (pci_count_lintr(bus) != 0) { dsdt_indent(2); dsdt_line("Name (PPRT, Package ()"); dsdt_line("{"); @@ -1771,6 +1788,7 @@ pci_bus_write_dsdt(int bus) dsdt_line("}"); dsdt_unindent(2); } +#endif dsdt_indent(2); for (slot = 0; slot < MAXSLOTS; slot++) { @@ -1866,6 +1884,7 @@ pci_generate_msi(struct pci_devinst *pi, int index) } } +#ifdef __amd64__ static bool pci_lintr_permitted(struct pci_devinst *pi) { @@ -2026,6 +2045,7 @@ pci_walk_lintr(int bus, pci_lintr_cb cb, void *arg) } } } +#endif /* __amd64__ */ /* * Return 1 if the emulated device in 'slot' is a multi-function device. @@ -2130,11 +2150,13 @@ pci_emul_cmd_changed(struct pci_devinst *pi, uint16_t old) } } +#ifdef __amd64__ /* * If INTx has been unmasked and is pending, assert the * interrupt. */ pci_lintr_update(pi); +#endif } static void diff --git a/usr.sbin/bhyve/pci_emul.h b/usr.sbin/bhyve/pci_emul.h index 0fd438151093..c367169113f8 100644 --- a/usr.sbin/bhyve/pci_emul.h +++ b/usr.sbin/bhyve/pci_emul.h @@ -115,12 +115,6 @@ struct msix_table_entry { #define MAX_MSIX_TABLE_ENTRIES 2048 #define PBA_SIZE(msgnum) (roundup2((msgnum), 64) / 8) -enum lintr_stat { - IDLE, - ASSERTED, - PENDING -}; - struct pci_devinst { struct pci_devemu *pi_d; struct vmctx *pi_vmctx; @@ -130,13 +124,19 @@ struct pci_devinst { int pi_prevcap; int pi_capend; +#ifdef __amd64__ struct { int8_t pin; - enum lintr_stat state; + enum { + IDLE, + ASSERTED, + PENDING, + } state; int pirq_pin; int ioapic_irq; pthread_mutex_t lock; } pi_lintr; +#endif struct { int enabled; @@ -221,8 +221,15 @@ struct pciecap { } __packed; static_assert(sizeof(struct pciecap) == 60, "compile-time assertion failed"); +#ifdef __amd64__ typedef void (*pci_lintr_cb)(int b, int s, int pin, int pirq_pin, int ioapic_irq, void *arg); +void pci_lintr_assert(struct pci_devinst *pi); +void pci_lintr_deassert(struct pci_devinst *pi); +void pci_lintr_request(struct pci_devinst *pi); +int pci_count_lintr(int bus); +void pci_walk_lintr(int bus, pci_lintr_cb cb, void *arg); +#endif int init_pci(struct vmctx *ctx); void pci_callback(void); @@ -241,9 +248,6 @@ void pci_emul_capwrite(struct pci_devinst *pi, int offset, int bytes, void pci_emul_cmd_changed(struct pci_devinst *pi, uint16_t old); void pci_generate_msi(struct pci_devinst *pi, int msgnum); void pci_generate_msix(struct pci_devinst *pi, int msgnum); -void pci_lintr_assert(struct pci_devinst *pi); -void pci_lintr_deassert(struct pci_devinst *pi); -void pci_lintr_request(struct pci_devinst *pi); int pci_msi_enabled(struct pci_devinst *pi); int pci_msix_enabled(struct pci_devinst *pi); int pci_msix_table_bar(struct pci_devinst *pi); @@ -257,11 +261,10 @@ int pci_emul_add_msixcap(struct pci_devinst *pi, int msgnum, int barnum); int pci_emul_msix_twrite(struct pci_devinst *pi, uint64_t offset, int size, uint64_t value); uint64_t pci_emul_msix_tread(struct pci_devinst *pi, uint64_t offset, int size); -int pci_count_lintr(int bus); -void pci_walk_lintr(int bus, pci_lintr_cb cb, void *arg); void pci_write_dsdt(void); uint64_t pci_ecfg_base(void); int pci_bus_configured(int bus); + #ifdef BHYVE_SNAPSHOT struct pci_devinst *pci_next(const struct pci_devinst *cursor); int pci_snapshot(struct vm_snapshot_meta *meta); diff --git a/usr.sbin/bhyve/qemu_fwcfg.c b/usr.sbin/bhyve/qemu_fwcfg.c index e845c70950b1..73a401ad8a81 100644 --- a/usr.sbin/bhyve/qemu_fwcfg.c +++ b/usr.sbin/bhyve/qemu_fwcfg.c @@ -23,7 +23,9 @@ #include "acpi_device.h" #include "bhyverun.h" #include "inout.h" -#include "pci_lpc.h" +#ifdef __amd64__ +#include "amd64/pci_lpc.h" +#endif #include "qemu_fwcfg.h" #define QEMU_FWCFG_ACPI_DEVICE_NAME "FWCF" @@ -423,6 +425,18 @@ int qemu_fwcfg_init(struct vmctx *const ctx) { int error; + bool fwcfg_enabled; + + /* + * The fwcfg implementation currently only provides an I/O port + * interface and thus is amd64-specific for now. An MMIO interface is + * required for other platforms. + */ +#ifdef __amd64__ + fwcfg_enabled = strcmp(lpc_fwcfg(), "qemu") == 0; +#else + fwcfg_enabled = false; +#endif /* * Bhyve supports fwctl (bhyve) and fwcfg (qemu) as firmware interfaces. @@ -430,7 +444,7 @@ qemu_fwcfg_init(struct vmctx *const ctx) * interfaces at the same time to the guest. Therefore, only create acpi * tables and register io ports for fwcfg, if it's used. */ - if (strcmp(lpc_fwcfg(), "qemu") == 0) { + if (fwcfg_enabled) { error = acpi_device_create(&fwcfg_sc.acpi_dev, &fwcfg_sc, ctx, &qemu_fwcfg_acpi_device_emul); if (error) { diff --git a/usr.sbin/bhyve/virtio.h b/usr.sbin/bhyve/virtio.h index 2b72b862ab21..4c6c8004b2d1 100644 --- a/usr.sbin/bhyve/virtio.h +++ b/usr.sbin/bhyve/virtio.h @@ -358,7 +358,9 @@ vi_interrupt(struct virtio_softc *vs, uint8_t isr, uint16_t msix_idx) VS_LOCK(vs); vs->vs_isr |= isr; pci_generate_msi(vs->vs_pi, 0); +#ifdef __amd64__ pci_lintr_assert(vs->vs_pi); +#endif VS_UNLOCK(vs); } }