[edk2] [RFC PATCH v1 5/5] OvmfPkg/BaseIoLibIntrinsic: Unroll String I/O when SEV is active

Brijesh Singh posted 5 patches 7 years, 8 months ago
There is a newer version of this series
[edk2] [RFC PATCH v1 5/5] OvmfPkg/BaseIoLibIntrinsic: Unroll String I/O when SEV is active
Posted by Brijesh Singh 7 years, 8 months ago
Secure Encrypted Virtualization (SEV) does not support string I/O, so
unroll the string I/O operation into a loop operating on one element at
a time.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 .../BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf      |    3 
 .../Library/BaseIoLibIntrinsic/Ia32/IoFifo.nasm    |   19 +++
 .../Library/BaseIoLibIntrinsic/Ia32/SevIoFifo.nasm |  141 ++++++++++++++++++++
 OvmfPkg/Library/BaseIoLibIntrinsic/X64/IoFifo.nasm |   19 +++
 .../Library/BaseIoLibIntrinsic/X64/SevIoFifo.nasm  |  143 ++++++++++++++++++++
 5 files changed, 324 insertions(+), 1 deletion(-)
 create mode 100644 OvmfPkg/Library/BaseIoLibIntrinsic/Ia32/SevIoFifo.nasm
 create mode 100644 OvmfPkg/Library/BaseIoLibIntrinsic/X64/SevIoFifo.nasm

diff --git a/OvmfPkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf b/OvmfPkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
index 8844b1c..e7eeb59 100644
--- a/OvmfPkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+++ b/OvmfPkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
@@ -28,7 +28,6 @@
   VERSION_STRING                 = 1.0
   LIBRARY_CLASS                  = IoLib 
 
-
 #
 #  VALID_ARCHITECTURES           = IA32 X64 EBC IPF ARM AARCH64
 #
@@ -45,6 +44,7 @@
   IoLib.c
   Ia32/IoFifo.nasm
   Ia32/IoFifo.asm
+  Ia32/SevIoFifo.nasm
 
 [Sources.X64]
   IoLibGcc.c    | GCC
@@ -53,6 +53,7 @@
   IoLib.c
   X64/IoFifo.nasm
   X64/IoFifo.asm
+  X64/SevIoFifo.nasm
 
 [Sources.EBC]
   IoLibEbc.c
diff --git a/OvmfPkg/Library/BaseIoLibIntrinsic/Ia32/IoFifo.nasm b/OvmfPkg/Library/BaseIoLibIntrinsic/Ia32/IoFifo.nasm
index bcaa743..fb585e6 100644
--- a/OvmfPkg/Library/BaseIoLibIntrinsic/Ia32/IoFifo.nasm
+++ b/OvmfPkg/Library/BaseIoLibIntrinsic/Ia32/IoFifo.nasm
@@ -13,6 +13,10 @@
 ;
 ;------------------------------------------------------------------------------
 
+    EXTERN ASM_PFX(SevIoReadFifo8)
+    EXTERN ASM_PFX(SevIoReadFifo16)
+    EXTERN ASM_PFX(SevIoReadFifo32)
+
     SECTION .text
 
 ;------------------------------------------------------------------------------
@@ -31,7 +35,12 @@ ASM_PFX(IoReadFifo8):
     mov     dx, [esp + 8]
     mov     ecx, [esp + 12]
     mov     edi, [esp + 16]
+    call    SevIoReadFifo8
+    cmp     ecx, 0
+    jz      IoReadFifo8Exit
 rep insb
+
+IoReadFifo8Exit:
     pop     edi
     ret
 
@@ -51,7 +60,12 @@ ASM_PFX(IoReadFifo16):
     mov     dx, [esp + 8]
     mov     ecx, [esp + 12]
     mov     edi, [esp + 16]
+    call    SevIoReadFifo16
+    cmp     ecx, 0
+    jz      IoReadFifo16Exit
 rep insw
+
+IoReadFifo16Exit:
     pop     edi
     ret
 
@@ -71,7 +85,12 @@ ASM_PFX(IoReadFifo32):
     mov     dx, [esp + 8]
     mov     ecx, [esp + 12]
     mov     edi, [esp + 16]
+    call    SevIoReadFifo32
+    cmp     ecx, 0
+    jz      IoReadFifo32Exit
 rep insd
+
+IoReadFifo32Exit:
     pop     edi
     ret
 
diff --git a/OvmfPkg/Library/BaseIoLibIntrinsic/Ia32/SevIoFifo.nasm b/OvmfPkg/Library/BaseIoLibIntrinsic/Ia32/SevIoFifo.nasm
new file mode 100644
index 0000000..ac6bee3
--- /dev/null
+++ b/OvmfPkg/Library/BaseIoLibIntrinsic/Ia32/SevIoFifo.nasm
@@ -0,0 +1,141 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
+;
+; This program and the accompanying materials are licensed and made available
+; under the terms and conditions of the BSD License which accompanies this
+; distribution.  The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+;------------------------------------------------------------------------------
+
+%define KVM_FEATURE_SEV         8
+
+    SECTION .data
+SevCheckedOnce    db            0
+SevStatus         db            0
+
+    SECTION .text
+
+;------------------------------------------------------------------------------
+; Check if Secure Encrypted Virtualization (SEV) feature
+; is enabled in KVM
+;
+; Return // eax   (1 - active, 0 - not active)
+;------------------------------------------------------------------------------
+global ASM_PFX(CheckSevFeature)
+ASM_PFX(CheckSevFeature):
+  ; Check CPUID once, if its already checked then return SevStatus
+  mov       eax, 1
+  cmp       [SevCheckedOnce], eax
+  jz        SevFeatureCheckExit
+
+  ; Start the SEV feature check
+  mov       [SevCheckedOnce], eax
+
+  ; CPUID clobbers ebx, ecx and edx
+  push      ebx
+  push      ecx
+  push      edx
+
+  mov       eax, 0x40000001
+  cpuid
+
+  bt        eax, KVM_FEATURE_SEV
+  jnc       SevCheckExit
+
+  ; Check for memory encryption feature:
+  ;  CPUID  Fn8000_001F[EAX] - Bit 0
+  ;
+  mov       eax,  0x8000001f
+  cpuid
+  bt        eax, 0
+  jnc       SevCheckExit
+  mov       eax, 1
+  mov       [SevStatus], eax
+
+SevCheckExit:
+  pop       edx
+  pop       ecx
+  pop       ebx
+
+SevFeatureCheckExit:
+  mov       eax, [SevStatus]
+  ret
+
+;------------------------------------------------------------------------------
+;  unroll 'rep ins' String I/O instructions when SEV is active
+;  nothing
+;
+;  Port    // dx
+;  Size    // ecx
+;  Buffer  // rdi
+;
+;------------------------------------------------------------------------------
+global ASM_PFX(SevIoReadFifo8)
+ASM_PFX(SevIoReadFifo8):
+  call      CheckSevFeature
+  cmp       eax, 1
+  jnz       ReadFifo8Exit
+ReadFifo8Loop:
+    cmp       ecx, 0
+    jz        ReadFifo8Exit
+    in        al, dx
+    mov       [edi], al
+    dec       ecx
+    inc       edi
+    jmp       ReadFifo8Loop
+ReadFifo8Exit:
+  ret
+
+;------------------------------------------------------------------------------
+;  unroll 'rep insw' String I/O instructions when SEV is active
+;
+;  Port    // dx
+;  Size    // ecx
+;  Buffer  // rdi
+;
+;------------------------------------------------------------------------------
+global ASM_PFX(SevIoReadFifo16)
+ASM_PFX(SevIoReadFifo16):
+  call      CheckSevFeature
+  cmp       eax, 1
+  jnz       ReadFifo16Exit
+ReadFifo16Loop:
+    cmp       ecx, 0
+    jz        ReadFifo16Exit
+    in        ax, dx
+    mov       [edi], ax
+    dec       ecx
+    add       edi, 2
+    jmp       ReadFifo16Loop
+ReadFifo16Exit:
+  ret
+
+;------------------------------------------------------------------------------
+;  unroll 'rep insl' String I/O instructions when SEV is active
+;
+;  Port    // dx
+;  Size    // ecx
+;  Buffer  // rdi
+;
+;------------------------------------------------------------------------------
+global ASM_PFX(SevIoReadFifo32)
+ASM_PFX(SevIoReadFifo32):
+  call      CheckSevFeature
+  cmp       eax, 1
+  jnz       ReadFifo32Exit
+ReadFifo32Loop:
+    cmp       ecx, 0
+    jz        ReadFifo32Exit
+    in        eax, dx
+    mov       [edi], eax
+    dec       ecx
+    add       edi, 4
+    jmp       ReadFifo32Loop
+ReadFifo32Exit:
+  ret
+
diff --git a/OvmfPkg/Library/BaseIoLibIntrinsic/X64/IoFifo.nasm b/OvmfPkg/Library/BaseIoLibIntrinsic/X64/IoFifo.nasm
index 7bd72d0..71fbe62 100644
--- a/OvmfPkg/Library/BaseIoLibIntrinsic/X64/IoFifo.nasm
+++ b/OvmfPkg/Library/BaseIoLibIntrinsic/X64/IoFifo.nasm
@@ -13,6 +13,10 @@
 ;
 ;------------------------------------------------------------------------------
 
+    EXTERN ASM_PFX(SevIoReadFifo8)
+    EXTERN ASM_PFX(SevIoReadFifo16)
+    EXTERN ASM_PFX(SevIoReadFifo32)
+
     DEFAULT REL
     SECTION .text
 
@@ -30,7 +34,12 @@ ASM_PFX(IoReadFifo8):
     cld
     xchg    rcx, rdx
     xchg    rdi, r8             ; rdi: buffer address; r8: save rdi
+    call    SevIoReadFifo8
+    cmp     ecx, 0
+    jz      IoReadFifo8Exit
 rep insb
+
+IoReadFifo8Exit:
     mov     rdi, r8             ; restore rdi
     ret
 
@@ -48,7 +57,12 @@ ASM_PFX(IoReadFifo16):
     cld
     xchg    rcx, rdx
     xchg    rdi, r8             ; rdi: buffer address; r8: save rdi
+    call    SevIoReadFifo16
+    cmp     ecx, 0
+    jz      IoReadFifo16Exit
 rep insw
+
+IoReadFifo16Exit:
     mov     rdi, r8             ; restore rdi
     ret
 
@@ -66,7 +80,12 @@ ASM_PFX(IoReadFifo32):
     cld
     xchg    rcx, rdx
     xchg    rdi, r8             ; rdi: buffer address; r8: save rdi
+    call    SevIoReadFifo32
+    cmp     ecx, 0
+    jz      IoReadFifo32Exit
 rep insd
+
+IoReadFifo32Exit:
     mov     rdi, r8             ; restore rdi
     ret
 
diff --git a/OvmfPkg/Library/BaseIoLibIntrinsic/X64/SevIoFifo.nasm b/OvmfPkg/Library/BaseIoLibIntrinsic/X64/SevIoFifo.nasm
new file mode 100644
index 0000000..5e70cb6
--- /dev/null
+++ b/OvmfPkg/Library/BaseIoLibIntrinsic/X64/SevIoFifo.nasm
@@ -0,0 +1,143 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
+;
+; This program and the accompanying materials are licensed and made available
+; under the terms and conditions of the BSD License which accompanies this
+; distribution.  The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+;------------------------------------------------------------------------------
+
+%define KVM_FEATURE_SEV         8
+
+    EXTERN ASM_PFX(SevEnabled)
+
+    SECTION .data
+SevCheckedOnce    db            0
+SevStatus         db            0
+
+    SECTION .text
+
+;------------------------------------------------------------------------------
+; Check if Secure Encrypted Virtualization (SEV) feature
+; is enabled in KVM
+;
+; Return // eax   (1 - active, 0 - not active)
+;------------------------------------------------------------------------------
+global ASM_PFX(CheckSevFeature)
+ASM_PFX(CheckSevFeature):
+  ; Check CPUID once, if its already checked then return SevStatus
+  mov       eax, 1
+  cmp       [SevCheckedOnce], eax
+  jz        SevFeatureCheckExit
+
+  ; Start the SEV feature check
+  mov       [SevCheckedOnce], eax
+
+  ; CPUID clobbers ebx, ecx and edx
+  push      rbx
+  push      rcx
+  push      rdx
+
+  mov       eax, 0x40000001
+  cpuid
+
+  bt        eax, KVM_FEATURE_SEV
+  jnc       SevCheckExit
+
+  ; Check for memory encryption feature:
+  ;  CPUID  Fn8000_001F[EAX] - Bit 0
+  ;
+  mov       eax,  0x8000001f
+  cpuid
+  bt        eax, 0
+  jnc       SevCheckExit
+  mov       eax, 1
+  mov       [SevStatus], eax
+
+SevCheckExit:
+  pop       rdx
+  pop       rcx
+  pop       rbx
+
+SevFeatureCheckExit:
+  mov       eax, [SevStatus]
+  ret
+
+;------------------------------------------------------------------------------
+;  unroll 'rep ins' String I/O instructions when SEV is active
+;  nothing
+;
+;  Port    // dx
+;  Size    // ecx
+;  Buffer  // rdi
+;
+;------------------------------------------------------------------------------
+global ASM_PFX(SevIoReadFifo8)
+ASM_PFX(SevIoReadFifo8):
+  call      CheckSevFeature
+  cmp       eax, 1
+  jnz       ReadFifo8Exit
+ReadFifo8Loop:
+    cmp       ecx, 0
+    jz        ReadFifo8Exit
+    in        al, dx
+    mov       [edi], al
+    dec       ecx
+    inc       edi
+    jmp       ReadFifo8Loop
+ReadFifo8Exit:
+  ret
+
+;------------------------------------------------------------------------------
+;  unroll 'rep insw' String I/O instructions when SEV is active
+;
+;  Port    // dx
+;  Size    // ecx
+;  Buffer  // rdi
+;
+;------------------------------------------------------------------------------
+global ASM_PFX(SevIoReadFifo16)
+ASM_PFX(SevIoReadFifo16):
+  call      CheckSevFeature
+  cmp       eax, 1
+  jnz       ReadFifo16Exit
+ReadFifo16Loop:
+    cmp       ecx, 0
+    jz        ReadFifo16Exit
+    in        ax, dx
+    mov       [edi], ax
+    dec       ecx
+    add       edi, 2
+    jmp       ReadFifo16Loop
+ReadFifo16Exit:
+  ret
+
+;------------------------------------------------------------------------------
+;  unroll 'rep insl' String I/O instructions when SEV is active
+;
+;  Port    // dx
+;  Size    // ecx
+;  Buffer  // rdi
+;
+;------------------------------------------------------------------------------
+global ASM_PFX(SevIoReadFifo32)
+ASM_PFX(SevIoReadFifo32):
+  call      CheckSevFeature
+  cmp       eax, 1
+  jnz       ReadFifo32Exit
+ReadFifo32Loop:
+    cmp       ecx, 0
+    jz        ReadFifo32Exit
+    in        eax, dx
+    mov       [edi], eax
+    dec       ecx
+    add       edi, 4
+    jmp       ReadFifo32Loop
+ReadFifo32Exit:
+  ret
+

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel