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  }