From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-io0-x244.google.com (mail-io0-x244.google.com [IPv6:2607:f8b0:4001:c06::244]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id C368A80333 for ; Mon, 6 Mar 2017 15:28:03 -0800 (PST) Received: by mail-io0-x244.google.com with SMTP id 68so16644648ioh.3 for ; Mon, 06 Mar 2017 15:28:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:subject:to:cc:date:message-id:in-reply-to:references :user-agent:mime-version:content-transfer-encoding; bh=SPQoecMTSpChdIsF5O08iquitMohyn8beY72Fk1INzQ=; b=FqEyAsjqL3a51sWTbfThYfzQVR8fNzL0WYaaNJNNzQQP2m4EGNViTwOqseq+NmW7Ij SIkmtYa0BAaYhxquSKOe93b6ZYeNEhzlycLjCaG9HsqfPZSlu8sRrS9UtjEYSfAphMIg ujmrHPNF0BxlkiIJoxzstBZ3xCFRa2MYztNC1lwN4WlopEcwTIFZq4YxWmVlhzdJO7iY wV4icgyu7yYjr8Q4UyQ0i8ZGyQ+u2kVl8f5gJOf+ygVSU+mL0DODDf709J3danys1dRA T9ag/Er4XHrK9Y5l8dex2uhjrtoaAFaFC0hLBHTFSRe0IarU1MhMxFYfFf/Nx7sIQxUj ohXw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:subject:to:cc:date:message-id:in-reply-to :references:user-agent:mime-version:content-transfer-encoding; bh=SPQoecMTSpChdIsF5O08iquitMohyn8beY72Fk1INzQ=; b=apEiTfuj99V0+O2/63+ZDlovPI23K4G4rFuQVhFJOQl0nfiw7PJFJUuwJD5gvm+us6 CwF4lfYs6QW0xL4/W19LFcyhSPqPGv39frUl5ujgEYMlZsIM+CQfhldsu3aXf0sjwVXW xalder4Mh9/aYFqnzCy/YZqkXOC0A+jC91KH2M2QzLK86jZO3shgwainojpAl+8e0eYw l2BNNQo4bR1J1kPxTlt00w5qHqSDHUlt4CPVAo9GMLBf+4Z0GAiDUt/S/UkQm3LSM25J aR5hdHo001uCL6sSvyFl8/TGSNFqsb+K4EO+KHqiy98qQZ6QpwZ/X2eYh1TRfb1Bnctx U3NQ== X-Gm-Message-State: AMke39nqLgqzNZqPlry6uu9A7v8tkxdU+nxzKYtG5M5M7+g3jSAEZaGuGIIZRdFbl4W5Ug== X-Received: by 10.107.166.207 with SMTP id p198mr17264404ioe.15.1488842883040; Mon, 06 Mar 2017 15:28:03 -0800 (PST) Received: from [127.0.1.1] ([165.204.77.1]) by smtp.gmail.com with ESMTPSA id m100sm9312360iod.14.2017.03.06.15.28.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 06 Mar 2017 15:28:02 -0800 (PST) From: Brijesh Singh X-Google-Original-From: Brijesh Singh To: jordan.l.justen@intel.com, edk2-devel@ml01.01.org, lersek@redhat.com Cc: Thomas.Lendacky@amd.com, leo.duran@amd.com, brijesh.sing@amd.com Date: Mon, 06 Mar 2017 18:28:01 -0500 Message-ID: <148884288152.29188.17347075963122121328.stgit@brijesh-build-machine> In-Reply-To: <148884284887.29188.7643544710695103939.stgit@brijesh-build-machine> References: <148884284887.29188.7643544710695103939.stgit@brijesh-build-machine> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Subject: [RFC PATCH v1 5/5] OvmfPkg/BaseIoLibIntrinsic: Unroll String I/O when SEV is active X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 06 Mar 2017 23:28:04 -0000 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit 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 --- .../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.
+; +; 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.
+; +; 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 +