|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v2] x86/svm: require VMSAVEvirt for nested virt
Virtual VMLOAD/VMSAVE lets an L1 guest execute VMLOAD and VMSAVE
without intercepts. Without it, Xen has to map the L1-provided VMCB
and re-execute each instruction in L0, handling a complex,
security-sensitive subset of state on the way.
Make VMSAVEvirt a hard requirement for nested SVM. The
cpu_has_svm_vloadsave test in svm_nested_features_on_efer_update() is
then redundant, as nested virt now requires the feature, and is
dropped.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Stephen Cheng <stephen.cheng@xxxxxxxxxx>
---
docs/designs/nested-svm-cpu-features.md | 17 +++++++++++++++++
xen/arch/x86/hvm/svm/nestedsvm.c | 16 +++++++++++-----
2 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/docs/designs/nested-svm-cpu-features.md
b/docs/designs/nested-svm-cpu-features.md
index ce168e68e1..eed40a958c 100644
--- a/docs/designs/nested-svm-cpu-features.md
+++ b/docs/designs/nested-svm-cpu-features.md
@@ -109,3 +109,20 @@ leaf 8000000A:edx
Using it in L0 reduces the chance that we'll make some sort of error
in the decode path. And if hardware supports it, it's easy enough
to provide to the L1.
+
+- 15 `VLoadSave` *Virtual VMLOAD/VMSAVE*: Require for L0
+
+ Without this feature Xen has to intercept the L1 hypervisor's VMLOAD
+ and VMSAVE instructions and emulate them by re-executing the real
+ instruction on a mapped copy of the L1-supplied VMCB. That path
+ handles a complex, security-sensitive subset of state (the hidden
+ segment descriptors for FS/GS/TR/LDTR plus the SYSCALL/SYSENTER
+ MSRs), so on faithfulness grounds we'd much rather let the hardware
+ do it. When present, the instructions execute natively in the guest
+ without a #VMEXIT, which is both simpler and faster.
+
+ Whether to provide it to the L1 is a separate question, deliberately
+ left for a later change. It needs care over whether an L2's
+ `vloadsave_enable` should follow L0's setting or L1's, and over what
+ should happen if L1 leaves the feature disabled without intercepting
+ VMLOAD/VMSAVE.
diff --git a/xen/arch/x86/hvm/svm/nestedsvm.c b/xen/arch/x86/hvm/svm/nestedsvm.c
index b06124c2c9..96de03a5ec 100644
--- a/xen/arch/x86/hvm/svm/nestedsvm.c
+++ b/xen/arch/x86/hvm/svm/nestedsvm.c
@@ -562,7 +562,10 @@ static int nsvm_vmcb_prepare4vmrun(struct vcpu *v, struct
cpu_user_regs *regs)
/* Keep the host values of the fs, gs, ldtr, tr, kerngsbase,
* star, lstar, cstar, sfmask, sysenter_cs, sysenter_esp,
- * sysenter_eip. These are handled via VMSAVE/VMLOAD emulation.
+ * sysenter_eip. These are not transferred by VMRUN/#VMEXIT; they
+ * are moved directly to/from the L1-provided VMCB by the guest's
+ * own VMSAVE/VMLOAD, which run natively (VMSAVEvirt is required
+ * for nested virt).
*/
/* PAT */
@@ -1097,7 +1100,10 @@ nsvm_vmcb_prepare4vmexit(struct vcpu *v, struct
cpu_user_regs *regs)
/* Keep the l2 guest values of the fs, gs, ldtr, tr, kerngsbase,
* star, lstar, cstar, sfmask, sysenter_cs, sysenter_esp,
- * sysenter_eip. These are handled via VMSAVE/VMLOAD emulation.
+ * sysenter_eip. These are not transferred by VMRUN/#VMEXIT; they
+ * are moved directly to/from the L1-provided VMCB by the guest's
+ * own VMSAVE/VMLOAD, which run natively (VMSAVEvirt is required
+ * for nested virt).
*/
/* CR2 */
@@ -1548,8 +1554,7 @@ void svm_nested_features_on_efer_update(struct vcpu *v)
if ( nsvm_efer_svm_enabled(v) )
{
if ( !vmcb->virt_ext.fields.vloadsave_enable &&
- paging_mode_hap(v->domain) &&
- cpu_has_svm_vloadsave )
+ paging_mode_hap(v->domain) )
{
vmcb->virt_ext.fields.vloadsave_enable = 1;
general2_intercepts = vmcb_get_general2_intercepts(vmcb);
@@ -1607,5 +1612,6 @@ void __init start_nested_svm(struct hvm_function_table
*hvm_function_table)
cpu_has_svm_lbrv &&
cpu_has_svm_nrips &&
cpu_has_svm_flushbyasid &&
- cpu_has_svm_decode;
+ cpu_has_svm_decode &&
+ cpu_has_svm_vloadsave;
}
base-commit: 644ea6f84510af27ee1847e981df945a94068479
--
2.49.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |