forked from kata-containers/kata-containers
-
Notifications
You must be signed in to change notification settings - Fork 0
/
hypervisor.go
826 lines (694 loc) · 23.2 KB
/
hypervisor.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
// Copyright (c) 2016 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
package virtcontainers
import (
"bufio"
"context"
"fmt"
"os"
"runtime"
"strings"
"github.com/pkg/errors"
"github.com/kata-containers/kata-containers/src/runtime/pkg/device/config"
"github.com/kata-containers/kata-containers/src/runtime/pkg/govmm"
hv "github.com/kata-containers/kata-containers/src/runtime/pkg/hypervisors"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
"github.com/sirupsen/logrus"
)
// HypervisorType describes an hypervisor type.
type HypervisorType string
type Operation int
const (
AddDevice Operation = iota
RemoveDevice
)
const (
// FirecrackerHypervisor is the FC hypervisor.
FirecrackerHypervisor HypervisorType = "firecracker"
// QemuHypervisor is the QEMU hypervisor.
QemuHypervisor HypervisorType = "qemu"
// AcrnHypervisor is the ACRN hypervisor.
AcrnHypervisor HypervisorType = "acrn"
// ClhHypervisor is the ICH hypervisor.
ClhHypervisor HypervisorType = "clh"
// DragonballHypervisor is the Dragonball hypervisor.
DragonballHypervisor HypervisorType = "dragonball"
// RemoteHypervisor is the Remote hypervisor.
RemoteHypervisor HypervisorType = "remote"
// VirtFrameworkHypervisor is the Darwin Virtualization.framework hypervisor
VirtframeworkHypervisor HypervisorType = "virtframework"
// MockHypervisor is a mock hypervisor for testing purposes
MockHypervisor HypervisorType = "mock"
procCPUInfo = "/proc/cpuinfo"
defaultVCPUs = 1
// 2 GiB
defaultMemSzMiB = 2048
defaultBridges = 1
defaultBlockDriver = config.VirtioSCSI
// port numbers below 1024 are called privileged ports. Only a process with
// CAP_NET_BIND_SERVICE capability may bind to these port numbers.
vSockPort = 1024
// Port where the agent will send the logs. Logs are sent through the vsock in cases
// where the hypervisor has no console.sock, i.e firecracker
vSockLogsPort = 1025
// MinHypervisorMemory is the minimum memory required for a VM.
MinHypervisorMemory = 256
defaultMsize9p = 8192
defaultDisableGuestSeLinux = true
)
var (
hvLogger = logrus.WithField("source", "virtcontainers/hypervisor")
noGuestMemHotplugErr error = errors.New("guest memory hotplug not supported")
)
// In some architectures the maximum number of vCPUs depends on the number of physical cores.
// TODO (dcantah): Find a suitable value for darwin/vfw. Seems perf degrades if > number of host
// cores.
var defaultMaxVCPUs = govmm.MaxVCPUs()
// RootfsDriver describes a rootfs driver.
type RootfsDriver string
const (
// VirtioBlk is the Virtio-Blk rootfs driver.
VirtioBlk RootfsDriver = "/dev/vda1"
// Nvdimm is the Nvdimm rootfs driver.
Nvdimm RootfsType = "/dev/pmem0p1"
)
// RootfsType describes a rootfs type.
type RootfsType string
const (
// EXT4 is the ext4 filesystem.
EXT4 RootfsType = "ext4"
// XFS is the xfs filesystem.
XFS RootfsType = "xfs"
// EROFS is the erofs filesystem.
EROFS RootfsType = "erofs"
)
func GetKernelRootParams(rootfstype string, disableNvdimm bool, dax bool) ([]Param, error) {
var kernelRootParams []Param
// EXT4 filesystem is used by default.
if rootfstype == "" {
rootfstype = string(EXT4)
}
if disableNvdimm && dax {
return []Param{}, fmt.Errorf("Virtio-Blk does not support DAX")
}
if disableNvdimm {
// Virtio-Blk
kernelRootParams = append(kernelRootParams, Param{"root", string(VirtioBlk)})
} else {
// Nvdimm
kernelRootParams = append(kernelRootParams, Param{"root", string(Nvdimm)})
}
switch RootfsType(rootfstype) {
case EROFS:
if dax {
kernelRootParams = append(kernelRootParams, Param{"rootflags", "dax ro"})
} else {
kernelRootParams = append(kernelRootParams, Param{"rootflags", "ro"})
}
case XFS:
fallthrough
// EXT4 filesystem is used by default.
case EXT4:
if dax {
kernelRootParams = append(kernelRootParams, Param{"rootflags", "dax,data=ordered,errors=remount-ro ro"})
} else {
kernelRootParams = append(kernelRootParams, Param{"rootflags", "data=ordered,errors=remount-ro ro"})
}
default:
return []Param{}, fmt.Errorf("unsupported rootfs type")
}
kernelRootParams = append(kernelRootParams, Param{"rootfstype", rootfstype})
return kernelRootParams, nil
}
// DeviceType describes a virtualized device type.
type DeviceType int
const (
// ImgDev is the image device type.
ImgDev DeviceType = iota
// FsDev is the filesystem device type.
FsDev
// NetDev is the network device type.
NetDev
// BlockDev is the block device type.
BlockDev
// SerialPortDev is the serial port device type.
SerialPortDev
// VSockPCIDev is the vhost vsock PCI device type.
VSockPCIDev
// VFIODevice is VFIO device type
VfioDev
// VhostuserDev is a Vhost-user device type
VhostuserDev
// CPUDevice is CPU device type
CpuDev
// MemoryDev is memory device type
MemoryDev
// HybridVirtioVsockDev is a hybrid virtio-vsock device supported
// only on certain hypervisors, like firecracker.
HybridVirtioVsockDev
)
type MemoryDevice struct {
Slot int
SizeMB int
Addr uint64
Probe bool
}
// SetHypervisorLogger sets up a logger for the hypervisor part of this pkg
func SetHypervisorLogger(logger *logrus.Entry) {
fields := hvLogger.Data
hvLogger = logger.WithFields(fields)
}
// Set sets an hypervisor type based on the input string.
func (hType *HypervisorType) Set(value string) error {
switch value {
case "qemu":
*hType = QemuHypervisor
return nil
case "firecracker":
*hType = FirecrackerHypervisor
return nil
case "acrn":
*hType = AcrnHypervisor
return nil
case "clh":
*hType = ClhHypervisor
return nil
case "dragonball":
*hType = DragonballHypervisor
return nil
case "remote":
*hType = RemoteHypervisor
return nil
case "virtframework":
*hType = VirtframeworkHypervisor
return nil
case "mock":
*hType = MockHypervisor
return nil
default:
return fmt.Errorf("Unknown hypervisor type %s", value)
}
}
// String converts an hypervisor type to a string.
func (hType *HypervisorType) String() string {
switch *hType {
case QemuHypervisor:
return string(QemuHypervisor)
case FirecrackerHypervisor:
return string(FirecrackerHypervisor)
case AcrnHypervisor:
return string(AcrnHypervisor)
case ClhHypervisor:
return string(ClhHypervisor)
case RemoteHypervisor:
return string(RemoteHypervisor)
case MockHypervisor:
return string(MockHypervisor)
default:
return ""
}
}
// GetHypervisorSocketTemplate returns the full "template" path to the
// hypervisor socket. If the specified hypervisor doesn't use a socket,
// an empty string is returned.
//
// The returned value is not the actual socket path since this function
// does not create a sandbox. Instead a path is returned with a special
// template value "{ID}" which would be replaced with the real sandbox
// name sandbox creation time.
func GetHypervisorSocketTemplate(hType HypervisorType, config *HypervisorConfig) (string, error) {
hypervisor, err := NewHypervisor(hType)
if err != nil {
return "", err
}
if err := hypervisor.setConfig(config); err != nil {
return "", err
}
// Tag that is used to represent the name of a sandbox
const sandboxID = "{ID}"
socket, err := hypervisor.GenerateSocket(sandboxID)
if err != nil {
return "", err
}
var socketPath string
if hybridVsock, ok := socket.(types.HybridVSock); ok {
socketPath = hybridVsock.UdsPath
}
return socketPath, nil
}
// Param is a key/value representation for hypervisor and kernel parameters.
type Param struct {
Key string
Value string
}
// HypervisorConfig is the hypervisor configuration.
// nolint: govet
type HypervisorConfig struct {
customAssets map[types.AssetType]*types.Asset
SeccompSandbox string
KernelPath string
ImagePath string
InitrdPath string
FirmwarePath string
FirmwareVolumePath string
MachineAccelerators string
CPUFeatures string
HypervisorPath string
HypervisorCtlPath string
GuestPreAttestationKeyset string
BlockDeviceDriver string
HypervisorMachineType string
GuestPreAttestationURI string
GuestPreAttestationMode string
DevicesStatePath string
EntropySource string
SharedFS string
SharedPath string
VirtioFSDaemon string
VirtioFSCache string
FileBackedMemRootDir string
VhostUserStorePath string
GuestMemoryDumpPath string
GuestHookPath string
VMid string
VMStorePath string
RunStorePath string
SELinuxProcessLabel string
JailerPath string
MemoryPath string
SEVCertChainPath string
BlockDeviceAIO string
User string
RemoteHypervisorSocket string
SandboxName string
SandboxNamespace string
JailerPathList []string
EntropySourceList []string
VirtioFSDaemonList []string
VirtioFSExtraArgs []string
EnableAnnotations []string
FileBackedMemRootList []string
PFlash []string
VhostUserStorePathList []string
HypervisorCtlPathList []string
KernelParams []Param
Groups []uint32
HypervisorPathList []string
HypervisorParams []Param
DiskRateLimiterBwOneTimeBurst int64
DiskRateLimiterOpsMaxRate int64
RootfsType string
VhostUserDeviceReconnect uint32
DiskRateLimiterOpsOneTimeBurst int64
SGXEPCSize int64
DefaultMaxMemorySize uint64
NetRateLimiterBwMaxRate int64
NetRateLimiterBwOneTimeBurst int64
NetRateLimiterOpsMaxRate int64
NetRateLimiterOpsOneTimeBurst int64
MemOffset uint64
TxRateLimiterMaxRate uint64
DiskRateLimiterBwMaxRate int64
RxRateLimiterMaxRate uint64
MemorySize uint32
DefaultMaxVCPUs uint32
DefaultBridges uint32
Msize9p uint32
MemSlots uint32
VirtioFSCacheSize uint32
VirtioFSQueueSize uint32
Uid uint32
Gid uint32
SEVGuestPolicy uint32
SNPGuestPolicy uint64
NumVCPUs uint32
RemoteHypervisorTimeout uint32
IOMMUPlatform bool
EnableIOThreads bool
Debug bool
MemPrealloc bool
HugePages bool
VirtioMem bool
IOMMU bool
DisableBlockDeviceUse bool
DisableNestingChecks bool
DisableImageNvdimm bool
HotplugVFIOOnRootBus bool
GuestMemoryDumpPaging bool
ConfidentialGuest bool
SevSnpGuest bool
GuestPreAttestation bool
BlockDeviceCacheNoflush bool
BlockDeviceCacheDirect bool
BlockDeviceCacheSet bool
BootToBeTemplate bool
BootFromTemplate bool
DisableVhostNet bool
EnableVhostUserStore bool
GuestSwap bool
Rootless bool
DisableSeccomp bool
DisableSeLinux bool
DisableGuestSeLinux bool
LegacySerial bool
HotPlugVFIO config.PCIePort
ColdPlugVFIO config.PCIePort
VFIODevices []config.DeviceInfo
VhostUserBlkDevices []config.DeviceInfo
}
// vcpu mapping from vcpu number to thread number
type VcpuThreadIDs struct {
vcpus map[int]int
}
func (conf *HypervisorConfig) CheckTemplateConfig() error {
if conf.BootToBeTemplate && conf.BootFromTemplate {
return fmt.Errorf("Cannot set both 'to be' and 'from' vm tempate")
}
if conf.BootToBeTemplate || conf.BootFromTemplate {
if conf.MemoryPath == "" {
return fmt.Errorf("Missing MemoryPath for vm template")
}
if conf.BootFromTemplate && conf.DevicesStatePath == "" {
return fmt.Errorf("Missing DevicesStatePath to Load from vm template")
}
}
return nil
}
// AddKernelParam allows the addition of new kernel parameters to an existing
// hypervisor configuration.
func (conf *HypervisorConfig) AddKernelParam(p Param) error {
if p.Key == "" {
return fmt.Errorf("Empty kernel parameter")
}
conf.KernelParams = append(conf.KernelParams, p)
return nil
}
func (conf *HypervisorConfig) AddCustomAsset(a *types.Asset) error {
if a == nil || a.Path() == "" {
// We did not get a custom asset, we will use the default one.
return nil
}
if !a.Valid() {
return fmt.Errorf("Invalid %s at %s", a.Type(), a.Path())
}
hvLogger.Debugf("Using custom %v asset %s", a.Type(), a.Path())
if conf.customAssets == nil {
conf.customAssets = make(map[types.AssetType]*types.Asset)
}
conf.customAssets[a.Type()] = a
return nil
}
func (conf *HypervisorConfig) assetPath(t types.AssetType) (string, error) {
// Custom assets take precedence over the configured ones
a, ok := conf.customAssets[t]
if ok {
return a.Path(), nil
}
// We could not find a custom asset for the given type, let's
// fall back to the configured ones.
switch t {
case types.KernelAsset:
return conf.KernelPath, nil
case types.ImageAsset:
return conf.ImagePath, nil
case types.InitrdAsset:
return conf.InitrdPath, nil
case types.HypervisorAsset:
return conf.HypervisorPath, nil
case types.HypervisorCtlAsset:
return conf.HypervisorCtlPath, nil
case types.JailerAsset:
return conf.JailerPath, nil
case types.FirmwareAsset:
return conf.FirmwarePath, nil
case types.FirmwareVolumeAsset:
return conf.FirmwareVolumePath, nil
default:
return "", fmt.Errorf("Unknown asset type %v", t)
}
}
func (conf *HypervisorConfig) isCustomAsset(t types.AssetType) bool {
_, ok := conf.customAssets[t]
return ok
}
// KernelAssetPath returns the guest kernel path
func (conf *HypervisorConfig) KernelAssetPath() (string, error) {
return conf.assetPath(types.KernelAsset)
}
// CustomKernelAsset returns true if the kernel asset is a custom one, false otherwise.
func (conf *HypervisorConfig) CustomKernelAsset() bool {
return conf.isCustomAsset(types.KernelAsset)
}
// ImageAssetPath returns the guest image path
func (conf *HypervisorConfig) ImageAssetPath() (string, error) {
return conf.assetPath(types.ImageAsset)
}
// CustomImageAsset returns true if the image asset is a custom one, false otherwise.
func (conf *HypervisorConfig) CustomImageAsset() bool {
return conf.isCustomAsset(types.ImageAsset)
}
// InitrdAssetPath returns the guest initrd path
func (conf *HypervisorConfig) InitrdAssetPath() (string, error) {
return conf.assetPath(types.InitrdAsset)
}
// CustomInitrdAsset returns true if the initrd asset is a custom one, false otherwise.
func (conf *HypervisorConfig) CustomInitrdAsset() bool {
return conf.isCustomAsset(types.InitrdAsset)
}
// HypervisorAssetPath returns the VM hypervisor path
func (conf *HypervisorConfig) HypervisorAssetPath() (string, error) {
return conf.assetPath(types.HypervisorAsset)
}
func (conf *HypervisorConfig) IfPVPanicEnabled() bool {
return conf.GuestMemoryDumpPath != ""
}
// HypervisorCtlAssetPath returns the VM hypervisor ctl path
func (conf *HypervisorConfig) HypervisorCtlAssetPath() (string, error) {
return conf.assetPath(types.HypervisorCtlAsset)
}
// CustomHypervisorAsset returns true if the hypervisor asset is a custom one, false otherwise.
func (conf *HypervisorConfig) CustomHypervisorAsset() bool {
return conf.isCustomAsset(types.HypervisorAsset)
}
// FirmwareAssetPath returns the guest firmware path
func (conf *HypervisorConfig) FirmwareAssetPath() (string, error) {
return conf.assetPath(types.FirmwareAsset)
}
// FirmwareVolumeAssetPath returns the guest firmware volume path
func (conf *HypervisorConfig) FirmwareVolumeAssetPath() (string, error) {
return conf.assetPath(types.FirmwareVolumeAsset)
}
func appendParam(params []Param, parameter string, value string) []Param {
return append(params, Param{parameter, value})
}
// SerializeParams converts []Param to []string
func SerializeParams(params []Param, delim string) []string {
var parameters []string
for _, p := range params {
if p.Key == "" && p.Value == "" {
continue
} else if p.Key == "" {
parameters = append(parameters, fmt.Sprint(p.Value))
} else if p.Value == "" {
parameters = append(parameters, fmt.Sprint(p.Key))
} else if delim == "" {
parameters = append(parameters, fmt.Sprint(p.Key))
parameters = append(parameters, fmt.Sprint(p.Value))
} else {
parameters = append(parameters, fmt.Sprintf("%s%s%s", p.Key, delim, p.Value))
}
}
return parameters
}
// DeserializeParams converts []string to []Param
func DeserializeParams(parameters []string) []Param {
var params []Param
for _, param := range parameters {
if param == "" {
continue
}
p := strings.SplitN(param, "=", 2)
if len(p) == 2 {
params = append(params, Param{Key: p[0], Value: p[1]})
} else {
params = append(params, Param{Key: p[0], Value: ""})
}
}
return params
}
// CheckCmdline checks whether an option or parameter is present in the kernel command line.
// Search is case-insensitive.
// Takes path to file that contains the kernel command line, desired option, and permitted values
// (empty values to Check for options).
func CheckCmdline(kernelCmdlinePath, searchParam string, searchValues []string) (bool, error) {
f, err := os.Open(kernelCmdlinePath)
if err != nil {
return false, err
}
defer f.Close()
// Create Check function -- either Check for verbatim option
// or Check for parameter and permitted values
var check func(string, string, []string) bool
if len(searchValues) == 0 {
check = func(option, searchParam string, _ []string) bool {
return strings.EqualFold(option, searchParam)
}
} else {
check = func(param, searchParam string, searchValues []string) bool {
// split parameter and value
split := strings.SplitN(param, "=", 2)
if len(split) < 2 || split[0] != searchParam {
return false
}
for _, value := range searchValues {
if strings.EqualFold(value, split[1]) {
return true
}
}
return false
}
}
scanner := bufio.NewScanner(f)
for scanner.Scan() {
for _, field := range strings.Fields(scanner.Text()) {
if check(field, searchParam, searchValues) {
return true, nil
}
}
}
return false, err
}
func CPUFlags(cpuInfoPath string) (map[string]bool, error) {
flagsField := "flags"
f, err := os.Open(cpuInfoPath)
if err != nil {
return map[string]bool{}, err
}
defer f.Close()
flags := make(map[string]bool)
scanner := bufio.NewScanner(f)
for scanner.Scan() {
// Expected format: ["flags", ":", ...] or ["flags:", ...]
fields := strings.Fields(scanner.Text())
if len(fields) < 2 {
continue
}
if !strings.HasPrefix(fields[0], flagsField) {
continue
}
for _, field := range fields[1:] {
flags[field] = true
}
return flags, nil
}
if err := scanner.Err(); err != nil {
return map[string]bool{}, err
}
return map[string]bool{}, fmt.Errorf("Couldn't find %q from %q output", flagsField, cpuInfoPath)
}
// RunningOnVMM checks if the system is running inside a VM.
func RunningOnVMM(cpuInfoPath string) (bool, error) {
if runtime.GOARCH == "amd64" {
flags, err := CPUFlags(cpuInfoPath)
if err != nil {
return false, err
}
return flags["hypervisor"], nil
}
hvLogger.WithField("arch", runtime.GOARCH).Info("Unable to know if the system is running inside a VM")
return false, nil
}
func GetHypervisorPid(h Hypervisor) int {
pids := h.GetPids()
if len(pids) == 0 {
return 0
}
return pids[0]
}
// Kind of guest protection
type guestProtection uint8
const (
noneProtection guestProtection = iota
//Intel Trust Domain Extensions
//https://software.intel.com/content/www/us/en/develop/articles/intel-trust-domain-extensions.html
// Exclude from lint checking for it won't be used on arm64 code
tdxProtection
// AMD Secure Encrypted Virtualization
// https://developer.amd.com/sev/
// Exclude from lint checking for it won't be used on arm64 code
sevProtection
// AMD Secure Encrypted Virtualization - Secure Nested Paging (SEV-SNP)
// https://developer.amd.com/sev/
// Exclude from lint checking for it won't be used on arm64 code
snpProtection
// IBM POWER 9 Protected Execution Facility
// https://www.kernel.org/doc/html/latest/powerpc/ultravisor.html
// Exclude from lint checking for it won't be used on arm64 code
pefProtection
// IBM Secure Execution (IBM Z & LinuxONE)
// https://www.kernel.org/doc/html/latest/virt/kvm/s390-pv.html
// Exclude from lint checking for it won't be used on arm64 code
seProtection
)
var guestProtectionStr = [...]string{
noneProtection: "none",
pefProtection: "pef",
seProtection: "se",
sevProtection: "sev",
snpProtection: "snp",
tdxProtection: "tdx",
}
func (gp guestProtection) String() string {
return guestProtectionStr[gp]
}
func genericAvailableGuestProtections() (protections []string) {
return
}
func AvailableGuestProtections() (protections []string) {
gp, err := availableGuestProtection()
if err != nil || gp == noneProtection {
return genericAvailableGuestProtections()
}
return []string{gp.String()}
}
// hypervisor is the virtcontainers hypervisor interface.
// The default hypervisor implementation is Qemu.
type Hypervisor interface {
CreateVM(ctx context.Context, id string, network Network, hypervisorConfig *HypervisorConfig) error
StartVM(ctx context.Context, timeout int) error
AttestVM(ctx context.Context) error
// If wait is set, don't actively stop the sandbox:
// just perform cleanup.
StopVM(ctx context.Context, waitOnly bool) error
PauseVM(ctx context.Context) error
SaveVM() error
ResumeVM(ctx context.Context) error
AddDevice(ctx context.Context, devInfo interface{}, devType DeviceType) error
HotplugAddDevice(ctx context.Context, devInfo interface{}, devType DeviceType) (interface{}, error)
HotplugRemoveDevice(ctx context.Context, devInfo interface{}, devType DeviceType) (interface{}, error)
ResizeMemory(ctx context.Context, memMB uint32, memoryBlockSizeMB uint32, probe bool) (uint32, MemoryDevice, error)
ResizeVCPUs(ctx context.Context, vcpus uint32) (uint32, uint32, error)
GetTotalMemoryMB(ctx context.Context) uint32
GetVMConsole(ctx context.Context, sandboxID string) (string, string, error)
Disconnect(ctx context.Context)
Capabilities(ctx context.Context) types.Capabilities
HypervisorConfig() HypervisorConfig
GetThreadIDs(ctx context.Context) (VcpuThreadIDs, error)
Cleanup(ctx context.Context) error
// getPids returns a slice of hypervisor related process ids.
// The hypervisor pid must be put at index 0.
setConfig(config *HypervisorConfig) error
GetPids() []int
GetVirtioFsPid() *int
fromGrpc(ctx context.Context, hypervisorConfig *HypervisorConfig, j []byte) error
toGrpc(ctx context.Context) ([]byte, error)
Check() error
Save() hv.HypervisorState
Load(hv.HypervisorState)
// generate the socket to communicate the host and guest
GenerateSocket(id string) (interface{}, error)
// check if hypervisor supports built-in rate limiter.
IsRateLimiterBuiltin() bool
}