From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM02-SN1-obe.outbound.protection.outlook.com (mail-sn1nam02on0626.outbound.protection.outlook.com [IPv6:2a01:111:f400:fe44::626]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 5E0E380466 for ; Mon, 20 Mar 2017 09:39:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amdcloud.onmicrosoft.com; s=selector1-amd-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=VF6QwkZJmn9Z9MYuyye5DgXr8EzHZbradFV3QZjoEGs=; b=KXMm3i2Gpnje2+jTdc5QDrpVF/1ZYhBPIo4aD3mVJtqtgbkfnGzyRjB7A+QEVlcvD5/+Cn8/Qd7GBRYSuYDcxLZDVIJU19PUi+9VY7jurhPeTq7VP4WuG7dDjOaLdY2pBOeeYtepSFciJjVuOywwbhCPeakEtvORHP7ukl+GCPk= Authentication-Results: ml01.01.org; dkim=none (message not signed) header.d=none;ml01.01.org; dmarc=none action=none header.from=amd.com; Received: from leduran-Precision-WorkStation-T5400.amd.com (165.204.77.1) by DM5PR12MB1243.namprd12.prod.outlook.com (10.168.237.22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.977.11; Mon, 20 Mar 2017 16:39:21 +0000 From: Leo Duran To: CC: Brijesh Singh , Michael D Kinney , Liming Gao , Leo Duran Date: Mon, 20 Mar 2017 11:39:10 -0500 Message-ID: <1490027950-8739-2-git-send-email-leo.duran@amd.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1490027950-8739-1-git-send-email-leo.duran@amd.com> References: <1490027950-8739-1-git-send-email-leo.duran@amd.com> MIME-Version: 1.0 X-Originating-IP: [165.204.77.1] X-ClientProxiedBy: CY4PR13CA0017.namprd13.prod.outlook.com (10.168.161.155) To DM5PR12MB1243.namprd12.prod.outlook.com (10.168.237.22) X-MS-Office365-Filtering-Correlation-Id: 3470b4d9-fe67-40b3-050f-08d46fafa99b X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001)(48565401081); SRVR:DM5PR12MB1243; X-Microsoft-Exchange-Diagnostics: 1; DM5PR12MB1243; 3:9WBzh6A3/V8VbfDyxn5jEV/EJxHx/6los+w1r2MGB6ti5l4UTmWWUh/E7L65Cg/zF1bXuEPvHP/vfr7Cx8vZncpWf7BJt9+hqaJoyfYrwO8bKAD3Wq/NpkZauXIdGhlyzmHhtcsRwoZNEINoU5rV+hR/yBZE73ROk/f/3bCAJhEJuef1DSUv4ER1SZ0ioyhpcBD0/+GChLP2Bp+Ri4G7NzWkyO3ZZreKOVj79Qk9KgC+2gseeCIIEyWiGaLbGLpzadlPXzsN3BZlYJWz30wF8kUs312phM0WowHyrGBOpQA=; 25:tL43n5E7ACa1LlN6Z54wbeNm2dF4m3L65CqAElwShHAujXZxIuPondhpvAkODu/yZj5DxA6YitsUTUKKKoilMehWL3DFIkzpOCnEu3wlHrGxfT3IcLqh2QmEDauHZ2CgKJHcElJf5EbhxIKcfayMbNtDZC5B9mNjddxqBlpttA53PUFZViTzmJYfUdlhVaXYv4ZyGLII/sD7yZBkjhTE04/P2QtT6k4T7eBT4qXljUBudHkui1VRFz/vnJ3uj9lllM+V4yR+l65YYVRvMYw6+Z+KHOr5BY0m5CsqKE699wTq+sZ4vvcbnpIRigePH0sclq/CbuNPPndF71QMlV1Ek/SvVWSBN4341b4qzkYlFaWAQl1neI9etDSh9yZfXiedcKUAE2j6wEC96nY+6SMeJknw1HpoZZy/h/6zc5G2lREuR+ZV/Cw2idFPX10jcXrfo0xf6oDXWNDsiNQqDcOaMA== X-Microsoft-Exchange-Diagnostics: 1; DM5PR12MB1243; 31:eQ8wD7KPGbbJzk1s2VMgKrPXvH7ETNRtvM5n4fcxhNbxXelE3X4/Xj/9NDTTRA6lqwGln2ehfznzm66aKJW3kj/0xe6vaaQM8fIaWeyeWA3Ondm7FJBbk9m4ylGNzjjm2a2+IMMG+OpPoyRmmZeW/aelOkmMyI8H3PxoaQ1CyPY14BXhOODLaDop5EUN1DiRwKc5dA/MbANfVqTg0pAdn1gj48hZhVcSBwKeWuC8ipfs0weE/4LykYuIWBuPLk4f; 20:qfMpI3pFFbLF2PkEBd+G2Vs2Te13Snozqlb9ACcnVjY3iwx2Ei4ZTwhftW5V843zFbrYGmb8IioAGvmqf0/HQy0IiuYN9AGeRbLpfiWRV7QrrMqcliazZ8UkcH/2MQ8c4bIti0kIuWScnF85wFvonkUSkj8hMz7E7/0F6hnfzD3DfJ+c/QBOvUUWdE7cFI3BZT9yCjRHidlyjfoWnKAqWuxgkpmRMhQRguB54Dn3dfzBDo6tBS6EHhGsOzTyKk20d8kOhOqPw1oCS1cIdW6tUKyTYs/0S+xQjqr5bLVj2TNiPGeYAosAp4fYY4px1+zy5wsb/vY+G7Pn/jD3wGuwghncQs/KFjvnDZy98Mz6FGz8ouqVZjD1ojTRPwJ8Jgor5i1Yb9fvp3OAcPyoDxltTXhfDYPQnu0Q+tYQT3i1aQS0kfQ5UfuMQBt5jrTIE3ZV45bjHEfqCbKzGrPOSF5GAk2dBjvAFZzeF3+AF5MvMk2yZYGl+jkdW0zrkn4+uR2F X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(767451399110)(228905959029699); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040375)(601004)(2401047)(8121501046)(5005006)(3002001)(10201501046)(6055026)(6041248)(20161123558025)(20161123555025)(20161123560025)(20161123562025)(20161123564025)(6072148); SRVR:DM5PR12MB1243; BCL:0; PCL:0; RULEID:; SRVR:DM5PR12MB1243; X-Microsoft-Exchange-Diagnostics: 1; DM5PR12MB1243; 4:KOTlWkAOnU8u6cYKRQbGr7aIIRThREfnUSXF7mnARGccrhrE2Ldv6byH7ZL9Ut9sfj97Hfxp+hYjNq7B4f+Pf6ySkOCpORsJZphi4OQISnJt/eI4/w87qJrxO9Ld1gBPEP/EKg7SCEoMejFnX0PmQKsyf7W5qi58zIah4TA4zvypvF6z9LRPBAIqZLx9VCEHSnIxXVnxqnlebZ1K06MKVB8aYrcn1c8m30XuqGCC2AVp07IvfifWcoNroDfyRi6yPLqP/2RurG3DWfN5S2W+HWwBEE0eaAsMxunAw9Z14xQBXDfFZ39qJL4JOHsbR3UxL/6glgxKF/Jxh7u8nE7gMYVPuvuKa+/RdNdPgEzacpXdSnLX8qYlU4/xn+aYGqvU4YAUpTUnNechoiXGrt68TiJI/sR6Vmq5xfKqf/xNJSh9jqu6rYSaQTsp+DqhuX8/sW+VQHOCJQ1VOp2R4to6lzDR1VC4WSFuuRZTY4OS5t3NeIrLfDKXUlpFxXVFzHOm4AJ+u4pUzzZwnMEhFqwLj40jfwzu+XsBWN/eM5ne9z091HGg6md4WskInKq1S0fVgC1nwzdmzGyrXEFUEK+q3W+314cup1qJox9v1xvpUlK93VtE7OA/L82qzZWtQsCvGrFbNoy/lnSnjBzNTj+zC7uadRBC9fYkgVFkO4h54s1xwwgmcz9LgilGN0R/NcOT X-Forefront-PRVS: 02524402D6 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(6029001)(39840400002)(39850400002)(39410400002)(39860400002)(39450400003)(2906002)(7736002)(2351001)(33646002)(4326008)(6666003)(2950100002)(53416004)(42186005)(6916009)(53936002)(36756003)(5003940100001)(50986999)(76176999)(110136004)(38730400002)(6486002)(25786008)(66066001)(8676002)(81166006)(48376002)(50466002)(3846002)(6116002)(5660300001)(47776003)(50226002)(305945005)(86362001)(189998001)(19627235001); DIR:OUT; SFP:1101; SCL:1; SRVR:DM5PR12MB1243; H:leduran-Precision-WorkStation-T5400.amd.com; FPR:; SPF:None; MLV:sfv; LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; DM5PR12MB1243; 23:HmdvthqXvOW7lVT/B5JPYh2c1TEX/VssDcqjhwx0r?= =?us-ascii?Q?ngwLdVZW9dEKQ4p46w+nH0hkRIalwa28EbsqgPfTE9guu80pACWKmXJyqEfT?= =?us-ascii?Q?1YBlHVZjpkgrpdCslWfSkmh1sY61Ln3LYkwsd/a1qAqJf+wtlcz+00snbpSg?= =?us-ascii?Q?IB4ykTITM5XJktPvnbcuhW2ZmFAWKo9yvR94UkDfiJoEJu8uekJZ8nF6otVK?= =?us-ascii?Q?3IynORiiCTOBzYTO2eFSuMPStWZb25u7Y7m8V4bXlSUhVH8/r3NE/1b8hEAS?= =?us-ascii?Q?YJaeH+Ylf5PBB+YyFSq3EMhZ11JaGvQ9MuoOAnr2zYVTFvpmwxbDGZriEEZD?= =?us-ascii?Q?NomGgUAj8H866xCho9PmjMeUlLlBdU6lxA+TNKXOT75e+QkEoGPk6lBewU3q?= =?us-ascii?Q?Sc0NgE9TtwGl8gEuxIgM1Nn1rUJpbQ7hb5tFavjdBZKv6rkjFaZYcmiClFNy?= =?us-ascii?Q?n6IRRfv+Ajo12JmHHit4bsINGeyvo4fTB4AnIjy5cYDDGiP4W4tiJ57laX07?= =?us-ascii?Q?DCxtcE2R65/UEVwjjXW2S4ZYaquZYTDusJ2ZB9VTR+gP0O+RVjjqdPfnn8Nx?= =?us-ascii?Q?/1rLcRopJgz8izmMet2SiS/0a7qSQg+tMqcQZiW8yB8kDWmhA26FvqCNvvlB?= =?us-ascii?Q?amqmJt8zPVB5YBXjvjQ6lBzkOJx9B0tqgbI+/7uyiIX6lFa4zMGr/ObkQHpb?= =?us-ascii?Q?hojVTZZL28203Rzq/V3j9wla1h6ivcb7cwSka5a6OaYpfcRyCDgQBMlWRuJH?= =?us-ascii?Q?8WO3kHGwqTHv91xYCPv4yhx+YzfFytD9Uga6uOKrgOQ/4UFfOZxkZVgO/FK4?= =?us-ascii?Q?RioN6JDmHewjRe/lEhsE8j3Exrumyut+gdLiuGQAFiuTwirZEX/WYvGW5swa?= =?us-ascii?Q?Bjxy16ewmXLCL3SBCpSS6RIiOpfESdHNM0neKCsGioVGvx+9Zxe1/uMmx64p?= =?us-ascii?Q?bBIqztvjqePI8+FnDWkVHKO3q/0DGBob2RZuNaEo7OMUPiVgIqtLZSB4UWNZ?= =?us-ascii?Q?lyhiAMCZZzDeAGX8peLj/Ih+P60CilxFIF4MGvwhJjgLA=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1; DM5PR12MB1243; 6:bvQ6ei4+7Lrz1AR8JW57KSh+4qZcbhqxYNEp6kCyx2JOC/cq4cCwSsY+wzi+lGm+2yJBBDRfwM8LrlOr96YgBgLjHbg4l9FuDAm5YWwCyz8oj4jvyDj6hHP+lvu7ZU+tY6A3+MWNtttFv7I3Z9p7ZvWS4XP3pfhvJc9aTmUEVvko5gV6/qbX9D0V4Ox3DEmaw/PolfRRMNyckzTpdLSRgzux5iBzy0meEio9vpLEsGm/sOMORh+EhrPh/gpWMeEKfVwf8aMPDLS5rZa+6SKO4RCXXme5fMs3BIUlYSHoo2ttAmHUqR4168TU2ek2miNJA+IDia4o4YhOZVleNMB53wDVDAiwJw1O0CvMc73mJzvhRse14OdWXxGIYotCAz6L7KT6t35K1sgySfPbOwtprqGxi+J5Ku+3XtiOSE/S8w4=; 5:WMpy+Xrh6+sp8CXZW4XUMOMuVq8ozoPRxnFZyJae7kq4CeSkpcYjuFmdJmtff92UB/Oz/XBaEtVLMbkMBCqSs/PatpcAOUYyEhhc2tcZulS5lCct+/CEPG7qb+vmTCV6YBeJFmU+YCUz25a8q5ITHA==; 24:w3ps1N/b06VEriadc+++Rcn1wvA6F8KobHrtMb6ecTKxskbtZ2NNeZhQd3Oq5lVLDonoy/4L7lLEeZ8FIi2yMjgZO1qKNfVH69/iXUgfLcQ= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; DM5PR12MB1243; 7:6VU8UaBAf2CffRjE6n/Xfl+pxc7SqQf5UQYmI/MciK22InEgFhiugDL7OB3yznTSzALv+6HqxG+26qSH8aS6wCm5evHrpg9n8YonZm4G9gcWTNj1xSEb92LJIFpMLeio0Gj7FaHFdeiHEhwGkwlU137qdXCvTOY1PiNh2X7oQOo/O6NghLF+REIt7UXQVuGG1ojw2Uk81eL35jyyOZ9HKSPz2D9utfEbee9QpWfEhox/r89u2hvFw22O8DH2wyROC/x2yIu4S9RS6GnyA4QSle9UpPSUGYfF9xAV5iHJFWGDJwLng+gYBsl2Znh5USgkan3zMIEsgAnbJuoOzviRAw==; 20:jB1te+K6dgK9ousfHxaCfjYHVO1iv34rPeKw2LDoCEUyOYQHb3XRYr/jSiyWHm2UOLVYwOPFP4+AqByR09zVgB7ISmeWoE5rPN8FJexLwPRU4x8NUKNOcqfzcCx7tddsf3KB5D5U/HvKFfXybj8Wpa6MU9MgO5+DFmqMNbBfTI/qDXEqzVLUnc9K59HIKGvrnmhzmD2AQTgE7VPuxgbYY1wZNAeD0pIbRDVrfspTEigSZZKc6PXTMnTBYqEZlOXQ X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 20 Mar 2017 16:39:21.8398 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM5PR12MB1243 Subject: [PATCH] MdePkg: BaseIoLibIntrinsic (IoLib class) library X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 20 Mar 2017 16:39:23 -0000 Content-Type: text/plain From: Brijesh Singh This patch unrolls REP INSx/OUTSx on IoRead/WriteFifo#() routines when the SEV feature is enabled under a hypervisor environment. Cc: Michael D Kinney Cc: Liming Gao Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Brijesh Singh Signed-off-by: Leo Duran --- 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