From baa553da07e8e2ea48ca2a727cb72c959b4665e9 Mon Sep 17 00:00:00 2001 From: Nitesh Konkar Date: Thu, 31 May 2018 18:40:43 +0530 Subject: [PATCH] virtcontainers: Get qemu suppport for ppc64le Fixes #302 Signed-off-by: Nitesh Konkar niteshkonkar@in.ibm.com --- virtcontainers/hypervisor.go | 4 +- virtcontainers/qemu.go | 2 + virtcontainers/qemu_arch_base.go | 3 + virtcontainers/qemu_ppc64le.go | 137 +++++++++++++++++++++++++++++++ 4 files changed, 144 insertions(+), 2 deletions(-) create mode 100644 virtcontainers/qemu_ppc64le.go diff --git a/virtcontainers/hypervisor.go b/virtcontainers/hypervisor.go index 8b501a3f5a..44df113262 100644 --- a/virtcontainers/hypervisor.go +++ b/virtcontainers/hypervisor.go @@ -443,8 +443,8 @@ func getHostMemorySizeKb(memInfoPath string) (uint64, error) { // RunningOnVMM checks if the system is running inside a VM. func RunningOnVMM(cpuInfoPath string) (bool, error) { - if runtime.GOARCH == "arm64" { - virtLog.Debugf("Unable to know if the system is running inside a VM") + if runtime.GOARCH == "arm64" || runtime.GOARCH == "ppc64le" { + virtLog.Info("Unable to know if the system is running inside a VM") return false, nil } diff --git a/virtcontainers/qemu.go b/virtcontainers/qemu.go index b19c4e3e99..efb1699b72 100644 --- a/virtcontainers/qemu.go +++ b/virtcontainers/qemu.go @@ -971,6 +971,8 @@ func genericBridges(number uint32, machineType string) []Bridge { fallthrough case QemuPC: bt = pciBridge + case QemuPseries: + bt = pciBridge default: return nil } diff --git a/virtcontainers/qemu_arch_base.go b/virtcontainers/qemu_arch_base.go index 49e97b7e02..54dbc3d1e3 100644 --- a/virtcontainers/qemu_arch_base.go +++ b/virtcontainers/qemu_arch_base.go @@ -134,6 +134,9 @@ const ( // QemuVirt is the QEMU virt machine type for aarch64 QemuVirt = "virt" + + // QemuPseries is a QEMU virt machine type for for ppc64le + QemuPseries = "pseries" ) // kernelParamsNonDebug is a list of the default kernel diff --git a/virtcontainers/qemu_ppc64le.go b/virtcontainers/qemu_ppc64le.go new file mode 100644 index 0000000000..10af79bc28 --- /dev/null +++ b/virtcontainers/qemu_ppc64le.go @@ -0,0 +1,137 @@ +// Copyright (c) 2018 IBM +// +// SPDX-License-Identifier: Apache-2.0 +// + +package virtcontainers + +import ( + "encoding/hex" + "os" + + govmmQemu "github.com/intel/govmm/qemu" + "github.com/kata-containers/runtime/virtcontainers/device/drivers" + "github.com/kata-containers/runtime/virtcontainers/utils" +) + +type qemuPPC64le struct { + // inherit from qemuArchBase, overwrite methods if needed + qemuArchBase +} + +const defaultQemuPath = "/usr/bin/qemu-system-ppc64le" + +const defaultQemuMachineType = QemuPseries + +const defaultQemuMachineOptions = "accel=kvm,usb=off" + +const defaultPCBridgeBus = "pci.0" + +var qemuPaths = map[string]string{ + QemuPseries: defaultQemuPath, +} + +var kernelRootParams = []Param{} + +var kernelParams = []Param{ + {"tsc", "reliable"}, + {"no_timer_check", ""}, + {"rcupdate.rcu_expedited", "1"}, + {"noreplace-smp", ""}, + {"reboot", "k"}, + {"console", "hvc0"}, + {"console", "hvc1"}, + {"iommu", "off"}, + {"cryptomgr.notests", ""}, + {"net.ifnames", "0"}, + {"pci", "lastbus=0"}, +} + +var supportedQemuMachines = []govmmQemu.Machine{ + { + Type: QemuPseries, + Options: defaultQemuMachineOptions, + }, +} + +// returns the maximum number of vCPUs supported +func MaxQemuVCPUs() uint32 { + return uint32(128) +} + +func newQemuArch(config HypervisorConfig) qemuArch { + machineType := config.HypervisorMachineType + if machineType == "" { + machineType = defaultQemuMachineType + } + + q := &qemuPPC64le{ + qemuArchBase{ + machineType: machineType, + qemuPaths: qemuPaths, + supportedQemuMachines: supportedQemuMachines, + kernelParamsNonDebug: kernelParamsNonDebug, + kernelParamsDebug: kernelParamsDebug, + kernelParams: kernelParams, + }, + } + + q.handleImagePath(config) + return q +} + +func (q *qemuPPC64le) capabilities() capabilities { + var caps capabilities + + // pseries machine type supports hotplugging drives + if q.machineType == QemuPseries { + caps.setBlockDeviceHotplugSupport() + } + + return caps +} + +func (q *qemuPPC64le) bridges(number uint32) []Bridge { + return genericBridges(number, q.machineType) +} + +func (q *qemuPPC64le) cpuModel() string { + cpuModel := defaultCPUModel + if q.nestedRun { + cpuModel += ",pmu=off" + } + return cpuModel +} + +func (q *qemuPPC64le) memoryTopology(memoryMb, hostMemoryMb uint64) govmmQemu.Memory { + + // align hostMemoryMb to 256 MB multiples + hostMemoryMb -= (hostMemoryMb % 256) + return genericMemoryTopology(memoryMb, hostMemoryMb) +} + +func (q *qemuPPC64le) appendImage(devices []govmmQemu.Device, path string) ([]govmmQemu.Device, error) { + if _, err := os.Stat(path); os.IsNotExist(err) { + return nil, err + } + + randBytes, err := utils.GenerateRandomBytes(8) + if err != nil { + return nil, err + } + + id := utils.MakeNameID("image", hex.EncodeToString(randBytes), maxDevIDSize) + + drive := drivers.Drive{ + File: path, + Format: "raw", + ID: id, + } + + return q.appendBlockDevice(devices, drive), nil +} + +// appendBridges appends to devices the given bridges +func (q *qemuPPC64le) appendBridges(devices []govmmQemu.Device, bridges []Bridge) []govmmQemu.Device { + return genericAppendBridges(devices, bridges, q.machineType) +}