From 275adba4eaedea520adb44ef3c47555256eec6cf Mon Sep 17 00:00:00 2001 From: wanyaoqi Date: Thu, 23 Feb 2023 18:28:21 +0800 Subject: [PATCH] fix(host): load existing guests desc init device desc after load pci infos Signed-off-by: wanyaoqi --- pkg/hostman/guestman/pci.go | 137 ++++++++++++++++++++------ pkg/hostman/guestman/pci_test.go | 2 +- pkg/hostman/guestman/qemu-kvm.go | 10 +- pkg/hostman/guestman/qemu/generate.go | 16 +-- 4 files changed, 123 insertions(+), 42 deletions(-) diff --git a/pkg/hostman/guestman/pci.go b/pkg/hostman/guestman/pci.go index 1f0e66ec68..d4866c593f 100644 --- a/pkg/hostman/guestman/pci.go +++ b/pkg/hostman/guestman/pci.go @@ -57,7 +57,7 @@ func (s *SKVMGuestInstance) initGuestDesc() error { s.initMemDesc(s.Desc.Mem) s.initMachineDesc() - pciRoot, pciBridge := s.initGuestPciControllers() + pciRoot, pciBridge := s.initGuestPciControllers(true) err = s.initGuestPciAddresses() if err != nil { return errors.Wrap(err, "init guest pci addresses") @@ -85,7 +85,7 @@ func (s *SKVMGuestInstance) initGuestDevicesDesc(pciRoot, pciBridge *desc.PCICon s.initGuestVga(pciRoot) s.initCdromDesc() s.initFloppyDesc() - s.initGuestDisks(pciRoot, pciBridge) + s.initGuestDisks(pciRoot, pciBridge, false) if err := s.initGuestNetworks(pciRoot, pciBridge); err != nil { return errors.Wrap(err, "init guest networks") } @@ -202,15 +202,23 @@ func (s *SKVMGuestInstance) isMachineDefaultAddress(pciAddr *desc.PCIAddr) bool return false } -func (s *SKVMGuestInstance) initGuestPciControllers() (*desc.PCIController, *desc.PCIController) { - var isPcie = s.isPcie() +func (s *SKVMGuestInstance) initGuestPciControllers(pciExtend bool) (*desc.PCIController, *desc.PCIController) { var pciRoot, pciBridge *desc.PCIController - if isPcie { + if len(s.Desc.PCIControllers) > 0 { + pciRoot = s.Desc.PCIControllers[0] + if len(s.Desc.PCIControllers) > 1 { + pciBridge = s.Desc.PCIControllers[1] + } + return pciRoot, pciBridge + } + if s.isPcie() { pciRoot = s.addPCIController(desc.CONTROLLER_TYPE_PCIE_ROOT, "") s.addPCIController(desc.CONTROLLER_TYPE_PCIE_TO_PCI_BRIDGE, desc.CONTROLLER_TYPE_PCIE_ROOT) - pciBridge = s.addPCIController(desc.CONTROLLER_TYPE_PCI_BRIDGE, desc.CONTROLLER_TYPE_PCIE_TO_PCI_BRIDGE) - for i := 0; i < options.HostOptions.PcieRootPortCount; i++ { - s.addPCIController(desc.CONTROLLER_TYPE_PCIE_ROOT_PORT, desc.CONTROLLER_TYPE_PCIE_ROOT) + if pciExtend { + pciBridge = s.addPCIController(desc.CONTROLLER_TYPE_PCI_BRIDGE, desc.CONTROLLER_TYPE_PCIE_TO_PCI_BRIDGE) + for i := 0; i < options.HostOptions.PcieRootPortCount; i++ { + s.addPCIController(desc.CONTROLLER_TYPE_PCIE_ROOT_PORT, desc.CONTROLLER_TYPE_PCIE_ROOT) + } } } else { pciRoot = s.addPCIController(desc.CONTROLLER_TYPE_PCI_ROOT, "") @@ -375,17 +383,20 @@ func (s *SKVMGuestInstance) initFloppyDesc() { } } -func (s *SKVMGuestInstance) initGuestDisks(pciRoot, pciBridge *desc.PCIController) { - hasVirtioScsi, hasPvScsi := s.fixDiskDriver() - if hasVirtioScsi && s.Desc.VirtioScsi == nil { - s.Desc.VirtioScsi = &desc.SGuestVirtioScsi{ - PCIDevice: desc.NewPCIDevice(pciRoot.CType, "virtio-scsi-pci", "scsi"), - } - } else if hasPvScsi && s.Desc.PvScsi == nil { - s.Desc.PvScsi = &desc.SGuestPvScsi{ - PCIDevice: desc.NewPCIDevice(pciRoot.CType, "pvscsi", "scsi"), +func (s *SKVMGuestInstance) initGuestDisks(pciRoot, pciBridge *desc.PCIController, loadGuest bool) { + if !loadGuest { + hasVirtioScsi, hasPvScsi := s.fixDiskDriver() + if hasVirtioScsi && s.Desc.VirtioScsi == nil { + s.Desc.VirtioScsi = &desc.SGuestVirtioScsi{ + PCIDevice: desc.NewPCIDevice(pciRoot.CType, "virtio-scsi-pci", "scsi"), + } + } else if hasPvScsi && s.Desc.PvScsi == nil { + s.Desc.PvScsi = &desc.SGuestPvScsi{ + PCIDevice: desc.NewPCIDevice(pciRoot.CType, "pvscsi", "scsi"), + } } } + cont := pciRoot if pciBridge != nil { cont = pciBridge @@ -717,16 +728,21 @@ func (s *SKVMGuestInstance) initGuestDescFromExistingGuest( } s.initMachineDesc() - pciRoot, _ := s.initGuestPciControllers() + // TODO: pcie extend bus + pciRoot, _ := s.initGuestPciControllers(false) err = s.initGuestPciAddresses() if err != nil { return errors.Wrap(err, "init guest pci addresses") } - err = s.initGuestDevicesDesc(pciRoot, nil) - if err != nil { - return err + if err := s.initGuestNetworks(pciRoot, nil); err != nil { + return errors.Wrap(err, "init guest networks") } + //s.initIsolatedDevices(pciRoot, nil) + s.initQgaDesc() + s.initPvpanicDesc() + s.initIsaSerialDesc() + s.Desc.VdiDevice = new(desc.SGuestVdi) for i := 0; i < len(pciInfoList[0].Devices); i++ { pciAddr := &desc.PCIAddr{ @@ -736,6 +752,17 @@ func (s *SKVMGuestInstance) initGuestDescFromExistingGuest( } switch pciInfoList[0].Devices[i].QdevID { case "scsi": + _, hasPvScsi := s.fixDiskDriver() + if hasPvScsi && s.Desc.PvScsi == nil { + s.Desc.PvScsi = &desc.SGuestPvScsi{ + PCIDevice: desc.NewPCIDevice(pciRoot.CType, "pvscsi", "scsi"), + } + } else if s.Desc.VirtioScsi == nil { + s.Desc.VirtioScsi = &desc.SGuestVirtioScsi{ + PCIDevice: desc.NewPCIDevice(pciRoot.CType, "virtio-scsi-pci", "scsi"), + } + } + if s.Desc.VirtioScsi != nil { s.Desc.VirtioScsi.PCIAddr = pciAddr err = s.ensureDevicePciAddress(s.Desc.VirtioScsi.PCIDevice, -1, nil) @@ -754,6 +781,10 @@ func (s *SKVMGuestInstance) initGuestDescFromExistingGuest( } } case "video0": + if s.Desc.VgaDevice == nil { + s.initGuestVga(pciRoot) + } + s.Desc.VgaDevice.PCIAddr = pciAddr err = s.ensureDevicePciAddress(s.Desc.VgaDevice.PCIDevice, -1, nil) if err != nil { @@ -770,6 +801,10 @@ func (s *SKVMGuestInstance) initGuestDescFromExistingGuest( return errors.Wrap(err, "ensure random device pci address") } case "usb": + if s.Desc.Usb == nil { + s.initUsbController(pciRoot) + } + s.Desc.Usb.PCIAddr = pciAddr err = s.ensureDevicePciAddress(s.Desc.Usb.PCIDevice, -1, nil) if err != nil { @@ -796,6 +831,10 @@ func (s *SKVMGuestInstance) initGuestDescFromExistingGuest( return errors.Wrap(err, "ensure vdagent serial pci address") } case "virtio-serial0": + if s.Desc.VirtioSerial == nil { + s.initVirtioSerial(pciRoot) + } + s.Desc.VirtioSerial.PCIAddr = pciAddr err = s.ensureDevicePciAddress(s.Desc.VirtioSerial.PCIDevice, -1, nil) if err != nil { @@ -808,24 +847,42 @@ func (s *SKVMGuestInstance) initGuestDescFromExistingGuest( } s.Desc.VdiDevice.Spice.UsbRedirct.EHCI1.PCIAddr = pciAddr multiFunc := true - err = s.ensureDevicePciAddress(s.Desc.VdiDevice.Spice.UsbRedirct.EHCI1.PCIDevice, 7, &multiFunc) + err = s.ensureDevicePciAddress(s.Desc.VdiDevice.Spice.UsbRedirct.EHCI1.PCIDevice, -1, &multiFunc) if err != nil { return errors.Wrap(err, "ensure vdi usb ehci1 pci address") } - s.Desc.VdiDevice.Spice.UsbRedirct.UHCI1.PCIAddr = s.Desc.VdiDevice.Spice.UsbRedirct.EHCI1.PCIAddr.Copy() - err = s.ensureDevicePciAddress(s.Desc.VdiDevice.Spice.UsbRedirct.UHCI1.PCIDevice, 0, &multiFunc) - if err != nil { - return errors.Wrap(err, "ensure vdi usb ehci1 pci address") + case "uhci1": + if s.Desc.VdiDevice.Spice == nil { + s.Desc.Vdi = "spice" + s.initSpiceDevices(pciRoot) } - s.Desc.VdiDevice.Spice.UsbRedirct.UHCI2.PCIAddr = s.Desc.VdiDevice.Spice.UsbRedirct.UHCI1.PCIAddr.Copy() - err = s.ensureDevicePciAddress(s.Desc.VdiDevice.Spice.UsbRedirct.UHCI2.PCIDevice, 1, &multiFunc) + multiFunc := true + s.Desc.VdiDevice.Spice.UsbRedirct.UHCI1.PCIAddr = pciAddr + err = s.ensureDevicePciAddress(s.Desc.VdiDevice.Spice.UsbRedirct.UHCI1.PCIDevice, -1, &multiFunc) if err != nil { - return errors.Wrap(err, "ensure vdi usb ehci1 pci address") + return errors.Wrap(err, "ensure vdi usb uhci1 pci address") } - s.Desc.VdiDevice.Spice.UsbRedirct.UHCI3.PCIAddr = s.Desc.VdiDevice.Spice.UsbRedirct.UHCI1.PCIAddr.Copy() - err = s.ensureDevicePciAddress(s.Desc.VdiDevice.Spice.UsbRedirct.UHCI3.PCIDevice, 2, &multiFunc) + case "uhci2": + if s.Desc.VdiDevice.Spice == nil { + s.Desc.Vdi = "spice" + s.initSpiceDevices(pciRoot) + } + multiFunc := true + s.Desc.VdiDevice.Spice.UsbRedirct.UHCI2.PCIAddr = pciAddr + err = s.ensureDevicePciAddress(s.Desc.VdiDevice.Spice.UsbRedirct.UHCI2.PCIDevice, -1, &multiFunc) if err != nil { - return errors.Wrap(err, "ensure vdi usb ehci1 pci address") + return errors.Wrap(err, "ensure vdi usb uhci2 pci address") + } + case "uhci3": + if s.Desc.VdiDevice.Spice == nil { + s.Desc.Vdi = "spice" + s.initSpiceDevices(pciRoot) + } + multiFunc := true + s.Desc.VdiDevice.Spice.UsbRedirct.UHCI3.PCIAddr = pciAddr + err = s.ensureDevicePciAddress(s.Desc.VdiDevice.Spice.UsbRedirct.UHCI3.PCIDevice, -1, &multiFunc) + if err != nil { + return errors.Wrap(err, "ensure vdi usb uhci3 pci address") } default: switch { @@ -844,6 +901,7 @@ func (s *SKVMGuestInstance) initGuestDescFromExistingGuest( s.Desc.Disks[i].Pci = desc.NewPCIDevice(pciRoot.CType, devType, pciInfoList[0].Devices[i].QdevID) s.Desc.Disks[i].Scsi = nil s.Desc.Disks[i].Ide = nil + s.Desc.Disks[i].Driver = DISK_DRIVER_VIRTIO } s.Desc.Disks[i].Pci.PCIAddr = pciAddr err = s.ensureDevicePciAddress(s.Desc.Disks[i].Pci, -1, nil) @@ -869,6 +927,10 @@ func (s *SKVMGuestInstance) initGuestDescFromExistingGuest( device := pciInfoList[0].Devices[i].ID.Device switch { // qemu: docs/specs/pci-ids.txt case class == 3075 && vendor == 6966 && device == 13: // { 0x0c03, "USB controller", "usb"}, 1b36:000d PCI xhci usb host adapter + if s.Desc.Usb == nil { + s.initUsbController(pciRoot) + } + s.Desc.Usb.PCIAddr = pciAddr err = s.ensureDevicePciAddress(s.Desc.Usb.PCIDevice, -1, nil) if err != nil { @@ -879,18 +941,27 @@ func (s *SKVMGuestInstance) initGuestDescFromExistingGuest( // in case rng device disable by host options s.initRandomDevice(pciRoot, true) } + s.Desc.Rng.PCIAddr = pciAddr err = s.ensureDevicePciAddress(s.Desc.Rng.PCIDevice, -1, nil) if err != nil { return errors.Wrap(err, "ensure random device pci address") } case class == 1920 && vendor == 6900 && device == 4099: // 0x0780, 1af4:1003 console device (legacy) + if s.Desc.VirtioSerial == nil { + s.initVirtioSerial(pciRoot) + } + s.Desc.VirtioSerial.PCIAddr = pciAddr err = s.ensureDevicePciAddress(s.Desc.VirtioSerial.PCIDevice, -1, nil) if err != nil { return errors.Wrap(err, "ensure virtio serial address") } case class == 768 && vendor == 4660 && device == 4369: // { 0x0300, "VGA controller", "display", 0x00ff}, PCI ID: 1234:1111 + if s.Desc.VgaDevice == nil { + s.initGuestVga(pciRoot) + } + s.Desc.VgaDevice.PCIAddr = pciAddr err = s.ensureDevicePciAddress(s.Desc.VgaDevice.PCIDevice, -1, nil) if err != nil { @@ -903,6 +974,8 @@ func (s *SKVMGuestInstance) initGuestDescFromExistingGuest( } } + s.initGuestDisks(pciRoot, nil, true) + for i := 0; i < len(unknownDevices); i++ { if unknownDevices[i].Bus == 0 && unknownDevices[i].Slot == 0 { continue // host bridge diff --git a/pkg/hostman/guestman/pci_test.go b/pkg/hostman/guestman/pci_test.go index 57dacdd1c0..4155b80a6e 100644 --- a/pkg/hostman/guestman/pci_test.go +++ b/pkg/hostman/guestman/pci_test.go @@ -158,7 +158,7 @@ func TestSKVMGuestInstance_initGuestDesc(t *testing.T) { } // s.initMachineDesc() - pciRoot, _ := s.initGuestPciControllers() + pciRoot, _ := s.initGuestPciControllers(true) err = s.initGuestPciAddresses() if err != nil { t.Error(err) diff --git a/pkg/hostman/guestman/qemu-kvm.go b/pkg/hostman/guestman/qemu-kvm.go index 89a92cc19c..7b5871cc5b 100644 --- a/pkg/hostman/guestman/qemu-kvm.go +++ b/pkg/hostman/guestman/qemu-kvm.go @@ -1009,9 +1009,13 @@ func (s *SKVMGuestInstance) syncStatusUnsync(reason string) { } func (s *SKVMGuestInstance) collectGuestDescription() error { - cpuList, err := s.getHotpluggableCPUList() - if err != nil { - return errors.Wrap(err, "get hotpluggable cpus") + var cpuList []monitor.HotpluggableCPU + var err error + if !s.manager.host.IsAarch64() { + cpuList, err = s.getHotpluggableCPUList() + if err != nil { + return errors.Wrap(err, "get hotpluggable cpus") + } } pciInfoList, err := s.getPciDevices() diff --git a/pkg/hostman/guestman/qemu/generate.go b/pkg/hostman/guestman/qemu/generate.go index b3ff7e1cd3..fa551048cb 100644 --- a/pkg/hostman/guestman/qemu/generate.go +++ b/pkg/hostman/guestman/qemu/generate.go @@ -686,12 +686,12 @@ func GenerateStartOptions( opts = append(opts, drvOpt.Device("isa-applesmc,osk=ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc")) } - if input.GuestDesc.Vga != "none" { + if input.GuestDesc.Vga != "none" && input.GuestDesc.VgaDevice != nil { opts = append(opts, generatePCIDeviceOption(input.GuestDesc.VgaDevice.PCIDevice)) } // vdi spice - if input.IsVdiSpice { + if input.IsVdiSpice && input.GuestDesc.VdiDevice != nil && input.GuestDesc.VdiDevice.Spice != nil { opts = append(opts, generateSpiceOptions(input.SpicePort, input.GuestDesc.VdiDevice.Spice)...) } else { opts = append(opts, drvOpt.VNC(input.VNCPort, input.VNCPassword)) @@ -735,16 +735,20 @@ func GenerateStartOptions( opts = append(opts, nicOpts...) if input.QemuArch == Arch_aarch64 { - opts = append(opts, generatePCIDeviceOption(input.GuestDesc.Usb.PCIDevice)) - for _, device := range input.Devices { - opts = append(opts, drvOpt.Device(device)) + if input.GuestDesc.Usb != nil { + opts = append(opts, generatePCIDeviceOption(input.GuestDesc.Usb.PCIDevice)) + for _, device := range input.Devices { + opts = append(opts, drvOpt.Device(device)) + } } } else { opts = append(opts, drvOpt.USB()) for _, device := range input.Devices { opts = append(opts, drvOpt.Device(device)) } - opts = append(opts, generatePCIDeviceOption(input.GuestDesc.Usb.PCIDevice)) + if input.GuestDesc.Usb != nil { + opts = append(opts, generatePCIDeviceOption(input.GuestDesc.Usb.PCIDevice)) + } } // isolated devices