aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/platform_hypercall.c
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2011-10-21 09:45:24 +0200
committerJan Beulich <jbeulich@suse.com>2011-10-21 09:45:24 +0200
commit47e0eeb7abc98e04fffd7aaa2158a28106048c44 (patch)
tree5a685e68a284fb535f2db731f86dfa6700bc899c /xen/arch/x86/platform_hypercall.c
parentc567ffce5c30d41e46e6c93b6aacf11ed62989cc (diff)
downloadxen-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.c20
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;