FW: newbus and acpi issue on Hyper-V
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 14 Oct 2022 06:03:19 UTC
Hi, We are working on enabling FreeBSD running on ARM64 Hyper-V at Microsoft. Right now we are hitting a road blocker which seems only happening on FreeBSD guest, due to its newbus architecture and how resources are presented in Hyper-V's ACPI tables. I am writing in hope to find a short term solution or workaround. Without it, it would be hard to make SRIOV work on ARM64 FreeBSD guests. Appreciate any inputs. Here are the details. Hyper-V presents two system resources at two different places/nodes in its ACPI table. 1) PCI mmio resource in HID "ACPI0004", which is needed by the FreeBSD guest for SRIOV devices. Device (\_SB.VMOD) <-- This is currently owned by acpi_syscontainer module on FreeBSD { Name (_HID, "ACPI0004" /* Module Device */) // _HID: Hardware ID Name (_UID, Zero) // _UID: Unique ID Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings { ... } CreateDWordField (_CRS, \_SB.VMOD._Y00._MIN, MIN6) // _MIN: Minimum Base Address CreateDWordField (_CRS, \_SB.VMOD._Y00._MAX, MAX6) // _MAX: Maximum Base Address CreateDWordField (_CRS, \_SB.VMOD._Y00._LEN, LEN6) // _LEN: Length CreateQWordField (_CRS, \_SB.VMOD._Y01._MIN, MIN7) // _MIN: Minimum Base Address CreateQWordField (_CRS, \_SB.VMOD._Y01._MAX, MAX7) // _MAX: Maximum Base Address CreateQWordField (_CRS, \_SB.VMOD._Y01._LEN, LEN7) // _LEN: Length Method (_INI, 0, NotSerialized) // _INI: Initialize { MIN6 = MG2B /* \MG2B */ LEN6 = MG2L /* \MG2L */ Local0 = MG2L /* \MG2L */ MAX6 = (MIN6 + Local0--) Local1 = (HMIB << 0x14) Local2 = (HMIL << 0x14) MIN7 = Local1 LEN7 = Local2 Local0 = Local2 MAX7 = (MIN7 + Local0--) } } 2) Vmbus IRQ resource in HID "VMBus", which is needed to get Hyper-V vmbus interrupt to work on guests. Device (\_SB.VMOD.VMBS) <--- currently owned by vmbus_res module on FreeBSD { ... Name (_HID, "VMBus") // _HID: Hardware ID Name (_UID, Zero) // _UID: Unique ID ... Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings { Interrupt (ResourceConsumer, Edge, ActiveHigh, Exclusive, ,, ) { 0x00000012, } }) } On x86, FreeBSD just needs PCI mmio resource 1). We ignore the vmbus IRQ resource in the ACPI and pick a fixed vector for all cpu interrupt. But on ARM64, the guest needs all the information in order to make bus_alloc_resouce() to work for both interrupt and mmio. Therefore, the main Hyper-V device driver vmbus needs to be the child for both these nodes to make the resource allocation to work. But it seems to us that one device driver can only have one parent in the newbus architecture, we can only make one resource allocation to work in this scenario, either IRQ or mmio, but not both. Following is a picture of current device tree on a AMD64 FreeBSD guest on Hyper-V [cid:image002.png@01D8DF2F.A3DB8800] As you can see vmbus module is under acpi_syscontainer which owns PCI mmio resource. The vmbus IRQ resouce is owned by vmbus_res module, which is just a place holder for this resouce and never been used on am64. On ARM64, vmbus module needs to be the child for both vmbus_res and acpi_syscontainer to get the both resources, which doesn't seem to be possible under newbus architecture. Any suggestions or workarounds are welcome. Thanks in advacne. Wei