* [PATCH] MdePkg: BaseIoLibIntrinsic (IoLib class) library
@ 2017-03-20 16:39 Leo Duran
2017-03-20 16:39 ` Leo Duran
0 siblings, 1 reply; 2+ messages in thread
From: Leo Duran @ 2017-03-20 16:39 UTC (permalink / raw)
To: edk2-devel; +Cc: Leo Duran
This patch unrolls REP INSx/OUTSx on IoRead/WriteFifo#() routines
when the SEV feature is enabled under a hypervisor environment.
This patch follows the series "[PATCH v3 00/10] IoLib class library",
which has already being pushed upstream.
Brijesh Singh (1):
MdePkg: BaseIoLibIntrinsic (IoLib class) library
MdePkg/Library/BaseIoLibIntrinsic/Ia32/IoFifo.asm | 180 +++++++++++++++++++--
MdePkg/Library/BaseIoLibIntrinsic/Ia32/IoFifo.nasm | 180 +++++++++++++++++++--
MdePkg/Library/BaseIoLibIntrinsic/X64/IoFifo.asm | 179 ++++++++++++++++++--
MdePkg/Library/BaseIoLibIntrinsic/X64/IoFifo.nasm | 180 +++++++++++++++++++--
4 files changed, 671 insertions(+), 48 deletions(-)
--
2.7.4
^ permalink raw reply [flat|nested] 2+ messages in thread
* [PATCH] MdePkg: BaseIoLibIntrinsic (IoLib class) library
2017-03-20 16:39 [PATCH] MdePkg: BaseIoLibIntrinsic (IoLib class) library Leo Duran
@ 2017-03-20 16:39 ` Leo Duran
0 siblings, 0 replies; 2+ messages in thread
From: Leo Duran @ 2017-03-20 16:39 UTC (permalink / raw)
To: edk2-devel; +Cc: Brijesh Singh, Michael D Kinney, Liming Gao, Leo Duran
From: Brijesh Singh <brijesh.singh@amd.com>
This patch unrolls REP INSx/OUTSx on IoRead/WriteFifo#() routines
when the SEV feature is enabled under a hypervisor environment.
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Signed-off-by: Leo Duran <leo.duran@amd.com>
---
MdePkg/Library/BaseIoLibIntrinsic/Ia32/IoFifo.asm | 180 +++++++++++++++++++--
MdePkg/Library/BaseIoLibIntrinsic/Ia32/IoFifo.nasm | 180 +++++++++++++++++++--
MdePkg/Library/BaseIoLibIntrinsic/X64/IoFifo.asm | 179 ++++++++++++++++++--
MdePkg/Library/BaseIoLibIntrinsic/X64/IoFifo.nasm | 180 +++++++++++++++++++--
4 files changed, 671 insertions(+), 48 deletions(-)
diff --git a/MdePkg/Library/BaseIoLibIntrinsic/Ia32/IoFifo.asm b/MdePkg/Library/BaseIoLibIntrinsic/Ia32/IoFifo.asm
index da767d1..d81871c 100644
--- a/MdePkg/Library/BaseIoLibIntrinsic/Ia32/IoFifo.asm
+++ b/MdePkg/Library/BaseIoLibIntrinsic/Ia32/IoFifo.asm
@@ -18,6 +18,60 @@
.code
;------------------------------------------------------------------------------
+; Check whether we need to unroll the String I/O under SEV guest
+;
+; Return // eax (1 - unroll, 0 - no unroll)
+;------------------------------------------------------------------------------
+SevNoRepIo PROC
+
+ ; CPUID clobbers ebx, ecx and edx
+ push ebx
+ push ecx
+ push edx
+
+ ; Check if we are running under hypervisor
+ ; CPUID(1).ECX Bit 31
+ mov eax, 1
+ cpuid
+ bt ecx, 31
+ jnc @UseRepIo
+
+ ; Check if we have Memory encryption CPUID leaf
+ mov eax, 0x80000000
+ cpuid
+ cmp eax, 0x8000001f
+ jl @UseRepIo
+
+ ; Check for memory encryption feature:
+ ; CPUID Fn8000_001F[EAX] - Bit 1
+ ;
+ mov eax, 0x8000001f
+ cpuid
+ bt eax, 1
+ jnc @UseRepIo
+
+ ; Check if memory encryption is enabled
+ ; MSR_0xC0010131 - Bit 0 (SEV enabled)
+ ; MSR_0xC0010131 - Bit 1 (SEV-ES enabled)
+ mov ecx, 0xc0010131
+ rdmsr
+
+ ; Check for (SevEsEnabled == 0 && SevEnabled == 1)
+ and eax, 3
+ cmp eax, 1
+ je @SevNoRepIo_Done
+
+@UseRepIo:
+ xor eax, eax
+
+@SevNoRepIo_Done:
+ pop edx
+ pop ecx
+ pop ebx
+ ret
+SevNoRepIo ENDP
+
+;------------------------------------------------------------------------------
; VOID
; EFIAPI
; IoReadFifo8 (
@@ -28,11 +82,28 @@
;------------------------------------------------------------------------------
IoReadFifo8 PROC
push edi
- cld
mov dx, [esp + 8]
mov ecx, [esp + 12]
mov edi, [esp + 16]
-rep insb
+
+ call SevNoRepIo ; Check if we need to unroll the rep
+ test eax, eax
+ jnz @IoReadFifo8_NoRep
+
+ cld
+ rep insb
+ jmp @IoReadFifo8_Done
+
+@IoReadFifo8_NoRep:
+ jecxz @IoReadFifo8_Done
+
+@IoReadFifo8_Loop:
+ in al, dx
+ mov byte [edi], al
+ inc edi
+ loop @IoReadFifo8_Loop
+
+@IoReadFifo8_Done:
pop edi
ret
IoReadFifo8 ENDP
@@ -48,11 +119,28 @@ IoReadFifo8 ENDP
;------------------------------------------------------------------------------
IoReadFifo16 PROC
push edi
- cld
mov dx, [esp + 8]
mov ecx, [esp + 12]
mov edi, [esp + 16]
-rep insw
+
+ call SevNoRepIo ; Check if we need to unroll the rep
+ test eax, eax
+ jnz @IoReadFifo16_NoRep
+
+ cld
+ rep insw
+ jmp @IoReadFifo16_Done
+
+@IoReadFifo16_NoRep:
+ jecxz @IoReadFifo16_Done
+
+@IoReadFifo16_Loop:
+ in ax, dx
+ mov word [edi], ax
+ add edi, 2
+ loop @IoReadFifo16_Loop
+
+@IoReadFifo16_Done:
pop edi
ret
IoReadFifo16 ENDP
@@ -68,11 +156,28 @@ IoReadFifo16 ENDP
;------------------------------------------------------------------------------
IoReadFifo32 PROC
push edi
- cld
mov dx, [esp + 8]
mov ecx, [esp + 12]
mov edi, [esp + 16]
-rep insd
+
+ call SevNoRepIo ; Check if we need to unroll the rep
+ test eax, eax
+ jnz @IoReadFifo32_NoRep
+
+ cld
+ rep insd
+ jmp @IoReadFifo32_Done
+
+@IoReadFifo32_NoRep:
+ jecxz @IoReadFifo32_Done
+
+@IoReadFifo32_Loop:
+ in eax, dx
+ mov dword [edi], eax
+ add edi, 4
+ loop @IoReadFifo32_Loop
+
+@IoReadFifo32_Done:
pop edi
ret
IoReadFifo32 ENDP
@@ -88,11 +193,28 @@ IoReadFifo32 ENDP
;------------------------------------------------------------------------------
IoWriteFifo8 PROC
push esi
- cld
mov dx, [esp + 8]
mov ecx, [esp + 12]
mov esi, [esp + 16]
-rep outsb
+
+ call SevNoRepIo ; Check if we need to unroll String I/O
+ test eax, eax
+ jnz @IoWriteFifo8_NoRep
+
+ cld
+ rep outsb
+ jmp @IoWriteFifo8_Done
+
+@IoWriteFifo8_NoRep:
+ jecxz @IoWriteFifo8_Done
+
+@IoWriteFifo8_Loop:
+ mov byte [esi], al
+ out dx, al
+ inc esi
+ loop @IoWriteFifo8_Loop
+
+@IoWriteFifo8_Done:
pop esi
ret
IoWriteFifo8 ENDP
@@ -108,11 +230,28 @@ IoWriteFifo8 ENDP
;------------------------------------------------------------------------------
IoWriteFifo16 PROC
push esi
- cld
mov dx, [esp + 8]
mov ecx, [esp + 12]
mov esi, [esp + 16]
-rep outsw
+
+ call SevNoRepIo ; Check if we need to unroll String I/O
+ test eax, eax
+ jnz @IoWriteFifo16_NoRep
+
+ cld
+ rep outsw
+ jmp @IoWriteFifo16_Done
+
+@IoWriteFifo16_NoRep:
+ jecxz @IoWriteFifo16_Done
+
+@IoWriteFifo16_Loop:
+ mov word [esi], ax
+ out dx, ax
+ add esi, 2
+ loop @IoWriteFifo16_Loop
+
+@IoWriteFifo16_Done:
pop esi
ret
IoWriteFifo16 ENDP
@@ -128,11 +267,28 @@ IoWriteFifo16 ENDP
;------------------------------------------------------------------------------
IoWriteFifo32 PROC
push esi
- cld
mov dx, [esp + 8]
mov ecx, [esp + 12]
mov esi, [esp + 16]
-rep outsd
+
+ call SevNoRepIo ; Check if we need to unroll String I/O
+ test eax, eax
+ jnz @IoWriteFifo32_NoRep
+
+ cld
+ rep outsd
+ jmp @IoWriteFifo32_Done
+
+@IoWriteFifo32_NoRep:
+ jecxz @IoWriteFifo32_Done
+
+@IoWriteFifo32_Loop:
+ mov dword [esi], eax
+ out dx, eax
+ add esi, 4
+ loop @IoWriteFifo32_Loop
+
+@IoWriteFifo32_Done:
pop esi
ret
IoWriteFifo32 ENDP
diff --git a/MdePkg/Library/BaseIoLibIntrinsic/Ia32/IoFifo.nasm b/MdePkg/Library/BaseIoLibIntrinsic/Ia32/IoFifo.nasm
index bcaa743..9adb972 100644
--- a/MdePkg/Library/BaseIoLibIntrinsic/Ia32/IoFifo.nasm
+++ b/MdePkg/Library/BaseIoLibIntrinsic/Ia32/IoFifo.nasm
@@ -16,6 +16,60 @@
SECTION .text
;------------------------------------------------------------------------------
+; Check whether we need to unroll the String I/O under SEV guest
+;
+; Return // eax (1 - unroll, 0 - no unroll)
+;------------------------------------------------------------------------------
+global ASM_PFX(SevNoRepIo)
+ASM_PFX(SevNoRepIo):
+
+ ; CPUID clobbers ebx, ecx and edx
+ push ebx
+ push ecx
+ push edx
+
+ ; Check if we are running under hypervisor
+ ; CPUID(1).ECX Bit 31
+ mov eax, 1
+ cpuid
+ bt ecx, 31
+ jnc @UseRepIo
+
+ ; Check if we have Memory encryption CPUID leaf
+ mov eax, 0x80000000
+ cpuid
+ cmp eax, 0x8000001f
+ jl @UseRepIo
+
+ ; Check for memory encryption feature:
+ ; CPUID Fn8000_001F[EAX] - Bit 1
+ ;
+ mov eax, 0x8000001f
+ cpuid
+ bt eax, 1
+ jnc @UseRepIo
+
+ ; Check if memory encryption is enabled
+ ; MSR_0xC0010131 - Bit 0 (SEV enabled)
+ ; MSR_0xC0010131 - Bit 1 (SEV-ES enabled)
+ mov ecx, 0xc0010131
+ rdmsr
+
+ ; Check for (SevEsEnabled == 0 && SevEnabled == 1)
+ and eax, 3
+ cmp eax, 1
+ je @SevNoRepIo_Done
+
+@UseRepIo:
+ xor eax, eax
+
+@SevNoRepIo_Done:
+ pop edx
+ pop ecx
+ pop ebx
+ ret
+
+;------------------------------------------------------------------------------
; VOID
; EFIAPI
; IoReadFifo8 (
@@ -27,11 +81,28 @@
global ASM_PFX(IoReadFifo8)
ASM_PFX(IoReadFifo8):
push edi
- cld
mov dx, [esp + 8]
mov ecx, [esp + 12]
mov edi, [esp + 16]
-rep insb
+
+ call SevNoRepIo ; Check if we need to unroll the rep
+ test eax, eax
+ jnz @IoReadFifo8_NoRep
+
+ cld
+ rep insb
+ jmp @IoReadFifo8_Done
+
+@IoReadFifo8_NoRep:
+ jecxz @IoReadFifo8_Done
+
+@IoReadFifo8_Loop:
+ in al, dx
+ mov byte [edi], al
+ inc edi
+ loop @IoReadFifo8_Loop
+
+@IoReadFifo8_Done:
pop edi
ret
@@ -47,11 +118,28 @@ rep insb
global ASM_PFX(IoReadFifo16)
ASM_PFX(IoReadFifo16):
push edi
- cld
mov dx, [esp + 8]
mov ecx, [esp + 12]
mov edi, [esp + 16]
-rep insw
+
+ call SevNoRepIo ; Check if we need to unroll the rep
+ test eax, eax
+ jnz @IoReadFifo16_NoRep
+
+ cld
+ rep insw
+ jmp @IoReadFifo16_Done
+
+@IoReadFifo16_NoRep:
+ jecxz @IoReadFifo16_Done
+
+@IoReadFifo16_Loop:
+ in ax, dx
+ mov word [edi], ax
+ add edi, 2
+ loop @IoReadFifo16_Loop
+
+@IoReadFifo16_Done:
pop edi
ret
@@ -67,11 +155,28 @@ rep insw
global ASM_PFX(IoReadFifo32)
ASM_PFX(IoReadFifo32):
push edi
- cld
mov dx, [esp + 8]
mov ecx, [esp + 12]
mov edi, [esp + 16]
-rep insd
+
+ call SevNoRepIo ; Check if we need to unroll the rep
+ test eax, eax
+ jnz @IoReadFifo32_NoRep
+
+ cld
+ rep insd
+ jmp @IoReadFifo32_Done
+
+@IoReadFifo32_NoRep:
+ jecxz @IoReadFifo32_Done
+
+@IoReadFifo32_Loop:
+ in eax, dx
+ mov dword [edi], eax
+ add edi, 4
+ loop @IoReadFifo32_Loop
+
+@IoReadFifo32_Done:
pop edi
ret
@@ -87,11 +192,28 @@ rep insd
global ASM_PFX(IoWriteFifo8)
ASM_PFX(IoWriteFifo8):
push esi
- cld
mov dx, [esp + 8]
mov ecx, [esp + 12]
mov esi, [esp + 16]
-rep outsb
+
+ call SevNoRepIo ; Check if we need to unroll String I/O
+ test eax, eax
+ jnz @IoWriteFifo8_NoRep
+
+ cld
+ rep outsb
+ jmp @IoWriteFifo8_Done
+
+@IoWriteFifo8_NoRep:
+ jecxz @IoWriteFifo8_Done
+
+@IoWriteFifo8_Loop:
+ mov byte [esi], al
+ out dx, al
+ inc esi
+ loop @IoWriteFifo8_Loop
+
+@IoWriteFifo8_Done:
pop esi
ret
@@ -107,11 +229,28 @@ rep outsb
global ASM_PFX(IoWriteFifo16)
ASM_PFX(IoWriteFifo16):
push esi
- cld
mov dx, [esp + 8]
mov ecx, [esp + 12]
mov esi, [esp + 16]
-rep outsw
+
+ call SevNoRepIo ; Check if we need to unroll String I/O
+ test eax, eax
+ jnz @IoWriteFifo16_NoRep
+
+ cld
+ rep outsw
+ jmp @IoWriteFifo16_Done
+
+@IoWriteFifo16_NoRep:
+ jecxz @IoWriteFifo16_Done
+
+@IoWriteFifo16_Loop:
+ mov word [esi], ax
+ out dx, ax
+ add esi, 2
+ loop @IoWriteFifo16_Loop
+
+@IoWriteFifo16_Done:
pop esi
ret
@@ -127,11 +266,28 @@ rep outsw
global ASM_PFX(IoWriteFifo32)
ASM_PFX(IoWriteFifo32):
push esi
- cld
mov dx, [esp + 8]
mov ecx, [esp + 12]
mov esi, [esp + 16]
-rep outsd
+
+ call SevNoRepIo ; Check if we need to unroll String I/O
+ test eax, eax
+ jnz @IoWriteFifo32_NoRep
+
+ cld
+ rep outsd
+ jmp @IoWriteFifo32_Done
+
+@IoWriteFifo32_NoRep:
+ jecxz @IoWriteFifo32_Done
+
+@IoWriteFifo32_Loop:
+ mov dword [esi], eax
+ out dx, eax
+ add esi, 4
+ loop @IoWriteFifo32_Loop
+
+@IoWriteFifo32_Done:
pop esi
ret
diff --git a/MdePkg/Library/BaseIoLibIntrinsic/X64/IoFifo.asm b/MdePkg/Library/BaseIoLibIntrinsic/X64/IoFifo.asm
index 87c6107..fe9e171 100644
--- a/MdePkg/Library/BaseIoLibIntrinsic/X64/IoFifo.asm
+++ b/MdePkg/Library/BaseIoLibIntrinsic/X64/IoFifo.asm
@@ -16,6 +16,59 @@
.code
;------------------------------------------------------------------------------
+; Check whether we need to unroll the String I/O in SEV guest
+;
+; Return // eax (1 - unroll, 0 - no unroll)
+;------------------------------------------------------------------------------
+SevNoRepIo PROC
+ ; CPUID clobbers ebx, ecx and edx
+ push rbx
+ push rcx
+ push rdx
+
+ ; Check if we are runing under hypervisor
+ ; CPUID(1).ECX Bit 31
+ mov eax, 1
+ cpuid
+ bt ecx, 31
+ jnc @UseRepIo
+
+ ; Check if we have Memory encryption CPUID leaf
+ mov eax, 0x80000000
+ cpuid
+ cmp eax, 0x8000001f
+ jl @UseRepIo
+
+ ; Check for memory encryption feature:
+ ; CPUID Fn8000_001F[EAX] - Bit 1
+ ;
+ mov eax, 0x8000001f
+ cpuid
+ bt eax, 1
+ jnc @UseRepIo
+
+ ; Check if memory encryption is enabled
+ ; MSR_0xC0010131 - Bit 0 (SEV enabled)
+ ; MSR_0xC0010131 - Bit 1 (SEV-ES enabled)
+ mov ecx, 0xc0010131
+ rdmsr
+
+ ; Check for (SevEsEnabled == 0 && SevEnabled == 1)
+ and eax, 3
+ cmp eax, 1
+ je @SevNoRepIo_Done
+
+@UseRepIo:
+ xor eax, eax
+
+@SevNoRepIo_Done:
+ pop rdx
+ pop rcx
+ pop rbx
+ ret
+SevNoRepIo ENDP
+
+;------------------------------------------------------------------------------
; VOID
; EFIAPI
; IoReadFifo8 (
@@ -25,10 +78,27 @@
; );
;------------------------------------------------------------------------------
IoReadFifo8 PROC
- cld
xchg rcx, rdx
xchg rdi, r8 ; rdi: buffer address; r8: save rdi
-rep insb
+
+ call SevNoRepIo ; Check if we need to unroll String I/O
+ test eax, eax
+ jnz @IoReadFifo8_NoRep
+
+ cld
+ rep insb
+ jmp @IoReadFifo8_Done
+
+@IoReadFifo8_NoRep:
+ jrcxz @IoReadFifo8_Done
+
+@IoReadFifo8_Loop:
+ in al, dx
+ mov byte [rdi], al
+ inc rdi
+ loop @IoReadFifo8_Loop
+
+@IoReadFifo8_Done:
mov rdi, r8 ; restore rdi
ret
IoReadFifo8 ENDP
@@ -43,10 +113,27 @@ IoReadFifo8 ENDP
; );
;------------------------------------------------------------------------------
IoReadFifo16 PROC
- cld
xchg rcx, rdx
xchg rdi, r8 ; rdi: buffer address; r8: save rdi
-rep insw
+
+ call SevNoRepIo ; Check if we need to unroll String I/O
+ test eax, eax
+ jnz @IoReadFifo16_NoRep
+
+ cld
+ rep insw
+ jmp @IoReadFifo16_Done
+
+@IoReadFifo16_NoRep:
+ jrcxz @IoReadFifo16_Done
+
+@IoReadFifo16_Loop:
+ in ax, dx
+ mov word [rdi], ax
+ add rdi, 2
+ loop @IoReadFifo16_Loop
+
+@IoReadFifo16_Done:
mov rdi, r8 ; restore rdi
ret
IoReadFifo16 ENDP
@@ -61,10 +148,27 @@ IoReadFifo16 ENDP
; );
;------------------------------------------------------------------------------
IoReadFifo32 PROC
- cld
xchg rcx, rdx
xchg rdi, r8 ; rdi: buffer address; r8: save rdi
-rep insd
+
+ call SevNoRepIo ; Check if we need to unroll String I/O
+ test eax, eax
+ jnz @IoReadFifo32_NoRep
+
+ cld
+ rep insd
+ jmp @IoReadFifo32_Done
+
+@IoReadFifo32_NoRep:
+ jrcxz @IoReadFifo32_Done
+
+@IoReadFifo32_Loop:
+ in eax, dx
+ mov dword [rdi], eax
+ add rdi, 4
+ loop @IoReadFifo32_Loop
+
+@IoReadFifo32_Done:
mov rdi, r8 ; restore rdi
ret
IoReadFifo32 ENDP
@@ -79,10 +183,27 @@ IoReadFifo32 ENDP
; );
;------------------------------------------------------------------------------
IoWriteFifo8 PROC
- cld
xchg rcx, rdx
xchg rsi, r8 ; rsi: buffer address; r8: save rsi
-rep outsb
+
+ call SevNoRepIo ; Check if we need to unroll String I/O
+ test eax, eax
+ jnz @IoWriteFifo8_NoRep
+
+ cld
+ rep outsb
+ jmp @IoWriteFifo8_Done
+
+@IoWriteFifo8_NoRep:
+ jrcxz @IoWriteFifo8_Done
+
+@IoWriteFifo8_Loop:
+ mov byte [rsi], al
+ out dx, al
+ inc rsi
+ loop @IoWriteFifo8_Loop
+
+@IoWriteFifo8_Done:
mov rsi, r8 ; restore rsi
ret
IoWriteFifo8 ENDP
@@ -97,10 +218,27 @@ IoWriteFifo8 ENDP
; );
;------------------------------------------------------------------------------
IoWriteFifo16 PROC
- cld
xchg rcx, rdx
xchg rsi, r8 ; rsi: buffer address; r8: save rsi
-rep outsw
+
+ call SevNoRepIo ; Check if we need to unroll String I/O
+ test eax, eax
+ jnz @IoWriteFifo16_NoRep
+
+ cld
+ rep outsw
+ jmp @IoWriteFifo16_Done
+
+@IoWriteFifo16_NoRep:
+ jrcxz @IoWriteFifo16_Done
+
+@IoWriteFifo16_Loop:
+ mov word [rsi], ax
+ out dx, ax
+ add rsi, 2
+ loop @IoWriteFifo16_Loop
+
+@IoWriteFifo16_Done:
mov rsi, r8 ; restore rsi
ret
IoWriteFifo16 ENDP
@@ -115,10 +253,27 @@ IoWriteFifo16 ENDP
; );
;------------------------------------------------------------------------------
IoWriteFifo32 PROC
- cld
xchg rcx, rdx
xchg rsi, r8 ; rsi: buffer address; r8: save rsi
-rep outsd
+
+ call SevNoRepIo ; Check if we need to unroll String I/O
+ test eax, eax
+ jnz @IoWriteFifo32_NoRep
+
+ cld
+ rep outsd
+ jmp @IoWriteFifo32_Done
+
+@IoWriteFifo32_NoRep:
+ jrcxz @IoWriteFifo32_Done
+
+@IoWriteFifo32_Loop:
+ mov dword [rsi], eax
+ out dx, eax
+ add rsi, 4
+ loop @IoWriteFifo32_Loop
+
+@IoWriteFifo32_Done:
mov rsi, r8 ; restore rsi
ret
IoWriteFifo32 ENDP
diff --git a/MdePkg/Library/BaseIoLibIntrinsic/X64/IoFifo.nasm b/MdePkg/Library/BaseIoLibIntrinsic/X64/IoFifo.nasm
index 7bd72d0..20e3e64 100644
--- a/MdePkg/Library/BaseIoLibIntrinsic/X64/IoFifo.nasm
+++ b/MdePkg/Library/BaseIoLibIntrinsic/X64/IoFifo.nasm
@@ -17,6 +17,60 @@
SECTION .text
;------------------------------------------------------------------------------
+; Check whether we need to unroll the String I/O in SEV guest
+;
+; Return // eax (1 - unroll, 0 - no unroll)
+;------------------------------------------------------------------------------
+global ASM_PFX(SevNoRepIo)
+ASM_PFX(SevNoRepIo):
+
+ ; CPUID clobbers ebx, ecx and edx
+ push rbx
+ push rcx
+ push rdx
+
+ ; Check if we are runing under hypervisor
+ ; CPUID(1).ECX Bit 31
+ mov eax, 1
+ cpuid
+ bt ecx, 31
+ jnc @UseRepIo
+
+ ; Check if we have Memory encryption CPUID leaf
+ mov eax, 0x80000000
+ cpuid
+ cmp eax, 0x8000001f
+ jl @UseRepIo
+
+ ; Check for memory encryption feature:
+ ; CPUID Fn8000_001F[EAX] - Bit 1
+ ;
+ mov eax, 0x8000001f
+ cpuid
+ bt eax, 1
+ jnc @UseRepIo
+
+ ; Check if memory encryption is enabled
+ ; MSR_0xC0010131 - Bit 0 (SEV enabled)
+ ; MSR_0xC0010131 - Bit 1 (SEV-ES enabled)
+ mov ecx, 0xc0010131
+ rdmsr
+
+ ; Check for (SevEsEnabled == 0 && SevEnabled == 1)
+ and eax, 3
+ cmp eax, 1
+ je @SevNoRepIo_Done
+
+@UseRepIo:
+ xor eax, eax
+
+@SevNoRepIo_Done:
+ pop rdx
+ pop rcx
+ pop rbx
+ ret
+
+;------------------------------------------------------------------------------
; VOID
; EFIAPI
; IoReadFifo8 (
@@ -27,10 +81,27 @@
;------------------------------------------------------------------------------
global ASM_PFX(IoReadFifo8)
ASM_PFX(IoReadFifo8):
- cld
xchg rcx, rdx
xchg rdi, r8 ; rdi: buffer address; r8: save rdi
-rep insb
+
+ call SevNoRepIo ; Check if we need to unroll String I/O
+ test eax, eax
+ jnz @IoReadFifo8_NoRep
+
+ cld
+ rep insb
+ jmp @IoReadFifo8_Done
+
+@IoReadFifo8_NoRep:
+ jrcxz @IoReadFifo8_Done
+
+@IoReadFifo8_Loop:
+ in al, dx
+ mov byte [rdi], al
+ inc rdi
+ loop @IoReadFifo8_Loop
+
+@IoReadFifo8_Done:
mov rdi, r8 ; restore rdi
ret
@@ -45,10 +116,27 @@ rep insb
;------------------------------------------------------------------------------
global ASM_PFX(IoReadFifo16)
ASM_PFX(IoReadFifo16):
- cld
xchg rcx, rdx
xchg rdi, r8 ; rdi: buffer address; r8: save rdi
-rep insw
+
+ call SevNoRepIo ; Check if we need to unroll String I/O
+ test eax, eax
+ jnz @IoReadFifo16_NoRep
+
+ cld
+ rep insw
+ jmp @IoReadFifo16_Done
+
+@IoReadFifo16_NoRep:
+ jrcxz @IoReadFifo16_Done
+
+@IoReadFifo16_Loop:
+ in ax, dx
+ mov word [rdi], ax
+ add rdi, 2
+ loop @IoReadFifo16_Loop
+
+@IoReadFifo16_Done:
mov rdi, r8 ; restore rdi
ret
@@ -63,10 +151,27 @@ rep insw
;------------------------------------------------------------------------------
global ASM_PFX(IoReadFifo32)
ASM_PFX(IoReadFifo32):
- cld
xchg rcx, rdx
xchg rdi, r8 ; rdi: buffer address; r8: save rdi
-rep insd
+
+ call SevNoRepIo ; Check if we need to unroll String I/O
+ test eax, eax
+ jnz @IoReadFifo32_NoRep
+
+ cld
+ rep insd
+ jmp @IoReadFifo32_Done
+
+@IoReadFifo32_NoRep:
+ jrcxz @IoReadFifo32_Done
+
+@IoReadFifo32_Loop:
+ in eax, dx
+ mov dword [rdi], eax
+ add rdi, 4
+ loop @IoReadFifo32_Loop
+
+@IoReadFifo32_Done:
mov rdi, r8 ; restore rdi
ret
@@ -81,10 +186,27 @@ rep insd
;------------------------------------------------------------------------------
global ASM_PFX(IoWriteFifo8)
ASM_PFX(IoWriteFifo8):
- cld
xchg rcx, rdx
xchg rsi, r8 ; rsi: buffer address; r8: save rsi
-rep outsb
+
+ call SevNoRepIo ; Check if we need to unroll String I/O
+ test eax, eax
+ jnz @IoWriteFifo8_NoRep
+
+ cld
+ rep outsb
+ jmp @IoWriteFifo8_Done
+
+@IoWriteFifo8_NoRep:
+ jrcxz @IoWriteFifo8_Done
+
+@IoWriteFifo8_Loop:
+ mov byte [rsi], al
+ out dx, al
+ inc rsi
+ loop @IoWriteFifo8_Loop
+
+@IoWriteFifo8_Done:
mov rsi, r8 ; restore rsi
ret
@@ -99,10 +221,27 @@ rep outsb
;------------------------------------------------------------------------------
global ASM_PFX(IoWriteFifo16)
ASM_PFX(IoWriteFifo16):
- cld
xchg rcx, rdx
xchg rsi, r8 ; rsi: buffer address; r8: save rsi
-rep outsw
+
+ call SevNoRepIo ; Check if we need to unroll String I/O
+ test eax, eax
+ jnz @IoWriteFifo16_NoRep
+
+ cld
+ rep outsw
+ jmp @IoWriteFifo16_Done
+
+@IoWriteFifo16_NoRep:
+ jrcxz @IoWriteFifo16_Done
+
+@IoWriteFifo16_Loop:
+ mov word [rsi], ax
+ out dx, ax
+ add rsi, 2
+ loop @IoWriteFifo16_Loop
+
+@IoWriteFifo16_Done:
mov rsi, r8 ; restore rsi
ret
@@ -117,10 +256,27 @@ rep outsw
;------------------------------------------------------------------------------
global ASM_PFX(IoWriteFifo32)
ASM_PFX(IoWriteFifo32):
- cld
xchg rcx, rdx
xchg rsi, r8 ; rsi: buffer address; r8: save rsi
-rep outsd
+
+ call SevNoRepIo ; Check if we need to unroll String I/O
+ test eax, eax
+ jnz @IoWriteFifo32_NoRep
+
+ cld
+ rep outsd
+ jmp @IoWriteFifo32_Done
+
+@IoWriteFifo32_NoRep:
+ jrcxz @IoWriteFifo32_Done
+
+@IoWriteFifo32_Loop:
+ mov dword [rsi], eax
+ out dx, eax
+ add rsi, 4
+ loop @IoWriteFifo32_Loop
+
+@IoWriteFifo32_Done:
mov rsi, r8 ; restore rsi
ret
--
2.7.4
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2017-03-20 16:39 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-03-20 16:39 [PATCH] MdePkg: BaseIoLibIntrinsic (IoLib class) library Leo Duran
2017-03-20 16:39 ` Leo Duran
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox