From 52f4da0246fa1dd170bb45f0216c2cff15968f24 Mon Sep 17 00:00:00 2001 From: Ruoqing He Date: Mon, 29 Apr 2024 16:20:35 +0800 Subject: [PATCH] Add support for riscv64 platform Signed-off-by: Ruoqing He --- src/agent/src/linux_abi.rs | 3 +- src/runtime/Makefile | 3 + src/runtime/arch/riscv64-options.mk | 13 ++ .../cmd/kata-runtime/kata-check_riscv64.go | 130 ++++++++++++++++++ src/runtime/pkg/govmm/vmm_riscv64.go | 12 ++ .../factory/template/template_riscv64.go | 14 ++ .../virtcontainers/hypervisor_riscv64.go | 11 ++ src/runtime/virtcontainers/qemu_riscv64.go | 68 +++++++++ 8 files changed, 253 insertions(+), 1 deletion(-) create mode 100644 src/runtime/arch/riscv64-options.mk create mode 100644 src/runtime/cmd/kata-runtime/kata-check_riscv64.go create mode 100644 src/runtime/pkg/govmm/vmm_riscv64.go create mode 100644 src/runtime/virtcontainers/factory/template/template_riscv64.go create mode 100644 src/runtime/virtcontainers/hypervisor_riscv64.go create mode 100644 src/runtime/virtcontainers/qemu_riscv64.go diff --git a/src/agent/src/linux_abi.rs b/src/agent/src/linux_abi.rs index b87da3c..fdb70be 100644 --- a/src/agent/src/linux_abi.rs +++ b/src/agent/src/linux_abi.rs @@ -15,7 +15,8 @@ pub const SYSFS_DIR: &str = "/sys"; target_arch = "powerpc64", target_arch = "s390x", target_arch = "x86_64", - target_arch = "x86" + target_arch = "x86", + target_arch = "riscv64" ))] pub fn create_pci_root_bus_path() -> String { String::from("/devices/pci0000:00") diff --git a/src/runtime/Makefile b/src/runtime/Makefile index 33fa8f2..977dbfc 100644 --- a/src/runtime/Makefile +++ b/src/runtime/Makefile @@ -22,6 +22,9 @@ endif ifeq ($(ARCH),aarch64) override ARCH = arm64 endif +ifeq ($(ARCH),riscv64) + override ARCH = riscv64 +endif ARCH_DIR = arch ARCH_FILE_SUFFIX = -options.mk diff --git a/src/runtime/arch/riscv64-options.mk b/src/runtime/arch/riscv64-options.mk new file mode 100644 index 0000000..91eef18 --- /dev/null +++ b/src/runtime/arch/riscv64-options.mk @@ -0,0 +1,13 @@ +# Copyright (c) 2023 Xin Liu +# +# SPDX-License-Identifier: Apache-2.0 +# + +# riscv64 settings + +MACHINETYPE := virt +KERNELPARAMS := +MACHINEACCELERATORS := +CPUFEATURES := + +QEMUCMD := qemu-system-riscv64 diff --git a/src/runtime/cmd/kata-runtime/kata-check_riscv64.go b/src/runtime/cmd/kata-runtime/kata-check_riscv64.go new file mode 100644 index 0000000..a16f869 --- /dev/null +++ b/src/runtime/cmd/kata-runtime/kata-check_riscv64.go @@ -0,0 +1,130 @@ +// Copyright (c) 2018 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 +// + +package main + +import ( + "fmt" + "strings" + + vc "github.com/kata-containers/kata-containers/src/runtime/virtcontainers" + "github.com/sirupsen/logrus" +) + +const ( + cpuFlagsTag = genericCPUFlagsTag + archCPUVendorField = "uarch" + archCPUModelField = "isa" +) + +// archRequiredCPUFlags maps a CPU flag value to search for and a +// human-readable description of that value. +var archRequiredCPUFlags = map[string]string{} + +// archRequiredCPUAttribs maps a CPU (non-CPU flag) attribute value to search for +// and a human-readable description of that value. +var archRequiredCPUAttribs = map[string]string{} + +// archRequiredKernelModules maps a required module name to a human-readable +// description of the modules functionality and an optional list of +// required module parameters. +var archRequiredKernelModules = map[string]kernelModule{ + "kvm": { + desc: "Kernel-based Virtual Machine", + required: true, + }, + "vhost_vsock": { + desc: "Host Support for Linux VM Sockets", + required: false, + }, +} + +func setCPUtype(hypervisorType vc.HypervisorType) error { + return nil +} + +// kvmIsUsable determines if it will be possible to create a full virtual machine +// by creating a minimal VM and then deleting it. +func kvmIsUsable() error { + return genericKvmIsUsable() +} + +func archHostCanCreateVMContainer(hypervisorType vc.HypervisorType) error { + return kvmIsUsable() +} + +// hostIsVMContainerCapable checks to see if the host is theoretically capable +// of creating a VM container. +func hostIsVMContainerCapable(details vmContainerCapableDetails) error { + + _, err := getCPUInfo(details.cpuInfoFile) + if err != nil { + return err + } + + count, err := checkKernelModules(details.requiredKernelModules, archKernelParamHandler) + if err != nil { + return err + } + + if count == 0 { + return nil + } + + return fmt.Errorf("ERROR: %s", failMessage) + +} + +func archKernelParamHandler(onVMM bool, fields logrus.Fields, msg string) bool { + return genericArchKernelParamHandler(onVMM, fields, msg) +} + +func getRiscv64CPUDetails() (vendor, model string, err error) { + prefixModel := "processor" + cpuinfo, err := getCPUInfo(procCPUInfo) + if err != nil { + return "", "", err + } + + lines := strings.Split(cpuinfo, "\n") + + for _, line := range lines { + if archCPUVendorField != "" { + if strings.HasPrefix(line, archCPUVendorField) { + fields := strings.Split(line, ":") + if len(fields) > 1 { + vendor = strings.TrimSpace(fields[1]) + } + } + } else { + vendor = "Unknown" + } + if archCPUModelField != "" { + if strings.HasPrefix(line, prefixModel) { + fields := strings.Split(line, ":") + if len(fields) > 1 { + model = strings.TrimSpace(fields[1]) + } + } + } + } + + if vendor == "" { + return "", "", fmt.Errorf("cannot find vendor field in file %v", procCPUInfo) + } + + if model == "" { + return "", "", fmt.Errorf("Error in parsing cpu model from %v", procCPUInfo) + } + + return vendor, model, nil +} + +func getCPUDetails() (string, string, error) { + if vendor, model, err := genericGetCPUDetails(); err == nil { + return vendor, model, nil + } + return getRiscv64CPUDetails() +} diff --git a/src/runtime/pkg/govmm/vmm_riscv64.go b/src/runtime/pkg/govmm/vmm_riscv64.go new file mode 100644 index 0000000..5ea2e94 --- /dev/null +++ b/src/runtime/pkg/govmm/vmm_riscv64.go @@ -0,0 +1,12 @@ +// +// Copyright (c) 2018 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 +// + +package govmm + +// MaxVCPUs returns the maximum number of vCPUs supported +func MaxVCPUs() uint32 { + return uint32(512) +} diff --git a/src/runtime/virtcontainers/factory/template/template_riscv64.go b/src/runtime/virtcontainers/factory/template/template_riscv64.go new file mode 100644 index 0000000..abb639b --- /dev/null +++ b/src/runtime/virtcontainers/factory/template/template_riscv64.go @@ -0,0 +1,14 @@ +// Copyright (c) 2023 Xin Liu +// +// SPDX-License-Identifier: Apache-2.0 +// +// template implements base vm factory with vm templating. + +package template + +// templateDeviceStateSize denotes device state size when +// mount tmpfs. +// when bypass-shared-memory is not support like arm64, +// creating template will occupy more space. That's why we +// put it here. +const templateDeviceStateSize = 8 diff --git a/src/runtime/virtcontainers/hypervisor_riscv64.go b/src/runtime/virtcontainers/hypervisor_riscv64.go new file mode 100644 index 0000000..78d128f --- /dev/null +++ b/src/runtime/virtcontainers/hypervisor_riscv64.go @@ -0,0 +1,11 @@ +// Copyright (c) 2021 Arm Ltd. +// +// SPDX-License-Identifier: Apache-2.0 + +package virtcontainers + +// Guest protection is not supported on RISCV64. +func availableGuestProtection() (guestProtection, error) { + return noneProtection, nil +} + diff --git a/src/runtime/virtcontainers/qemu_riscv64.go b/src/runtime/virtcontainers/qemu_riscv64.go new file mode 100644 index 0000000..846a5f2 --- /dev/null +++ b/src/runtime/virtcontainers/qemu_riscv64.go @@ -0,0 +1,68 @@ +// Copyright (c) 2023 Xin Liu +// +// SPDX-License-Identifier: Apache-2.0 +// + +package virtcontainers + +import ( + "fmt" + "time" + + govmmQemu "github.com/kata-containers/kata-containers/src/runtime/pkg/govmm/qemu" +) + +type qemuRiscv64 struct { + // inherit from qemuArchBase, overwrite methods if needed + qemuArchBase +} + +const defaultQemuPath = "/usr/bin/qemu-system-riscv64" + +const defaultQemuMachineType = QemuVirt + +const qmpMigrationWaitTimeout = 10 * time.Second + +const defaultQemuMachineOptions = "" + +var defaultGICVersion = uint32(3) + +var kernelParams = []Param{ + {"numa", "off"}, +} + +var supportedQemuMachine = govmmQemu.Machine{ + Type: QemuVirt, + Options: defaultQemuMachineOptions, +} + +// MaxQemuVCPUs returns the maximum number of vCPUs supported +func MaxQemuVCPUs() uint32 { + return uint32(512) +} + +func newQemuArch(config HypervisorConfig) (qemuArch, error) { + machineType := config.HypervisorMachineType + if machineType == "" { + machineType = defaultQemuMachineType + } + + if machineType != defaultQemuMachineType { + return nil, fmt.Errorf("unrecognised machinetype: %v", machineType) + } + + q := &qemuRiscv64{ + qemuArchBase{ + qemuMachine: supportedQemuMachine, + qemuExePath: defaultQemuPath, + memoryOffset: config.MemOffset, + kernelParamsNonDebug: kernelParamsNonDebug, + kernelParamsDebug: kernelParamsDebug, + kernelParams: kernelParams, + }, + } + + q.handleImagePath(config) + + return q, nil +} -- 2.43.0