lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <7bd09c03-0ab1-2843-d77f-900456fc10c4@amd.com>
Date:   Fri, 3 Dec 2021 12:16:05 -0600
From:   Tom Lendacky <thomas.lendacky@....com>
To:     "Kirill A. Shutemov" <kirill.shutemov@...ux.intel.com>,
        tglx@...utronix.de, mingo@...hat.com, bp@...en8.de,
        dave.hansen@...ux.intel.com, x86@...nel.org, jroedel@...e.de
Cc:     sathyanarayanan.kuppuswamy@...ux.intel.com, ak@...ux.intel.com,
        dan.j.williams@...el.com, hpa@...or.com, knsathya@...nel.org,
        linux-kernel@...r.kernel.org, luto@...nel.org,
        peterz@...radead.org, tony.luck@...el.com
Subject: Re: [PATCHv2 1/3] x86/sev: Use CC_ATTR attribute to generalize string
 I/O unroll

On 12/3/21 7:23 AM, Kirill A. Shutemov wrote:
> From: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@...ux.intel.com>
> 
> INS/OUTS instructions are obsolete and hence many hypervisors do not
> support its emulation. To support existing usage, string I/O operations
> are unrolled using IN/OUT instructions.

So this statement is a bit confusing.

The reason they are unrolled for SEV is because, as is stated, the 
hypervisor has to emulate the operation. Since the string is in guest 
private memory, the hypervisor will read encrypted memory and so is unable 
to perform this operation successfully. This is probably the same reason 
the unrolling will be needed for TDX - hypervisor will read all 0xff's, 
correct?

But they won't be unrolled for non-SEV and non-TDX guests. And with 
SEV-ES, the GHCB is used to supply the string in shared memory and so the 
string operations won't be unrolled there, too.

> 
> AMD SEV platform implements this support by adding unroll logic in
> ins#bwl()/outs#bwl() macros with SEV specific checks. Since TDX VM
> guests will also need similar support, use CC_ATTR_GUEST_UNROLL_STRING_IO
> and generic cc_platform_has() API to implement it.

> 
> String I/O helpers were the last users of sev_key_active() interface and
> sev_enable_key static key. Remove them.
> 
> Suggested-by: Tom Lendacky <thomas.lendacky@....com>
> Reviewed-by: Tony Luck <tony.luck@...el.com>
> Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@...ux.intel.com>
> Signed-off-by: Kirill A. Shutemov <kirill.shutemov@...ux.intel.com>
> ---
>   arch/x86/include/asm/io.h     | 20 +++-----------------
>   arch/x86/kernel/cc_platform.c |  4 ++++
>   arch/x86/mm/mem_encrypt.c     | 10 ----------
>   include/linux/cc_platform.h   | 11 +++++++++++
>   4 files changed, 18 insertions(+), 27 deletions(-)
> 
> diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
> index 5c6a4af0b911..f6d91ecb8026 100644
> --- a/arch/x86/include/asm/io.h
> +++ b/arch/x86/include/asm/io.h
> @@ -40,6 +40,7 @@
>   
>   #include <linux/string.h>
>   #include <linux/compiler.h>
> +#include <linux/cc_platform.h>
>   #include <asm/page.h>
>   #include <asm/early_ioremap.h>
>   #include <asm/pgtable_types.h>
> @@ -256,21 +257,6 @@ static inline void slow_down_io(void)
>   
>   #endif
>   
> -#ifdef CONFIG_AMD_MEM_ENCRYPT
> -#include <linux/jump_label.h>
> -
> -extern struct static_key_false sev_enable_key;
> -static inline bool sev_key_active(void)
> -{
> -	return static_branch_unlikely(&sev_enable_key);
> -}
> -
> -#else /* !CONFIG_AMD_MEM_ENCRYPT */
> -
> -static inline bool sev_key_active(void) { return false; }
> -
> -#endif /* CONFIG_AMD_MEM_ENCRYPT */
> -
>   #define BUILDIO(bwl, bw, type)						\
>   static inline void out##bwl(unsigned type value, int port)		\
>   {									\
> @@ -301,7 +287,7 @@ static inline unsigned type in##bwl##_p(int port)			\
>   									\
>   static inline void outs##bwl(int port, const void *addr, unsigned long count) \
>   {									\
> -	if (sev_key_active()) {						\
> +	if (cc_platform_has(CC_ATTR_GUEST_UNROLL_STRING_IO)) {		\
>   		unsigned type *value = (unsigned type *)addr;		\
>   		while (count) {						\
>   			out##bwl(*value, port);				\
> @@ -317,7 +303,7 @@ static inline void outs##bwl(int port, const void *addr, unsigned long count) \
>   									\
>   static inline void ins##bwl(int port, void *addr, unsigned long count)	\
>   {									\
> -	if (sev_key_active()) {						\
> +	if (cc_platform_has(CC_ATTR_GUEST_UNROLL_STRING_IO)) {		\
>   		unsigned type *value = (unsigned type *)addr;		\
>   		while (count) {						\
>   			*value = in##bwl(port);				\
> diff --git a/arch/x86/kernel/cc_platform.c b/arch/x86/kernel/cc_platform.c
> index 03bb2f343ddb..cc1ffe710dd2 100644
> --- a/arch/x86/kernel/cc_platform.c
> +++ b/arch/x86/kernel/cc_platform.c
> @@ -50,6 +50,10 @@ static bool amd_cc_platform_has(enum cc_attr attr)
>   	case CC_ATTR_GUEST_STATE_ENCRYPT:
>   		return sev_status & MSR_AMD64_SEV_ES_ENABLED;
>   
> +	case CC_ATTR_GUEST_UNROLL_STRING_IO:
> +		return (sev_status & MSR_AMD64_SEV_ENABLED) &&
> +			!(sev_status & MSR_AMD64_SEV_ES_ENABLED);
> +
>   	default:
>   		return false;
>   	}
> diff --git a/arch/x86/mm/mem_encrypt.c b/arch/x86/mm/mem_encrypt.c
> index 35487305d8af..b520021a7e7b 100644
> --- a/arch/x86/mm/mem_encrypt.c
> +++ b/arch/x86/mm/mem_encrypt.c
> @@ -43,8 +43,6 @@ u64 sme_me_mask __section(".data") = 0;
>   u64 sev_status __section(".data") = 0;
>   u64 sev_check_data __section(".data") = 0;
>   EXPORT_SYMBOL(sme_me_mask);
> -DEFINE_STATIC_KEY_FALSE(sev_enable_key);
> -EXPORT_SYMBOL_GPL(sev_enable_key);
>   
>   /* Buffer used for early in-place encryption by BSP, no locking needed */
>   static char sme_early_buffer[PAGE_SIZE] __initdata __aligned(PAGE_SIZE);
> @@ -499,14 +497,6 @@ void __init mem_encrypt_init(void)
>   	/* Call into SWIOTLB to update the SWIOTLB DMA buffers */
>   	swiotlb_update_mem_attributes();
>   
> -	/*
> -	 * With SEV, we need to unroll the rep string I/O instructions,
> -	 * but SEV-ES supports them through the #VC handler.
> -	 */

I missed this earlier, but can this comment be included with the newly 
added case statement in cc_platform.c?

Thanks,
Tom

> -	if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT) &&
> -	    !cc_platform_has(CC_ATTR_GUEST_STATE_ENCRYPT))
> -		static_branch_enable(&sev_enable_key);
> -
>   	print_mem_encrypt_feature_info();
>   }
>   
> diff --git a/include/linux/cc_platform.h b/include/linux/cc_platform.h
> index a075b70b9a70..f47f0c9edb3b 100644
> --- a/include/linux/cc_platform.h
> +++ b/include/linux/cc_platform.h
> @@ -61,6 +61,17 @@ enum cc_attr {
>   	 * Examples include SEV-ES.
>   	 */
>   	CC_ATTR_GUEST_STATE_ENCRYPT,
> +
> +	/**
> +	 * @CC_ATTR_GUEST_UNROLL_STRING_IO: String I/O is implemented with
> +	 *                                  IN/OUT instructions
> +	 *
> +	 * The platform/OS is running as a guest/virtual machine and uses
> +	 * IN/OUT instructions in place of string I/O.
> +	 *
> +	 * Examples include TDX Guest & SEV.
> +	 */
> +	CC_ATTR_GUEST_UNROLL_STRING_IO,
>   };
>   
>   #ifdef CONFIG_ARCH_HAS_CC_PLATFORM
> 

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ