• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kubevirt / kubevirt / db9927fa-6ef4-4b9f-b267-16b157867172

26 Apr 2026 07:37PM UTC coverage: 71.762% (+0.006%) from 71.756%
db9927fa-6ef4-4b9f-b267-16b157867172

push

prow

web-flow
Merge pull request #17606 from akalenyu/revert-cross-ns-mig-dq

e2e quarantine: revert accidental cross ns migration dequarantine

77616 of 108158 relevant lines covered (71.76%)

572.11 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

80.41
/pkg/virt-launcher/virtwrap/device/hostdevice/dra/gpu_hostdev.go
1
/*
2
 * This file is part of the KubeVirt project
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 *
16
 * Copyright The KubeVirt Authors.
17
 *
18
 */
19

20
package dra
21

22
import (
23
        "fmt"
24

25
        k8sv1 "k8s.io/api/core/v1"
26

27
        v1 "kubevirt.io/api/core/v1"
28
        "kubevirt.io/client-go/log"
29

30
        drautil "kubevirt.io/kubevirt/pkg/dra"
31
        "kubevirt.io/kubevirt/pkg/virt-launcher/virtwrap/api"
32
        "kubevirt.io/kubevirt/pkg/virt-launcher/virtwrap/device"
33
)
34

35
const (
36
        failedCreateGPUHostDeviceFmt = "failed to create DRA GPU host-devices: %v"
37
        AliasPrefix                  = "dra-gpu-"
38
        DefaultDisplayOn             = true
39
)
40

41
// CreateDRAGPUHostDevices creates host devices for GPUs allocated via DRA.
42
func CreateDRAGPUHostDevices(vmi *v1.VirtualMachineInstance, basePath string) ([]api.HostDevice, error) {
36✔
43
        var hostDevices []api.HostDevice
36✔
44
        if !hasGPUsWithDRA(vmi) {
67✔
45
                log.Log.V(3).Infof("No DRA GPU devices found for vmi %s/%s", vmi.GetNamespace(), vmi.GetName())
31✔
46
                return hostDevices, nil
31✔
47
        }
31✔
48

49
        for _, gpu := range vmi.Spec.Domain.Devices.GPUs {
12✔
50
                if !drautil.IsGPUDRA(gpu) {
7✔
51
                        continue
×
52
                }
53

54
                hostDevice, err := createHostDeviceForGPU(gpu, basePath, vmi.Spec.ResourceClaims)
7✔
55
                if err != nil {
8✔
56
                        return nil, fmt.Errorf(failedCreateGPUHostDeviceFmt, err)
1✔
57
                }
1✔
58
                if hostDevice != nil {
12✔
59
                        hostDevices = append(hostDevices, *hostDevice)
6✔
60
                }
6✔
61
        }
62

63
        if err := validateCreationOfDRAGPUDevices(vmi.Spec.Domain.Devices.GPUs, hostDevices); err != nil {
4✔
64
                return nil, fmt.Errorf(failedCreateGPUHostDeviceFmt, err)
×
65
        }
×
66

67
        // Set default display on first vGPU if not explicitly set
68
        if DefaultDisplayOn && !isVgpuDisplaySet(vmi.Spec.Domain.Devices.GPUs) {
8✔
69
                for i := range hostDevices {
9✔
70
                        if hostDevices[i].Type == api.HostDeviceMDev {
8✔
71
                                hostDevices[i].Display = "on"
3✔
72
                                hostDevices[i].RamFB = "on"
3✔
73
                                break
3✔
74
                        }
75
                }
76
        }
77

78
        return hostDevices, nil
4✔
79
}
80

81
func createHostDeviceForGPU(gpu v1.GPU, basePath string, resourceClaims []k8sv1.PodResourceClaim) (*api.HostDevice, error) {
7✔
82
        if gpu.ClaimRequest == nil || gpu.ClaimRequest.ClaimName == nil || *gpu.ClaimRequest.ClaimName == "" || gpu.ClaimRequest.RequestName == nil || *gpu.ClaimRequest.RequestName == "" {
7✔
83
                return nil, fmt.Errorf("GPU %s has incomplete ClaimRequest", gpu.Name)
×
84
        }
×
85

86
        claimName := *gpu.ClaimRequest.ClaimName
7✔
87
        requestName := *gpu.ClaimRequest.RequestName
7✔
88

7✔
89
        // Check mdevUUID first: a device with both pciBusID and mdevUUID is a
7✔
90
        // mediated (vGPU) device whose parent happens to expose pciBusID. Treating
7✔
91
        // it as PCI passthrough would be incorrect.
7✔
92
        mdevUUID, mdevErr := drautil.GetMDevUUIDForClaim(basePath, resourceClaims, claimName, requestName)
7✔
93
        if mdevErr == nil {
10✔
94
                log.Log.V(2).Infof("Adding DRA MDEV GPU device for %s", gpu.Name)
3✔
95
                hostDevice := api.HostDevice{
3✔
96
                        Alias: api.NewUserDefinedAlias(AliasPrefix + gpu.Name),
3✔
97
                        Source: api.HostDeviceSource{
3✔
98
                                Address: &api.Address{
3✔
99
                                        UUID: mdevUUID,
3✔
100
                                },
3✔
101
                        },
3✔
102
                        Type:  api.HostDeviceMDev,
3✔
103
                        Mode:  "subsystem",
3✔
104
                        Model: "vfio-pci",
3✔
105
                }
3✔
106

3✔
107
                if gpu.VirtualGPUOptions != nil && gpu.VirtualGPUOptions.Display != nil {
3✔
108
                        displayEnabled := gpu.VirtualGPUOptions.Display.Enabled
×
109
                        if displayEnabled == nil || *displayEnabled {
×
110
                                hostDevice.Display = "on"
×
111
                                if gpu.VirtualGPUOptions.Display.RamFB == nil || *gpu.VirtualGPUOptions.Display.RamFB.Enabled {
×
112
                                        hostDevice.RamFB = "on"
×
113
                                }
×
114
                        }
115
                }
116
                return &hostDevice, nil
3✔
117
        }
118

119
        pciAddr, pciErr := drautil.GetPCIAddressForClaim(basePath, resourceClaims, claimName, requestName)
4✔
120
        if pciErr == nil {
7✔
121
                log.Log.V(2).Infof("Adding DRA PCI GPU device for %s", gpu.Name)
3✔
122
                hostAddr, err := device.NewPciAddressField(pciAddr)
3✔
123
                if err != nil {
3✔
124
                        return nil, fmt.Errorf("failed to create PCI device for %s: %v", gpu.Name, err)
×
125
                }
×
126
                return &api.HostDevice{
3✔
127
                        Alias:   api.NewUserDefinedAlias(AliasPrefix + gpu.Name),
3✔
128
                        Source:  api.HostDeviceSource{Address: hostAddr},
3✔
129
                        Type:    api.HostDevicePCI,
3✔
130
                        Managed: "no",
3✔
131
                }, nil
3✔
132
        }
133

134
        return nil, fmt.Errorf("GPU %s has no mdevUUID or pciBusID in metadata for claim %s request %s (mdev: %v, pci: %v)", gpu.Name, claimName, requestName, mdevErr, pciErr)
1✔
135
}
136

137
func hasGPUsWithDRA(vmi *v1.VirtualMachineInstance) bool {
36✔
138
        for _, gpu := range vmi.Spec.Domain.Devices.GPUs {
42✔
139
                if drautil.IsGPUDRA(gpu) {
11✔
140
                        return true
5✔
141
                }
5✔
142
        }
143
        return false
31✔
144
}
145

146
func isVgpuDisplaySet(gpuSpecs []v1.GPU) bool {
4✔
147
        for _, gpu := range gpuSpecs {
9✔
148
                if gpu.VirtualGPUOptions != nil && gpu.VirtualGPUOptions.Display != nil {
5✔
149
                        return true
×
150
                }
×
151
        }
152
        return false
4✔
153
}
154

155
func validateCreationOfDRAGPUDevices(gpus []v1.GPU, hostDevices []api.HostDevice) error {
4✔
156
        gpusWithDRA := []v1.GPU{}
4✔
157
        for _, gpu := range gpus {
9✔
158
                if drautil.IsGPUDRA(gpu) {
10✔
159
                        gpusWithDRA = append(gpusWithDRA, gpu)
5✔
160
                }
5✔
161
        }
162
        if len(gpusWithDRA) > 0 && len(gpusWithDRA) != len(hostDevices) {
4✔
163
                return fmt.Errorf(
×
164
                        "the number of DRA GPU/s do not match the number of devices:\nGPU: %v\nDevice: %v", gpusWithDRA, hostDevices,
×
165
                )
×
166
        }
×
167
        return nil
4✔
168
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc