From mboxrd@z Thu Jan 1 00:00:00 1970 From: Brijesh Singh Subject: [Part1 PATCH v4 13/17] x86/io: Unroll string I/O when SEV is active Date: Sat, 16 Sep 2017 07:34:14 -0500 Message-ID: <20170916123418.37807-14-brijesh.singh@amd.com> References: <20170916123418.37807-1-brijesh.singh@amd.com> Mime-Version: 1.0 Content-Type: text/plain Cc: Thomas Gleixner , Ingo Molnar , "H . Peter Anvin" , Borislav Petkov , Andy Lutomirski , Tom Lendacky , Andy Shevchenko , David Laight , Arnd Bergmann , Brijesh Singh To: linux-kernel@vger.kernel.org, x86@kernel.org, kvm@vger.kernel.org Return-path: In-Reply-To: <20170916123418.37807-1-brijesh.singh@amd.com> Sender: linux-kernel-owner@vger.kernel.org List-Id: kvm.vger.kernel.org From: Tom Lendacky 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. Cc: Thomas Gleixner Cc: Ingo Molnar Cc: "H. Peter Anvin" Cc: Borislav Petkov Cc: Andy Shevchenko Cc: David Laight Cc: Arnd Bergmann Cc: x86@kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Tom Lendacky Signed-off-by: Brijesh Singh --- arch/x86/include/asm/io.h | 42 ++++++++++++++++++++++++++++++++++++++---- arch/x86/mm/mem_encrypt.c | 8 ++++++++ 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h index c40a95c33bb8..07c28ee398d9 100644 --- a/arch/x86/include/asm/io.h +++ b/arch/x86/include/asm/io.h @@ -265,6 +265,20 @@ static inline void slow_down_io(void) #endif +#ifdef CONFIG_AMD_MEM_ENCRYPT + +extern struct static_key_false __sev; +static inline bool __sev_active(void) +{ + return static_branch_unlikely(&__sev); +} + +#else /* !CONFIG_AMD_MEM_ENCRYPT */ + +static inline bool __sev_active(void) { return false; } + +#endif /* CONFIG_AMD_MEM_ENCRYPT */ + #define BUILDIO(bwl, bw, type) \ static inline void out##bwl(unsigned type value, int port) \ { \ @@ -295,14 +309,34 @@ static inline unsigned type in##bwl##_p(int port) \ \ static inline void outs##bwl(int port, const void *addr, unsigned long count) \ { \ - asm volatile("rep; outs" #bwl \ - : "+S"(addr), "+c"(count) : "d"(port) : "memory"); \ + if (__sev_active()) { \ + unsigned type *value = (unsigned type *)addr; \ + while (count) { \ + out##bwl(*value, port); \ + value++; \ + count--; \ + } \ + } else { \ + asm volatile("rep; outs" #bwl \ + : "+S"(addr), "+c"(count) \ + : "d"(port) : "memory"); \ + } \ } \ \ static inline void ins##bwl(int port, void *addr, unsigned long count) \ { \ - asm volatile("rep; ins" #bwl \ - : "+D"(addr), "+c"(count) : "d"(port) : "memory"); \ + if (__sev_active()) { \ + unsigned type *value = (unsigned type *)addr; \ + while (count) { \ + *value = in##bwl(port); \ + value++; \ + count--; \ + } \ + } else { \ + asm volatile("rep; ins" #bwl \ + : "+D"(addr), "+c"(count) \ + : "d"(port) : "memory"); \ + } \ } BUILDIO(b, b, char) diff --git a/arch/x86/mm/mem_encrypt.c b/arch/x86/mm/mem_encrypt.c index 9b0c921c0597..b361fabde4c8 100644 --- a/arch/x86/mm/mem_encrypt.c +++ b/arch/x86/mm/mem_encrypt.c @@ -39,6 +39,8 @@ static char sme_cmdline_off[] __initdata = "off"; */ u64 sme_me_mask __section(.data) = 0; EXPORT_SYMBOL_GPL(sme_me_mask); +DEFINE_STATIC_KEY_FALSE(__sev); +EXPORT_SYMBOL_GPL(__sev); unsigned int sev_enabled __section(.data) = 0; @@ -311,6 +313,12 @@ void __init mem_encrypt_init(void) if (sev_active()) dma_ops = &sev_dma_ops; + /* + * With SEV, we need to unroll the rep string I/O instructions. + */ + if (sev_active()) + static_branch_enable(&__sev); + pr_info("AMD %s active\n", sev_active() ? "Secure Encrypted Virtualization (SEV)" : "Secure Memory Encryption (SME)"); -- 2.9.5