SHA256
1
0
forked from pool/xen
xen/CVE-2013-1918-xsa45-4-vcpu-reset-preemptible.patch
Olaf Hering b9d38dfc8d - add xorg-x11-util-devel to BuildRequires to get lndir(1)
- remove xen.migrate.tools_notify_restore_to_hangup_during_migration_--abort_if_busy.patch
  It changed migration protocol and upstream wants a different solution

- bnc#802221 - fix xenpaging
  readd xenpaging.qemu.flush-cache.patch

- Upstream patches from Jan
  26891-x86-S3-Fix-cpu-pool-scheduling-after-suspend-resume.patch
  26930-x86-EFI-fix-runtime-call-status-for-compat-mode-Dom0.patch
- Additional fix for bnc#816159
  CVE-2013-1918-xsa45-followup.patch

- bnc#817068 - Xen guest with >1 sr-iov vf won't start
  xen-managed-pci-device.patch

- Update to Xen 4.2.2 c/s 26064
  The following recent security patches are included in the tarball
  CVE-2013-0151-xsa34.patch (bnc#797285)
  CVE-2012-6075-xsa41.patch (bnc#797523)
  CVE-2013-1917-xsa44.patch (bnc#813673)
  CVE-2013-1919-xsa46.patch (bnc#813675)

- Upstream patch from Jan
  26902-x86-EFI-pass-boot-services-variable-info-to-runtime-code.patch 

- bnc#816159 - VUL-0: xen: CVE-2013-1918: XSA-45: Several long
  latency operations are not preemptible
  CVE-2013-1918-xsa45-1-vcpu-destroy-pagetables-preemptible.patch

OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=237
2013-05-07 14:35:00 +00:00

219 lines
7.0 KiB
Diff

x86: make vcpu_reset() preemptible
... as dropping the old page tables may take significant amounts of
time.
This is part of CVE-2013-1918 / XSA-45.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Tim Deegan <tim@xen.org>
Index: xen-4.2.2-testing/xen/arch/x86/domain.c
===================================================================
--- xen-4.2.2-testing.orig/xen/arch/x86/domain.c
+++ xen-4.2.2-testing/xen/arch/x86/domain.c
@@ -1051,17 +1051,16 @@ int arch_set_info_guest(
#undef c
}
-void arch_vcpu_reset(struct vcpu *v)
+int arch_vcpu_reset(struct vcpu *v)
{
if ( !is_hvm_vcpu(v) )
{
destroy_gdt(v);
- vcpu_destroy_pagetables(v, 0);
- }
- else
- {
- vcpu_end_shutdown_deferral(v);
+ return vcpu_destroy_pagetables(v);
}
+
+ vcpu_end_shutdown_deferral(v);
+ return 0;
}
/*
@@ -2085,7 +2084,7 @@ int domain_relinquish_resources(struct d
/* Drop the in-use references to page-table bases. */
for_each_vcpu ( d, v )
{
- ret = vcpu_destroy_pagetables(v, 1);
+ ret = vcpu_destroy_pagetables(v);
if ( ret )
return ret;
}
Index: xen-4.2.2-testing/xen/arch/x86/hvm/hvm.c
===================================================================
--- xen-4.2.2-testing.orig/xen/arch/x86/hvm/hvm.c
+++ xen-4.2.2-testing/xen/arch/x86/hvm/hvm.c
@@ -3577,8 +3577,11 @@ static void hvm_s3_suspend(struct domain
for_each_vcpu ( d, v )
{
+ int rc;
+
vlapic_reset(vcpu_vlapic(v));
- vcpu_reset(v);
+ rc = vcpu_reset(v);
+ ASSERT(!rc);
}
vpic_reset(d);
Index: xen-4.2.2-testing/xen/arch/x86/hvm/vlapic.c
===================================================================
--- xen-4.2.2-testing.orig/xen/arch/x86/hvm/vlapic.c
+++ xen-4.2.2-testing/xen/arch/x86/hvm/vlapic.c
@@ -255,10 +255,13 @@ static void vlapic_init_sipi_action(unsi
{
case APIC_DM_INIT: {
bool_t fpu_initialised;
+ int rc;
+
domain_lock(target->domain);
/* Reset necessary VCPU state. This does not include FPU state. */
fpu_initialised = target->fpu_initialised;
- vcpu_reset(target);
+ rc = vcpu_reset(target);
+ ASSERT(!rc);
target->fpu_initialised = fpu_initialised;
vlapic_reset(vcpu_vlapic(target));
domain_unlock(target->domain);
Index: xen-4.2.2-testing/xen/arch/x86/mm.c
===================================================================
--- xen-4.2.2-testing.orig/xen/arch/x86/mm.c
+++ xen-4.2.2-testing/xen/arch/x86/mm.c
@@ -2844,7 +2844,7 @@ static int put_old_guest_table(struct vc
return rc;
}
-int vcpu_destroy_pagetables(struct vcpu *v, bool_t preemptible)
+int vcpu_destroy_pagetables(struct vcpu *v)
{
unsigned long mfn = pagetable_get_pfn(v->arch.guest_table);
struct page_info *page;
@@ -2864,7 +2864,7 @@ int vcpu_destroy_pagetables(struct vcpu
if ( paging_mode_refcounts(v->domain) )
put_page(page);
else
- rc = put_page_and_type_preemptible(page, preemptible);
+ rc = put_page_and_type_preemptible(page, 1);
}
#ifdef __x86_64__
@@ -2890,7 +2890,7 @@ int vcpu_destroy_pagetables(struct vcpu
if ( paging_mode_refcounts(v->domain) )
put_page(page);
else
- rc = put_page_and_type_preemptible(page, preemptible);
+ rc = put_page_and_type_preemptible(page, 1);
}
if ( !rc )
v->arch.guest_table_user = pagetable_null();
Index: xen-4.2.2-testing/xen/common/domain.c
===================================================================
--- xen-4.2.2-testing.orig/xen/common/domain.c
+++ xen-4.2.2-testing/xen/common/domain.c
@@ -779,14 +779,18 @@ void domain_unpause_by_systemcontroller(
domain_unpause(d);
}
-void vcpu_reset(struct vcpu *v)
+int vcpu_reset(struct vcpu *v)
{
struct domain *d = v->domain;
+ int rc;
vcpu_pause(v);
domain_lock(d);
- arch_vcpu_reset(v);
+ set_bit(_VPF_in_reset, &v->pause_flags);
+ rc = arch_vcpu_reset(v);
+ if ( rc )
+ goto out_unlock;
set_bit(_VPF_down, &v->pause_flags);
@@ -802,9 +806,13 @@ void vcpu_reset(struct vcpu *v)
#endif
cpumask_clear(v->cpu_affinity_tmp);
clear_bit(_VPF_blocked, &v->pause_flags);
+ clear_bit(_VPF_in_reset, &v->pause_flags);
+ out_unlock:
domain_unlock(v->domain);
vcpu_unpause(v);
+
+ return rc;
}
Index: xen-4.2.2-testing/xen/common/domctl.c
===================================================================
--- xen-4.2.2-testing.orig/xen/common/domctl.c
+++ xen-4.2.2-testing/xen/common/domctl.c
@@ -307,8 +307,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
if ( guest_handle_is_null(op->u.vcpucontext.ctxt) )
{
- vcpu_reset(v);
- ret = 0;
+ ret = vcpu_reset(v);
+ if ( ret == -EAGAIN )
+ ret = hypercall_create_continuation(
+ __HYPERVISOR_domctl, "h", u_domctl);
goto svc_out;
}
Index: xen-4.2.2-testing/xen/include/asm-x86/mm.h
===================================================================
--- xen-4.2.2-testing.orig/xen/include/asm-x86/mm.h
+++ xen-4.2.2-testing/xen/include/asm-x86/mm.h
@@ -605,7 +605,7 @@ void audit_domains(void);
int new_guest_cr3(unsigned long pfn);
void make_cr3(struct vcpu *v, unsigned long mfn);
void update_cr3(struct vcpu *v);
-int vcpu_destroy_pagetables(struct vcpu *, bool_t preemptible);
+int vcpu_destroy_pagetables(struct vcpu *);
void propagate_page_fault(unsigned long addr, u16 error_code);
void *do_page_walk(struct vcpu *v, unsigned long addr);
Index: xen-4.2.2-testing/xen/include/xen/domain.h
===================================================================
--- xen-4.2.2-testing.orig/xen/include/xen/domain.h
+++ xen-4.2.2-testing/xen/include/xen/domain.h
@@ -13,7 +13,7 @@ typedef union {
struct vcpu *alloc_vcpu(
struct domain *d, unsigned int vcpu_id, unsigned int cpu_id);
struct vcpu *alloc_dom0_vcpu0(void);
-void vcpu_reset(struct vcpu *v);
+int vcpu_reset(struct vcpu *);
struct xen_domctl_getdomaininfo;
void getdomaininfo(struct domain *d, struct xen_domctl_getdomaininfo *info);
@@ -67,7 +67,7 @@ void arch_dump_vcpu_info(struct vcpu *v)
void arch_dump_domain_info(struct domain *d);
-void arch_vcpu_reset(struct vcpu *v);
+int arch_vcpu_reset(struct vcpu *);
extern spinlock_t vcpu_alloc_lock;
bool_t domctl_lock_acquire(void);
Index: xen-4.2.2-testing/xen/include/xen/sched.h
===================================================================
--- xen-4.2.2-testing.orig/xen/include/xen/sched.h
+++ xen-4.2.2-testing/xen/include/xen/sched.h
@@ -644,6 +644,9 @@ static inline struct domain *next_domain
/* VCPU is blocked due to missing mem_sharing ring. */
#define _VPF_mem_sharing 6
#define VPF_mem_sharing (1UL<<_VPF_mem_sharing)
+ /* VCPU is being reset. */
+#define _VPF_in_reset 7
+#define VPF_in_reset (1UL<<_VPF_in_reset)
static inline int vcpu_runnable(struct vcpu *v)
{