Commit
a6f2cdb6 "keep APIC assist page mapped..." introduced a page
leak because it relied on viridian_vcpu_deinit() always being called
to release the page mapping. This does not happen in the case a normal
domain shutdown.
This patch fixes the problem by introducing a new function,
viridian_domain_deinit(), which will iterate through the vCPUs and
release any page mappings still present.
Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
if ( hvm_funcs.nhvm_domain_relinquish_resources )
hvm_funcs.nhvm_domain_relinquish_resources(d);
+ viridian_domain_deinit(d);
+
hvm_destroy_all_ioreq_servers(d);
msixtbl_pt_cleanup(d);
if ( viridian_feature_mask(v->domain) & HVMPV_apic_assist )
{
+ /*
+ * If we overwrite an existing address here then something has
+ * gone wrong and a domain page will leak. Instead crash the
+ * domain to make the problem obvious.
+ */
+ if ( v->arch.hvm_vcpu.viridian.apic_assist.va )
+ domain_crash(d);
+
v->arch.hvm_vcpu.viridian.apic_assist.va = va;
return;
}
teardown_apic_assist(v);
}
+void viridian_domain_deinit(struct domain *d)
+{
+ struct vcpu *v;
+
+ for_each_vcpu ( d, v )
+ teardown_apic_assist(v);
+}
+
static DEFINE_PER_CPU(cpumask_t, ipi_cpumask);
int viridian_hypercall(struct cpu_user_regs *regs)
void viridian_time_ref_count_thaw(struct domain *d);
void viridian_vcpu_deinit(struct vcpu *v);
+void viridian_domain_deinit(struct domain *d);
void viridian_start_apic_assist(struct vcpu *v, int vector);
int viridian_complete_apic_assist(struct vcpu *v);