]> xenbits.xensource.com Git - people/iwj/xen.git/commitdiff
x86/svm: Add virtual GIF support
authorBrian Woods <brian.woods@amd.com>
Thu, 16 Nov 2017 22:11:15 +0000 (16:11 -0600)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Fri, 1 Dec 2017 19:03:28 +0000 (19:03 +0000)
This patch detects and enables Virtual GIF if available.  This allows
a nested hypervisor to perform STGIs and CLGIs without having to be
intercepted by host hypervisor.

Signed-off-by: Brian Woods <brian.woods@amd.com>
Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
xen/arch/x86/hvm/svm/nestedsvm.c
xen/arch/x86/hvm/svm/svm.c
xen/arch/x86/hvm/svm/vmcb.c

index 5513f7a3883a7f5282d9b9efd2445d10bc3c8e19..b6f6449d756ec21d2d4f52045ffde1a9364cd43e 100644 (file)
@@ -1597,8 +1597,13 @@ bool_t
 nestedsvm_gif_isset(struct vcpu *v)
 {
     struct nestedsvm *svm = &vcpu_nestedsvm(v);
+    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
 
-    return (!!svm->ns_gif);
+    /* get the vmcb gif value if using vgif */
+    if ( vmcb->_vintr.fields.vgif_enable )
+        return vmcb->_vintr.fields.vgif;
+    else
+        return svm->ns_gif;
 }
 
 void svm_vmexit_do_stgi(struct cpu_user_regs *regs, struct vcpu *v)
index 60b1288a3125a40618d70d58ccb5104550d9733d..2e62b9bb6df8ce3b78dc15516b75e61ae304c270 100644 (file)
@@ -1670,6 +1670,7 @@ const struct hvm_function_table * __init start_svm(void)
     P(cpu_has_svm_cleanbits, "VMCB Clean Bits");
     P(cpu_has_svm_decode, "DecodeAssists");
     P(cpu_has_svm_vloadsave, "Virtual VMLOAD/VMSAVE");
+    P(cpu_has_svm_vgif, "Virtual GIF");
     P(cpu_has_pause_filter, "Pause-Intercept Filter");
     P(cpu_has_tsc_ratio, "TSC Rate MSR");
 #undef P
index 2e48fdde325d8439d3f5f4bc29fb15bd1886369f..0e6cba5b7bcc0a8a19176d540de7a7e9e642925a 100644 (file)
@@ -214,6 +214,15 @@ static int construct_vmcb(struct vcpu *v)
         vmcb->_exception_intercepts |= (1U << TRAP_page_fault);
     }
 
+    /* if available, enable and configure virtual gif */
+    if ( cpu_has_svm_vgif )
+    {
+        vmcb->_vintr.fields.vgif = 1;
+        vmcb->_vintr.fields.vgif_enable = 1;
+        vmcb->_general2_intercepts &= ~GENERAL2_INTERCEPT_STGI;
+        vmcb->_general2_intercepts &= ~GENERAL2_INTERCEPT_CLGI;
+    }
+
     if ( cpu_has_pause_filter )
     {
         vmcb->_pause_filter_count = SVM_PAUSEFILTER_INIT;