Merge pull request #3771 from fidencio/wip/clh-tdx

clh: Add TDX support
This commit is contained in:
Fabiano Fidêncio 2022-02-25 18:45:31 +01:00 committed by GitHub
commit ea1876f057
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 240 additions and 107 deletions

View File

@ -15,6 +15,33 @@ path = "@CLHPATH@"
kernel = "@KERNELPATH_CLH@" kernel = "@KERNELPATH_CLH@"
image = "@IMAGEPATH@" image = "@IMAGEPATH@"
# Enable confidential guest support.
# Toggling that setting may trigger different hardware features, ranging
# from memory encryption to both memory and CPU-state encryption and integrity.
# The Kata Containers runtime dynamically detects the available feature set and
# aims at enabling the largest possible one.
#
# Known limitations:
# * Does not work by design:
# - CPU Hotplug
# - Device Hotplug
# - Memory Hotplug
# - NVDIMM devices
#
# Default false
# confidential_guest = true
# Path to the firmware.
# If you want Cloud Hypervisor to use a specific firmware, set its path below.
# This is option is only used when confidential_guest is enabled.
#
# For more information about firmwared that can be used with specific TEEs,
# please, refer to:
# * TDX:
# - td-shim: https://github.com/confidential-containers/td-shim
#
# firmware = "@FIRMWAREPATH@"
# List of valid annotation names for the hypervisor # List of valid annotation names for the hypervisor
# Each member of the list is a regular expression, which is the base name # Each member of the list is a regular expression, which is the base name
# of the annotation, e.g. "path" for io.katacontainers.config.hypervisor.path" # of the annotation, e.g. "path" for io.katacontainers.config.hypervisor.path"

View File

@ -21,6 +21,14 @@ machine_type = "@MACHINETYPE@"
# from memory encryption to both memory and CPU-state encryption and integrity. # from memory encryption to both memory and CPU-state encryption and integrity.
# The Kata Containers runtime dynamically detects the available feature set and # The Kata Containers runtime dynamically detects the available feature set and
# aims at enabling the largest possible one. # aims at enabling the largest possible one.
#
# Known limitations:
# * Does not work by design:
# - CPU Hotplug
# - Device Hotplug
# - Memory Hotplug
# - NVDIMM devices
#
# Default false # Default false
# confidential_guest = true # confidential_guest = true
@ -279,6 +287,9 @@ pflashes = []
# If false and nvdimm is supported, use nvdimm device to plug guest image. # If false and nvdimm is supported, use nvdimm device to plug guest image.
# Otherwise virtio-block device is used. # Otherwise virtio-block device is used.
#
# nvdimm is not supported when `confidential_guest = true`.
#
# Default is false # Default is false
#disable_image_nvdimm = true #disable_image_nvdimm = true

View File

@ -877,6 +877,7 @@ func newClhHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) {
SGXEPCSize: defaultSGXEPCSize, SGXEPCSize: defaultSGXEPCSize,
EnableAnnotations: h.EnableAnnotations, EnableAnnotations: h.EnableAnnotations,
DisableSeccomp: h.DisableSeccomp, DisableSeccomp: h.DisableSeccomp,
ConfidentialGuest: h.ConfidentialGuest,
}, nil }, nil
} }

View File

@ -171,12 +171,9 @@ type cloudHypervisor struct {
} }
var clhKernelParams = []Param{ var clhKernelParams = []Param{
{"root", "/dev/pmem0p1"},
{"panic", "1"}, // upon kernel panic wait 1 second before reboot {"panic", "1"}, // upon kernel panic wait 1 second before reboot
{"no_timer_check", ""}, // do not Check broken timer IRQ resources {"no_timer_check", ""}, // do not Check broken timer IRQ resources
{"noreplace-smp", ""}, // do not replace SMP instructions {"noreplace-smp", ""}, // do not replace SMP instructions
{"rootflags", "dax,data=ordered,errors=remount-ro ro"}, // mount the root filesystem as readonly
{"rootfstype", "ext4"},
} }
var clhDebugKernelParams = []Param{ var clhDebugKernelParams = []Param{
@ -205,6 +202,34 @@ func (clh *cloudHypervisor) nydusdAPISocketPath(id string) (string, error) {
return utils.BuildSocketPath(clh.config.VMStorePath, id, nydusdAPISock) return utils.BuildSocketPath(clh.config.VMStorePath, id, nydusdAPISock)
} }
func (clh *cloudHypervisor) enableProtection() error {
protection, err := availableGuestProtection()
if err != nil {
return err
}
switch protection {
case tdxProtection:
firmwarePath, err := clh.config.FirmwareAssetPath()
if err != nil {
return err
}
if firmwarePath == "" {
return errors.New("Firmware path is not specified")
}
clh.vmconfig.Tdx = chclient.NewTdxConfig(firmwarePath)
return nil
case sevProtection:
return errors.New("SEV protection is not supported by Cloud Hypervisor")
default:
return errors.New("This system doesn't support Confidentian Computing (Guest Protection)")
}
}
// For cloudHypervisor this call only sets the internal structure up. // For cloudHypervisor this call only sets the internal structure up.
// The VM will be created and started through StartVM(). // The VM will be created and started through StartVM().
func (clh *cloudHypervisor) CreateVM(ctx context.Context, id string, network Network, hypervisorConfig *HypervisorConfig) error { func (clh *cloudHypervisor) CreateVM(ctx context.Context, id string, network Network, hypervisorConfig *HypervisorConfig) error {
@ -251,23 +276,35 @@ func (clh *cloudHypervisor) CreateVM(ctx context.Context, id string, network Net
// Create the VM config via the constructor to ensure default values are properly assigned // Create the VM config via the constructor to ensure default values are properly assigned
clh.vmconfig = *chclient.NewVmConfig(*chclient.NewKernelConfig(kernelPath)) clh.vmconfig = *chclient.NewVmConfig(*chclient.NewKernelConfig(kernelPath))
if clh.config.ConfidentialGuest {
if err := clh.enableProtection(); err != nil {
return err
}
}
// Create the VM memory config via the constructor to ensure default values are properly assigned // Create the VM memory config via the constructor to ensure default values are properly assigned
clh.vmconfig.Memory = chclient.NewMemoryConfig(int64((utils.MemUnit(clh.config.MemorySize) * utils.MiB).ToBytes())) clh.vmconfig.Memory = chclient.NewMemoryConfig(int64((utils.MemUnit(clh.config.MemorySize) * utils.MiB).ToBytes()))
// shared memory should be enabled if using vhost-user(kata uses virtiofsd) // shared memory should be enabled if using vhost-user(kata uses virtiofsd)
clh.vmconfig.Memory.Shared = func(b bool) *bool { return &b }(true) clh.vmconfig.Memory.Shared = func(b bool) *bool { return &b }(true)
// Enable hugepages if needed // Enable hugepages if needed
clh.vmconfig.Memory.Hugepages = func(b bool) *bool { return &b }(clh.config.HugePages) clh.vmconfig.Memory.Hugepages = func(b bool) *bool { return &b }(clh.config.HugePages)
if !clh.config.ConfidentialGuest {
hostMemKb, err := GetHostMemorySizeKb(procMemInfo) hostMemKb, err := GetHostMemorySizeKb(procMemInfo)
if err != nil { if err != nil {
return nil return nil
} }
// OpenAPI only supports int64 values // OpenAPI only supports int64 values
clh.vmconfig.Memory.HotplugSize = func(i int64) *int64 { return &i }(int64((utils.MemUnit(hostMemKb) * utils.KiB).ToBytes())) clh.vmconfig.Memory.HotplugSize = func(i int64) *int64 { return &i }(int64((utils.MemUnit(hostMemKb) * utils.KiB).ToBytes()))
}
// Set initial amount of cpu's for the virtual machine // Set initial amount of cpu's for the virtual machine
clh.vmconfig.Cpus = chclient.NewCpusConfig(int32(clh.config.NumVCPUs), int32(clh.config.DefaultMaxVCPUs)) clh.vmconfig.Cpus = chclient.NewCpusConfig(int32(clh.config.NumVCPUs), int32(clh.config.DefaultMaxVCPUs))
// First take the default parameters defined by this driver // First take the default parameters defined by this driver
params := clhKernelParams params := commonNvdimmKernelRootParams
if clh.config.ConfidentialGuest {
params = commonVirtioblkKernelRootParams
}
params = append(params, clhKernelParams...)
// Followed by extra debug parameters if debug enabled in configuration file // Followed by extra debug parameters if debug enabled in configuration file
if clh.config.Debug { if clh.config.Debug {
@ -291,12 +328,17 @@ func (clh *cloudHypervisor) CreateVM(ctx context.Context, id string, network Net
return err return err
} }
initrdPath, err := clh.config.InitrdAssetPath()
if err != nil {
return err
}
if imagePath != "" { if imagePath != "" {
if clh.config.ConfidentialGuest {
disk := chclient.NewDiskConfig(imagePath)
disk.SetReadonly(true)
if clh.vmconfig.Disks != nil {
*clh.vmconfig.Disks = append(*clh.vmconfig.Disks, *disk)
} else {
clh.vmconfig.Disks = &[]chclient.DiskConfig{*disk}
}
} else {
pmem := chclient.NewPmemConfig(imagePath) pmem := chclient.NewPmemConfig(imagePath)
*pmem.DiscardWrites = true *pmem.DiscardWrites = true
@ -305,12 +347,16 @@ func (clh *cloudHypervisor) CreateVM(ctx context.Context, id string, network Net
} else { } else {
clh.vmconfig.Pmem = &[]chclient.PmemConfig{*pmem} clh.vmconfig.Pmem = &[]chclient.PmemConfig{*pmem}
} }
} else if initrdPath != "" { }
} else {
initrdPath, err := clh.config.InitrdAssetPath()
if err != nil {
return err
}
initrd := chclient.NewInitramfsConfig(initrdPath) initrd := chclient.NewInitramfsConfig(initrdPath)
clh.vmconfig.SetInitramfs(*initrd) clh.vmconfig.SetInitramfs(*initrd)
} else {
return errors.New("no image or initrd specified")
} }
// Use serial port as the guest console only in debug mode, // Use serial port as the guest console only in debug mode,
@ -589,6 +635,10 @@ func (clh *cloudHypervisor) HotplugAddDevice(ctx context.Context, devInfo interf
span, _ := katatrace.Trace(ctx, clh.Logger(), "HotplugAddDevice", clhTracingTags, map[string]string{"sandbox_id": clh.id}) span, _ := katatrace.Trace(ctx, clh.Logger(), "HotplugAddDevice", clhTracingTags, map[string]string{"sandbox_id": clh.id})
defer span.End() defer span.End()
if clh.config.ConfidentialGuest {
return nil, errors.New("Device hotplug addition is not supported in confidential mode")
}
switch devType { switch devType {
case BlockDev: case BlockDev:
drive := devInfo.(*config.BlockDrive) drive := devInfo.(*config.BlockDrive)
@ -606,6 +656,10 @@ func (clh *cloudHypervisor) HotplugRemoveDevice(ctx context.Context, devInfo int
span, _ := katatrace.Trace(ctx, clh.Logger(), "HotplugRemoveDevice", clhTracingTags, map[string]string{"sandbox_id": clh.id}) span, _ := katatrace.Trace(ctx, clh.Logger(), "HotplugRemoveDevice", clhTracingTags, map[string]string{"sandbox_id": clh.id})
defer span.End() defer span.End()
if clh.config.ConfidentialGuest {
return nil, errors.New("Device hotplug addition is not supported in confidential mode")
}
var deviceID string var deviceID string
switch devType { switch devType {
@ -860,7 +914,9 @@ func (clh *cloudHypervisor) Capabilities(ctx context.Context) types.Capabilities
clh.Logger().WithField("function", "Capabilities").Info("get Capabilities") clh.Logger().WithField("function", "Capabilities").Info("get Capabilities")
var caps types.Capabilities var caps types.Capabilities
caps.SetFsSharingSupport() caps.SetFsSharingSupport()
if !clh.config.ConfidentialGuest {
caps.SetBlockDeviceHotplugSupport() caps.SetBlockDeviceHotplugSupport()
}
return caps return caps
} }

View File

@ -564,6 +564,11 @@ func (conf *HypervisorConfig) Valid() error {
conf.DefaultMaxVCPUs = defaultMaxVCPUs conf.DefaultMaxVCPUs = defaultMaxVCPUs
} }
if conf.ConfidentialGuest && conf.NumVCPUs != conf.DefaultMaxVCPUs {
hvLogger.Warnf("Confidential guests do not support hotplugging of vCPUs. Setting DefaultMaxVCPUs to NumVCPUs (%d)", conf.NumVCPUs)
conf.DefaultMaxVCPUs = conf.NumVCPUs
}
if conf.Msize9p == 0 && conf.SharedFS != config.VirtioFS { if conf.Msize9p == 0 && conf.SharedFS != config.VirtioFS {
conf.Msize9p = defaultMsize9p conf.Msize9p = defaultMsize9p
} }

View File

@ -181,6 +181,8 @@ paths:
schema: schema:
$ref: '#/components/schemas/PciDeviceInfo' $ref: '#/components/schemas/PciDeviceInfo'
description: The new device was successfully added to the VM instance. description: The new device was successfully added to the VM instance.
"204":
description: The new device was successfully (cold) added to the VM instance.
"404": "404":
description: The new device could not be added to the VM instance. description: The new device could not be added to the VM instance.
summary: Add a new device to the VM summary: Add a new device to the VM
@ -215,6 +217,8 @@ paths:
schema: schema:
$ref: '#/components/schemas/PciDeviceInfo' $ref: '#/components/schemas/PciDeviceInfo'
description: The new disk was successfully added to the VM instance. description: The new disk was successfully added to the VM instance.
"204":
description: The new disk was successfully (cold) added to the VM instance.
"500": "500":
description: The new disk could not be added to the VM instance. description: The new disk could not be added to the VM instance.
summary: Add a new disk to the VM summary: Add a new disk to the VM
@ -234,6 +238,8 @@ paths:
schema: schema:
$ref: '#/components/schemas/PciDeviceInfo' $ref: '#/components/schemas/PciDeviceInfo'
description: The new device was successfully added to the VM instance. description: The new device was successfully added to the VM instance.
"204":
description: The new device was successfully (cold) added to the VM instance.
"500": "500":
description: The new device could not be added to the VM instance. description: The new device could not be added to the VM instance.
summary: Add a new virtio-fs device to the VM summary: Add a new virtio-fs device to the VM
@ -253,6 +259,8 @@ paths:
schema: schema:
$ref: '#/components/schemas/PciDeviceInfo' $ref: '#/components/schemas/PciDeviceInfo'
description: The new device was successfully added to the VM instance. description: The new device was successfully added to the VM instance.
"204":
description: The new device was successfully (cold) added to the VM instance.
"500": "500":
description: The new device could not be added to the VM instance. description: The new device could not be added to the VM instance.
summary: Add a new pmem device to the VM summary: Add a new pmem device to the VM
@ -272,6 +280,8 @@ paths:
schema: schema:
$ref: '#/components/schemas/PciDeviceInfo' $ref: '#/components/schemas/PciDeviceInfo'
description: The new device was successfully added to the VM instance. description: The new device was successfully added to the VM instance.
"204":
description: The new device was successfully (cold) added to the VM instance.
"500": "500":
description: The new device could not be added to the VM instance. description: The new device could not be added to the VM instance.
summary: Add a new network device to the VM summary: Add a new network device to the VM
@ -291,6 +301,8 @@ paths:
schema: schema:
$ref: '#/components/schemas/PciDeviceInfo' $ref: '#/components/schemas/PciDeviceInfo'
description: The new device was successfully added to the VM instance. description: The new device was successfully added to the VM instance.
"204":
description: The new device was successfully (cold) added to the VM instance.
"500": "500":
description: The new device could not be added to the VM instance. description: The new device could not be added to the VM instance.
summary: Add a new vsock device to the VM summary: Add a new vsock device to the VM
@ -632,7 +644,7 @@ components:
children: children:
- children - children
- children - children
pci_bdf: 3 pci_bdf: pci_bdf
resources: resources:
- '{}' - '{}'
- '{}' - '{}'
@ -663,7 +675,7 @@ components:
children: children:
- children - children
- children - children
pci_bdf: 3 pci_bdf: pci_bdf
resources: resources:
- '{}' - '{}'
- '{}' - '{}'
@ -680,8 +692,7 @@ components:
type: string type: string
type: array type: array
pci_bdf: pci_bdf:
format: int32 type: string
type: integer
type: object type: object
VmCounters: VmCounters:
additionalProperties: additionalProperties:
@ -1757,6 +1768,8 @@ components:
properties: properties:
receiver_url: receiver_url:
type: string type: string
required:
- receiver_url
type: object type: object
SendMigrationData: SendMigrationData:
example: example:
@ -1767,4 +1780,6 @@ components:
type: string type: string
local: local:
type: boolean type: boolean
required:
- destination_url
type: object type: object

View File

@ -1071,7 +1071,7 @@ import (
) )
func main() { func main() {
receiveMigrationData := *openapiclient.NewReceiveMigrationData() // ReceiveMigrationData | The URL for the reception of migration state receiveMigrationData := *openapiclient.NewReceiveMigrationData("ReceiverUrl_example") // ReceiveMigrationData | The URL for the reception of migration state
configuration := openapiclient.NewConfiguration() configuration := openapiclient.NewConfiguration()
api_client := openapiclient.NewAPIClient(configuration) api_client := openapiclient.NewAPIClient(configuration)
@ -1381,7 +1381,7 @@ import (
) )
func main() { func main() {
sendMigrationData := *openapiclient.NewSendMigrationData() // SendMigrationData | The URL for sending the migration state sendMigrationData := *openapiclient.NewSendMigrationData("DestinationUrl_example") // SendMigrationData | The URL for sending the migration state
configuration := openapiclient.NewConfiguration() configuration := openapiclient.NewConfiguration()
api_client := openapiclient.NewAPIClient(configuration) api_client := openapiclient.NewAPIClient(configuration)

View File

@ -7,7 +7,7 @@ Name | Type | Description | Notes
**Id** | Pointer to **string** | | [optional] **Id** | Pointer to **string** | | [optional]
**Resources** | Pointer to **[]map[string]interface{}** | | [optional] **Resources** | Pointer to **[]map[string]interface{}** | | [optional]
**Children** | Pointer to **[]string** | | [optional] **Children** | Pointer to **[]string** | | [optional]
**PciBdf** | Pointer to **int32** | | [optional] **PciBdf** | Pointer to **string** | | [optional]
## Methods ## Methods
@ -105,20 +105,20 @@ HasChildren returns a boolean if a field has been set.
### GetPciBdf ### GetPciBdf
`func (o *DeviceNode) GetPciBdf() int32` `func (o *DeviceNode) GetPciBdf() string`
GetPciBdf returns the PciBdf field if non-nil, zero value otherwise. GetPciBdf returns the PciBdf field if non-nil, zero value otherwise.
### GetPciBdfOk ### GetPciBdfOk
`func (o *DeviceNode) GetPciBdfOk() (*int32, bool)` `func (o *DeviceNode) GetPciBdfOk() (*string, bool)`
GetPciBdfOk returns a tuple with the PciBdf field if it's non-nil, zero value otherwise GetPciBdfOk returns a tuple with the PciBdf field if it's non-nil, zero value otherwise
and a boolean to check if the value has been set. and a boolean to check if the value has been set.
### SetPciBdf ### SetPciBdf
`func (o *DeviceNode) SetPciBdf(v int32)` `func (o *DeviceNode) SetPciBdf(v string)`
SetPciBdf sets PciBdf field to given value. SetPciBdf sets PciBdf field to given value.

View File

@ -4,13 +4,13 @@
Name | Type | Description | Notes Name | Type | Description | Notes
------------ | ------------- | ------------- | ------------- ------------ | ------------- | ------------- | -------------
**ReceiverUrl** | Pointer to **string** | | [optional] **ReceiverUrl** | **string** | |
## Methods ## Methods
### NewReceiveMigrationData ### NewReceiveMigrationData
`func NewReceiveMigrationData() *ReceiveMigrationData` `func NewReceiveMigrationData(receiverUrl string, ) *ReceiveMigrationData`
NewReceiveMigrationData instantiates a new ReceiveMigrationData object NewReceiveMigrationData instantiates a new ReceiveMigrationData object
This constructor will assign default values to properties that have it defined, This constructor will assign default values to properties that have it defined,
@ -44,11 +44,6 @@ and a boolean to check if the value has been set.
SetReceiverUrl sets ReceiverUrl field to given value. SetReceiverUrl sets ReceiverUrl field to given value.
### HasReceiverUrl
`func (o *ReceiveMigrationData) HasReceiverUrl() bool`
HasReceiverUrl returns a boolean if a field has been set.
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

View File

@ -4,14 +4,14 @@
Name | Type | Description | Notes Name | Type | Description | Notes
------------ | ------------- | ------------- | ------------- ------------ | ------------- | ------------- | -------------
**DestinationUrl** | Pointer to **string** | | [optional] **DestinationUrl** | **string** | |
**Local** | Pointer to **bool** | | [optional] **Local** | Pointer to **bool** | | [optional]
## Methods ## Methods
### NewSendMigrationData ### NewSendMigrationData
`func NewSendMigrationData() *SendMigrationData` `func NewSendMigrationData(destinationUrl string, ) *SendMigrationData`
NewSendMigrationData instantiates a new SendMigrationData object NewSendMigrationData instantiates a new SendMigrationData object
This constructor will assign default values to properties that have it defined, This constructor will assign default values to properties that have it defined,
@ -45,11 +45,6 @@ and a boolean to check if the value has been set.
SetDestinationUrl sets DestinationUrl field to given value. SetDestinationUrl sets DestinationUrl field to given value.
### HasDestinationUrl
`func (o *SendMigrationData) HasDestinationUrl() bool`
HasDestinationUrl returns a boolean if a field has been set.
### GetLocal ### GetLocal

View File

@ -19,7 +19,7 @@ type DeviceNode struct {
Id *string `json:"id,omitempty"` Id *string `json:"id,omitempty"`
Resources *[]map[string]interface{} `json:"resources,omitempty"` Resources *[]map[string]interface{} `json:"resources,omitempty"`
Children *[]string `json:"children,omitempty"` Children *[]string `json:"children,omitempty"`
PciBdf *int32 `json:"pci_bdf,omitempty"` PciBdf *string `json:"pci_bdf,omitempty"`
} }
// NewDeviceNode instantiates a new DeviceNode object // NewDeviceNode instantiates a new DeviceNode object
@ -136,9 +136,9 @@ func (o *DeviceNode) SetChildren(v []string) {
} }
// GetPciBdf returns the PciBdf field value if set, zero value otherwise. // GetPciBdf returns the PciBdf field value if set, zero value otherwise.
func (o *DeviceNode) GetPciBdf() int32 { func (o *DeviceNode) GetPciBdf() string {
if o == nil || o.PciBdf == nil { if o == nil || o.PciBdf == nil {
var ret int32 var ret string
return ret return ret
} }
return *o.PciBdf return *o.PciBdf
@ -146,7 +146,7 @@ func (o *DeviceNode) GetPciBdf() int32 {
// GetPciBdfOk returns a tuple with the PciBdf field value if set, nil otherwise // GetPciBdfOk returns a tuple with the PciBdf field value if set, nil otherwise
// and a boolean to check if the value has been set. // and a boolean to check if the value has been set.
func (o *DeviceNode) GetPciBdfOk() (*int32, bool) { func (o *DeviceNode) GetPciBdfOk() (*string, bool) {
if o == nil || o.PciBdf == nil { if o == nil || o.PciBdf == nil {
return nil, false return nil, false
} }
@ -162,8 +162,8 @@ func (o *DeviceNode) HasPciBdf() bool {
return false return false
} }
// SetPciBdf gets a reference to the given int32 and assigns it to the PciBdf field. // SetPciBdf gets a reference to the given string and assigns it to the PciBdf field.
func (o *DeviceNode) SetPciBdf(v int32) { func (o *DeviceNode) SetPciBdf(v string) {
o.PciBdf = &v o.PciBdf = &v
} }

View File

@ -16,15 +16,16 @@ import (
// ReceiveMigrationData struct for ReceiveMigrationData // ReceiveMigrationData struct for ReceiveMigrationData
type ReceiveMigrationData struct { type ReceiveMigrationData struct {
ReceiverUrl *string `json:"receiver_url,omitempty"` ReceiverUrl string `json:"receiver_url"`
} }
// NewReceiveMigrationData instantiates a new ReceiveMigrationData object // NewReceiveMigrationData instantiates a new ReceiveMigrationData object
// This constructor will assign default values to properties that have it defined, // This constructor will assign default values to properties that have it defined,
// and makes sure properties required by API are set, but the set of arguments // and makes sure properties required by API are set, but the set of arguments
// will change when the set of required properties is changed // will change when the set of required properties is changed
func NewReceiveMigrationData() *ReceiveMigrationData { func NewReceiveMigrationData(receiverUrl string) *ReceiveMigrationData {
this := ReceiveMigrationData{} this := ReceiveMigrationData{}
this.ReceiverUrl = receiverUrl
return &this return &this
} }
@ -36,41 +37,33 @@ func NewReceiveMigrationDataWithDefaults() *ReceiveMigrationData {
return &this return &this
} }
// GetReceiverUrl returns the ReceiverUrl field value if set, zero value otherwise. // GetReceiverUrl returns the ReceiverUrl field value
func (o *ReceiveMigrationData) GetReceiverUrl() string { func (o *ReceiveMigrationData) GetReceiverUrl() string {
if o == nil || o.ReceiverUrl == nil { if o == nil {
var ret string var ret string
return ret return ret
} }
return *o.ReceiverUrl
return o.ReceiverUrl
} }
// GetReceiverUrlOk returns a tuple with the ReceiverUrl field value if set, nil otherwise // GetReceiverUrlOk returns a tuple with the ReceiverUrl field value
// and a boolean to check if the value has been set. // and a boolean to check if the value has been set.
func (o *ReceiveMigrationData) GetReceiverUrlOk() (*string, bool) { func (o *ReceiveMigrationData) GetReceiverUrlOk() (*string, bool) {
if o == nil || o.ReceiverUrl == nil { if o == nil {
return nil, false return nil, false
} }
return o.ReceiverUrl, true return &o.ReceiverUrl, true
} }
// HasReceiverUrl returns a boolean if a field has been set. // SetReceiverUrl sets field value
func (o *ReceiveMigrationData) HasReceiverUrl() bool {
if o != nil && o.ReceiverUrl != nil {
return true
}
return false
}
// SetReceiverUrl gets a reference to the given string and assigns it to the ReceiverUrl field.
func (o *ReceiveMigrationData) SetReceiverUrl(v string) { func (o *ReceiveMigrationData) SetReceiverUrl(v string) {
o.ReceiverUrl = &v o.ReceiverUrl = v
} }
func (o ReceiveMigrationData) MarshalJSON() ([]byte, error) { func (o ReceiveMigrationData) MarshalJSON() ([]byte, error) {
toSerialize := map[string]interface{}{} toSerialize := map[string]interface{}{}
if o.ReceiverUrl != nil { if true {
toSerialize["receiver_url"] = o.ReceiverUrl toSerialize["receiver_url"] = o.ReceiverUrl
} }
return json.Marshal(toSerialize) return json.Marshal(toSerialize)

View File

@ -16,7 +16,7 @@ import (
// SendMigrationData struct for SendMigrationData // SendMigrationData struct for SendMigrationData
type SendMigrationData struct { type SendMigrationData struct {
DestinationUrl *string `json:"destination_url,omitempty"` DestinationUrl string `json:"destination_url"`
Local *bool `json:"local,omitempty"` Local *bool `json:"local,omitempty"`
} }
@ -24,8 +24,9 @@ type SendMigrationData struct {
// This constructor will assign default values to properties that have it defined, // This constructor will assign default values to properties that have it defined,
// and makes sure properties required by API are set, but the set of arguments // and makes sure properties required by API are set, but the set of arguments
// will change when the set of required properties is changed // will change when the set of required properties is changed
func NewSendMigrationData() *SendMigrationData { func NewSendMigrationData(destinationUrl string) *SendMigrationData {
this := SendMigrationData{} this := SendMigrationData{}
this.DestinationUrl = destinationUrl
return &this return &this
} }
@ -37,36 +38,28 @@ func NewSendMigrationDataWithDefaults() *SendMigrationData {
return &this return &this
} }
// GetDestinationUrl returns the DestinationUrl field value if set, zero value otherwise. // GetDestinationUrl returns the DestinationUrl field value
func (o *SendMigrationData) GetDestinationUrl() string { func (o *SendMigrationData) GetDestinationUrl() string {
if o == nil || o.DestinationUrl == nil { if o == nil {
var ret string var ret string
return ret return ret
} }
return *o.DestinationUrl
return o.DestinationUrl
} }
// GetDestinationUrlOk returns a tuple with the DestinationUrl field value if set, nil otherwise // GetDestinationUrlOk returns a tuple with the DestinationUrl field value
// and a boolean to check if the value has been set. // and a boolean to check if the value has been set.
func (o *SendMigrationData) GetDestinationUrlOk() (*string, bool) { func (o *SendMigrationData) GetDestinationUrlOk() (*string, bool) {
if o == nil || o.DestinationUrl == nil { if o == nil {
return nil, false return nil, false
} }
return o.DestinationUrl, true return &o.DestinationUrl, true
} }
// HasDestinationUrl returns a boolean if a field has been set. // SetDestinationUrl sets field value
func (o *SendMigrationData) HasDestinationUrl() bool {
if o != nil && o.DestinationUrl != nil {
return true
}
return false
}
// SetDestinationUrl gets a reference to the given string and assigns it to the DestinationUrl field.
func (o *SendMigrationData) SetDestinationUrl(v string) { func (o *SendMigrationData) SetDestinationUrl(v string) {
o.DestinationUrl = &v o.DestinationUrl = v
} }
// GetLocal returns the Local field value if set, zero value otherwise. // GetLocal returns the Local field value if set, zero value otherwise.
@ -103,7 +96,7 @@ func (o *SendMigrationData) SetLocal(v bool) {
func (o SendMigrationData) MarshalJSON() ([]byte, error) { func (o SendMigrationData) MarshalJSON() ([]byte, error) {
toSerialize := map[string]interface{}{} toSerialize := map[string]interface{}{}
if o.DestinationUrl != nil { if true {
toSerialize["destination_url"] = o.DestinationUrl toSerialize["destination_url"] = o.DestinationUrl
} }
if o.Local != nil { if o.Local != nil {

View File

@ -195,6 +195,8 @@ paths:
application/json: application/json:
schema: schema:
$ref: '#/components/schemas/PciDeviceInfo' $ref: '#/components/schemas/PciDeviceInfo'
204:
description: The new device was successfully (cold) added to the VM instance.
404: 404:
description: The new device could not be added to the VM instance. description: The new device could not be added to the VM instance.
@ -231,6 +233,8 @@ paths:
application/json: application/json:
schema: schema:
$ref: '#/components/schemas/PciDeviceInfo' $ref: '#/components/schemas/PciDeviceInfo'
204:
description: The new disk was successfully (cold) added to the VM instance.
500: 500:
description: The new disk could not be added to the VM instance. description: The new disk could not be added to the VM instance.
@ -251,6 +255,8 @@ paths:
application/json: application/json:
schema: schema:
$ref: '#/components/schemas/PciDeviceInfo' $ref: '#/components/schemas/PciDeviceInfo'
204:
description: The new device was successfully (cold) added to the VM instance.
500: 500:
description: The new device could not be added to the VM instance. description: The new device could not be added to the VM instance.
@ -271,6 +277,8 @@ paths:
application/json: application/json:
schema: schema:
$ref: '#/components/schemas/PciDeviceInfo' $ref: '#/components/schemas/PciDeviceInfo'
204:
description: The new device was successfully (cold) added to the VM instance.
500: 500:
description: The new device could not be added to the VM instance. description: The new device could not be added to the VM instance.
@ -291,6 +299,8 @@ paths:
application/json: application/json:
schema: schema:
$ref: '#/components/schemas/PciDeviceInfo' $ref: '#/components/schemas/PciDeviceInfo'
204:
description: The new device was successfully (cold) added to the VM instance.
500: 500:
description: The new device could not be added to the VM instance. description: The new device could not be added to the VM instance.
@ -311,6 +321,8 @@ paths:
application/json: application/json:
schema: schema:
$ref: '#/components/schemas/PciDeviceInfo' $ref: '#/components/schemas/PciDeviceInfo'
204:
description: The new device was successfully (cold) added to the VM instance.
500: 500:
description: The new device could not be added to the VM instance. description: The new device could not be added to the VM instance.
@ -428,8 +440,7 @@ components:
items: items:
type: string type: string
pci_bdf: pci_bdf:
type: integer type: string
format: int32
VmCounters: VmCounters:
type: object type: object
@ -1055,12 +1066,16 @@ components:
type: boolean type: boolean
ReceiveMigrationData: ReceiveMigrationData:
required:
- receiver_url
type: object type: object
properties: properties:
receiver_url: receiver_url:
type: string type: string
SendMigrationData: SendMigrationData:
required:
- destination_url
type: object type: object
properties: properties:
destination_url: destination_url:

View File

@ -132,6 +132,11 @@ func newQemuArch(config HypervisorConfig) (qemuArch, error) {
if err := q.enableProtection(); err != nil { if err := q.enableProtection(); err != nil {
return nil, err return nil, err
} }
if !q.qemuArchBase.disableNvdimm {
hvLogger.WithField("subsystem", "qemuAmd64").Warn("Nvdimm is not supported with confidential guest, disabling it.")
q.qemuArchBase.disableNvdimm = true
}
} }
if config.SGXEPCSize != 0 { if config.SGXEPCSize != 0 {
@ -153,8 +158,9 @@ func newQemuArch(config HypervisorConfig) (qemuArch, error) {
func (q *qemuAmd64) capabilities() types.Capabilities { func (q *qemuAmd64) capabilities() types.Capabilities {
var caps types.Capabilities var caps types.Capabilities
if q.qemuMachine.Type == QemuQ35 || if (q.qemuMachine.Type == QemuQ35 ||
q.qemuMachine.Type == QemuVirt { q.qemuMachine.Type == QemuVirt) &&
q.protection == noneProtection {
caps.SetBlockDeviceHotplugSupport() caps.SetBlockDeviceHotplugSupport()
} }
@ -188,7 +194,11 @@ func (q *qemuAmd64) memoryTopology(memoryMb, hostMemoryMb uint64, slots uint8) g
// Is Memory Hotplug supported by this architecture/machine type combination? // Is Memory Hotplug supported by this architecture/machine type combination?
func (q *qemuAmd64) supportGuestMemoryHotplug() bool { func (q *qemuAmd64) supportGuestMemoryHotplug() bool {
// true for all amd64 machine types except for microvm. // true for all amd64 machine types except for microvm.
return q.qemuMachine.Type != govmmQemu.MachineTypeMicrovm if q.qemuMachine.Type == govmmQemu.MachineTypeMicrovm {
return false
}
return q.protection == noneProtection
} }
func (q *qemuAmd64) appendImage(ctx context.Context, devices []govmmQemu.Device, path string) ([]govmmQemu.Device, error) { func (q *qemuAmd64) appendImage(ctx context.Context, devices []govmmQemu.Device, path string) ([]govmmQemu.Device, error) {

View File

@ -277,7 +277,9 @@ func (q *qemuArchBase) kernelParameters(debug bool) []Param {
func (q *qemuArchBase) capabilities() types.Capabilities { func (q *qemuArchBase) capabilities() types.Capabilities {
var caps types.Capabilities var caps types.Capabilities
if q.protection == noneProtection {
caps.SetBlockDeviceHotplugSupport() caps.SetBlockDeviceHotplugSupport()
}
caps.SetMultiQueueSupport() caps.SetMultiQueueSupport()
caps.SetFsSharingSupport() caps.SetFsSharingSupport()
return caps return caps
@ -690,7 +692,7 @@ func (q *qemuArchBase) handleImagePath(config HypervisorConfig) {
} }
func (q *qemuArchBase) supportGuestMemoryHotplug() bool { func (q *qemuArchBase) supportGuestMemoryHotplug() bool {
return true return q.protection == noneProtection
} }
func (q *qemuArchBase) setIgnoreSharedMemoryMigrationCaps(ctx context.Context, qmp *govmmQemu.QMP) error { func (q *qemuArchBase) setIgnoreSharedMemoryMigrationCaps(ctx context.Context, qmp *govmmQemu.QMP) error {

View File

@ -83,6 +83,11 @@ func newQemuArch(config HypervisorConfig) (qemuArch, error) {
if err := q.enableProtection(); err != nil { if err := q.enableProtection(); err != nil {
return nil, err 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
}
} }
q.handleImagePath(config) q.handleImagePath(config)
@ -96,7 +101,8 @@ func (q *qemuPPC64le) capabilities() types.Capabilities {
var caps types.Capabilities var caps types.Capabilities
// pseries machine type supports hotplugging drives // pseries machine type supports hotplugging drives
if q.qemuMachine.Type == QemuPseries { if q.qemuMachine.Type == QemuPseries &&
q.protection == noneProtection {
caps.SetBlockDeviceHotplugSupport() caps.SetBlockDeviceHotplugSupport()
} }

View File

@ -77,6 +77,11 @@ func newQemuArch(config HypervisorConfig) (qemuArch, error) {
if err := q.enableProtection(); err != nil { if err := q.enableProtection(); err != nil {
return nil, err return nil, err
} }
if !q.qemuArchBase.disableNvdimm {
hvLogger.WithField("subsystem", "qemuS390x").Warn("Nvdimm is not supported with confidential guest, disabling it.")
q.qemuArchBase.disableNvdimm = true
}
} }
if config.ImagePath != "" { if config.ImagePath != "" {

View File

@ -28,6 +28,8 @@ readonly shimv2_builder="${static_build_dir}/shim-v2/build.sh"
readonly rootfs_builder="${repo_root_dir}/tools/packaging/guest-image/build_image.sh" readonly rootfs_builder="${repo_root_dir}/tools/packaging/guest-image/build_image.sh"
ARCH=$(uname -m)
workdir="${WORKDIR:-$PWD}" workdir="${WORKDIR:-$PWD}"
destdir="${workdir}/kata-static" destdir="${workdir}/kata-static"
@ -125,7 +127,9 @@ install_firecracker() {
# Install static cloud-hypervisor asset # Install static cloud-hypervisor asset
install_clh() { install_clh() {
export extra_build_args="--features tdx" if [[ "${ARCH}" == "x86_64" ]]; then
export features="tdx"
fi
info "build static cloud-hypervisor" info "build static cloud-hypervisor"
"${clh_builder}" "${clh_builder}"

View File

@ -52,9 +52,9 @@ build_clh_from_source() {
pushd "${repo_dir}" pushd "${repo_dir}"
git fetch || true git fetch || true
git checkout "${cloud_hypervisor_version}" git checkout "${cloud_hypervisor_version}"
if [ -n "${extra_build_args}" ]; then if [ -n "${features}" ]; then
info "Build cloud-hypervisor with extra args: ${extra_build_args}" info "Build cloud-hypervisor enabling the following features: ${features}"
./scripts/dev_cli.sh build --release --libc musl -- ${extra_build_args} ./scripts/dev_cli.sh build --release --libc musl --features "${features}"
else else
./scripts/dev_cli.sh build --release --libc musl ./scripts/dev_cli.sh build --release --libc musl
fi fi

View File

@ -75,7 +75,7 @@ assets:
url: "https://github.com/cloud-hypervisor/cloud-hypervisor" url: "https://github.com/cloud-hypervisor/cloud-hypervisor"
uscan-url: >- uscan-url: >-
https://github.com/cloud-hypervisor/cloud-hypervisor/tags.*/v?(\d\S+)\.tar\.gz https://github.com/cloud-hypervisor/cloud-hypervisor/tags.*/v?(\d\S+)\.tar\.gz
version: "55479a64d237d4c757dba19a696abefd27ec74fd" version: "5343e09e7b8dbd5dd8ac0d90a3ad52037490dd86"
firecracker: firecracker:
description: "Firecracker micro-VMM" description: "Firecracker micro-VMM"