23
23
#include <asm/pkru.h>
24
24
#include <asm/trapnr.h>
25
25
#include <asm/fpu/xcr.h>
26
+ #include <asm/debugreg.h>
26
27
27
28
#include "mmu.h"
28
29
#include "x86.h"
@@ -54,9 +55,14 @@ module_param_named(sev, sev_enabled, bool, 0444);
54
55
/* enable/disable SEV-ES support */
55
56
static bool sev_es_enabled = true;
56
57
module_param_named (sev_es , sev_es_enabled , bool , 0444 );
58
+
59
+ /* enable/disable SEV-ES DebugSwap support */
60
+ static bool sev_es_debug_swap_enabled = true;
61
+ module_param_named (debug_swap , sev_es_debug_swap_enabled , bool , 0444 );
57
62
#else
58
63
#define sev_enabled false
59
64
#define sev_es_enabled false
65
+ #define sev_es_debug_swap_enabled false
60
66
#endif /* CONFIG_KVM_AMD_SEV */
61
67
62
68
static u8 sev_enc_bit ;
@@ -606,6 +612,9 @@ static int sev_es_sync_vmsa(struct vcpu_svm *svm)
606
612
save -> xss = svm -> vcpu .arch .ia32_xss ;
607
613
save -> dr6 = svm -> vcpu .arch .dr6 ;
608
614
615
+ if (sev_es_debug_swap_enabled )
616
+ save -> sev_features |= SVM_SEV_FEAT_DEBUG_SWAP ;
617
+
609
618
pr_debug ("Virtual Machine Save Area (VMSA):\n" );
610
619
print_hex_dump_debug ("" , DUMP_PREFIX_NONE , 16 , 1 , save , sizeof (* save ), false);
611
620
@@ -619,6 +628,11 @@ static int __sev_launch_update_vmsa(struct kvm *kvm, struct kvm_vcpu *vcpu,
619
628
struct vcpu_svm * svm = to_svm (vcpu );
620
629
int ret ;
621
630
631
+ if (vcpu -> guest_debug ) {
632
+ pr_warn_once ("KVM_SET_GUEST_DEBUG for SEV-ES guest is not supported" );
633
+ return - EINVAL ;
634
+ }
635
+
622
636
/* Perform some pre-encryption checks against the VMSA */
623
637
ret = sev_es_sync_vmsa (svm );
624
638
if (ret )
@@ -1725,7 +1739,7 @@ static void sev_migrate_from(struct kvm *dst_kvm, struct kvm *src_kvm)
1725
1739
* Note, the source is not required to have the same number of
1726
1740
* vCPUs as the destination when migrating a vanilla SEV VM.
1727
1741
*/
1728
- src_vcpu = kvm_get_vcpu (dst_kvm , i );
1742
+ src_vcpu = kvm_get_vcpu (src_kvm , i );
1729
1743
src_svm = to_svm (src_vcpu );
1730
1744
1731
1745
/*
@@ -2171,7 +2185,7 @@ void __init sev_hardware_setup(void)
2171
2185
bool sev_es_supported = false;
2172
2186
bool sev_supported = false;
2173
2187
2174
- if (!sev_enabled || !npt_enabled )
2188
+ if (!sev_enabled || !npt_enabled || ! nrips )
2175
2189
goto out ;
2176
2190
2177
2191
/*
@@ -2256,6 +2270,9 @@ void __init sev_hardware_setup(void)
2256
2270
2257
2271
sev_enabled = sev_supported ;
2258
2272
sev_es_enabled = sev_es_supported ;
2273
+ if (!sev_es_enabled || !cpu_feature_enabled (X86_FEATURE_DEBUG_SWAP ) ||
2274
+ !cpu_feature_enabled (X86_FEATURE_NO_NESTED_DATA_BP ))
2275
+ sev_es_debug_swap_enabled = false;
2259
2276
#endif
2260
2277
}
2261
2278
@@ -2881,7 +2898,10 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
2881
2898
svm -> sev_es .ghcb_sa );
2882
2899
break ;
2883
2900
case SVM_VMGEXIT_NMI_COMPLETE :
2884
- ret = svm_invoke_exit_handler (vcpu , SVM_EXIT_IRET );
2901
+ ++ vcpu -> stat .nmi_window_exits ;
2902
+ svm -> nmi_masked = false;
2903
+ kvm_make_request (KVM_REQ_EVENT , vcpu );
2904
+ ret = 1 ;
2885
2905
break ;
2886
2906
case SVM_VMGEXIT_AP_HLT_LOOP :
2887
2907
ret = kvm_emulate_ap_reset_hold (vcpu );
@@ -2944,6 +2964,7 @@ int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in)
2944
2964
2945
2965
static void sev_es_init_vmcb (struct vcpu_svm * svm )
2946
2966
{
2967
+ struct vmcb * vmcb = svm -> vmcb01 .ptr ;
2947
2968
struct kvm_vcpu * vcpu = & svm -> vcpu ;
2948
2969
2949
2970
svm -> vmcb -> control .nested_ctl |= SVM_NESTED_CTL_SEV_ES_ENABLE ;
@@ -2952,9 +2973,12 @@ static void sev_es_init_vmcb(struct vcpu_svm *svm)
2952
2973
/*
2953
2974
* An SEV-ES guest requires a VMSA area that is a separate from the
2954
2975
* VMCB page. Do not include the encryption mask on the VMSA physical
2955
- * address since hardware will access it using the guest key.
2976
+ * address since hardware will access it using the guest key. Note,
2977
+ * the VMSA will be NULL if this vCPU is the destination for intrahost
2978
+ * migration, and will be copied later.
2956
2979
*/
2957
- svm -> vmcb -> control .vmsa_pa = __pa (svm -> sev_es .vmsa );
2980
+ if (svm -> sev_es .vmsa )
2981
+ svm -> vmcb -> control .vmsa_pa = __pa (svm -> sev_es .vmsa );
2958
2982
2959
2983
/* Can't intercept CR register access, HV can't modify CR registers */
2960
2984
svm_clr_intercept (svm , INTERCEPT_CR0_READ );
@@ -2972,8 +2996,23 @@ static void sev_es_init_vmcb(struct vcpu_svm *svm)
2972
2996
svm_set_intercept (svm , TRAP_CR4_WRITE );
2973
2997
svm_set_intercept (svm , TRAP_CR8_WRITE );
2974
2998
2975
- /* No support for enable_vmware_backdoor */
2976
- clr_exception_intercept (svm , GP_VECTOR );
2999
+ vmcb -> control .intercepts [INTERCEPT_DR ] = 0 ;
3000
+ if (!sev_es_debug_swap_enabled ) {
3001
+ vmcb_set_intercept (& vmcb -> control , INTERCEPT_DR7_READ );
3002
+ vmcb_set_intercept (& vmcb -> control , INTERCEPT_DR7_WRITE );
3003
+ recalc_intercepts (svm );
3004
+ } else {
3005
+ /*
3006
+ * Disable #DB intercept iff DebugSwap is enabled. KVM doesn't
3007
+ * allow debugging SEV-ES guests, and enables DebugSwap iff
3008
+ * NO_NESTED_DATA_BP is supported, so there's no reason to
3009
+ * intercept #DB when DebugSwap is enabled. For simplicity
3010
+ * with respect to guest debug, intercept #DB for other VMs
3011
+ * even if NO_NESTED_DATA_BP is supported, i.e. even if the
3012
+ * guest can't DoS the CPU with infinite #DB vectoring.
3013
+ */
3014
+ clr_exception_intercept (svm , DB_VECTOR );
3015
+ }
2977
3016
2978
3017
/* Can't intercept XSETBV, HV can't modify XCR0 directly */
2979
3018
svm_clr_intercept (svm , INTERCEPT_XSETBV );
@@ -3000,6 +3039,12 @@ void sev_init_vmcb(struct vcpu_svm *svm)
3000
3039
svm -> vmcb -> control .nested_ctl |= SVM_NESTED_CTL_SEV_ENABLE ;
3001
3040
clr_exception_intercept (svm , UD_VECTOR );
3002
3041
3042
+ /*
3043
+ * Don't intercept #GP for SEV guests, e.g. for the VMware backdoor, as
3044
+ * KVM can't decrypt guest memory to decode the faulting instruction.
3045
+ */
3046
+ clr_exception_intercept (svm , GP_VECTOR );
3047
+
3003
3048
if (sev_es_guest (svm -> vcpu .kvm ))
3004
3049
sev_es_init_vmcb (svm );
3005
3050
}
@@ -3018,20 +3063,41 @@ void sev_es_vcpu_reset(struct vcpu_svm *svm)
3018
3063
void sev_es_prepare_switch_to_guest (struct sev_es_save_area * hostsa )
3019
3064
{
3020
3065
/*
3021
- * As an SEV-ES guest, hardware will restore the host state on VMEXIT,
3022
- * of which one step is to perform a VMLOAD. KVM performs the
3023
- * corresponding VMSAVE in svm_prepare_guest_switch for both
3024
- * traditional and SEV-ES guests.
3066
+ * All host state for SEV-ES guests is categorized into three swap types
3067
+ * based on how it is handled by hardware during a world switch:
3068
+ *
3069
+ * A: VMRUN: Host state saved in host save area
3070
+ * VMEXIT: Host state loaded from host save area
3071
+ *
3072
+ * B: VMRUN: Host state _NOT_ saved in host save area
3073
+ * VMEXIT: Host state loaded from host save area
3074
+ *
3075
+ * C: VMRUN: Host state _NOT_ saved in host save area
3076
+ * VMEXIT: Host state initialized to default(reset) values
3077
+ *
3078
+ * Manually save type-B state, i.e. state that is loaded by VMEXIT but
3079
+ * isn't saved by VMRUN, that isn't already saved by VMSAVE (performed
3080
+ * by common SVM code).
3025
3081
*/
3026
-
3027
- /* XCR0 is restored on VMEXIT, save the current host value */
3028
3082
hostsa -> xcr0 = xgetbv (XCR_XFEATURE_ENABLED_MASK );
3029
-
3030
- /* PKRU is restored on VMEXIT, save the current host value */
3031
3083
hostsa -> pkru = read_pkru ();
3032
-
3033
- /* MSR_IA32_XSS is restored on VMEXIT, save the currnet host value */
3034
3084
hostsa -> xss = host_xss ;
3085
+
3086
+ /*
3087
+ * If DebugSwap is enabled, debug registers are loaded but NOT saved by
3088
+ * the CPU (Type-B). If DebugSwap is disabled/unsupported, the CPU both
3089
+ * saves and loads debug registers (Type-A).
3090
+ */
3091
+ if (sev_es_debug_swap_enabled ) {
3092
+ hostsa -> dr0 = native_get_debugreg (0 );
3093
+ hostsa -> dr1 = native_get_debugreg (1 );
3094
+ hostsa -> dr2 = native_get_debugreg (2 );
3095
+ hostsa -> dr3 = native_get_debugreg (3 );
3096
+ hostsa -> dr0_addr_mask = amd_get_dr_addr_mask (0 );
3097
+ hostsa -> dr1_addr_mask = amd_get_dr_addr_mask (1 );
3098
+ hostsa -> dr2_addr_mask = amd_get_dr_addr_mask (2 );
3099
+ hostsa -> dr3_addr_mask = amd_get_dr_addr_mask (3 );
3100
+ }
3035
3101
}
3036
3102
3037
3103
void sev_vcpu_deliver_sipi_vector (struct kvm_vcpu * vcpu , u8 vector )
0 commit comments