@@ -7,6 +7,15 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
+#include <linux/printk.h>
+#include <asm/asi.h>
+#include <asm/vmx.h>
+
+#include "vmx.h"
+#include "x86.h"
+
+#define VMX_ASI_MAP_FLAGS \
+ (ASI_MAP_STACK_CANARY | ASI_MAP_CPU_PTR | ASI_MAP_CURRENT_TASK)
/*
* When set to true, KVM #VMExit handlers run in isolated address space
@@ -24,3 +33,52 @@
*/
static bool __read_mostly address_space_isolation;
module_param(address_space_isolation, bool, 0444);
+
+static int vmx_isolation_init_mapping(struct asi *asi, struct vcpu_vmx *vmx)
+{
+ /* TODO: Populate the KVM ASI page-table */
+
+ return 0;
+}
+
+int vmx_isolation_init(struct vcpu_vmx *vmx)
+{
+ struct kvm_vcpu *vcpu = &vmx->vcpu;
+ struct asi *asi;
+ int err;
+
+ if (!address_space_isolation) {
+ vcpu->asi = NULL;
+ return 0;
+ }
+
+ asi = asi_create(VMX_ASI_MAP_FLAGS);
+ if (!asi) {
+ pr_debug("KVM: x86: Failed to create address space isolation\n");
+ return -ENXIO;
+ }
+
+ err = vmx_isolation_init_mapping(asi, vmx);
+ if (err) {
+ vcpu->asi = NULL;
+ return err;
+ }
+
+ vcpu->asi = asi;
+
+ pr_info("KVM: x86: Running with isolated address space\n");
+
+ return 0;
+}
+
+void vmx_isolation_uninit(struct vcpu_vmx *vmx)
+{
+ struct kvm_vcpu *vcpu = &vmx->vcpu;
+
+ if (!address_space_isolation || !vcpu->asi)
+ return;
+
+ asi_destroy(vcpu->asi);
+ vcpu->asi = NULL;
+ pr_info("KVM: x86: End of isolated address space\n");
+}
@@ -202,7 +202,7 @@
};
#define L1D_CACHE_ORDER 4
-static void *vmx_l1d_flush_pages;
+void *vmx_l1d_flush_pages;
static int vmx_setup_l1d_flush(enum vmx_l1d_flush_state l1tf)
{
@@ -6561,6 +6561,7 @@ static void vmx_free_vcpu(struct kvm_vcpu *vcpu)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
+ vmx_isolation_uninit(vmx);
if (enable_pml)
vmx_destroy_pml_buffer(vmx);
free_vpid(vmx->vpid);
@@ -6672,6 +6673,10 @@ static void vmx_free_vcpu(struct kvm_vcpu *vcpu)
vmx->ept_pointer = INVALID_PAGE;
+ err = vmx_isolation_init(vmx);
+ if (err)
+ goto free_vmcs;
+
return &vmx->vcpu;
free_vmcs:
@@ -525,4 +525,7 @@ static inline void decache_tsc_multiplier(struct vcpu_vmx *vmx)
void dump_vmcs(void);
+int vmx_isolation_init(struct vcpu_vmx *vmx);
+void vmx_isolation_uninit(struct vcpu_vmx *vmx);
+
#endif /* __KVM_X86_VMX_H */
@@ -34,6 +34,7 @@
#include <linux/kvm_types.h>
#include <asm/kvm_host.h>
+#include <asm/asi.h>
#ifndef KVM_MAX_VCPU_ID
#define KVM_MAX_VCPU_ID KVM_MAX_VCPUS
@@ -320,6 +321,10 @@ struct kvm_vcpu {
bool preempted;
struct kvm_vcpu_arch arch;
struct dentry *debugfs_dentry;
+
+#ifdef CONFIG_ADDRESS_SPACE_ISOLATION
+ struct asi *asi;
+#endif
};
static inline int kvm_vcpu_exiting_guest_mode(struct kvm_vcpu *vcpu)