/root/src/xen/xen/arch/x86/x86_64/cpu_idle.c
Line | Count | Source (jump to first uncovered line) |
1 | | /****************************************************************************** |
2 | | * cpu_idle.c -- adapt x86/acpi/cpu_idle.c to compat guest. |
3 | | * |
4 | | * Copyright (C) 2007, 2008 Intel Corporation |
5 | | * |
6 | | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
7 | | * |
8 | | * This program is free software; you can redistribute it and/or modify |
9 | | * it under the terms of the GNU General Public License as published by |
10 | | * the Free Software Foundation; either version 2 of the License, or (at |
11 | | * your option) any later version. |
12 | | * |
13 | | * This program is distributed in the hope that it will be useful, but |
14 | | * WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
16 | | * General Public License for more details. |
17 | | * |
18 | | * You should have received a copy of the GNU General Public License along |
19 | | * with this program; If not, see <http://www.gnu.org/licenses/>. |
20 | | * |
21 | | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
22 | | */ |
23 | | |
24 | | #include <xen/types.h> |
25 | | #include <xen/xmalloc.h> |
26 | | #include <xen/guest_access.h> |
27 | | #include <xen/pmstat.h> |
28 | | #include <compat/platform.h> |
29 | | |
30 | | CHECK_processor_csd; |
31 | | |
32 | | DEFINE_XEN_GUEST_HANDLE(compat_processor_csd_t); |
33 | | DEFINE_XEN_GUEST_HANDLE(compat_processor_cx_t); |
34 | | |
35 | | void *xlat_malloc(unsigned long *xlat_page_current, size_t size) |
36 | 0 | { |
37 | 0 | void *ret; |
38 | 0 |
|
39 | 0 | /* normalize size to be 64 * n */ |
40 | 0 | size = (size + 0x3fUL) & ~0x3fUL; |
41 | 0 |
|
42 | 0 | if ( unlikely(size > xlat_page_left_size(*xlat_page_current)) ) |
43 | 0 | return NULL; |
44 | 0 |
|
45 | 0 | ret = (void *) *xlat_page_current; |
46 | 0 | *xlat_page_current += size; |
47 | 0 |
|
48 | 0 | return ret; |
49 | 0 | } |
50 | | |
51 | | static int copy_from_compat_state(xen_processor_cx_t *xen_state, |
52 | | compat_processor_cx_t *state) |
53 | 0 | { |
54 | 0 | #define XLAT_processor_cx_HNDL_dp(_d_, _s_) do { \ |
55 | 0 | XEN_GUEST_HANDLE(compat_processor_csd_t) dps; \ |
56 | 0 | XEN_GUEST_HANDLE_PARAM(xen_processor_csd_t) dps_param; \ |
57 | 0 | if ( unlikely(!compat_handle_okay((_s_)->dp, (_s_)->dpcnt)) ) \ |
58 | 0 | return -EFAULT; \ |
59 | 0 | guest_from_compat_handle(dps, (_s_)->dp); \ |
60 | 0 | dps_param = guest_handle_cast(dps, xen_processor_csd_t); \ |
61 | 0 | (_d_)->dp = guest_handle_from_param(dps_param, xen_processor_csd_t); \ |
62 | 0 | } while (0) |
63 | 0 | XLAT_processor_cx(xen_state, state); |
64 | 0 | #undef XLAT_processor_cx_HNDL_dp |
65 | 0 |
|
66 | 0 | return 0; |
67 | 0 | } |
68 | | |
69 | | long compat_set_cx_pminfo(uint32_t cpu, struct compat_processor_power *power) |
70 | 0 | { |
71 | 0 | struct xen_processor_power *xen_power; |
72 | 0 | unsigned long xlat_page_current; |
73 | 0 |
|
74 | 0 | xlat_malloc_init(xlat_page_current); |
75 | 0 |
|
76 | 0 | xen_power = xlat_malloc_array(xlat_page_current, |
77 | 0 | struct xen_processor_power, 1); |
78 | 0 | if ( unlikely(xen_power == NULL) ) |
79 | 0 | return -EFAULT; |
80 | 0 |
|
81 | 0 | #define XLAT_processor_power_HNDL_states(_d_, _s_) do { \ |
82 | 0 | xen_processor_cx_t *xen_states = NULL; \ |
83 | 0 | \ |
84 | 0 | if ( likely((_s_)->count > 0) ) \ |
85 | 0 | { \ |
86 | 0 | XEN_GUEST_HANDLE(compat_processor_cx_t) states; \ |
87 | 0 | compat_processor_cx_t state; \ |
88 | 0 | int i; \ |
89 | 0 | \ |
90 | 0 | xen_states = xlat_malloc_array(xlat_page_current, \ |
91 | 0 | xen_processor_cx_t, (_s_)->count); \ |
92 | 0 | if ( unlikely(xen_states == NULL) ) \ |
93 | 0 | return -EFAULT; \ |
94 | 0 | \ |
95 | 0 | if ( unlikely(!compat_handle_okay((_s_)->states, (_s_)->count)) ) \ |
96 | 0 | return -EFAULT; \ |
97 | 0 | guest_from_compat_handle(states, (_s_)->states); \ |
98 | 0 | \ |
99 | 0 | for ( i = 0; i < _s_->count; i++ ) \ |
100 | 0 | { \ |
101 | 0 | if ( unlikely(copy_from_guest_offset(&state, states, i, 1)) ) \ |
102 | 0 | return -EFAULT; \ |
103 | 0 | if ( unlikely(copy_from_compat_state(&xen_states[i], &state)) ) \ |
104 | 0 | return -EFAULT; \ |
105 | 0 | } \ |
106 | 0 | } \ |
107 | 0 | \ |
108 | 0 | set_xen_guest_handle((_d_)->states, xen_states); \ |
109 | 0 | } while (0) |
110 | 0 | XLAT_processor_power(xen_power, power); |
111 | 0 | #undef XLAT_processor_power_HNDL_states |
112 | 0 |
|
113 | 0 | return set_cx_pminfo(cpu, xen_power); |
114 | 0 | } |