forked from kata-containers/kata-containers
-
Notifications
You must be signed in to change notification settings - Fork 0
/
qemu_ppc64le.go
177 lines (140 loc) · 4.56 KB
/
qemu_ppc64le.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
//go:build linux
// Copyright (c) 2018 IBM
//
// SPDX-License-Identifier: Apache-2.0
//
package virtcontainers
import (
"fmt"
"time"
"github.com/kata-containers/kata-containers/src/runtime/pkg/device/config"
govmmQemu "github.com/kata-containers/kata-containers/src/runtime/pkg/govmm/qemu"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
"github.com/sirupsen/logrus"
)
type qemuPPC64le struct {
// inherit from qemuArchBase, overwrite methods if needed
qemuArchBase
}
const defaultQemuPath = "/usr/bin/qemu-system-ppc64"
const defaultQemuMachineType = QemuPseries
const defaultQemuMachineOptions = "accel=kvm,usb=off,cap-ail-mode-3=off"
const qmpMigrationWaitTimeout = 5 * time.Second
const pefSysFirmwareDir = "/sys/firmware/ultravisor/"
const pefID = "pef0"
const tpmID = "tpm0"
const tpmHostPath = "/dev/tpmrm0"
var kernelParams = []Param{
{"rcupdate.rcu_expedited", "1"},
{"reboot", "k"},
{"cryptomgr.notests", ""},
{"net.ifnames", "0"},
}
var supportedQemuMachine = govmmQemu.Machine{
Type: QemuPseries,
Options: defaultQemuMachineOptions,
}
// Logger returns a logrus logger appropriate for logging qemu messages
func (q *qemuPPC64le) Logger() *logrus.Entry {
return hvLogger.WithField("subsystem", "qemuPPC64le")
}
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 := &qemuPPC64le{
qemuArchBase{
qemuMachine: supportedQemuMachine,
qemuExePath: defaultQemuPath,
memoryOffset: config.MemOffset,
kernelParamsNonDebug: kernelParamsNonDebug,
kernelParamsDebug: kernelParamsDebug,
kernelParams: kernelParams,
protection: noneProtection,
legacySerial: config.LegacySerial,
},
}
if config.ConfidentialGuest {
if err := q.enableProtection(); err != nil {
return nil, err
}
if !q.qemuArchBase.disableNvdimm {
hvLogger.WithField("subsystem", "qemuPPC64le").Warn("Nvdimm is not supported with confidential guest, disabling it.")
q.qemuArchBase.disableNvdimm = true
}
}
if err := q.handleImagePath(config); err != nil {
return nil, err
}
q.memoryOffset = config.MemOffset
return q, nil
}
func (q *qemuPPC64le) capabilities(hConfig HypervisorConfig) types.Capabilities {
var caps types.Capabilities
// pseries machine type supports hotplugging drives
if q.qemuMachine.Type == QemuPseries {
caps.SetBlockDeviceHotplugSupport()
caps.SetNetworkDeviceHotplugSupported()
}
caps.SetMultiQueueSupport()
if hConfig.SharedFS != config.NoSharedFS {
caps.SetFsSharingSupport()
}
return caps
}
func (q *qemuPPC64le) bridges(number uint32) {
q.Bridges = genericBridges(number, q.qemuMachine.Type)
}
func (q *qemuPPC64le) memoryTopology(memoryMb, hostMemoryMb uint64, slots uint8) govmmQemu.Memory {
q.Logger().Debug("Aligning maxmem to multiples of 256MB. Assumption: Kernel Version >= 4.11")
hostMemoryMb -= (hostMemoryMb % 256)
return genericMemoryTopology(memoryMb, hostMemoryMb, slots, q.memoryOffset)
}
func (q *qemuPPC64le) appendIOMMU(devices []govmmQemu.Device) ([]govmmQemu.Device, error) {
return devices, fmt.Errorf("PPC64le does not support appending a vIOMMU")
}
// Enables guest protection
func (q *qemuPPC64le) enableProtection() error {
var err error
q.protection, err = availableGuestProtection()
if err != nil {
return err
}
switch q.protection {
case pefProtection:
if q.qemuMachine.Options != "" {
q.qemuMachine.Options += ","
}
q.qemuMachine.Options += fmt.Sprintf("confidential-guest-support=%s", pefID)
hvLogger.WithFields(logrus.Fields{
"subsystem": "qemuPPC64le",
"machine": q.qemuMachine,
"kernel-params": q.kernelParams,
}).Info("Enabling PEF protection")
return nil
default:
return fmt.Errorf("This system doesn't support Confidential Computing (Guest Protection)")
}
}
// append protection device
func (q *qemuPPC64le) appendProtectionDevice(devices []govmmQemu.Device, firmware, firmwareVolume string) ([]govmmQemu.Device, string, error) {
switch q.protection {
case pefProtection:
return append(devices,
govmmQemu.Object{
Driver: govmmQemu.SpaprTPMProxy,
Type: govmmQemu.PEFGuest,
ID: pefID,
DeviceID: tpmID,
File: tpmHostPath,
}), firmware, nil
case noneProtection:
return devices, firmware, nil
default:
return devices, "", fmt.Errorf("Unsupported guest protection technology: %v", q.protection)
}
}