@@ -1665,19 +1665,24 @@ static void sev_migrate_from(struct kvm *dst_kvm, struct kvm *src_kvm)
1665
1665
{
1666
1666
struct kvm_sev_info * dst = & to_kvm_svm (dst_kvm )-> sev_info ;
1667
1667
struct kvm_sev_info * src = & to_kvm_svm (src_kvm )-> sev_info ;
1668
+ struct kvm_vcpu * dst_vcpu , * src_vcpu ;
1669
+ struct vcpu_svm * dst_svm , * src_svm ;
1668
1670
struct kvm_sev_info * mirror ;
1671
+ unsigned long i ;
1669
1672
1670
1673
dst -> active = true;
1671
1674
dst -> asid = src -> asid ;
1672
1675
dst -> handle = src -> handle ;
1673
1676
dst -> pages_locked = src -> pages_locked ;
1674
1677
dst -> enc_context_owner = src -> enc_context_owner ;
1678
+ dst -> es_active = src -> es_active ;
1675
1679
1676
1680
src -> asid = 0 ;
1677
1681
src -> active = false;
1678
1682
src -> handle = 0 ;
1679
1683
src -> pages_locked = 0 ;
1680
1684
src -> enc_context_owner = NULL ;
1685
+ src -> es_active = false;
1681
1686
1682
1687
list_cut_before (& dst -> regions_list , & src -> regions_list , & src -> regions_list );
1683
1688
@@ -1704,26 +1709,21 @@ static void sev_migrate_from(struct kvm *dst_kvm, struct kvm *src_kvm)
1704
1709
list_del (& src -> mirror_entry );
1705
1710
list_add_tail (& dst -> mirror_entry , & owner_sev_info -> mirror_vms );
1706
1711
}
1707
- }
1708
1712
1709
- static int sev_es_migrate_from (struct kvm * dst , struct kvm * src )
1710
- {
1711
- unsigned long i ;
1712
- struct kvm_vcpu * dst_vcpu , * src_vcpu ;
1713
- struct vcpu_svm * dst_svm , * src_svm ;
1713
+ kvm_for_each_vcpu (i , dst_vcpu , dst_kvm ) {
1714
+ dst_svm = to_svm (dst_vcpu );
1714
1715
1715
- if (atomic_read (& src -> online_vcpus ) != atomic_read (& dst -> online_vcpus ))
1716
- return - EINVAL ;
1716
+ sev_init_vmcb (dst_svm );
1717
1717
1718
- kvm_for_each_vcpu (i , src_vcpu , src ) {
1719
- if (!src_vcpu -> arch .guest_state_protected )
1720
- return - EINVAL ;
1721
- }
1718
+ if (!dst -> es_active )
1719
+ continue ;
1722
1720
1723
- kvm_for_each_vcpu (i , src_vcpu , src ) {
1721
+ /*
1722
+ * Note, the source is not required to have the same number of
1723
+ * vCPUs as the destination when migrating a vanilla SEV VM.
1724
+ */
1725
+ src_vcpu = kvm_get_vcpu (dst_kvm , i );
1724
1726
src_svm = to_svm (src_vcpu );
1725
- dst_vcpu = kvm_get_vcpu (dst , i );
1726
- dst_svm = to_svm (dst_vcpu );
1727
1727
1728
1728
/*
1729
1729
* Transfer VMSA and GHCB state to the destination. Nullify and
@@ -1740,8 +1740,23 @@ static int sev_es_migrate_from(struct kvm *dst, struct kvm *src)
1740
1740
src_svm -> vmcb -> control .vmsa_pa = INVALID_PAGE ;
1741
1741
src_vcpu -> arch .guest_state_protected = false;
1742
1742
}
1743
- to_kvm_svm (src )-> sev_info .es_active = false;
1744
- to_kvm_svm (dst )-> sev_info .es_active = true;
1743
+ }
1744
+
1745
+ static int sev_check_source_vcpus (struct kvm * dst , struct kvm * src )
1746
+ {
1747
+ struct kvm_vcpu * src_vcpu ;
1748
+ unsigned long i ;
1749
+
1750
+ if (!sev_es_guest (src ))
1751
+ return 0 ;
1752
+
1753
+ if (atomic_read (& src -> online_vcpus ) != atomic_read (& dst -> online_vcpus ))
1754
+ return - EINVAL ;
1755
+
1756
+ kvm_for_each_vcpu (i , src_vcpu , src ) {
1757
+ if (!src_vcpu -> arch .guest_state_protected )
1758
+ return - EINVAL ;
1759
+ }
1745
1760
1746
1761
return 0 ;
1747
1762
}
@@ -1789,11 +1804,9 @@ int sev_vm_move_enc_context_from(struct kvm *kvm, unsigned int source_fd)
1789
1804
if (ret )
1790
1805
goto out_dst_vcpu ;
1791
1806
1792
- if (sev_es_guest (source_kvm )) {
1793
- ret = sev_es_migrate_from (kvm , source_kvm );
1794
- if (ret )
1795
- goto out_source_vcpu ;
1796
- }
1807
+ ret = sev_check_source_vcpus (kvm , source_kvm );
1808
+ if (ret )
1809
+ goto out_source_vcpu ;
1797
1810
1798
1811
sev_migrate_from (kvm , source_kvm );
1799
1812
kvm_vm_dead (source_kvm );
@@ -2914,7 +2927,7 @@ int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in)
2914
2927
count , in );
2915
2928
}
2916
2929
2917
- void sev_es_init_vmcb (struct vcpu_svm * svm )
2930
+ static void sev_es_init_vmcb (struct vcpu_svm * svm )
2918
2931
{
2919
2932
struct kvm_vcpu * vcpu = & svm -> vcpu ;
2920
2933
@@ -2967,6 +2980,15 @@ void sev_es_init_vmcb(struct vcpu_svm *svm)
2967
2980
}
2968
2981
}
2969
2982
2983
+ void sev_init_vmcb (struct vcpu_svm * svm )
2984
+ {
2985
+ svm -> vmcb -> control .nested_ctl |= SVM_NESTED_CTL_SEV_ENABLE ;
2986
+ clr_exception_intercept (svm , UD_VECTOR );
2987
+
2988
+ if (sev_es_guest (svm -> vcpu .kvm ))
2989
+ sev_es_init_vmcb (svm );
2990
+ }
2991
+
2970
2992
void sev_es_vcpu_reset (struct vcpu_svm * svm )
2971
2993
{
2972
2994
/*
0 commit comments