vdpa: support vdpa blk/scsi device boot

Signed-off-by: jiangdongxu <jiangdongxu1@huawei.com>
This commit is contained in:
jiangdongxu 2024-09-20 17:15:00 +08:00
parent 5443b91758
commit 534ec14e22
4 changed files with 599 additions and 1 deletions

View File

@ -0,0 +1,218 @@
From fdbe00ab92845e2c878eea62be2becc2101dd9b6 Mon Sep 17 00:00:00 2001
From: jiangdongxu <jiangdongxu1@huawei.com>
Date: Sat, 7 Sep 2024 17:23:41 +0800
Subject: [PATCH 1/3] VirtioDxe: add support of MMIO Bar for virtio devices
As some virtio devices support MMIO BAR, add support for
it in Virtio10Dxe and VirtioPciDeviceDXE.
Signed-off-by: jiangdongxu <jiangdongxu1@huawei.com>
---
OvmfPkg/Include/Protocol/VirtioDevice.h | 12 +++
.../VirtioMmioDeviceLib/VirtioMmioDevice.c | 1 +
OvmfPkg/Virtio10Dxe/Virtio10.c | 1 +
OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c | 89 +++++++++++++++----
4 files changed, 85 insertions(+), 18 deletions(-)
diff --git a/OvmfPkg/Include/Protocol/VirtioDevice.h b/OvmfPkg/Include/Protocol/VirtioDevice.h
index ea56071..70491ca 100644
--- a/OvmfPkg/Include/Protocol/VirtioDevice.h
+++ b/OvmfPkg/Include/Protocol/VirtioDevice.h
@@ -466,6 +466,16 @@ EFI_STATUS
IN VOID *Mapping
);
+/**
+ * Note: Zero virtio devices has BAR0 of type MMIO but not PIO which do not
+ * flow the virtio 0.95 spec due to hw limiation. We extend edk2 to support
+ * such variant.
+ */
+typedef enum {
+ VirtioCfgSpaceAcessIo = 0,
+ VirtioCfgSpaceAcessMem
+} VIRTIO_CFG_SPACE_ACCESS_MODE;
+
///
/// This protocol provides an abstraction over the VirtIo transport layer
///
@@ -482,6 +492,8 @@ struct _VIRTIO_DEVICE_PROTOCOL {
//
INT32 SubSystemDeviceId;
+ VIRTIO_CFG_SPACE_ACCESS_MODE CfgAccessMode;
+
VIRTIO_GET_DEVICE_FEATURES GetDeviceFeatures;
VIRTIO_SET_GUEST_FEATURES SetGuestFeatures;
diff --git a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c
index 6dbbba0..ac6facc 100644
--- a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c
+++ b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c
@@ -17,6 +17,7 @@
STATIC CONST VIRTIO_DEVICE_PROTOCOL mMmioDeviceProtocolTemplate = {
0, // Revision
0, // SubSystemDeviceId
+ 0, // CfgAccessMode
VirtioMmioGetDeviceFeatures, // GetDeviceFeatures
VirtioMmioSetGuestFeatures, // SetGuestFeatures
VirtioMmioSetQueueAddress, // SetQueueAddress
diff --git a/OvmfPkg/Virtio10Dxe/Virtio10.c b/OvmfPkg/Virtio10Dxe/Virtio10.c
index 4d8e5b5..795b81b 100644
--- a/OvmfPkg/Virtio10Dxe/Virtio10.c
+++ b/OvmfPkg/Virtio10Dxe/Virtio10.c
@@ -848,6 +848,7 @@ Virtio10UnmapSharedBuffer (
STATIC CONST VIRTIO_DEVICE_PROTOCOL mVirtIoTemplate = {
VIRTIO_SPEC_REVISION (1, 0, 0),
0, // SubSystemDeviceId, filled in dynamically
+ 0, // CfgAccessMode
Virtio10GetDeviceFeatures,
Virtio10SetGuestFeatures,
Virtio10SetQueueAddress,
diff --git a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c
index c5c8d5e..cfbe5e1 100644
--- a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c
+++ b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c
@@ -23,6 +23,7 @@
STATIC VIRTIO_DEVICE_PROTOCOL mDeviceProtocolTemplate = {
0, // Revision
0, // SubSystemDeviceId
+ 0, // CfgAccessMode
VirtioPciGetDeviceFeatures, // GetDeviceFeatures
VirtioPciSetGuestFeatures, // SetGuestFeatures
VirtioPciSetQueueAddress, // SetQueueAddress
@@ -117,14 +118,25 @@ VirtioPciIoRead (
return EFI_INVALID_PARAMETER;
}
- return PciIo->Io.Read (
- PciIo,
- Width,
- PCI_BAR_IDX0,
- FieldOffset,
- Count,
- Buffer
- );
+ if (Dev->VirtioDevice.CfgAccessMode == VirtioCfgSpaceAcessIo) {
+ return PciIo->Io.Read (
+ PciIo,
+ Width,
+ PCI_BAR_IDX0,
+ FieldOffset,
+ Count,
+ Buffer
+ );
+ } else {
+ return PciIo->Mem.Read (
+ PciIo,
+ Width,
+ PCI_BAR_IDX0,
+ FieldOffset,
+ Count,
+ Buffer
+ );
+ }
}
/**
@@ -197,14 +209,25 @@ VirtioPciIoWrite (
return EFI_INVALID_PARAMETER;
}
- return PciIo->Io.Write (
- PciIo,
- Width,
- PCI_BAR_IDX0,
- FieldOffset,
- Count,
- &Value
- );
+ if (Dev->VirtioDevice.CfgAccessMode == VirtioCfgSpaceAcessIo) {
+ return PciIo->Io.Write (
+ PciIo,
+ Width,
+ PCI_BAR_IDX0,
+ FieldOffset,
+ Count,
+ &Value
+ );
+ } else {
+ return PciIo->Mem.Write (
+ PciIo,
+ Width,
+ PCI_BAR_IDX0,
+ FieldOffset,
+ Count,
+ &Value
+ );
+ }
}
/**
@@ -327,6 +350,7 @@ VirtioPciInit (
EFI_STATUS Status;
EFI_PCI_IO_PROTOCOL *PciIo;
PCI_TYPE00 Pci;
+ VOID *Resources;
ASSERT (Device != NULL);
PciIo = Device->PciIo;
@@ -365,6 +389,27 @@ VirtioPciInit (
Device->DeviceSpecificConfigurationOffset =
VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_PCI;
+ Status = PciIo->GetBarAttributes(PciIo, PCI_BAR_IDX0, NULL, &Resources);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (*(UINT8 *)Resources == ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR) {
+ EFI_ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR *Descriptor;
+
+ Descriptor = Resources;
+ if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
+ Device->VirtioDevice.CfgAccessMode = VirtioCfgSpaceAcessMem;
+ DEBUG ((DEBUG_INFO, "%a: Legacy Virtio MMIO BAR used.\n", __FUNCTION__));
+ } else {
+ Device->VirtioDevice.CfgAccessMode = VirtioCfgSpaceAcessIo;
+ DEBUG ((DEBUG_INFO, "%a: Legacy Virtio IO BAR used.\n", __FUNCTION__));
+ }
+ } else {
+ DEBUG ((DEBUG_WARN, "%a: Cannot determine BAR0 type, assume IO.\n", __FUNCTION__));
+ Device->VirtioDevice.CfgAccessMode = VirtioCfgSpaceAcessIo;
+ }
+
return EFI_SUCCESS;
}
@@ -427,6 +472,7 @@ VirtioPciDeviceBindingStart (
{
VIRTIO_PCI_DEVICE *Device;
EFI_STATUS Status;
+ UINT64 Attributes;
Device = (VIRTIO_PCI_DEVICE *) AllocateZeroPool (sizeof *Device);
if (Device == NULL) {
@@ -457,11 +503,18 @@ VirtioPciDeviceBindingStart (
goto ClosePciIo;
}
+ Status = Device->PciIo->Attributes (Device->PciIo,
+ EfiPciIoAttributeOperationSupported,
+ 0, &Attributes);
+ if (EFI_ERROR (Status)) {
+ goto ClosePciIo;
+ }
+
+ Attributes &= (EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_IO);
Status = Device->PciIo->Attributes (
Device->PciIo,
EfiPciIoAttributeOperationEnable,
- (EFI_PCI_IO_ATTRIBUTE_IO |
- EFI_PCI_IO_ATTRIBUTE_BUS_MASTER),
+ Attributes | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER,
NULL
);
if (EFI_ERROR (Status)) {
--
2.46.0.windows.1

View File

@ -0,0 +1,123 @@
From 11085d9350aa63b67ed51a4d8d0010a274a190e6 Mon Sep 17 00:00:00 2001
From: jiangdongxu <jiangdongxu1@huawei.com>
Date: Sat, 7 Sep 2024 17:25:41 +0800
Subject: [PATCH 2/3] Virtio: wait virtio device reset done.
The Virtio 1.0 driver performs subsequent negotiation operations
only after the device reset operation is complete.
Implement this in the VirtioScsiDxe and VirtioBlkDxe.
Signed-off-by: jiangdongxu <jiangdongxu1@huawei.com>
---
OvmfPkg/VirtioBlkDxe/VirtioBlk.c | 21 +++++++++++++++++++++
OvmfPkg/VirtioScsiDxe/VirtioScsi.c | 21 +++++++++++++++++++++
2 files changed, 42 insertions(+)
diff --git a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
index 06b9859..70fc8dd 100644
--- a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
+++ b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
@@ -28,6 +28,9 @@
#include "VirtioBlk.h"
+#define MAX_RETRY_TIMES 1000
+#define DEVICE_WAIT_INTVL 1000
+
/**
Convenience macros to read and write region 0 IO space elements of the
@@ -723,6 +726,10 @@ VirtioBlkInit (
UINT32 OptIoSize;
UINT16 QueueSize;
UINT64 RingBaseShift;
+ UINT8 DevStat;
+ UINT16 RetryTimes;
+
+ RetryTimes = MAX_RETRY_TIMES;
PhysicalBlockExp = 0;
AlignmentOffset = 0;
@@ -737,12 +744,26 @@ VirtioBlkInit (
goto Failed;
}
+ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat);
+ while (DevStat != NextDevStat && RetryTimes) {
+ gBS->Stall(DEVICE_WAIT_INTVL);
+ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat);
+ RetryTimes--;
+ }
+
NextDevStat |= VSTAT_ACK; // step 2 -- acknowledge device presence
Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
if (EFI_ERROR (Status)) {
goto Failed;
}
+ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat);
+ while (DevStat != NextDevStat && RetryTimes) {
+ gBS->Stall(DEVICE_WAIT_INTVL);
+ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat);
+ RetryTimes--;
+ }
+
NextDevStat |= VSTAT_DRIVER; // step 3 -- we know how to drive it
Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
if (EFI_ERROR (Status)) {
diff --git a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
index 935d154..0b9ad60 100644
--- a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
+++ b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
@@ -43,6 +43,9 @@
#include "VirtioScsi.h"
+#define MAX_RETRY_TIMES 1000
+#define DEVICE_WAIT_INTVL 1000
+
/**
Convenience macros to read and write configuration elements of the
@@ -930,6 +933,10 @@ VirtioScsiInit (
UINT16 MaxChannel; // for validation only
UINT32 NumQueues; // for validation only
UINT16 QueueSize;
+ UINT8 DevStat;
+ UINT16 RetryTimes;
+
+ RetryTimes = MAX_RETRY_TIMES;
//
// Execute virtio-0.9.5, 2.2.1 Device Initialization Sequence.
@@ -940,12 +947,26 @@ VirtioScsiInit (
goto Failed;
}
+ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat);
+ while (DevStat != NextDevStat && RetryTimes) {
+ gBS->Stall(DEVICE_WAIT_INTVL);
+ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat);
+ RetryTimes--;
+ }
+
NextDevStat |= VSTAT_ACK; // step 2 -- acknowledge device presence
Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
if (EFI_ERROR (Status)) {
goto Failed;
}
+ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat);
+ while (DevStat != NextDevStat && RetryTimes) {
+ gBS->Stall(DEVICE_WAIT_INTVL);
+ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat);
+ RetryTimes--;
+ }
+
NextDevStat |= VSTAT_DRIVER; // step 3 -- we know how to drive it
Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
if (EFI_ERROR (Status)) {
--
2.46.0.windows.1

View File

@ -0,0 +1,249 @@
From 58abc1e5f9c374f2b26634b7f41def82ae3233f6 Mon Sep 17 00:00:00 2001
From: jiangdongxu <jiangdongxu1@huawei.com>
Date: Sat, 7 Sep 2024 17:30:28 +0800
Subject: [PATCH 3/3] VirtioBlk: split large IO according to segment_size_max
When the VirtioBlk device is initialized, the value of SegmentSizeMax
is obtained based on the feature capability. Then delivere the requests
based on the value of SegmentSizeMax.
Signed-off-by: jiangdongxu <jiangdongxu1@huawei.com>
---
MdePkg/Include/Protocol/BlockIo.h | 10 ++
OvmfPkg/VirtioBlkDxe/VirtioBlk.c | 147 +++++++++++++++++++++---------
2 files changed, 116 insertions(+), 41 deletions(-)
diff --git a/MdePkg/Include/Protocol/BlockIo.h b/MdePkg/Include/Protocol/BlockIo.h
index 3bd7688..30b20d0 100644
--- a/MdePkg/Include/Protocol/BlockIo.h
+++ b/MdePkg/Include/Protocol/BlockIo.h
@@ -197,6 +197,16 @@ typedef struct {
/// granularity as a number of logical blocks.
///
UINT32 OptimalTransferLengthGranularity;
+
+ ///
+ /// Maximum size of any single segment
+ ///
+ UINT32 MaxSegmentSize;
+
+ ///
+ /// Maximum number of segments in a request
+ ///
+ UINT32 MaxSegments;
} EFI_BLOCK_IO_MEDIA;
#define EFI_BLOCK_IO_PROTOCOL_REVISION 0x00010000
diff --git a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
index 70fc8dd..d13cb37 100644
--- a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
+++ b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
@@ -31,6 +31,8 @@
#define MAX_RETRY_TIMES 1000
#define DEVICE_WAIT_INTVL 1000
+#define DEFAULT_MAX_SEGMENTS 32
+
/**
Convenience macros to read and write region 0 IO space elements of the
@@ -457,6 +459,67 @@ FreeHostStatusBuffer:
return Status;
}
+STATIC
+EFI_STATUS
+EFIAPI
+VirtioBlkReadWriteBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA Lba,
+ IN UINTN BufferSize,
+ IN OUT VOID *Buffer,
+ IN BOOLEAN RequestIsWrite
+ )
+{
+ VBLK_DEV *Dev;
+ EFI_STATUS Status;
+ UINT32 SizeMax;
+
+ if (BufferSize == 0) {
+ return EFI_SUCCESS;
+ }
+
+ Dev = VIRTIO_BLK_FROM_BLOCK_IO (This);
+ Status = VerifyReadWriteRequest (
+ &Dev->BlockIoMedia,
+ Lba,
+ BufferSize,
+ RequestIsWrite
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ SizeMax = Dev->BlockIoMedia.MaxSegmentSize;
+ while (BufferSize >= SizeMax) {
+ Status = SynchronousRequest (
+ Dev,
+ Lba,
+ SizeMax,
+ Buffer,
+ RequestIsWrite
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Lba += SizeMax / Dev->BlockIoMedia.BlockSize;
+ BufferSize -= SizeMax;
+ Buffer = (CHAR8 *)Buffer + SizeMax;
+ }
+
+ if (BufferSize == 0) {
+ return EFI_SUCCESS;
+ }
+
+ return SynchronousRequest (
+ Dev,
+ Lba,
+ BufferSize,
+ Buffer,
+ RequestIsWrite
+ );
+}
/**
@@ -486,30 +549,13 @@ VirtioBlkReadBlocks (
OUT VOID *Buffer
)
{
- VBLK_DEV *Dev;
- EFI_STATUS Status;
-
- if (BufferSize == 0) {
- return EFI_SUCCESS;
- }
-
- Dev = VIRTIO_BLK_FROM_BLOCK_IO (This);
- Status = VerifyReadWriteRequest (
- &Dev->BlockIoMedia,
- Lba,
- BufferSize,
- FALSE // RequestIsWrite
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- return SynchronousRequest (
- Dev,
+ return VirtioBlkReadWriteBlocks(
+ This,
+ MediaId,
Lba,
BufferSize,
Buffer,
- FALSE // RequestIsWrite
+ FALSE // RequestIsRead
);
}
@@ -541,26 +587,9 @@ VirtioBlkWriteBlocks (
IN VOID *Buffer
)
{
- VBLK_DEV *Dev;
- EFI_STATUS Status;
-
- if (BufferSize == 0) {
- return EFI_SUCCESS;
- }
-
- Dev = VIRTIO_BLK_FROM_BLOCK_IO (This);
- Status = VerifyReadWriteRequest (
- &Dev->BlockIoMedia,
- Lba,
- BufferSize,
- TRUE // RequestIsWrite
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- return SynchronousRequest (
- Dev,
+ return VirtioBlkReadWriteBlocks(
+ This,
+ MediaId,
Lba,
BufferSize,
Buffer,
@@ -718,6 +747,8 @@ VirtioBlkInit (
UINT8 NextDevStat;
EFI_STATUS Status;
+ UINT32 MaxSegmentSize;
+ UINT32 MaxSegments;
UINT64 Features;
UINT64 NumSectors;
UINT32 BlockSize;
@@ -814,6 +845,36 @@ VirtioBlkInit (
BlockSize = 512;
}
+ if (Features & VIRTIO_BLK_F_SIZE_MAX) {
+ Status = VIRTIO_CFG_READ (Dev, SizeMax, &MaxSegmentSize);
+ if (EFI_ERROR (Status)) {
+ goto Failed;
+ }
+ if (MaxSegmentSize == 0) {
+ //
+ // We need at least one 4KB page.
+ //
+ MaxSegmentSize = SIZE_4KB;
+ }
+ } else {
+ MaxSegmentSize = SIZE_512KB;
+ }
+
+ if (Features & VIRTIO_BLK_F_SEG_MAX) {
+ Status = VIRTIO_CFG_READ (Dev, SegMax, &MaxSegments);
+ if (EFI_ERROR (Status)) {
+ goto Failed;
+ }
+ if (MaxSegments == 0) {
+ //
+ // We need at least one SG element, whatever they say.
+ //
+ MaxSegments = 1;
+ }
+ } else {
+ MaxSegments = DEFAULT_MAX_SEGMENTS;
+ }
+
if (Features & VIRTIO_BLK_F_TOPOLOGY) {
Status = VIRTIO_CFG_READ (Dev, Topology.PhysicalBlockExp,
&PhysicalBlockExp);
@@ -949,6 +1010,8 @@ VirtioBlkInit (
Dev->BlockIoMedia.ReadOnly = (BOOLEAN) ((Features & VIRTIO_BLK_F_RO) != 0);
Dev->BlockIoMedia.WriteCaching = (BOOLEAN) ((Features & VIRTIO_BLK_F_FLUSH) != 0);
Dev->BlockIoMedia.BlockSize = BlockSize;
+ Dev->BlockIoMedia.MaxSegments = MaxSegments;
+ Dev->BlockIoMedia.MaxSegmentSize = MaxSegmentSize;
Dev->BlockIoMedia.IoAlign = 0;
Dev->BlockIoMedia.LastBlock = DivU64x32 (NumSectors,
BlockSize / 512) - 1;
@@ -956,6 +1019,8 @@ VirtioBlkInit (
DEBUG ((DEBUG_INFO, "%a: LbaSize=0x%x[B] NumBlocks=0x%Lx[Lba]\n",
__FUNCTION__, Dev->BlockIoMedia.BlockSize,
Dev->BlockIoMedia.LastBlock + 1));
+ DEBUG ((DEBUG_INFO, "%a: MaxSegments=0x%x[B] MaxSegmentSize=0x%x[B]\n",
+ __FUNCTION__, Dev->BlockIoMedia.MaxSegments, Dev->BlockIoMedia.MaxSegmentSize));
if (Features & VIRTIO_BLK_F_TOPOLOGY) {
Dev->BlockIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;
--
2.46.0.windows.1

View File

@ -5,7 +5,7 @@
Name: edk2
Version: %{stable_date}
Release: 20
Release: 21
Summary: EFI Development Kit II
License: BSD-2-Clause-Patent
URL: https://github.com/tianocore/edk2
@ -126,6 +126,11 @@ Patch0086: 0086-Fix-NETSCAPE_SPKI_print-function-to-not-assume-NUL-t.patch
Patch0087: 0087-Fix-EC_GROUP_new_from_ecparameters-to-check-the-base.patch
Patch0088: 0088-Fix-possible-infinite-loop-in-BN_mod_sqrt.patch
# support vdpa blk/scsi device boot
Patch0089: 0089-VirtioDxe-add-support-of-MMIO-Bar-for-virtio-devices.patch
Patch0090: 0090-Virtio-wait-virtio-device-reset-done.patch
Patch0091: 0091-VirtioBlk-split-large-IO-according-to-segment_size_m.patch
BuildRequires: acpica-tools gcc gcc-c++ libuuid-devel python3 bc nasm python3-unversioned-command
%description
@ -326,6 +331,9 @@ chmod +x %{buildroot}%{_bindir}/Rsa2048Sha256GenerateKeys
%endif
%changelog
* Wed Sep 18 2024 jiangdongxu<jiangdongxu1@huawei.com> - 202011-21
- vdpa: support vdpa blk/scsi device boot
* Tue Sep 3 2024 shenyage<shenyage1@huawei.com> - 202011-20
- fix CVE-2021-3712、CVE-2022-0778