x86/io: Unroll string I/O when SEV is active
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. [ tglx: Gave the static key a real name instead of the obscure __sev ] Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Borislav Petkov <bp@suse.de> Tested-by: Borislav Petkov <bp@suse.de> Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Cc: Arnd Bergmann <arnd@arndb.de> Cc: kvm@vger.kernel.org Cc: David Laight <David.Laight@ACULAB.COM> Cc: Borislav Petkov <bp@alien8.de> Link: https://lkml.kernel.org/r/20171020143059.3291-14-brijesh.singh@amd.com
This commit is contained in:

committed by
Thomas Gleixner

parent
1958b5fc40
commit
606b21d4a6
@@ -266,6 +266,21 @@ 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) \
|
||||
{ \
|
||||
@@ -296,14 +311,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_key_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_key_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)
|
||||
|
Reference in New Issue
Block a user