github.com/kata-containers/runtime@v0.0.0-20210505125100-04f29832a923/virtcontainers/qemu_arm64.go (about) 1 // Copyright (c) 2018 Intel Corporation 2 // 3 // SPDX-License-Identifier: Apache-2.0 4 // 5 6 package virtcontainers 7 8 import ( 9 "context" 10 "fmt" 11 "time" 12 13 govmmQemu "github.com/kata-containers/govmm/qemu" 14 "github.com/kata-containers/runtime/virtcontainers/types" 15 ) 16 17 type qemuArm64 struct { 18 // inherit from qemuArchBase, overwrite methods if needed 19 qemuArchBase 20 } 21 22 const defaultQemuPath = "/usr/bin/qemu-system-aarch64" 23 24 const defaultQemuMachineType = QemuVirt 25 26 const qmpMigrationWaitTimeout = 10 * time.Second 27 28 const defaultQemuMachineOptions = "usb=off,accel=kvm,gic-version=host" 29 30 var defaultGICVersion = uint32(3) 31 32 var qemuPaths = map[string]string{ 33 QemuVirt: defaultQemuPath, 34 } 35 36 var kernelParams = []Param{ 37 {"console", "hvc0"}, 38 {"console", "hvc1"}, 39 {"iommu.passthrough", "0"}, 40 } 41 42 var supportedQemuMachines = []govmmQemu.Machine{ 43 { 44 Type: QemuVirt, 45 Options: defaultQemuMachineOptions, 46 }, 47 } 48 49 //In qemu, maximum number of vCPUs depends on the GIC version, or on how 50 //many redistributors we can fit into the memory map. 51 //related codes are under github.com/qemu/qemu/hw/arm/virt.c(Line 135 and 1306 in stable-2.11) 52 //for now, qemu only supports v2 and v3, we treat v4 as v3 based on 53 //backward compatibility. 54 var gicList = map[uint32]uint32{ 55 uint32(2): uint32(8), 56 uint32(3): uint32(123), 57 uint32(4): uint32(123), 58 } 59 60 // MaxQemuVCPUs returns the maximum number of vCPUs supported 61 func MaxQemuVCPUs() uint32 { 62 return gicList[defaultGICVersion] 63 } 64 65 func newQemuArch(config HypervisorConfig) qemuArch { 66 machineType := config.HypervisorMachineType 67 if machineType == "" { 68 machineType = defaultQemuMachineType 69 } 70 71 qemuMachines := make([]govmmQemu.Machine, len(supportedQemuMachines)) 72 copy(qemuMachines, supportedQemuMachines) 73 74 q := &qemuArm64{ 75 qemuArchBase{ 76 machineType: machineType, 77 memoryOffset: config.MemOffset, 78 qemuPaths: qemuPaths, 79 supportedQemuMachines: qemuMachines, 80 kernelParamsNonDebug: kernelParamsNonDebug, 81 kernelParamsDebug: kernelParamsDebug, 82 kernelParams: kernelParams, 83 disableNvdimm: config.DisableImageNvdimm, 84 dax: true, 85 }, 86 } 87 88 q.handleImagePath(config) 89 90 return q 91 } 92 93 func (q *qemuArm64) bridges(number uint32) { 94 q.Bridges = genericBridges(number, q.machineType) 95 } 96 97 // appendBridges appends to devices the given bridges 98 func (q *qemuArm64) appendBridges(devices []govmmQemu.Device) []govmmQemu.Device { 99 return genericAppendBridges(devices, q.Bridges, q.machineType) 100 } 101 102 func (q *qemuArm64) appendImage(devices []govmmQemu.Device, path string) ([]govmmQemu.Device, error) { 103 if !q.disableNvdimm { 104 return q.appendNvdimmImage(devices, path) 105 } 106 return q.appendBlockImage(devices, path) 107 } 108 109 func (q *qemuArm64) setIgnoreSharedMemoryMigrationCaps(_ context.Context, _ *govmmQemu.QMP) error { 110 // x-ignore-shared not support in arm64 for now 111 return nil 112 } 113 114 func (q *qemuArm64) appendIOMMU(devices []govmmQemu.Device) ([]govmmQemu.Device, error) { 115 return devices, fmt.Errorf("Arm64 architecture does not support vIOMMU") 116 } 117 118 func (q *qemuArm64) append9PVolume(devices []govmmQemu.Device, volume types.Volume) ([]govmmQemu.Device, error) { 119 d, err := genericAppend9PVolume(devices, volume, q.nestedRun) 120 if err != nil { 121 return nil, err 122 } 123 124 d.Multidev = "" 125 devices = append(devices, d) 126 return devices, nil 127 } 128 129 func (q *qemuArm64) getPFlash() ([]string, error) { 130 length := len(q.PFlash) 131 if length == 0 { 132 return nil, nil 133 } else if length == 1 { 134 return nil, fmt.Errorf("two pflash images needed for arm64") 135 } else if length == 2 { 136 return q.PFlash, nil 137 } else { 138 return nil, fmt.Errorf("too many pflash images for arm64") 139 } 140 }