mirror of
https://github.com/aljazceru/kata-containers.git
synced 2025-12-26 18:44:47 +01:00
This value will be plused to max memory of hypervisor. It is the memory address space for the NVDIMM devie. If set block storage driver (block_device_driver) to "nvdimm", should set memory_offset to the size of block device. Signed-off-by: Hui Zhu <teawater@hyper.sh>
156 lines
3.9 KiB
Go
156 lines
3.9 KiB
Go
// Copyright (c) 2018 Intel Corporation
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
package virtcontainers
|
|
|
|
import (
|
|
"io/ioutil"
|
|
"runtime"
|
|
"strings"
|
|
|
|
govmmQemu "github.com/intel/govmm/qemu"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
type qemuArm64 struct {
|
|
// inherit from qemuArchBase, overwrite methods if needed
|
|
qemuArchBase
|
|
}
|
|
|
|
const defaultQemuPath = "/usr/bin/qemu-system-aarch64"
|
|
|
|
const defaultQemuMachineType = QemuVirt
|
|
|
|
var defaultQemuMachineOptions = "usb=off,accel=kvm,gic-version=" + getGuestGICVersion()
|
|
|
|
// Not used
|
|
const defaultPCBridgeBus = ""
|
|
|
|
var qemuPaths = map[string]string{
|
|
QemuVirt: defaultQemuPath,
|
|
}
|
|
|
|
var kernelParams = []Param{
|
|
{"console", "hvc0"},
|
|
{"console", "hvc1"},
|
|
{"iommu.passthrough", "0"},
|
|
}
|
|
|
|
var kernelRootParams = []Param{
|
|
{"root", "/dev/vda1"},
|
|
}
|
|
|
|
var supportedQemuMachines = []govmmQemu.Machine{
|
|
{
|
|
Type: QemuVirt,
|
|
Options: defaultQemuMachineOptions,
|
|
},
|
|
}
|
|
|
|
// Logger returns a logrus logger appropriate for logging qemu-aarch64 messages
|
|
func qemuArmLogger() *logrus.Entry {
|
|
return virtLog.WithField("subsystem", "qemu-aarch64")
|
|
}
|
|
|
|
// On ARM platform, we have different GIC interrupt controllers. Different
|
|
// GIC supports different QEMU parameters for virtual GIC and max VCPUs
|
|
var hostGICVersion = getHostGICVersion()
|
|
|
|
// We will access this file on host to detect host GIC version
|
|
var gicProfile = "/proc/interrupts"
|
|
|
|
// Detect the host GIC version.
|
|
// Success: return the number of GIC version
|
|
// Failed: return 0
|
|
func getHostGICVersion() (version uint32) {
|
|
bytes, err := ioutil.ReadFile(gicProfile)
|
|
if err != nil {
|
|
qemuArmLogger().WithField("GIC profile", gicProfile).WithError(err).Error("Failed to parse GIC profile")
|
|
return 0
|
|
}
|
|
|
|
s := string(bytes)
|
|
if strings.Contains(s, "GICv2") {
|
|
return 2
|
|
}
|
|
|
|
if strings.Contains(s, "GICv3") {
|
|
return 3
|
|
}
|
|
|
|
if strings.Contains(s, "GICv4") {
|
|
return 4
|
|
}
|
|
|
|
return 0
|
|
}
|
|
|
|
// QEMU supports GICv2, GICv3 and host parameters for gic-version. The host
|
|
// parameter will let QEMU detect GIC version by itself. This parameter
|
|
// will work properly when host GIC version is GICv2 or GICv3. But the
|
|
// detection will failed when host GIC is gicv4 or higher. In this case,
|
|
// we have to detect the host GIC version manually and force QEMU to use
|
|
// GICv3 when host GIC is GICv4 or higher.
|
|
func getGuestGICVersion() (version string) {
|
|
if hostGICVersion == 2 {
|
|
return "2"
|
|
}
|
|
|
|
if hostGICVersion >= 3 {
|
|
return "3"
|
|
}
|
|
|
|
// We can't parse valid host GIC version from GIC profile.
|
|
// But we can use "host" to ask QEMU to detect valid GIC
|
|
// through KVM API for a try.
|
|
return "host"
|
|
}
|
|
|
|
//In qemu, maximum number of vCPUs depends on the GIC version, or on how
|
|
//many redistributors we can fit into the memory map.
|
|
//related codes are under github.com/qemu/qemu/hw/arm/virt.c(Line 135 and 1306 in stable-2.11)
|
|
//for now, qemu only supports v2 and v3, we treat v4 as v3 based on
|
|
//backward compatibility.
|
|
var gicList = map[uint32]uint32{
|
|
uint32(2): uint32(8),
|
|
uint32(3): uint32(123),
|
|
uint32(4): uint32(123),
|
|
}
|
|
|
|
// MaxQemuVCPUs returns the maximum number of vCPUs supported
|
|
func MaxQemuVCPUs() uint32 {
|
|
if hostGICVersion != 0 {
|
|
return gicList[hostGICVersion]
|
|
}
|
|
return uint32(runtime.NumCPU())
|
|
}
|
|
|
|
func newQemuArch(config HypervisorConfig) qemuArch {
|
|
machineType := config.HypervisorMachineType
|
|
if machineType == "" {
|
|
machineType = defaultQemuMachineType
|
|
}
|
|
|
|
q := &qemuArm64{
|
|
qemuArchBase{
|
|
machineType: machineType,
|
|
memoryOffset: config.MemOffset,
|
|
qemuPaths: qemuPaths,
|
|
supportedQemuMachines: supportedQemuMachines,
|
|
kernelParamsNonDebug: kernelParamsNonDebug,
|
|
kernelParamsDebug: kernelParamsDebug,
|
|
kernelParams: kernelParams,
|
|
},
|
|
}
|
|
|
|
if config.ImagePath != "" {
|
|
q.kernelParams = append(q.kernelParams, kernelRootParams...)
|
|
q.kernelParamsNonDebug = append(q.kernelParamsNonDebug, kernelParamsSystemdNonDebug...)
|
|
q.kernelParamsDebug = append(q.kernelParamsDebug, kernelParamsSystemdDebug...)
|
|
}
|
|
|
|
return q
|
|
}
|