ia64/xen-unstable

changeset 16927:a4bd1371196e

x86: Fix XENPF_change_freq hypercall to not dereference a non-existent
stack variable. Also sanity check (slightly) the frequency argument to
cpu_frequency_change().
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Jan 29 11:19:04 2008 +0000 (2008-01-29)
parents e23144190f93
children 7aa2149a3b0e
files xen/arch/x86/platform_hypercall.c xen/arch/x86/time.c
line diff
     1.1 --- a/xen/arch/x86/platform_hypercall.c	Tue Jan 29 09:36:37 2008 +0000
     1.2 +++ b/xen/arch/x86/platform_hypercall.c	Tue Jan 29 11:19:04 2008 +0000
     1.3 @@ -42,9 +42,11 @@ DEFINE_SPINLOCK(xenpf_lock);
     1.4  extern spinlock_t xenpf_lock;
     1.5  #endif
     1.6  
     1.7 +static DEFINE_PER_CPU(uint64_t, freq);
     1.8 +
     1.9  static long cpu_frequency_change_helper(void *data)
    1.10  {
    1.11 -    return cpu_frequency_change(*(uint64_t *)data);
    1.12 +    return cpu_frequency_change(this_cpu(freq));
    1.13  }
    1.14  
    1.15  ret_t do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op)
    1.16 @@ -284,11 +286,12 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
    1.17          if ( cpufreq_controller != FREQCTL_dom0_kernel )
    1.18              break;
    1.19          ret = -EINVAL;
    1.20 -        if ( op->u.change_freq.flags != 0 )
    1.21 +        if ( op->u.change_freq.flags || !cpu_online(op->u.change_freq.cpu) )
    1.22              break;
    1.23 +        per_cpu(freq, op->u.change_freq.cpu) = op->u.change_freq.freq;
    1.24          ret = continue_hypercall_on_cpu(op->u.change_freq.cpu,
    1.25                                          cpu_frequency_change_helper,
    1.26 -                                        &op->u.change_freq.freq);
    1.27 +                                        NULL);
    1.28          break;
    1.29  
    1.30      case XENPF_getidletime:
     2.1 --- a/xen/arch/x86/time.c	Tue Jan 29 09:36:37 2008 +0000
     2.2 +++ b/xen/arch/x86/time.c	Tue Jan 29 11:19:04 2008 +0000
     2.3 @@ -729,6 +729,14 @@ int cpu_frequency_change(u64 freq)
     2.4      struct cpu_time *t = &this_cpu(cpu_time);
     2.5      u64 curr_tsc;
     2.6  
     2.7 +    /* Sanity check: CPU frequency allegedly dropping below 1MHz? */
     2.8 +    if ( freq < 1000000u )
     2.9 +    {
    2.10 +        gdprintk(XENLOG_WARNING, "Rejecting CPU frequency change "
    2.11 +                 "to %"PRIu64" Hz.\n", freq);
    2.12 +        return -EINVAL;
    2.13 +    }
    2.14 +
    2.15      local_irq_disable();
    2.16      rdtscll(curr_tsc);
    2.17      t->local_tsc_stamp = curr_tsc;