Same as EPT page table, We initialized the SPPT,
and write the SPPT point into VMCS field.

Signed-off-by: Zhang Yi <yi.z.zh...@linux.intel.com>
---
 arch/x86/include/asm/vmx.h |  2 ++
 arch/x86/kvm/vmx.c         | 17 +++++++++++++++++
 2 files changed, 19 insertions(+)

diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h
index 2aa088f..bd4ec8a 100644
--- a/arch/x86/include/asm/vmx.h
+++ b/arch/x86/include/asm/vmx.h
@@ -217,6 +217,8 @@ enum vmcs_field {
        XSS_EXIT_BITMAP_HIGH            = 0x0000202D,
        ENCLS_EXITING_BITMAP            = 0x0000202E,
        ENCLS_EXITING_BITMAP_HIGH       = 0x0000202F,
+       SPPT_POINTER                    = 0x00002030,
+       SPPT_POINTER_HIGH               = 0x00002031,
        TSC_MULTIPLIER                  = 0x00002032,
        TSC_MULTIPLIER_HIGH             = 0x00002033,
        GUEST_PHYSICAL_ADDRESS          = 0x00002400,
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index f76d3fb..e96b4c7 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -600,6 +600,7 @@ struct __packed vmcs12 {
        u16 host_gs_selector;
        u16 host_tr_selector;
        u16 guest_pml_index;
+       u64 sppt_pointer;
 };
 
 /*
@@ -1158,6 +1159,7 @@ static const unsigned short vmcs_field_to_offset_table[] 
= {
        FIELD64(VMREAD_BITMAP, vmread_bitmap),
        FIELD64(VMWRITE_BITMAP, vmwrite_bitmap),
        FIELD64(XSS_EXIT_BITMAP, xss_exit_bitmap),
+       FIELD64(SPPT_POINTER, sppt_pointer),
        FIELD64(GUEST_PHYSICAL_ADDRESS, guest_physical_address),
        FIELD64(VMCS_LINK_POINTER, vmcs_link_pointer),
        FIELD64(GUEST_IA32_DEBUGCTL, guest_ia32_debugctl),
@@ -5348,11 +5350,17 @@ static u64 construct_eptp(struct kvm_vcpu *vcpu, 
unsigned long root_hpa)
        return eptp;
 }
 
+static inline u64 construct_spptp(unsigned long root_hpa)
+{
+       return root_hpa & PAGE_MASK;
+}
+
 static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
 {
        struct kvm *kvm = vcpu->kvm;
        unsigned long guest_cr3;
        u64 eptp;
+       u64 spptp;
 
        guest_cr3 = cr3;
        if (enable_ept) {
@@ -5375,6 +5383,13 @@ static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned 
long cr3)
                ept_load_pdptrs(vcpu);
        }
 
+       if (vcpu->arch.mmu->sppt_root != INVALID_PAGE &&
+           enable_ept_spp) {
+               spptp = construct_spptp(vcpu->arch.mmu->sppt_root);
+               vmcs_write64(SPPT_POINTER, spptp);
+               vmx_flush_tlb(vcpu, true);
+       }
+
        vmcs_writel(GUEST_CR3, guest_cr3);
 }
 
@@ -10505,6 +10520,8 @@ static void dump_vmcs(void)
                pr_err("PostedIntrVec = 0x%02x\n", vmcs_read16(POSTED_INTR_NV));
        if ((secondary_exec_control & SECONDARY_EXEC_ENABLE_EPT))
                pr_err("EPT pointer = 0x%016llx\n", vmcs_read64(EPT_POINTER));
+       if ((secondary_exec_control & SECONDARY_EXEC_ENABLE_SPP))
+               pr_err("SPPT pointer = 0x%016llx\n", vmcs_read64(SPPT_POINTER));
        n = vmcs_read32(CR3_TARGET_COUNT);
        for (i = 0; i + 1 < n; i += 4)
                pr_err("CR3 target%u=%016lx target%u=%016lx\n",
-- 
2.7.4

Reply via email to