1
0
mirror of https://github.com/kata-containers/kata-containers.git synced 2025-05-08 00:17:31 +00:00

virtcontainers: Add CCW device to endpoint

To support virtio-net-ccw for s390x, add CCW devices to the Endpoint
interface. Add respective fields and functions to implementing structs.

Device paths may be empty. PciPath resolves this by being a list that
may be empty, but this design does not map to CcwDevice. Use a pointer
instead.

Signed-off-by: Jakob Naucke <jakob.naucke@ibm.com>
This commit is contained in:
Jakob Naucke 2025-01-30 16:59:12 +01:00
parent b325069d72
commit 2a992c4080
No known key found for this signature in database
GPG Key ID: D34F14412FB929FC
14 changed files with 186 additions and 4 deletions

View File

@ -39,8 +39,8 @@ message Interface {
string hwAddr = 5;
// Path for the device (see the pci::Path (Rust) and types.PciPath
// (Go) or ccw::Device (Rust) types for format details, depending on
// architecture)
// (Go) or ccw::Device (Rust) and types.CcwDevice (Go) types for
// format details, depending on architecture)
string devicePath = 6;
// Type defines the type of interface described by this structure.

View File

@ -20,10 +20,12 @@ type Endpoint interface {
HardwareAddr() string
Type() EndpointType
PciPath() vcTypes.PciPath
CcwDevice() *vcTypes.CcwDevice
NetworkPair() *NetworkInterfacePair
SetProperties(NetworkInfo)
SetPciPath(vcTypes.PciPath)
SetCcwDevice(vcTypes.CcwDevice)
Attach(context.Context, *Sandbox) error
Detach(ctx context.Context, netNsCreated bool, netNsPath string) error
HotAttach(context.Context, *Sandbox) error

View File

@ -22,6 +22,7 @@ var ipvlanTrace = getNetworkTrace(IPVlanEndpointType)
type IPVlanEndpoint struct {
EndpointType EndpointType
PCIPath vcTypes.PciPath
CCWDevice *vcTypes.CcwDevice
EndpointProperties NetworkInfo
NetPair NetworkInterfacePair
RxRateLimiter bool
@ -88,6 +89,16 @@ func (endpoint *IPVlanEndpoint) SetPciPath(pciPath vcTypes.PciPath) {
endpoint.PCIPath = pciPath
}
// CcwDevice returns the CCW device of the endpoint.
func (endpoint *IPVlanEndpoint) CcwDevice() *vcTypes.CcwDevice {
return endpoint.CCWDevice
}
// SetCcwDevice sets the CCW device of the endpoint.
func (endpoint *IPVlanEndpoint) SetCcwDevice(ccwDev vcTypes.CcwDevice) {
endpoint.CCWDevice = &ccwDev
}
// NetworkPair returns the network pair of the endpoint.
func (endpoint *IPVlanEndpoint) NetworkPair() *NetworkInterfacePair {
return &endpoint.NetPair

View File

@ -22,6 +22,7 @@ var macvlanTrace = getNetworkTrace(MacvlanEndpointType)
type MacvlanEndpoint struct {
EndpointType EndpointType
PCIPath vcTypes.PciPath
CCWDevice *vcTypes.CcwDevice
EndpointProperties NetworkInfo
NetPair NetworkInterfacePair
RxRateLimiter bool
@ -85,6 +86,16 @@ func (endpoint *MacvlanEndpoint) SetPciPath(pciPath vcTypes.PciPath) {
endpoint.PCIPath = pciPath
}
// CcwDevice returns the CCW device of the endpoint.
func (endpoint *MacvlanEndpoint) CcwDevice() *vcTypes.CcwDevice {
return endpoint.CCWDevice
}
// SetCcwDevice sets the CCW device of the endpoint.
func (endpoint *MacvlanEndpoint) SetCcwDevice(ccwDev vcTypes.CcwDevice) {
endpoint.CCWDevice = &ccwDev
}
// NetworkPair returns the network pair of the endpoint.
func (endpoint *MacvlanEndpoint) NetworkPair() *NetworkInterfacePair {
return &endpoint.NetPair

View File

@ -25,6 +25,7 @@ type MacvtapEndpoint struct {
VMFds []*os.File
VhostFds []*os.File
PCIPath vcTypes.PciPath
CCWDevice *vcTypes.CcwDevice
RxRateLimiter bool
TxRateLimiter bool
}
@ -112,6 +113,16 @@ func (endpoint *MacvtapEndpoint) SetPciPath(pciPath vcTypes.PciPath) {
endpoint.PCIPath = pciPath
}
// CcwDevice returns the CCW device of the endpoint.
func (endpoint *MacvtapEndpoint) CcwDevice() *vcTypes.CcwDevice {
return endpoint.CCWDevice
}
// SetCcwDevice sets the CCW device of the endpoint.
func (endpoint *MacvtapEndpoint) SetCcwDevice(ccwDev vcTypes.CcwDevice) {
endpoint.CCWDevice = &ccwDev
}
// NetworkPair returns the network pair of the endpoint.
func (endpoint *MacvtapEndpoint) NetworkPair() *NetworkInterfacePair {
return nil

View File

@ -34,6 +34,7 @@ type PhysicalEndpoint struct {
Driver string
VendorDeviceID string
PCIPath vcTypes.PciPath
CCWDevice *vcTypes.CcwDevice
}
// Properties returns the properties of the physical interface.
@ -66,6 +67,16 @@ func (endpoint *PhysicalEndpoint) SetPciPath(pciPath vcTypes.PciPath) {
endpoint.PCIPath = pciPath
}
// CcwDevice returns the CCW device of the endpoint.
func (endpoint *PhysicalEndpoint) CcwDevice() *vcTypes.CcwDevice {
return endpoint.CCWDevice
}
// SetCcwDevice sets the CCW device of the endpoint.
func (endpoint *PhysicalEndpoint) SetCcwDevice(ccwDev vcTypes.CcwDevice) {
endpoint.CCWDevice = &ccwDev
}
// SetProperties sets the properties of the physical endpoint.
func (endpoint *PhysicalEndpoint) SetProperties(properties NetworkInfo) {
endpoint.EndpointProperties = properties

View File

@ -197,8 +197,8 @@ type Interface struct {
Mtu uint64 `protobuf:"varint,4,opt,name=mtu,proto3" json:"mtu,omitempty"`
HwAddr string `protobuf:"bytes,5,opt,name=hwAddr,proto3" json:"hwAddr,omitempty"`
// Path for the device (see the pci::Path (Rust) and types.PciPath
// (Go) or ccw::Device (Rust) types for format details, depending on
// architecture)
// (Go) or ccw::Device (Rust) and types.CcwDevice (Go) types for
// format details, depending on architecture)
DevicePath string `protobuf:"bytes,6,opt,name=devicePath,proto3" json:"devicePath,omitempty"`
// Type defines the type of interface described by this structure.
// The expected values are the one that are defined by the netlink

View File

@ -27,6 +27,7 @@ type TapEndpoint struct {
EndpointProperties NetworkInfo
EndpointType EndpointType
PCIPath vcTypes.PciPath
CCWDevice *vcTypes.CcwDevice
RxRateLimiter bool
TxRateLimiter bool
}
@ -66,6 +67,16 @@ func (endpoint *TapEndpoint) NetworkPair() *NetworkInterfacePair {
return nil
}
// CcwDevice returns the CCW device of the endpoint.
func (endpoint *TapEndpoint) CcwDevice() *vcTypes.CcwDevice {
return endpoint.CCWDevice
}
// SetCcwDevice sets the CCW device of the endpoint.
func (endpoint *TapEndpoint) SetCcwDevice(ccwDev vcTypes.CcwDevice) {
endpoint.CCWDevice = &ccwDev
}
// SetProperties sets the properties for the endpoint.
func (endpoint *TapEndpoint) SetProperties(properties NetworkInfo) {
endpoint.EndpointProperties = properties

View File

@ -26,6 +26,7 @@ var tuntapTrace = getNetworkTrace(TuntapEndpointType)
type TuntapEndpoint struct {
EndpointType EndpointType
PCIPath vcTypes.PciPath
CCWDevice *vcTypes.CcwDevice
TuntapInterface TuntapInterface
EndpointProperties NetworkInfo
NetPair NetworkInterfacePair
@ -63,6 +64,16 @@ func (endpoint *TuntapEndpoint) SetPciPath(pciPath vcTypes.PciPath) {
endpoint.PCIPath = pciPath
}
// CcwDevice returns the CCW device of the endpoint.
func (endpoint *TuntapEndpoint) CcwDevice() *vcTypes.CcwDevice {
return endpoint.CCWDevice
}
// SetCcwDevice sets the CCW device of the endpoint.
func (endpoint *TuntapEndpoint) SetCcwDevice(ccwDev vcTypes.CcwDevice) {
endpoint.CCWDevice = &ccwDev
}
// NetworkPair returns the network pair of the endpoint.
func (endpoint *TuntapEndpoint) NetworkPair() *NetworkInterfacePair {
return &endpoint.NetPair

View File

@ -0,0 +1,42 @@
// Copyright 2025 IBM
//
// SPDX-License-Identifier: Apache-2.0
//
package types
import (
"fmt"
"strconv"
)
// CCW bus ID follow the format <xx>.<d>.<xxxx> [1, p. 11], where
// - <xx> is the channel subsystem ID, which is always 0 from the guest side, but different from
// the host side, e.g. 0xfe for virtio-*-ccw [1, p. 435],
// - <d> is the subchannel set ID, which ranges from 0-3 [2], and
// - <xxxx> is the device number (0000-ffff; leading zeroes can be omitted,
// e.g. 3 instead of 0003).
//
// [1] https://www.ibm.com/docs/en/linuxonibm/pdf/lku4dd04.pdf
// [2] https://qemu.readthedocs.io/en/master/system/s390x/css.html
const subchannelSetMax = 3
type CcwDevice struct {
ssid uint8
devno uint16
}
func CcwDeviceFrom(ssid int, devno string) (CcwDevice, error) {
if ssid < 0 || ssid > subchannelSetMax {
return CcwDevice{}, fmt.Errorf("Subchannel set ID %d should be in range [0..%d]", ssid, subchannelSetMax)
}
v, err := strconv.ParseUint(devno, 16, 16)
if err != nil {
return CcwDevice{}, fmt.Errorf("Failed to parse 0x%v as CCW device number: %v", devno, err)
}
return CcwDevice{ssid: uint8(ssid), devno: uint16(v)}, nil
}
func (dev CcwDevice) String() string {
return fmt.Sprintf("0.%x.%04x", dev.ssid, dev.devno)
}

View File

@ -0,0 +1,39 @@
// Copyright 2025 IBM
//
// SPDX-License-Identifier: Apache-2.0
//
package types
import (
"github.com/stretchr/testify/assert"
"testing"
)
func TestPciDevice(t *testing.T) {
assert := assert.New(t)
// Valid devices
dev, err := CcwDeviceFrom(0, "0000")
assert.NoError(err)
assert.Equal(dev, CcwDevice{0, 0})
assert.Equal(dev.String(), "0.0.0000")
dev, err = CcwDeviceFrom(3, "ffff")
assert.NoError(err)
assert.Equal(dev, CcwDevice{3, 65535})
assert.Equal(dev.String(), "0.3.ffff")
// Invalid devices
_, err = CcwDeviceFrom(4, "0000")
assert.Error(err)
_, err = CcwDeviceFrom(-1, "0000")
assert.Error(err)
_, err = CcwDeviceFrom(-1, "10000")
assert.Error(err)
_, err = CcwDeviceFrom(-1, "NaN")
assert.Error(err)
}

View File

@ -22,6 +22,7 @@ var vethTrace = getNetworkTrace(VethEndpointType)
type VethEndpoint struct {
EndpointType EndpointType
PCIPath vcTypes.PciPath
CCWDevice *vcTypes.CcwDevice
EndpointProperties NetworkInfo
NetPair NetworkInterfacePair
RxRateLimiter bool
@ -83,6 +84,16 @@ func (endpoint *VethEndpoint) SetPciPath(pciPath vcTypes.PciPath) {
endpoint.PCIPath = pciPath
}
// CcwDevice returns the CCW device of the endpoint.
func (endpoint *VethEndpoint) CcwDevice() *vcTypes.CcwDevice {
return endpoint.CCWDevice
}
// SetCcwDevice sets the CCW device of the endpoint.
func (endpoint *VethEndpoint) SetCcwDevice(ccwDev vcTypes.CcwDevice) {
endpoint.CCWDevice = &ccwDev
}
// NetworkPair returns the network pair of the endpoint.
func (endpoint *VethEndpoint) NetworkPair() *NetworkInterfacePair {
return &endpoint.NetPair

View File

@ -18,6 +18,7 @@ type VfioEndpoint struct {
EndpointType EndpointType
HostBDF string
PCIPath vcTypes.PciPath
CCWDevice *vcTypes.CcwDevice
Iface NetworkInterface
EndpointProperties NetworkInfo
}
@ -64,6 +65,16 @@ func (endpoint *VfioEndpoint) SetPciPath(path vcTypes.PciPath) {
endpoint.PCIPath = path
}
// CcwDevice returns the CCW device of the endpoint.
func (endpoint *VfioEndpoint) CcwDevice() *vcTypes.CcwDevice {
return endpoint.CCWDevice
}
// SetCcwDevice sets the CCW device of the endpoint.
func (endpoint *VfioEndpoint) SetCcwDevice(ccwDev vcTypes.CcwDevice) {
endpoint.CCWDevice = &ccwDev
}
// Attach for VFIO endpoint
func (endpoint *VfioEndpoint) Attach(ctx context.Context, s *Sandbox) error {
return fmt.Errorf("attach is unsupported for VFIO endpoint")

View File

@ -37,6 +37,7 @@ type VhostUserEndpoint struct {
EndpointProperties NetworkInfo
EndpointType EndpointType
PCIPath vcTypes.PciPath
CCWDevice *vcTypes.CcwDevice
}
// Properties returns the properties of the interface.
@ -74,6 +75,16 @@ func (endpoint *VhostUserEndpoint) SetPciPath(pciPath vcTypes.PciPath) {
endpoint.PCIPath = pciPath
}
// CcwDevice returns the CCW device of the endpoint.
func (endpoint *VhostUserEndpoint) CcwDevice() *vcTypes.CcwDevice {
return endpoint.CCWDevice
}
// SetCcwDevice sets the CCW device of the endpoint.
func (endpoint *VhostUserEndpoint) SetCcwDevice(ccwDev vcTypes.CcwDevice) {
endpoint.CCWDevice = &ccwDev
}
// NetworkPair returns the network pair of the endpoint.
func (endpoint *VhostUserEndpoint) NetworkPair() *NetworkInterfacePair {
return nil