Signed-off-by: Fu Siyuan <siyuan.fu@intel.com>
Reviewed-by: Ye Ting <ting.ye@intel.com>
Reviewed-by: Jin Eric <eric.jin@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14682 6f19259b-4bc3-4df7-8a09-765794883524
1. DiskIo2 shouldn't signal the event when the *Ex interface returns failure status per the UEFI spec.
2. PartitionDxe should close DiskIo2 protocol when error happens in DriverBindingStart() otherwise Fat driver cannot open the DiskIo2 BY_DRIVER.
3. PartitionDxe should create event using TPL_NOTIFY instead of TPL_CALLBACK otherwise asynchronous FileIo may be blocked.
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Reviewed-by: Feng Tian <feng.tian@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14680 6f19259b-4bc3-4df7-8a09-765794883524
DiskIoCreateSubtaskList() may split the transfer into three segments:
- a leading segment, called underrun, which is the fractional, trailing
subset of the first underlying block,
- a middle segment, which is an integral multiple of underlying blocks,
- a trailing segment, called overrun, which is the fractional, leading
subset of the last underlying block.
This is an example read from the /EFI/BOOT/BOOTX64.EFI file, on the
RHEL-6.4 installation ISO (debug log enabled with EFI_D_BLKIO). The
underlying block size is 2048 bytes (IDE CD-ROM).
DiskIo: Create subtasks for task: Offset/BufferSize/Buffer = 0000000000004600/00002000/BD890018
R:Lba/Offset/Length/WorkingBuffer/Buffer = 0000000000000008/00000600/00000200/BD90D000/BD890018
R:Lba/Offset/Length/WorkingBuffer/Buffer = 000000000000000C/00000000/00000600/BD90D000/BD890218
R:Lba/Offset/Length/WorkingBuffer/Buffer = 0000000000000009/00000000/00001800/00000000/BD890218
The first line corresponds to the underrun.
The second line corresponds to the overrun.
The third line corresponds to the middle segment.
In decimal:
- task: read 8192 bytes from offset 17920, storing it at BD890018
- underrun:
- read block 8 [16384..18432) into the transfer area,
- copy 512 bytes from offset 1536 of the transfer area to BD890018
(target buffer offset 0, running total: 512)
- middle segment:
- read blocks 9, 10, 11 [18432..24576) into the transfer area,
- copy 6144 bytes from offset 0 of the transfer area to BD890218
(target buffer offset 512, running total: 6656)
- overrun:
- read block 12 [24576..26624) into the transfer area,
- copy 1536 bytes from offset 0 of the transfer area to BD890218 (!!!)
(target buffer offset 512 (!!!), running total 8192)
The values marked with (!!!) constitute the bug --
DiskIoCreateSubtaskList() doesn't take the size of the middle segment into
account when it calculates the destination (for reads) or source (for
writes) pointer for the overrun. This leads to data corruption.
When reading, data is copied form the transfer area to the target buffer
with
CopyMem (Subtask->Buffer, Subtask->WorkingBuffer + Subtask->Offset, Subtask->Length);
calls in DiskIo2OnReadWriteComplete() for nonblocking reads, and in
DiskIo2ReadWriteDisk() for blocking reads. Therefore it's enough to adjust
Subtask->Buffer when it is initialized. (See BD891A18 below.)
DiskIo: Create subtasks for task: Offset/BufferSize/Buffer = 0000000000004600/00002000/BD890018
R:Lba/Offset/Length/WorkingBuffer/Buffer = 0000000000000008/00000600/00000200/BD90D000/BD890018
R:Lba/Offset/Length/WorkingBuffer/Buffer = 000000000000000C/00000000/00000600/BD90D000/BD891A18
R:Lba/Offset/Length/WorkingBuffer/Buffer = 0000000000000009/00000000/00001800/00000000/BD890218
The patched call to DiskIoCreateSubtask() is also executed for write
requests. The changed Subtask->Buffer initialization fixes the "overrun
half writes" in DiskIo2ReadWriteDisk() too:
//
// A sub task before this one should be a block read operation, causing
// the WorkingBuffer filled with the entire one block data.
//
CopyMem (Subtask->WorkingBuffer + Subtask->Offset, Subtask->Buffer, Subtask->Length);
This code doubles for underrun and overrun half-writes. The patch doesn't
modify the underrun case.
If we're storing the overrun at the beginning of the pre-read last block
(which we're going to write out as a full block), then
- Subtask->Offset == 0,
- Subtask->Length == OverRun,
- the first byte *not* accessed in the source area is
((Buffer + UnderRunLength) + BufferSize) + OverRun.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14602 6f19259b-4bc3-4df7-8a09-765794883524
Error: Variable "Media" was set but never used.
Change-Id: I1297b3de797e436ed403375c801945b3202b532c
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Olivier Martin <olivier.martin@arm.com>
Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14575 6f19259b-4bc3-4df7-8a09-765794883524
Change DiskIoDxe to produce DiskIo2 protocol when the BlockIo2 protocol is available.
Change PartitionDxe to produce BlockIo2 protocol based on DiskIo2 protocol instead of BlockIo2 protocol.
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Reviewed-by: Kinney Michael <michael.d.kinney@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14570 6f19259b-4bc3-4df7-8a09-765794883524
Two exceptions to this rule:
1. No access attributes specified
2. The only attribute differing is EFI_VARIABLE_APPEND_WRITE
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Star Zeng <star.zeng@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14552 6f19259b-4bc3-4df7-8a09-765794883524
Add a new instance of DevicePathLib which tries to locate the protocol and if it's not found, it uses the internal functions.
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14504 6f19259b-4bc3-4df7-8a09-765794883524
PEI variable implementation checks only the variable header signature for validity. This does not seem robust if system crash occurred during previous Reclaim() operation. If the crash occurred while FTW was rewriting the variable FV, the signature could be valid even though the rest of the FV isn't valid.
Solution: Add a FaultTolerantWritePei driver to check and provide the FTW last write status, then PEI variable and early phase(before FTW protocol ready) of DXE variable can check the status and determine if all or partial variable data has been backed up in spare block, and then use the backed up data.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Star Zeng <star.zeng@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14454 6f19259b-4bc3-4df7-8a09-765794883524
convert the list when transferring from physical to virtual mode.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14425 6f19259b-4bc3-4df7-8a09-765794883524
convert the list when transferring from physical to virtual mode.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14403 6f19259b-4bc3-4df7-8a09-765794883524