From: Paul Durrant Date: Tue, 29 Mar 2016 12:26:33 +0000 (+0200) Subject: x86/hvm/viridian: fix APIC assist page leak X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~1482 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=b93687291574ee64b8244e15455a71d663787962;p=xen.git x86/hvm/viridian: fix APIC assist page leak 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 Reviewed-by: Jan Beulich --- diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 80d59ff44d..611470ee70 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -1726,6 +1726,8 @@ void hvm_domain_relinquish_resources(struct domain *d) 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); diff --git a/xen/arch/x86/hvm/viridian.c b/xen/arch/x86/hvm/viridian.c index dceed2c9f9..5c76c1af2f 100644 --- a/xen/arch/x86/hvm/viridian.c +++ b/xen/arch/x86/hvm/viridian.c @@ -251,6 +251,14 @@ static void initialize_apic_assist(struct vcpu *v) 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; } @@ -608,6 +616,14 @@ void viridian_vcpu_deinit(struct vcpu *v) 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) diff --git a/xen/include/asm-x86/hvm/viridian.h b/xen/include/asm-x86/hvm/viridian.h index 7f281b2137..bdbccd5376 100644 --- a/xen/include/asm-x86/hvm/viridian.h +++ b/xen/include/asm-x86/hvm/viridian.h @@ -122,6 +122,7 @@ void viridian_time_ref_count_freeze(struct domain *d); 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);