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:
parent
b325069d72
commit
2a992c4080
src
libs/protocols/protos
runtime/virtcontainers
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
42
src/runtime/virtcontainers/types/ccw.go
Normal file
42
src/runtime/virtcontainers/types/ccw.go
Normal 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)
|
||||
}
|
39
src/runtime/virtcontainers/types/ccw_test.go
Normal file
39
src/runtime/virtcontainers/types/ccw_test.go
Normal 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)
|
||||
}
|
@ -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
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user