nestedsvm: Allow destroying the domain fully

Unmapping the virtual VMCB is performed near the end of the domain
destroy procedure but the mapped guest frame prevents domain destroy
from getting to that point. This means guests that call VMRUN cannot
be fully destroyed.

Move the unmap of the virtual VMCB earlier to fix the issue.

Fixes: bcf557675d ("x86: properly use map_domain_page() in nested HVM code")
Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
Ross Lagerwall authored and Jan Beulich committed 2026-06-30 09:41:35 +02:00
1 parent c780db53fa
commit 4d069a84ee
3 files changed
+15 -2

No files matched your search

+1
View File
@@ -48,6 +48,7 @@ bool cf_check nsvm_vmcb_guest_intercepts_event(
struct vcpu *v, unsigned int vector, int errcode); struct vcpu *v, unsigned int vector, int errcode);
bool cf_check nsvm_vmcb_hap_enabled(struct vcpu *v); bool cf_check nsvm_vmcb_hap_enabled(struct vcpu *v);
enum hvm_intblk cf_check nsvm_intr_blocked(struct vcpu *v); enum hvm_intblk cf_check nsvm_intr_blocked(struct vcpu *v);
void cf_check nsvm_domain_relinquish_resources(struct domain *d);
/* Interrupts, vGIF */ /* Interrupts, vGIF */
void svm_vmexit_do_clgi(struct cpu_user_regs *regs, struct vcpu *v); void svm_vmexit_do_clgi(struct cpu_user_regs *regs, struct vcpu *v);
+13 -2
View File
@@ -110,8 +110,6 @@ void cf_check nsvm_vcpu_destroy(struct vcpu *v)
svm->ns_merged_msrpm = NULL; svm->ns_merged_msrpm = NULL;
} }
hvm_unmap_guest_frame(nv->nv_vvmcx, 1);
nv->nv_vvmcx = NULL;
if ( nv->nv_n2vmcx ) if ( nv->nv_n2vmcx )
{ {
free_vmcb(nv->nv_n2vmcx); free_vmcb(nv->nv_n2vmcx);
@@ -122,6 +120,19 @@ void cf_check nsvm_vcpu_destroy(struct vcpu *v)
svm->ns_iomap = NULL; svm->ns_iomap = NULL;
} }
void cf_check nsvm_domain_relinquish_resources(struct domain *d)
{
struct vcpu *v;
struct nestedvcpu *nv;
for_each_vcpu ( d, v )
{
nv = &vcpu_nestedhvm(v);
hvm_unmap_guest_frame(nv->nv_vvmcx, 1);
nv->nv_vvmcx = NULL;
}
}
int cf_check nsvm_vcpu_reset(struct vcpu *v) int cf_check nsvm_vcpu_reset(struct vcpu *v)
{ {
struct nestedsvm *svm = &vcpu_nestedsvm(v); struct nestedsvm *svm = &vcpu_nestedsvm(v);
+1
View File
@@ -2420,6 +2420,7 @@ static struct hvm_function_table __initdata_cf_clobber svm_function_table = {
.nhvm_vmcx_hap_enabled = nsvm_vmcb_hap_enabled, .nhvm_vmcx_hap_enabled = nsvm_vmcb_hap_enabled,
.nhvm_intr_blocked = nsvm_intr_blocked, .nhvm_intr_blocked = nsvm_intr_blocked,
.nhvm_hap_walk_L1_p2m = nsvm_hap_walk_L1_p2m, .nhvm_hap_walk_L1_p2m = nsvm_hap_walk_L1_p2m,
.nhvm_domain_relinquish_resources = nsvm_domain_relinquish_resources,
.get_reg = svm_get_reg, .get_reg = svm_get_reg,
.set_reg = svm_set_reg, .set_reg = svm_set_reg,
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.