diff options
author | Jan Beulich <jbeulich@suse.com> | 2011-10-21 09:45:24 +0200 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2011-10-21 09:45:24 +0200 |
commit | 47e0eeb7abc98e04fffd7aaa2158a28106048c44 (patch) | |
tree | 5a685e68a284fb535f2db731f86dfa6700bc899c /xen/arch/x86/platform_hypercall.c | |
parent | c567ffce5c30d41e46e6c93b6aacf11ed62989cc (diff) | |
download | xen-47e0eeb7abc98e04fffd7aaa2158a28106048c44.tar.gz xen-47e0eeb7abc98e04fffd7aaa2158a28106048c44.tar.bz2 xen-47e0eeb7abc98e04fffd7aaa2158a28106048c44.zip |
cpumask <=> xenctl_cpumap: allocate CPU masks and byte maps dynamically
Generally there was a NR_CPUS-bits wide array in these functions and
another (through a cpumask_t) on their callers' stacks, which may get
a little large for big NR_CPUS. As the functions can fail anyway, do
the allocation in there.
For the x86/MCA case this require a little code restructuring: By using
different CPU mask accessors it was possible to avoid allocating a mask
in the broadcast case. Also, this was the only user that failed to
check the return value of the conversion function (which could have led
to undefined behvior).
Also constify the input parameters of the two functions.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen/arch/x86/platform_hypercall.c')
-rw-r--r-- | xen/arch/x86/platform_hypercall.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/xen/arch/x86/platform_hypercall.c b/xen/arch/x86/platform_hypercall.c index 0269e507c9..c1ad9ef636 100644 --- a/xen/arch/x86/platform_hypercall.c +++ b/xen/arch/x86/platform_hypercall.c @@ -346,7 +346,7 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op) uint32_t cpu; uint64_t idletime, now = NOW(); struct xenctl_cpumap ctlmap; - cpumask_t cpumap; + cpumask_var_t cpumap; XEN_GUEST_HANDLE(uint8) cpumap_bitmap; XEN_GUEST_HANDLE(uint64) idletimes; @@ -366,22 +366,26 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op) goto out; guest_from_compat_handle(idletimes, op->u.getidletime.idletime); - for_each_cpu_mask ( cpu, cpumap ) + for_each_cpu_mask ( cpu, *cpumap ) { if ( idle_vcpu[cpu] == NULL ) - cpu_clear(cpu, cpumap); + cpumask_clear_cpu(cpu, cpumap); idletime = get_cpu_idle_time(cpu); - ret = -EFAULT; if ( copy_to_guest_offset(idletimes, cpu, &idletime, 1) ) - goto out; + { + ret = -EFAULT; + break; + } } op->u.getidletime.now = now; - if ( (ret = cpumask_to_xenctl_cpumap(&ctlmap, &cpumap)) != 0 ) - goto out; + if ( ret == 0 ) + ret = cpumask_to_xenctl_cpumap(&ctlmap, cpumap); + free_cpumask_var(cpumap); - ret = copy_to_guest(u_xenpf_op, op, 1) ? -EFAULT : 0; + if ( ret == 0 && copy_to_guest(u_xenpf_op, op, 1) ) + ret = -EFAULT; } break; |