All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] KVM: nVMX: Sync L2 guest CET states between L1/L2
@ 2021-02-09  8:37 Yang Weijiang
  2021-02-09 10:53   ` kernel test robot
  2021-02-11 17:18 ` Sean Christopherson
  0 siblings, 2 replies; 5+ messages in thread
From: Yang Weijiang @ 2021-02-09  8:37 UTC (permalink / raw)
  To: pbonzini, seanjc, kvm, linux-kernel; +Cc: Yang Weijiang

When L2 guest status has been changed by L1 QEMU/KVM, sync the change back
to L2 guest before the later's next vm-entry. On the other hand, if it's
changed due to L2 guest, sync it back so as to let L1 guest see the change.

Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
---
 arch/x86/kvm/vmx/nested.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
index 9728efd529a1..b9d8db8facea 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -2602,6 +2602,12 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
 	/* Note: may modify VM_ENTRY/EXIT_CONTROLS and GUEST/HOST_IA32_EFER */
 	vmx_set_efer(vcpu, vcpu->arch.efer);
 
+	if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_CET_STATE) {
+		vmcs_writel(GUEST_SSP, vmcs12->guest_ssp);
+		vmcs_writel(GUEST_INTR_SSP_TABLE, vmcs12->guest_ssp_tbl);
+		vmcs_writel(GUEST_S_CET, vmcs12->guest_s_cet);
+	}
+
 	/*
 	 * Guest state is invalid and unrestricted guest is disabled,
 	 * which means L1 attempted VMEntry to L2 with invalid state.
@@ -4152,6 +4158,12 @@ static void sync_vmcs02_to_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
 
 	if (vmcs12->vm_exit_controls & VM_EXIT_SAVE_IA32_EFER)
 		vmcs12->guest_ia32_efer = vcpu->arch.efer;
+
+	if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_CET_STATE) {
+		vmcs12->guest_ssp = vmcs_readl(GUEST_SSP);
+		vmcs12->guest_ssp_tbl = vmcs_readl(GUEST_INTR_SSP_TABLE);
+		vmcs12->guest_s_cet = vmcs_readl(GUEST_S_CET);
+	}
 }
 
 /*
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] KVM: nVMX: Sync L2 guest CET states between L1/L2
  2021-02-09  8:37 [PATCH] KVM: nVMX: Sync L2 guest CET states between L1/L2 Yang Weijiang
@ 2021-02-09 10:53   ` kernel test robot
  2021-02-11 17:18 ` Sean Christopherson
  1 sibling, 0 replies; 5+ messages in thread
From: kernel test robot @ 2021-02-09 10:53 UTC (permalink / raw)
  To: Yang Weijiang, pbonzini, seanjc, kvm, linux-kernel
  Cc: kbuild-all, Yang Weijiang

[-- Attachment #1: Type: text/plain, Size: 11714 bytes --]

Hi Yang,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on kvm/linux-next]
[also build test ERROR on v5.11-rc6 next-20210125]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Yang-Weijiang/KVM-nVMX-Sync-L2-guest-CET-states-between-L1-L2/20210209-162909
base:   https://git.kernel.org/pub/scm/virt/kvm/kvm.git linux-next
config: x86_64-rhel (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
reproduce (this is a W=1 build):
        # https://github.com/0day-ci/linux/commit/892519e752407d6c2c5fd732108f397291d3eb97
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Yang-Weijiang/KVM-nVMX-Sync-L2-guest-CET-states-between-L1-L2/20210209-162909
        git checkout 892519e752407d6c2c5fd732108f397291d3eb97
        # save the attached .config to linux build tree
        make W=1 ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   arch/x86/kvm/vmx/nested.c: In function 'prepare_vmcs02':
>> arch/x86/kvm/vmx/nested.c:2575:34: error: 'VM_ENTRY_LOAD_CET_STATE' undeclared (first use in this function); did you mean 'VM_ENTRY_LOAD_IA32_PAT'?
    2575 |  if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_CET_STATE) {
         |                                  ^~~~~~~~~~~~~~~~~~~~~~~
         |                                  VM_ENTRY_LOAD_IA32_PAT
   arch/x86/kvm/vmx/nested.c:2575:34: note: each undeclared identifier is reported only once for each function it appears in
>> arch/x86/kvm/vmx/nested.c:2576:15: error: 'GUEST_SSP' undeclared (first use in this function); did you mean 'GUEST_RSP'?
    2576 |   vmcs_writel(GUEST_SSP, vmcs12->guest_ssp);
         |               ^~~~~~~~~
         |               GUEST_RSP
>> arch/x86/kvm/vmx/nested.c:2576:34: error: 'struct vmcs12' has no member named 'guest_ssp'; did you mean 'guest_rsp'?
    2576 |   vmcs_writel(GUEST_SSP, vmcs12->guest_ssp);
         |                                  ^~~~~~~~~
         |                                  guest_rsp
>> arch/x86/kvm/vmx/nested.c:2577:15: error: 'GUEST_INTR_SSP_TABLE' undeclared (first use in this function); did you mean 'GUEST_INTR_STATUS'?
    2577 |   vmcs_writel(GUEST_INTR_SSP_TABLE, vmcs12->guest_ssp_tbl);
         |               ^~~~~~~~~~~~~~~~~~~~
         |               GUEST_INTR_STATUS
>> arch/x86/kvm/vmx/nested.c:2577:43: error: 'struct vmcs12' has no member named 'guest_ssp_tbl'
    2577 |   vmcs_writel(GUEST_INTR_SSP_TABLE, vmcs12->guest_ssp_tbl);
         |                                           ^~
>> arch/x86/kvm/vmx/nested.c:2578:15: error: 'GUEST_S_CET' undeclared (first use in this function); did you mean 'GUEST_CR4'?
    2578 |   vmcs_writel(GUEST_S_CET, vmcs12->guest_s_cet);
         |               ^~~~~~~~~~~
         |               GUEST_CR4
>> arch/x86/kvm/vmx/nested.c:2578:36: error: 'struct vmcs12' has no member named 'guest_s_cet'; did you mean 'guest_cr0'?
    2578 |   vmcs_writel(GUEST_S_CET, vmcs12->guest_s_cet);
         |                                    ^~~~~~~~~~~
         |                                    guest_cr0
   arch/x86/kvm/vmx/nested.c: In function 'sync_vmcs02_to_vmcs12':
   arch/x86/kvm/vmx/nested.c:4113:34: error: 'VM_ENTRY_LOAD_CET_STATE' undeclared (first use in this function); did you mean 'VM_ENTRY_LOAD_IA32_PAT'?
    4113 |  if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_CET_STATE) {
         |                                  ^~~~~~~~~~~~~~~~~~~~~~~
         |                                  VM_ENTRY_LOAD_IA32_PAT
   arch/x86/kvm/vmx/nested.c:4114:11: error: 'struct vmcs12' has no member named 'guest_ssp'; did you mean 'guest_rsp'?
    4114 |   vmcs12->guest_ssp = vmcs_readl(GUEST_SSP);
         |           ^~~~~~~~~
         |           guest_rsp
   arch/x86/kvm/vmx/nested.c:4114:34: error: 'GUEST_SSP' undeclared (first use in this function); did you mean 'GUEST_RSP'?
    4114 |   vmcs12->guest_ssp = vmcs_readl(GUEST_SSP);
         |                                  ^~~~~~~~~
         |                                  GUEST_RSP
   arch/x86/kvm/vmx/nested.c:4115:9: error: 'struct vmcs12' has no member named 'guest_ssp_tbl'
    4115 |   vmcs12->guest_ssp_tbl = vmcs_readl(GUEST_INTR_SSP_TABLE);
         |         ^~
   arch/x86/kvm/vmx/nested.c:4115:38: error: 'GUEST_INTR_SSP_TABLE' undeclared (first use in this function); did you mean 'GUEST_INTR_STATUS'?
    4115 |   vmcs12->guest_ssp_tbl = vmcs_readl(GUEST_INTR_SSP_TABLE);
         |                                      ^~~~~~~~~~~~~~~~~~~~
         |                                      GUEST_INTR_STATUS
   arch/x86/kvm/vmx/nested.c:4116:11: error: 'struct vmcs12' has no member named 'guest_s_cet'; did you mean 'guest_cr0'?
    4116 |   vmcs12->guest_s_cet = vmcs_readl(GUEST_S_CET);
         |           ^~~~~~~~~~~
         |           guest_cr0
   arch/x86/kvm/vmx/nested.c:4116:36: error: 'GUEST_S_CET' undeclared (first use in this function); did you mean 'GUEST_CR4'?
    4116 |   vmcs12->guest_s_cet = vmcs_readl(GUEST_S_CET);
         |                                    ^~~~~~~~~~~
         |                                    GUEST_CR4


vim +2575 arch/x86/kvm/vmx/nested.c

  2490	
  2491	/*
  2492	 * prepare_vmcs02 is called when the L1 guest hypervisor runs its nested
  2493	 * L2 guest. L1 has a vmcs for L2 (vmcs12), and this function "merges" it
  2494	 * with L0's requirements for its guest (a.k.a. vmcs01), so we can run the L2
  2495	 * guest in a way that will both be appropriate to L1's requests, and our
  2496	 * needs. In addition to modifying the active vmcs (which is vmcs02), this
  2497	 * function also has additional necessary side-effects, like setting various
  2498	 * vcpu->arch fields.
  2499	 * Returns 0 on success, 1 on failure. Invalid state exit qualification code
  2500	 * is assigned to entry_failure_code on failure.
  2501	 */
  2502	static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
  2503				  enum vm_entry_failure_code *entry_failure_code)
  2504	{
  2505		struct vcpu_vmx *vmx = to_vmx(vcpu);
  2506		struct hv_enlightened_vmcs *hv_evmcs = vmx->nested.hv_evmcs;
  2507		bool load_guest_pdptrs_vmcs12 = false;
  2508	
  2509		if (vmx->nested.dirty_vmcs12 || hv_evmcs) {
  2510			prepare_vmcs02_rare(vmx, vmcs12);
  2511			vmx->nested.dirty_vmcs12 = false;
  2512	
  2513			load_guest_pdptrs_vmcs12 = !hv_evmcs ||
  2514				!(hv_evmcs->hv_clean_fields &
  2515				  HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP1);
  2516		}
  2517	
  2518		if (vmx->nested.nested_run_pending &&
  2519		    (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_DEBUG_CONTROLS)) {
  2520			kvm_set_dr(vcpu, 7, vmcs12->guest_dr7);
  2521			vmcs_write64(GUEST_IA32_DEBUGCTL, vmcs12->guest_ia32_debugctl);
  2522		} else {
  2523			kvm_set_dr(vcpu, 7, vcpu->arch.dr7);
  2524			vmcs_write64(GUEST_IA32_DEBUGCTL, vmx->nested.vmcs01_debugctl);
  2525		}
  2526		if (kvm_mpx_supported() && (!vmx->nested.nested_run_pending ||
  2527		    !(vmcs12->vm_entry_controls & VM_ENTRY_LOAD_BNDCFGS)))
  2528			vmcs_write64(GUEST_BNDCFGS, vmx->nested.vmcs01_guest_bndcfgs);
  2529		vmx_set_rflags(vcpu, vmcs12->guest_rflags);
  2530	
  2531		/* EXCEPTION_BITMAP and CR0_GUEST_HOST_MASK should basically be the
  2532		 * bitwise-or of what L1 wants to trap for L2, and what we want to
  2533		 * trap. Note that CR0.TS also needs updating - we do this later.
  2534		 */
  2535		update_exception_bitmap(vcpu);
  2536		vcpu->arch.cr0_guest_owned_bits &= ~vmcs12->cr0_guest_host_mask;
  2537		vmcs_writel(CR0_GUEST_HOST_MASK, ~vcpu->arch.cr0_guest_owned_bits);
  2538	
  2539		if (vmx->nested.nested_run_pending &&
  2540		    (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_PAT)) {
  2541			vmcs_write64(GUEST_IA32_PAT, vmcs12->guest_ia32_pat);
  2542			vcpu->arch.pat = vmcs12->guest_ia32_pat;
  2543		} else if (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PAT) {
  2544			vmcs_write64(GUEST_IA32_PAT, vmx->vcpu.arch.pat);
  2545		}
  2546	
  2547		vmcs_write64(TSC_OFFSET, vcpu->arch.tsc_offset);
  2548	
  2549		if (kvm_has_tsc_control)
  2550			decache_tsc_multiplier(vmx);
  2551	
  2552		nested_vmx_transition_tlb_flush(vcpu, vmcs12, true);
  2553	
  2554		if (nested_cpu_has_ept(vmcs12))
  2555			nested_ept_init_mmu_context(vcpu);
  2556	
  2557		/*
  2558		 * This sets GUEST_CR0 to vmcs12->guest_cr0, possibly modifying those
  2559		 * bits which we consider mandatory enabled.
  2560		 * The CR0_READ_SHADOW is what L2 should have expected to read given
  2561		 * the specifications by L1; It's not enough to take
  2562		 * vmcs12->cr0_read_shadow because on our cr0_guest_host_mask we we
  2563		 * have more bits than L1 expected.
  2564		 */
  2565		vmx_set_cr0(vcpu, vmcs12->guest_cr0);
  2566		vmcs_writel(CR0_READ_SHADOW, nested_read_cr0(vmcs12));
  2567	
  2568		vmx_set_cr4(vcpu, vmcs12->guest_cr4);
  2569		vmcs_writel(CR4_READ_SHADOW, nested_read_cr4(vmcs12));
  2570	
  2571		vcpu->arch.efer = nested_vmx_calc_efer(vmx, vmcs12);
  2572		/* Note: may modify VM_ENTRY/EXIT_CONTROLS and GUEST/HOST_IA32_EFER */
  2573		vmx_set_efer(vcpu, vcpu->arch.efer);
  2574	
> 2575		if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_CET_STATE) {
> 2576			vmcs_writel(GUEST_SSP, vmcs12->guest_ssp);
> 2577			vmcs_writel(GUEST_INTR_SSP_TABLE, vmcs12->guest_ssp_tbl);
> 2578			vmcs_writel(GUEST_S_CET, vmcs12->guest_s_cet);
  2579		}
  2580	
  2581		/*
  2582		 * Guest state is invalid and unrestricted guest is disabled,
  2583		 * which means L1 attempted VMEntry to L2 with invalid state.
  2584		 * Fail the VMEntry.
  2585		 */
  2586		if (CC(!vmx_guest_state_valid(vcpu))) {
  2587			*entry_failure_code = ENTRY_FAIL_DEFAULT;
  2588			return -EINVAL;
  2589		}
  2590	
  2591		/* Shadow page tables on either EPT or shadow page tables. */
  2592		if (nested_vmx_load_cr3(vcpu, vmcs12->guest_cr3, nested_cpu_has_ept(vmcs12),
  2593					entry_failure_code))
  2594			return -EINVAL;
  2595	
  2596		/*
  2597		 * Immediately write vmcs02.GUEST_CR3.  It will be propagated to vmcs12
  2598		 * on nested VM-Exit, which can occur without actually running L2 and
  2599		 * thus without hitting vmx_load_mmu_pgd(), e.g. if L1 is entering L2 with
  2600		 * vmcs12.GUEST_ACTIVITYSTATE=HLT, in which case KVM will intercept the
  2601		 * transition to HLT instead of running L2.
  2602		 */
  2603		if (enable_ept)
  2604			vmcs_writel(GUEST_CR3, vmcs12->guest_cr3);
  2605	
  2606		/* Late preparation of GUEST_PDPTRs now that EFER and CRs are set. */
  2607		if (load_guest_pdptrs_vmcs12 && nested_cpu_has_ept(vmcs12) &&
  2608		    is_pae_paging(vcpu)) {
  2609			vmcs_write64(GUEST_PDPTR0, vmcs12->guest_pdptr0);
  2610			vmcs_write64(GUEST_PDPTR1, vmcs12->guest_pdptr1);
  2611			vmcs_write64(GUEST_PDPTR2, vmcs12->guest_pdptr2);
  2612			vmcs_write64(GUEST_PDPTR3, vmcs12->guest_pdptr3);
  2613		}
  2614	
  2615		if (!enable_ept)
  2616			vcpu->arch.walk_mmu->inject_page_fault = vmx_inject_page_fault_nested;
  2617	
  2618		if ((vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL) &&
  2619		    WARN_ON_ONCE(kvm_set_msr(vcpu, MSR_CORE_PERF_GLOBAL_CTRL,
  2620					     vmcs12->guest_ia32_perf_global_ctrl)))
  2621			return -EINVAL;
  2622	
  2623		kvm_rsp_write(vcpu, vmcs12->guest_rsp);
  2624		kvm_rip_write(vcpu, vmcs12->guest_rip);
  2625		return 0;
  2626	}
  2627	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 45659 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] KVM: nVMX: Sync L2 guest CET states between L1/L2
@ 2021-02-09 10:53   ` kernel test robot
  0 siblings, 0 replies; 5+ messages in thread
From: kernel test robot @ 2021-02-09 10:53 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 11946 bytes --]

Hi Yang,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on kvm/linux-next]
[also build test ERROR on v5.11-rc6 next-20210125]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Yang-Weijiang/KVM-nVMX-Sync-L2-guest-CET-states-between-L1-L2/20210209-162909
base:   https://git.kernel.org/pub/scm/virt/kvm/kvm.git linux-next
config: x86_64-rhel (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
reproduce (this is a W=1 build):
        # https://github.com/0day-ci/linux/commit/892519e752407d6c2c5fd732108f397291d3eb97
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Yang-Weijiang/KVM-nVMX-Sync-L2-guest-CET-states-between-L1-L2/20210209-162909
        git checkout 892519e752407d6c2c5fd732108f397291d3eb97
        # save the attached .config to linux build tree
        make W=1 ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   arch/x86/kvm/vmx/nested.c: In function 'prepare_vmcs02':
>> arch/x86/kvm/vmx/nested.c:2575:34: error: 'VM_ENTRY_LOAD_CET_STATE' undeclared (first use in this function); did you mean 'VM_ENTRY_LOAD_IA32_PAT'?
    2575 |  if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_CET_STATE) {
         |                                  ^~~~~~~~~~~~~~~~~~~~~~~
         |                                  VM_ENTRY_LOAD_IA32_PAT
   arch/x86/kvm/vmx/nested.c:2575:34: note: each undeclared identifier is reported only once for each function it appears in
>> arch/x86/kvm/vmx/nested.c:2576:15: error: 'GUEST_SSP' undeclared (first use in this function); did you mean 'GUEST_RSP'?
    2576 |   vmcs_writel(GUEST_SSP, vmcs12->guest_ssp);
         |               ^~~~~~~~~
         |               GUEST_RSP
>> arch/x86/kvm/vmx/nested.c:2576:34: error: 'struct vmcs12' has no member named 'guest_ssp'; did you mean 'guest_rsp'?
    2576 |   vmcs_writel(GUEST_SSP, vmcs12->guest_ssp);
         |                                  ^~~~~~~~~
         |                                  guest_rsp
>> arch/x86/kvm/vmx/nested.c:2577:15: error: 'GUEST_INTR_SSP_TABLE' undeclared (first use in this function); did you mean 'GUEST_INTR_STATUS'?
    2577 |   vmcs_writel(GUEST_INTR_SSP_TABLE, vmcs12->guest_ssp_tbl);
         |               ^~~~~~~~~~~~~~~~~~~~
         |               GUEST_INTR_STATUS
>> arch/x86/kvm/vmx/nested.c:2577:43: error: 'struct vmcs12' has no member named 'guest_ssp_tbl'
    2577 |   vmcs_writel(GUEST_INTR_SSP_TABLE, vmcs12->guest_ssp_tbl);
         |                                           ^~
>> arch/x86/kvm/vmx/nested.c:2578:15: error: 'GUEST_S_CET' undeclared (first use in this function); did you mean 'GUEST_CR4'?
    2578 |   vmcs_writel(GUEST_S_CET, vmcs12->guest_s_cet);
         |               ^~~~~~~~~~~
         |               GUEST_CR4
>> arch/x86/kvm/vmx/nested.c:2578:36: error: 'struct vmcs12' has no member named 'guest_s_cet'; did you mean 'guest_cr0'?
    2578 |   vmcs_writel(GUEST_S_CET, vmcs12->guest_s_cet);
         |                                    ^~~~~~~~~~~
         |                                    guest_cr0
   arch/x86/kvm/vmx/nested.c: In function 'sync_vmcs02_to_vmcs12':
   arch/x86/kvm/vmx/nested.c:4113:34: error: 'VM_ENTRY_LOAD_CET_STATE' undeclared (first use in this function); did you mean 'VM_ENTRY_LOAD_IA32_PAT'?
    4113 |  if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_CET_STATE) {
         |                                  ^~~~~~~~~~~~~~~~~~~~~~~
         |                                  VM_ENTRY_LOAD_IA32_PAT
   arch/x86/kvm/vmx/nested.c:4114:11: error: 'struct vmcs12' has no member named 'guest_ssp'; did you mean 'guest_rsp'?
    4114 |   vmcs12->guest_ssp = vmcs_readl(GUEST_SSP);
         |           ^~~~~~~~~
         |           guest_rsp
   arch/x86/kvm/vmx/nested.c:4114:34: error: 'GUEST_SSP' undeclared (first use in this function); did you mean 'GUEST_RSP'?
    4114 |   vmcs12->guest_ssp = vmcs_readl(GUEST_SSP);
         |                                  ^~~~~~~~~
         |                                  GUEST_RSP
   arch/x86/kvm/vmx/nested.c:4115:9: error: 'struct vmcs12' has no member named 'guest_ssp_tbl'
    4115 |   vmcs12->guest_ssp_tbl = vmcs_readl(GUEST_INTR_SSP_TABLE);
         |         ^~
   arch/x86/kvm/vmx/nested.c:4115:38: error: 'GUEST_INTR_SSP_TABLE' undeclared (first use in this function); did you mean 'GUEST_INTR_STATUS'?
    4115 |   vmcs12->guest_ssp_tbl = vmcs_readl(GUEST_INTR_SSP_TABLE);
         |                                      ^~~~~~~~~~~~~~~~~~~~
         |                                      GUEST_INTR_STATUS
   arch/x86/kvm/vmx/nested.c:4116:11: error: 'struct vmcs12' has no member named 'guest_s_cet'; did you mean 'guest_cr0'?
    4116 |   vmcs12->guest_s_cet = vmcs_readl(GUEST_S_CET);
         |           ^~~~~~~~~~~
         |           guest_cr0
   arch/x86/kvm/vmx/nested.c:4116:36: error: 'GUEST_S_CET' undeclared (first use in this function); did you mean 'GUEST_CR4'?
    4116 |   vmcs12->guest_s_cet = vmcs_readl(GUEST_S_CET);
         |                                    ^~~~~~~~~~~
         |                                    GUEST_CR4


vim +2575 arch/x86/kvm/vmx/nested.c

  2490	
  2491	/*
  2492	 * prepare_vmcs02 is called when the L1 guest hypervisor runs its nested
  2493	 * L2 guest. L1 has a vmcs for L2 (vmcs12), and this function "merges" it
  2494	 * with L0's requirements for its guest (a.k.a. vmcs01), so we can run the L2
  2495	 * guest in a way that will both be appropriate to L1's requests, and our
  2496	 * needs. In addition to modifying the active vmcs (which is vmcs02), this
  2497	 * function also has additional necessary side-effects, like setting various
  2498	 * vcpu->arch fields.
  2499	 * Returns 0 on success, 1 on failure. Invalid state exit qualification code
  2500	 * is assigned to entry_failure_code on failure.
  2501	 */
  2502	static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
  2503				  enum vm_entry_failure_code *entry_failure_code)
  2504	{
  2505		struct vcpu_vmx *vmx = to_vmx(vcpu);
  2506		struct hv_enlightened_vmcs *hv_evmcs = vmx->nested.hv_evmcs;
  2507		bool load_guest_pdptrs_vmcs12 = false;
  2508	
  2509		if (vmx->nested.dirty_vmcs12 || hv_evmcs) {
  2510			prepare_vmcs02_rare(vmx, vmcs12);
  2511			vmx->nested.dirty_vmcs12 = false;
  2512	
  2513			load_guest_pdptrs_vmcs12 = !hv_evmcs ||
  2514				!(hv_evmcs->hv_clean_fields &
  2515				  HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP1);
  2516		}
  2517	
  2518		if (vmx->nested.nested_run_pending &&
  2519		    (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_DEBUG_CONTROLS)) {
  2520			kvm_set_dr(vcpu, 7, vmcs12->guest_dr7);
  2521			vmcs_write64(GUEST_IA32_DEBUGCTL, vmcs12->guest_ia32_debugctl);
  2522		} else {
  2523			kvm_set_dr(vcpu, 7, vcpu->arch.dr7);
  2524			vmcs_write64(GUEST_IA32_DEBUGCTL, vmx->nested.vmcs01_debugctl);
  2525		}
  2526		if (kvm_mpx_supported() && (!vmx->nested.nested_run_pending ||
  2527		    !(vmcs12->vm_entry_controls & VM_ENTRY_LOAD_BNDCFGS)))
  2528			vmcs_write64(GUEST_BNDCFGS, vmx->nested.vmcs01_guest_bndcfgs);
  2529		vmx_set_rflags(vcpu, vmcs12->guest_rflags);
  2530	
  2531		/* EXCEPTION_BITMAP and CR0_GUEST_HOST_MASK should basically be the
  2532		 * bitwise-or of what L1 wants to trap for L2, and what we want to
  2533		 * trap. Note that CR0.TS also needs updating - we do this later.
  2534		 */
  2535		update_exception_bitmap(vcpu);
  2536		vcpu->arch.cr0_guest_owned_bits &= ~vmcs12->cr0_guest_host_mask;
  2537		vmcs_writel(CR0_GUEST_HOST_MASK, ~vcpu->arch.cr0_guest_owned_bits);
  2538	
  2539		if (vmx->nested.nested_run_pending &&
  2540		    (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_PAT)) {
  2541			vmcs_write64(GUEST_IA32_PAT, vmcs12->guest_ia32_pat);
  2542			vcpu->arch.pat = vmcs12->guest_ia32_pat;
  2543		} else if (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PAT) {
  2544			vmcs_write64(GUEST_IA32_PAT, vmx->vcpu.arch.pat);
  2545		}
  2546	
  2547		vmcs_write64(TSC_OFFSET, vcpu->arch.tsc_offset);
  2548	
  2549		if (kvm_has_tsc_control)
  2550			decache_tsc_multiplier(vmx);
  2551	
  2552		nested_vmx_transition_tlb_flush(vcpu, vmcs12, true);
  2553	
  2554		if (nested_cpu_has_ept(vmcs12))
  2555			nested_ept_init_mmu_context(vcpu);
  2556	
  2557		/*
  2558		 * This sets GUEST_CR0 to vmcs12->guest_cr0, possibly modifying those
  2559		 * bits which we consider mandatory enabled.
  2560		 * The CR0_READ_SHADOW is what L2 should have expected to read given
  2561		 * the specifications by L1; It's not enough to take
  2562		 * vmcs12->cr0_read_shadow because on our cr0_guest_host_mask we we
  2563		 * have more bits than L1 expected.
  2564		 */
  2565		vmx_set_cr0(vcpu, vmcs12->guest_cr0);
  2566		vmcs_writel(CR0_READ_SHADOW, nested_read_cr0(vmcs12));
  2567	
  2568		vmx_set_cr4(vcpu, vmcs12->guest_cr4);
  2569		vmcs_writel(CR4_READ_SHADOW, nested_read_cr4(vmcs12));
  2570	
  2571		vcpu->arch.efer = nested_vmx_calc_efer(vmx, vmcs12);
  2572		/* Note: may modify VM_ENTRY/EXIT_CONTROLS and GUEST/HOST_IA32_EFER */
  2573		vmx_set_efer(vcpu, vcpu->arch.efer);
  2574	
> 2575		if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_CET_STATE) {
> 2576			vmcs_writel(GUEST_SSP, vmcs12->guest_ssp);
> 2577			vmcs_writel(GUEST_INTR_SSP_TABLE, vmcs12->guest_ssp_tbl);
> 2578			vmcs_writel(GUEST_S_CET, vmcs12->guest_s_cet);
  2579		}
  2580	
  2581		/*
  2582		 * Guest state is invalid and unrestricted guest is disabled,
  2583		 * which means L1 attempted VMEntry to L2 with invalid state.
  2584		 * Fail the VMEntry.
  2585		 */
  2586		if (CC(!vmx_guest_state_valid(vcpu))) {
  2587			*entry_failure_code = ENTRY_FAIL_DEFAULT;
  2588			return -EINVAL;
  2589		}
  2590	
  2591		/* Shadow page tables on either EPT or shadow page tables. */
  2592		if (nested_vmx_load_cr3(vcpu, vmcs12->guest_cr3, nested_cpu_has_ept(vmcs12),
  2593					entry_failure_code))
  2594			return -EINVAL;
  2595	
  2596		/*
  2597		 * Immediately write vmcs02.GUEST_CR3.  It will be propagated to vmcs12
  2598		 * on nested VM-Exit, which can occur without actually running L2 and
  2599		 * thus without hitting vmx_load_mmu_pgd(), e.g. if L1 is entering L2 with
  2600		 * vmcs12.GUEST_ACTIVITYSTATE=HLT, in which case KVM will intercept the
  2601		 * transition to HLT instead of running L2.
  2602		 */
  2603		if (enable_ept)
  2604			vmcs_writel(GUEST_CR3, vmcs12->guest_cr3);
  2605	
  2606		/* Late preparation of GUEST_PDPTRs now that EFER and CRs are set. */
  2607		if (load_guest_pdptrs_vmcs12 && nested_cpu_has_ept(vmcs12) &&
  2608		    is_pae_paging(vcpu)) {
  2609			vmcs_write64(GUEST_PDPTR0, vmcs12->guest_pdptr0);
  2610			vmcs_write64(GUEST_PDPTR1, vmcs12->guest_pdptr1);
  2611			vmcs_write64(GUEST_PDPTR2, vmcs12->guest_pdptr2);
  2612			vmcs_write64(GUEST_PDPTR3, vmcs12->guest_pdptr3);
  2613		}
  2614	
  2615		if (!enable_ept)
  2616			vcpu->arch.walk_mmu->inject_page_fault = vmx_inject_page_fault_nested;
  2617	
  2618		if ((vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL) &&
  2619		    WARN_ON_ONCE(kvm_set_msr(vcpu, MSR_CORE_PERF_GLOBAL_CTRL,
  2620					     vmcs12->guest_ia32_perf_global_ctrl)))
  2621			return -EINVAL;
  2622	
  2623		kvm_rsp_write(vcpu, vmcs12->guest_rsp);
  2624		kvm_rip_write(vcpu, vmcs12->guest_rip);
  2625		return 0;
  2626	}
  2627	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 45659 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] KVM: nVMX: Sync L2 guest CET states between L1/L2
  2021-02-09  8:37 [PATCH] KVM: nVMX: Sync L2 guest CET states between L1/L2 Yang Weijiang
  2021-02-09 10:53   ` kernel test robot
@ 2021-02-11 17:18 ` Sean Christopherson
  2021-02-13  2:03   ` Yang Weijiang
  1 sibling, 1 reply; 5+ messages in thread
From: Sean Christopherson @ 2021-02-11 17:18 UTC (permalink / raw)
  To: Yang Weijiang; +Cc: pbonzini, kvm, linux-kernel

On Tue, Feb 09, 2021, Yang Weijiang wrote:
> When L2 guest status has been changed by L1 QEMU/KVM, sync the change back
> to L2 guest before the later's next vm-entry. On the other hand, if it's
> changed due to L2 guest, sync it back so as to let L1 guest see the change.
> 
> Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
> ---
>  arch/x86/kvm/vmx/nested.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
> index 9728efd529a1..b9d8db8facea 100644
> --- a/arch/x86/kvm/vmx/nested.c
> +++ b/arch/x86/kvm/vmx/nested.c
> @@ -2602,6 +2602,12 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
>  	/* Note: may modify VM_ENTRY/EXIT_CONTROLS and GUEST/HOST_IA32_EFER */
>  	vmx_set_efer(vcpu, vcpu->arch.efer);
>  
> +	if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_CET_STATE) {
> +		vmcs_writel(GUEST_SSP, vmcs12->guest_ssp);
> +		vmcs_writel(GUEST_INTR_SSP_TABLE, vmcs12->guest_ssp_tbl);
> +		vmcs_writel(GUEST_S_CET, vmcs12->guest_s_cet);
> +	}
> +

This is incomplete.  If VM_ENTRY_LOAD_CET_STATE is not set, then CET state needs
to be propagated from vmcs01 to vmcs02.  See nested.vmcs01_debugctl and
nested.vmcs01_guest_bndcfgs.

It's tempting to say that we should add machinery to simplify implementing new
fields that are conditionally loading, e.g. define an array that specifies the
field, its control, and its offset in vmcs12, then process the array at the
appropriate time.  That might be overkill though...

>  	/*
>  	 * Guest state is invalid and unrestricted guest is disabled,
>  	 * which means L1 attempted VMEntry to L2 with invalid state.
> @@ -4152,6 +4158,12 @@ static void sync_vmcs02_to_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
>  
>  	if (vmcs12->vm_exit_controls & VM_EXIT_SAVE_IA32_EFER)
>  		vmcs12->guest_ia32_efer = vcpu->arch.efer;
> +
> +	if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_CET_STATE) {

This is wrong, guest state is saved on VM-Exit if the control is _supported_,
it doesn't have to be enabled.

  If the processor supports the 1-setting of the “load CET” VM-entry control,
  the contents of the IA32_S_CET and IA32_INTERRUPT_SSP_TABLE_ADDR MSRs are
  saved into the corresponding fields. On processors that do not support Intel
  64 architecture, bits 63:32 of these MSRs are not saved.

And I'm pretty sure we should define these fields as a so called "rare" fields,
i.e. add 'em to the case statement in is_vmcs12_ext_field() and process them in
sync_vmcs02_to_vmcs12_rare().  CET isn't easily emulated, so they should almost
never be read/written by a VMM, and thus aren't with synchronizing to vmcs12 on
every exit.

> +		vmcs12->guest_ssp = vmcs_readl(GUEST_SSP);
> +		vmcs12->guest_ssp_tbl = vmcs_readl(GUEST_INTR_SSP_TABLE);
> +		vmcs12->guest_s_cet = vmcs_readl(GUEST_S_CET);
> +	}
>  }
>  
>  /*
> -- 
> 2.26.2
> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] KVM: nVMX: Sync L2 guest CET states between L1/L2
  2021-02-11 17:18 ` Sean Christopherson
@ 2021-02-13  2:03   ` Yang Weijiang
  0 siblings, 0 replies; 5+ messages in thread
From: Yang Weijiang @ 2021-02-13  2:03 UTC (permalink / raw)
  To: Sean Christopherson; +Cc: Yang Weijiang, pbonzini, kvm, linux-kernel

On Thu, Feb 11, 2021 at 09:18:03AM -0800, Sean Christopherson wrote:
> On Tue, Feb 09, 2021, Yang Weijiang wrote:
> > When L2 guest status has been changed by L1 QEMU/KVM, sync the change back
> > to L2 guest before the later's next vm-entry. On the other hand, if it's
> > changed due to L2 guest, sync it back so as to let L1 guest see the change.
> > 
> > Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
> > ---
> >  arch/x86/kvm/vmx/nested.c | 12 ++++++++++++
> >  1 file changed, 12 insertions(+)
> > 
> > diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
> > index 9728efd529a1..b9d8db8facea 100644
> > --- a/arch/x86/kvm/vmx/nested.c
> > +++ b/arch/x86/kvm/vmx/nested.c
> > @@ -2602,6 +2602,12 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
> >  	/* Note: may modify VM_ENTRY/EXIT_CONTROLS and GUEST/HOST_IA32_EFER */
> >  	vmx_set_efer(vcpu, vcpu->arch.efer);
> >  
> > +	if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_CET_STATE) {
> > +		vmcs_writel(GUEST_SSP, vmcs12->guest_ssp);
> > +		vmcs_writel(GUEST_INTR_SSP_TABLE, vmcs12->guest_ssp_tbl);
> > +		vmcs_writel(GUEST_S_CET, vmcs12->guest_s_cet);
> > +	}
> > +
> 
> This is incomplete.  If VM_ENTRY_LOAD_CET_STATE is not set, then CET state needs
> to be propagated from vmcs01 to vmcs02.  See nested.vmcs01_debugctl and
> nested.vmcs01_guest_bndcfgs.
> 
> It's tempting to say that we should add machinery to simplify implementing new
> fields that are conditionally loading, e.g. define an array that specifies the
> field, its control, and its offset in vmcs12, then process the array at the
> appropriate time.  That might be overkill though...
>
Thanks Sean! I'll check the implementation of the two features.

> >  	/*
> >  	 * Guest state is invalid and unrestricted guest is disabled,
> >  	 * which means L1 attempted VMEntry to L2 with invalid state.
> > @@ -4152,6 +4158,12 @@ static void sync_vmcs02_to_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
> >  
> >  	if (vmcs12->vm_exit_controls & VM_EXIT_SAVE_IA32_EFER)
> >  		vmcs12->guest_ia32_efer = vcpu->arch.efer;
> > +
> > +	if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_CET_STATE) {
> 
> This is wrong, guest state is saved on VM-Exit if the control is _supported_,
> it doesn't have to be enabled.
> 
>   If the processor supports the 1-setting of the “load CET” VM-entry control,
>   the contents of the IA32_S_CET and IA32_INTERRUPT_SSP_TABLE_ADDR MSRs are
>   saved into the corresponding fields. On processors that do not support Intel
>   64 architecture, bits 63:32 of these MSRs are not saved.
> 
> And I'm pretty sure we should define these fields as a so called "rare" fields,
> i.e. add 'em to the case statement in is_vmcs12_ext_field() and process them in
> sync_vmcs02_to_vmcs12_rare().  CET isn't easily emulated, so they should almost
> never be read/written by a VMM, and thus aren't with synchronizing to vmcs12 on
> every exit.
Sure, will modifiy the patch accordingly.
> 
> > +		vmcs12->guest_ssp = vmcs_readl(GUEST_SSP);
> > +		vmcs12->guest_ssp_tbl = vmcs_readl(GUEST_INTR_SSP_TABLE);
> > +		vmcs12->guest_s_cet = vmcs_readl(GUEST_S_CET);
> > +	}
> >  }
> >  
> >  /*
> > -- 
> > 2.26.2
> > 

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-02-13  1:51 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-09  8:37 [PATCH] KVM: nVMX: Sync L2 guest CET states between L1/L2 Yang Weijiang
2021-02-09 10:53 ` kernel test robot
2021-02-09 10:53   ` kernel test robot
2021-02-11 17:18 ` Sean Christopherson
2021-02-13  2:03   ` Yang Weijiang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.