@@ -799,6 +799,7 @@ config KVM_GUEST
depends on PARAVIRT
select PARAVIRT_CLOCK
select ARCH_CPUIDLE_HALTPOLL
+ select X86_MEM_ENCRYPT_COMMON
default y
---help---
This option enables various optimizations for running under the KVM
@@ -10,14 +10,15 @@
#include <linux/mm.h>
#include <linux/mem_encrypt.h>
#include <linux/dma-mapping.h>
+#include <asm/kvm_para.h>
/* Override for DMA direct allocation check - ARCH_HAS_FORCE_DMA_UNENCRYPTED */
bool force_dma_unencrypted(struct device *dev)
{
/*
- * For SEV, all DMA must be to unencrypted/shared addresses.
+ * For SEV and KVM, all DMA must be to unencrypted/shared addresses.
*/
- if (sev_active())
+ if (sev_active() || kvm_mem_protected())
return true;
/*
@@ -16,6 +16,7 @@
#include <linux/pci.h>
#include <linux/vmalloc.h>
#include <linux/libnvdimm.h>
+#include <linux/kvm_para.h>
#include <asm/e820/api.h>
#include <asm/processor.h>
@@ -1972,6 +1973,12 @@ static int __set_memory_enc_dec(unsigned long addr, int numpages, bool enc)
struct cpa_data cpa;
int ret;
+ if (kvm_mem_protected()) {
+ unsigned long gfn = __pa(addr) >> PAGE_SHIFT;
+ int call = enc ? KVM_HC_MEM_UNSHARE : KVM_HC_MEM_SHARE;
+ return kvm_hypercall2(call, gfn, numpages);
+ }
+
/* Nothing to do if memory encryption is not active */
if (!mem_encrypt_active())
return 0;
@@ -30,6 +30,8 @@
#define KVM_HC_SEND_IPI 10
#define KVM_HC_SCHED_YIELD 11
#define KVM_HC_ENABLE_MEM_PROTECTED 12
+#define KVM_HC_MEM_SHARE 13
+#define KVM_HC_MEM_UNSHARE 14
/*
* hypercalls use architecture specific
Make force_dma_unencrypted() return true for KVM to get DMA pages mapped as shared. __set_memory_enc_dec() now informs the host via hypercall if the state of the page has changed from shared to private or back. Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> --- arch/x86/Kconfig | 1 + arch/x86/mm/mem_encrypt_common.c | 5 +++-- arch/x86/mm/pat/set_memory.c | 7 +++++++ include/uapi/linux/kvm_para.h | 2 ++ 4 files changed, 13 insertions(+), 2 deletions(-)