All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] target/i386: Added VGIF feature
@ 2021-07-23 11:27 Lara Lazier
  2021-07-23 13:52 ` Paolo Bonzini
  0 siblings, 1 reply; 2+ messages in thread
From: Lara Lazier @ 2021-07-23 11:27 UTC (permalink / raw)
  To: qemu-devel; +Cc: Lara Lazier

VGIF allows STGI and CLGI to execute in guest mode and control virtual
interrupts in guest mode.
When the VGIF feature is enabled then:
 * executing STGI in the guest sets bit 9 of the VMCB offset 60h.
 * executing CLGI in the guest clears bit 9 of the VMCB offset 60h.

Signed-off-by: Lara Lazier <laramglazier@gmail.com>
---
 target/i386/cpu.c                   |  3 ++-
 target/i386/svm.h                   |  6 +++++
 target/i386/tcg/sysemu/svm_helper.c | 36 +++++++++++++++++++++++++----
 3 files changed, 39 insertions(+), 6 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 48b55ebd0a..5e6d2b4294 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -631,7 +631,8 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
 #define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | \
           CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A)
 #define TCG_EXT4_FEATURES 0
-#define TCG_SVM_FEATURES CPUID_SVM_NPT
+#define TCG_SVM_FEATURES (CPUID_SVM_NPT | CPUID_SVM_VGIF | \
+          CPUID_SVM_SVME_ADDR_CHK)
 #define TCG_KVM_FEATURES 0
 #define TCG_7_0_EBX_FEATURES (CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_SMAP | \
           CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ADX | \
diff --git a/target/i386/svm.h b/target/i386/svm.h
index e54670ef12..dab2f90925 100644
--- a/target/i386/svm.h
+++ b/target/i386/svm.h
@@ -9,6 +9,12 @@
 #define V_IRQ_SHIFT 8
 #define V_IRQ_MASK (1 << V_IRQ_SHIFT)
 
+#define V_GIF_ENABLED_SHIFT 25
+#define V_GIF_ENABLED_MASK (1 << V_GIF_ENABLED_SHIFT)
+
+#define V_GIF_SHIFT 9
+#define V_GIF_MASK (1 << V_GIF_SHIFT)
+
 #define V_INTR_PRIO_SHIFT 16
 #define V_INTR_PRIO_MASK (0x0f << V_INTR_PRIO_SHIFT)
 
diff --git a/target/i386/tcg/sysemu/svm_helper.c b/target/i386/tcg/sysemu/svm_helper.c
index 6118f6f587..ea85e3cae8 100644
--- a/target/i386/tcg/sysemu/svm_helper.c
+++ b/target/i386/tcg/sysemu/svm_helper.c
@@ -118,6 +118,11 @@ static inline void svm_vmrun_canonicalization(CPUX86State *env)
     env->tr.base = (long) ((uint32_t) env->tr.base);
 }
 
+static inline bool virtual_gif_enabled(CPUX86State *env, uint32_t int_ctl)
+{
+    return (int_ctl & V_GIF_ENABLED_MASK) && (env->features[FEAT_SVM] & CPUID_SVM_VGIF);
+}
+
 void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
 {
     CPUState *cs = env_cpu(env);
@@ -353,9 +358,12 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
         tlb_flush(cs);
         break;
     }
-
-    env->hflags2 |= HF2_GIF_MASK;
-
+    if (virtual_gif_enabled(env, int_ctl)) {
+        x86_stl_phys(cs, env->vm_vmcb + offsetof(struct vmcb, control.int_ctl),
+                        int_ctl |= V_GIF_MASK);
+    } else {
+        env->hflags2 |= HF2_GIF_MASK;
+    }
     if (int_ctl & V_IRQ_MASK) {
         CPUState *cs = env_cpu(env);
 
@@ -513,13 +521,31 @@ void helper_vmsave(CPUX86State *env, int aflag)
 void helper_stgi(CPUX86State *env)
 {
     cpu_svm_check_intercept_param(env, SVM_EXIT_STGI, 0, GETPC());
-    env->hflags2 |= HF2_GIF_MASK;
+
+    CPUState *cs = env_cpu(env);
+    uint32_t int_ctl = x86_ldl_phys(cs,
+                       env->vm_vmcb + offsetof(struct vmcb, control.int_ctl));
+    if (virtual_gif_enabled(env, int_ctl) && likely(env->hflags & HF_GUEST_MASK)) {
+        x86_stl_phys(cs, env->vm_vmcb + offsetof(struct vmcb, control.int_ctl),
+                        int_ctl |= V_GIF_MASK);
+    } else {
+        env->hflags2 |= HF2_GIF_MASK;
+    }
 }
 
 void helper_clgi(CPUX86State *env)
 {
     cpu_svm_check_intercept_param(env, SVM_EXIT_CLGI, 0, GETPC());
-    env->hflags2 &= ~HF2_GIF_MASK;
+
+    CPUState *cs = env_cpu(env);
+    uint32_t int_ctl = x86_ldl_phys(cs,
+                       env->vm_vmcb + offsetof(struct vmcb, control.int_ctl));
+    if (virtual_gif_enabled(env, int_ctl) && likely(env->hflags & HF_GUEST_MASK)) {
+        x86_stl_phys(cs, env->vm_vmcb + offsetof(struct vmcb, control.int_ctl),
+                        int_ctl &= ~V_GIF_MASK);
+    } else {
+        env->hflags2 &= ~HF2_GIF_MASK;
+    }
 }
 
 bool cpu_svm_has_intercept(CPUX86State *env, uint32_t type)
-- 
2.25.1



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

* Re: [PATCH] target/i386: Added VGIF feature
  2021-07-23 11:27 [PATCH] target/i386: Added VGIF feature Lara Lazier
@ 2021-07-23 13:52 ` Paolo Bonzini
  0 siblings, 0 replies; 2+ messages in thread
From: Paolo Bonzini @ 2021-07-23 13:52 UTC (permalink / raw)
  To: Lara Lazier, qemu-devel

On 23/07/21 13:27, Lara Lazier wrote:
> @@ -353,9 +358,12 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
>           tlb_flush(cs);
>           break;
>       }
> -
> -    env->hflags2 |= HF2_GIF_MASK;
> -
> +    if (virtual_gif_enabled(env, int_ctl)) {
> +        x86_stl_phys(cs, env->vm_vmcb + offsetof(struct vmcb, control.int_ctl),
> +                        int_ctl |= V_GIF_MASK);
> +    } else {
> +        env->hflags2 |= HF2_GIF_MASK;
> +    }

This should not be changed, because it is setting the "real" GIF; vGIF 
hasn't taken effect yet.

The CLGI/VMRUN/STGI sequence is there to avoid delivering an interrupt 
while the processor state has been partly changed to whatever the guest 
wants.  VMRUN sets GIF so that it is possible for interrupts (or 
NMI/SMI) to cause a vmexit, but the vmexit immediately clears the GIF 
again so that it is only handled after the host executes STGI.

>       if (int_ctl & V_IRQ_MASK) {
>           CPUState *cs = env_cpu(env);
>   
> @@ -513,13 +521,31 @@ void helper_vmsave(CPUX86State *env, int aflag)
>   void helper_stgi(CPUX86State *env)
>   {
>       cpu_svm_check_intercept_param(env, SVM_EXIT_STGI, 0, GETPC());
> -    env->hflags2 |= HF2_GIF_MASK;
> +
> +    CPUState *cs = env_cpu(env);
> +    uint32_t int_ctl = x86_ldl_phys(cs,
> +                       env->vm_vmcb + offsetof(struct vmcb, control.int_ctl));
> +    if (virtual_gif_enabled(env, int_ctl) && likely(env->hflags & HF_GUEST_MASK)) {
> +        x86_stl_phys(cs, env->vm_vmcb + offsetof(struct vmcb, control.int_ctl),
> +                        int_ctl |= V_GIF_MASK);

No need to use "|=", likewise for "&=" below.

Thanks,

Paolo

> +    } else {
> +        env->hflags2 |= HF2_GIF_MASK;
> +    }
>   }
>   
>   void helper_clgi(CPUX86State *env)
>   {
>       cpu_svm_check_intercept_param(env, SVM_EXIT_CLGI, 0, GETPC());
> -    env->hflags2 &= ~HF2_GIF_MASK;
> +
> +    CPUState *cs = env_cpu(env);
> +    uint32_t int_ctl = x86_ldl_phys(cs,
> +                       env->vm_vmcb + offsetof(struct vmcb, control.int_ctl));
> +    if (virtual_gif_enabled(env, int_ctl) && likely(env->hflags & HF_GUEST_MASK)) {
> +        x86_stl_phys(cs, env->vm_vmcb + offsetof(struct vmcb, control.int_ctl),
> +                        int_ctl &= ~V_GIF_MASK);
> +    } else {
> +        env->hflags2 &= ~HF2_GIF_MASK;
> +    }
>   }
>   
>   bool cpu_svm_has_intercept(CPUX86State *env, uint32_t type)
> 



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

end of thread, other threads:[~2021-07-23 13:54 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-23 11:27 [PATCH] target/i386: Added VGIF feature Lara Lazier
2021-07-23 13:52 ` Paolo Bonzini

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.