github.com/vmware/govmomi@v0.51.0/cli/device/pci/add.go (about) 1 // © Broadcom. All Rights Reserved. 2 // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 // SPDX-License-Identifier: Apache-2.0 4 5 package pci 6 7 import ( 8 "context" 9 "errors" 10 "flag" 11 "fmt" 12 13 "github.com/vmware/govmomi/cli" 14 "github.com/vmware/govmomi/cli/flags" 15 "github.com/vmware/govmomi/vim25/types" 16 ) 17 18 type add struct { 19 *flags.VirtualMachineFlag 20 } 21 22 func init() { 23 cli.Register("device.pci.add", &add{}) 24 } 25 26 func (cmd *add) Register(ctx context.Context, f *flag.FlagSet) { 27 cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx) 28 cmd.VirtualMachineFlag.Register(ctx, f) 29 } 30 31 func (cmd *add) Description() string { 32 return `Add PCI Passthrough device to VM. 33 34 Examples: 35 govc device.pci.ls -vm $vm 36 govc device.pci.add -vm $vm $pci_address 37 govc device.info -vm $vm 38 39 Assuming vm name is helloworld, list command has below output 40 41 $ govc device.pci.ls -vm helloworld 42 System ID Address Vendor Name Device Name 43 5b087ce4-ce46-72c0-c7c2-28ac9e22c3c2 0000:60:00.0 Pensando Ethernet Controller 1 44 5b087ce4-ce46-72c0-c7c2-28ac9e22c3c2 0000:61:00.0 Pensando Ethernet Controller 2 45 46 To add only 'Ethernet Controller 1', command should be as below. No output upon success. 47 48 $ govc device.pci.add -vm helloworld 0000:60:00.0 49 50 To add both 'Ethernet Controller 1' and 'Ethernet Controller 2', command should be as below. 51 No output upon success. 52 53 $ govc device.pci.add -vm helloworld 0000:60:00.0 0000:61:00.0 54 55 $ govc device.info -vm helloworld 56 ... 57 Name: pcipassthrough-13000 58 Type: VirtualPCIPassthrough 59 Label: PCI device 0 60 Summary: 61 Key: 13000 62 Controller: pci-100 63 Unit number: 18 64 Name: pcipassthrough-13001 65 Type: VirtualPCIPassthrough 66 Label: PCI device 1 67 Summary: 68 Key: 13001 69 Controller: pci-100 70 Unit number: 19` 71 } 72 73 func (cmd *add) Usage() string { 74 return "PCI_ADDRESS..." 75 } 76 77 func (cmd *add) Run(ctx context.Context, f *flag.FlagSet) error { 78 if len(f.Args()) == 0 { 79 return flag.ErrHelp 80 } 81 82 reqDevices := map[string]*types.VirtualMachinePciPassthroughInfo{} 83 for _, n := range f.Args() { 84 reqDevices[n] = nil 85 } 86 87 vm, err := cmd.VirtualMachine() 88 if err != nil { 89 return err 90 } 91 if vm == nil { 92 return flag.ErrHelp 93 } 94 95 vmConfigOptions, err := queryConfigTarget(ctx, vm) 96 if err != nil { 97 return err 98 } 99 100 for _, d := range vmConfigOptions.PciPassthrough { 101 info := d.GetVirtualMachinePciPassthroughInfo() 102 if info == nil { 103 return errors.New("received invalid pci passthrough info") 104 } 105 106 _, ok := reqDevices[info.PciDevice.Id] 107 if !ok { 108 continue 109 } 110 reqDevices[info.PciDevice.Id] = info 111 } 112 113 newDevices := []types.BaseVirtualDevice{} 114 for id, d := range reqDevices { 115 if d == nil { 116 return fmt.Errorf("%s is not found in allowed PCI passthrough device list", id) 117 } 118 device := &types.VirtualPCIPassthrough{} 119 device.Backing = &types.VirtualPCIPassthroughDeviceBackingInfo{ 120 Id: d.PciDevice.Id, DeviceId: fmt.Sprintf("%x", d.PciDevice.DeviceId), 121 SystemId: d.SystemId, VendorId: d.PciDevice.VendorId, 122 } 123 device.Connectable = &types.VirtualDeviceConnectInfo{StartConnected: true, Connected: true} 124 newDevices = append(newDevices, device) 125 } 126 127 return vm.AddDevice(ctx, newDevices...) 128 }