Merge pull request #1797 from Pennyzct/IPA

kata-check: add kvm extension check on aarch64
This commit is contained in:
Xu Wang 2019-06-21 19:10:35 +08:00 committed by GitHub
commit 21c8cf4f9f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 81 additions and 1 deletions

View File

@ -11,6 +11,7 @@ package main
#include <linux/kvm.h> #include <linux/kvm.h>
const int ioctl_KVM_CREATE_VM = KVM_CREATE_VM; const int ioctl_KVM_CREATE_VM = KVM_CREATE_VM;
const int ioctl_KVM_CHECK_EXTENSION = KVM_CHECK_EXTENSION;
*/ */
import "C" import "C"
@ -40,6 +41,15 @@ type kernelModule struct {
required bool required bool
} }
// nolint: structcheck, unused, deadcode
type kvmExtension struct {
// description
desc string
// extension identifier
id int
}
type vmContainerCapableDetails struct { type vmContainerCapableDetails struct {
cpuInfoFile string cpuInfoFile string
requiredCPUFlags map[string]string requiredCPUFlags map[string]string
@ -388,3 +398,42 @@ func genericKvmIsUsable() error {
return nil return nil
} }
// genericCheckKVMExtension allows to query about the specific kvm extensions
// nolint: unused, deadcode
func genericCheckKVMExtensions(extensions map[string]kvmExtension) (map[string]int, error) {
results := make(map[string]int)
flags := syscall.O_RDWR | syscall.O_CLOEXEC
kvm, err := syscall.Open(kvmDevice, flags, 0)
if err != nil {
return results, err
}
defer syscall.Close(kvm)
for name, extension := range extensions {
fields := logrus.Fields{
"type": "kvm extension",
"name": name,
"description": extension.desc,
"id": extension.id,
}
ret, _, errno := syscall.Syscall(syscall.SYS_IOCTL,
uintptr(kvm),
uintptr(C.ioctl_KVM_CHECK_EXTENSION),
uintptr(extension.id))
// Generally return value(ret) 0 means no and 1 means yes,
// but some extensions may report additional information in the integer return value.
if errno != 0 || ret <= 0 {
kataLog.WithFields(fields).Error("is not supported")
return results, errno
}
results[name] = int(ret)
kataLog.WithFields(fields).Info("kvm extension is supported")
}
return results, nil
}

View File

@ -47,6 +47,15 @@ var archRequiredKernelModules = map[string]kernelModule{
}, },
} }
// archRequiredKVMExtensions maps a required kvm extension to a human-readable
// description of what this extension intends to do and its unique identifier.
var archRequiredKVMExtensions = map[string]kvmExtension{
"KVM_CAP_ARM_VM_IPA_SIZE": {
desc: "Maximum IPA shift supported by the host",
id: 165,
},
}
func setCPUtype() error { func setCPUtype() error {
return nil return nil
} }
@ -57,8 +66,30 @@ func kvmIsUsable() error {
return genericKvmIsUsable() return genericKvmIsUsable()
} }
func checkKVMExtensions() error {
results, err := genericCheckKVMExtensions(archRequiredKVMExtensions)
if err != nil {
return err
}
// different host supports different maximum IPA limit
ipa := results["KVM_CAP_ARM_VM_IPA_SIZE"]
fields := logrus.Fields{
"type": "kvm extension",
"name": "KVM_CAP_ARM_VM_IPA_SIZE",
}
kataLog.WithFields(fields).Infof("IPA limit size: %d bits.", ipa)
return nil
}
func archHostCanCreateVMContainer() error { func archHostCanCreateVMContainer() error {
return kvmIsUsable() if err := kvmIsUsable(); err != nil {
return err
}
return checkKVMExtensions()
} }
// hostIsVMContainerCapable checks to see if the host is theoretically capable // hostIsVMContainerCapable checks to see if the host is theoretically capable