diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h index 30680d35f2..83d64e50cf 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h @@ -10,9 +10,6 @@ #include #include -extern EFI_BLOCK_IO_PROTOCOL mCoreBlockIo; -extern EFI_DISK_IO_PROTOCOL mCoreDiskIo; - EFI_STATUS EFIAPI SysCall ( diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c index 6bec0eee9e..2bd03a1a37 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c @@ -17,7 +17,11 @@ Ring3BlockIoReset ( IN BOOLEAN ExtendedVerification ) { - return EFI_UNSUPPORTED; + return SysCall ( + SysCallBlockIoReset, + This, + ExtendedVerification + ); } EFI_STATUS @@ -30,7 +34,14 @@ Ring3BlockIoRead ( OUT VOID *Buffer ) { - return EFI_UNSUPPORTED; + return SysCall ( + SysCallBlockIoRead, + This, + MediaId, + Lba, + BufferSize, + Buffer + ); } EFI_STATUS @@ -43,7 +54,14 @@ Ring3BlockIoWrite ( IN VOID *Buffer ) { - return EFI_UNSUPPORTED; + return SysCall ( + SysCallBlockIoWrite, + This, + MediaId, + Lba, + BufferSize, + Buffer + ); } EFI_STATUS @@ -52,7 +70,10 @@ Ring3BlockIoFlush ( IN EFI_BLOCK_IO_PROTOCOL *This ) { - return EFI_UNSUPPORTED; + return SysCall ( + SysCallBlockIoFlush, + This + ); } EFI_STATUS @@ -65,7 +86,14 @@ Ring3DiskIoRead ( OUT VOID *Buffer ) { - return EFI_UNSUPPORTED; + return SysCall ( + SysCallDiskIoRead, + This, + MediaId, + Offset, + BufferSize, + Buffer + ); } EFI_STATUS @@ -78,5 +106,12 @@ Ring3DiskIoWrite ( IN VOID *Buffer ) { - return EFI_UNSUPPORTED; + return SysCall ( + SysCallDiskIoWrite, + This, + MediaId, + Offset, + BufferSize, + Buffer + ); } diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c index fb04ac7f32..d6950485f5 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c @@ -413,11 +413,6 @@ Ring3OpenProtocol ( BlockIo = (EFI_BLOCK_IO_PROTOCOL *)*Interface; - mCoreBlockIo.Reset = BlockIo->Reset; - mCoreBlockIo.ReadBlocks = BlockIo->ReadBlocks; - mCoreBlockIo.WriteBlocks = BlockIo->WriteBlocks; - mCoreBlockIo.FlushBlocks = BlockIo->FlushBlocks; - BlockIo->Reset = Ring3BlockIoReset; BlockIo->ReadBlocks = Ring3BlockIoRead; BlockIo->WriteBlocks = Ring3BlockIoWrite; @@ -427,9 +422,6 @@ Ring3OpenProtocol ( DiskIo = (EFI_DISK_IO_PROTOCOL *)*Interface; - mCoreDiskIo.ReadDisk = DiskIo->ReadDisk; - mCoreDiskIo.WriteDisk = DiskIo->WriteDisk; - DiskIo->ReadDisk = Ring3DiskIoRead; DiskIo->WriteDisk = Ring3DiskIoWrite; diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index c72242c3a1..c7566b46d6 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -8,6 +8,9 @@ #include "DxeMain.h" #include "SupportedProtocols.h" +EFI_DISK_IO_PROTOCOL *mCoreDiskIoProtocol; +EFI_BLOCK_IO_PROTOCOL *mCoreBlockIoProtocol; + EFI_STATUS EFIAPI CallInstallMultipleProtocolInterfaces ( @@ -119,9 +122,9 @@ CallBootService ( VOID *Interface; EFI_GUID *CoreProtocol; UINT32 MemoryCoreSize; - EFI_HANDLE Argument4; - EFI_HANDLE Argument5; - UINT32 Argument6; + UINTN Argument4; + UINTN Argument5; + UINTN Argument6; UINT32 Index; VOID **UserArgList; VOID *CoreArgList[MAX_LIST]; @@ -160,7 +163,7 @@ CallBootService ( if (Interface == NULL) { EnableSMAP (); return EFI_OUT_OF_RESOURCES; - } + } } *(VOID **)CoreRbp->Argument3 = Interface; @@ -184,22 +187,28 @@ CallBootService ( return Status; } - Argument4 = (EFI_HANDLE)UserRsp->Arguments[4]; - Argument5 = (EFI_HANDLE)UserRsp->Arguments[5]; - Argument6 = (UINT32)UserRsp->Arguments[6]; + Argument4 = UserRsp->Arguments[4]; + Argument5 = UserRsp->Arguments[5]; + Argument6 = UserRsp->Arguments[6]; EnableSMAP (); Status = gBS->OpenProtocol ( (EFI_HANDLE)CoreRbp->Argument1, CoreProtocol, &Interface, - Argument4, - Argument5, - Argument6 + (EFI_HANDLE)Argument4, + (EFI_HANDLE)Argument5, + (UINT32)Argument6 ); DisableSMAP (); if (Interface != NULL) { + if (CompareGuid (CoreProtocol, &gEfiDiskIoProtocolGuid)) { + mCoreDiskIoProtocol = (EFI_DISK_IO_PROTOCOL *)Interface; + } else if (CompareGuid (CoreProtocol, &gEfiBlockIoProtocolGuid)) { + mCoreBlockIoProtocol = (EFI_BLOCK_IO_PROTOCOL *)Interface; + } + Interface = AllocateRing3Copy (Interface, MemoryCoreSize, MemoryCoreSize); if (Interface == NULL) { EnableSMAP (); @@ -287,6 +296,152 @@ CallBootService ( ); EnableSMAP (); + return Status; + + case SysCallBlockIoReset: + // + // Argument 1: EFI_BLOCK_IO_PROTOCOL *This + // Argument 2: BOOLEAN ExtendedVerification + // + return mCoreBlockIoProtocol->Reset ( + mCoreBlockIoProtocol, + (BOOLEAN)CoreRbp->Argument2 + ); + + case SysCallBlockIoRead: + // + // Argument 1: EFI_BLOCK_IO_PROTOCOL *This + // Argument 2: UINT32 MediaId + // Argument 3: EFI_LBA Lba + // Argument 4: UINTN BufferSize + // Argument 5: VOID *Buffer + // + DisableSMAP (); + Argument4 = UserRsp->Arguments[4]; + EnableSMAP (); + + Argument5 = (UINTN)AllocatePool (Argument4); + if ((VOID *)Argument5 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = mCoreBlockIoProtocol->ReadBlocks ( + mCoreBlockIoProtocol, + (UINT32)CoreRbp->Argument2, + (EFI_LBA)CoreRbp->Argument3, + Argument4, + (VOID *)Argument5 + ); + DisableSMAP (); + CopyMem ((VOID *)UserRsp->Arguments[5], (VOID *)Argument5, Argument4); + EnableSMAP (); + + FreePool ((VOID *)Argument5); + + return Status; + + case SysCallBlockIoWrite: + // + // Argument 1: EFI_BLOCK_IO_PROTOCOL *This + // Argument 2: UINT32 MediaId + // Argument 3: EFI_LBA Lba + // Argument 4: UINTN BufferSize + // Argument 5: VOID *Buffer + // + DisableSMAP (); + Argument4 = UserRsp->Arguments[4]; + EnableSMAP (); + + Argument5 = (UINTN)AllocatePool (Argument4); + if ((VOID *)Argument5 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = mCoreBlockIoProtocol->WriteBlocks ( + mCoreBlockIoProtocol, + (UINT32)CoreRbp->Argument2, + (EFI_LBA)CoreRbp->Argument3, + Argument4, + (VOID *)Argument5 + ); + DisableSMAP (); + CopyMem ((VOID *)UserRsp->Arguments[5], (VOID *)Argument5, Argument4); + EnableSMAP (); + + FreePool ((VOID *)Argument5); + + return Status; + + case SysCallBlockIoFlush: + // + // Argument 1: EFI_BLOCK_IO_PROTOCOL *This + // + return mCoreBlockIoProtocol->FlushBlocks ( + mCoreBlockIoProtocol + ); + + case SysCallDiskIoRead: + // + // Argument 1: EFI_DISK_IO_PROTOCOL *This + // Argument 2: UINT32 MediaId + // Argument 3: UINT64 Offset + // Argument 4: UINTN BufferSize + // Argument 5: VOID *Buffer + // + DisableSMAP (); + Argument4 = UserRsp->Arguments[4]; + EnableSMAP (); + + Argument5 = (UINTN)AllocatePool (Argument4); + if ((VOID *)Argument5 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = mCoreDiskIoProtocol->ReadDisk ( + mCoreDiskIoProtocol, + (UINT32)CoreRbp->Argument2, + (UINT64)CoreRbp->Argument3, + Argument4, + (VOID *)Argument5 + ); + DisableSMAP (); + CopyMem ((VOID *)UserRsp->Arguments[5], (VOID *)Argument5, Argument4); + EnableSMAP (); + + FreePool ((VOID *)Argument5); + + return Status; + + case SysCallDiskIoWrite: + // + // Argument 1: EFI_DISK_IO_PROTOCOL *This + // Argument 2: UINT32 MediaId + // Argument 3: UINT64 Offset + // Argument 4: UINTN BufferSize + // Argument 5: VOID *Buffer + // + DisableSMAP (); + Argument4 = UserRsp->Arguments[4]; + EnableSMAP (); + + Argument5 = (UINTN)AllocatePool (Argument4); + if ((VOID *)Argument5 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = mCoreDiskIoProtocol->WriteDisk ( + mCoreDiskIoProtocol, + (UINT32)CoreRbp->Argument2, + (UINT64)CoreRbp->Argument3, + Argument4, + (VOID *)Argument5 + ); + DisableSMAP (); + CopyMem ((VOID *)UserRsp->Arguments[5], (VOID *)Argument5, Argument4); + EnableSMAP (); + + FreePool ((VOID *)Argument5); + return Status; default: DEBUG ((DEBUG_ERROR, "Ring0: Unknown syscall type.\n")); diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index cf8e598d19..f8a898590b 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -1969,6 +1969,15 @@ typedef enum { SysCallInstallMultipleProtocolInterfaces, SysCallAllocatePool, SysCallFreePool, + // + // Protocols + // + SysCallBlockIoReset, + SysCallBlockIoRead, + SysCallBlockIoWrite, + SysCallBlockIoFlush, + SysCallDiskIoRead, + SysCallDiskIoWrite, SysCallMax } SYS_CALL_TYPE;