diff options
author | Glauber de Oliveira Costa <gcosta@redhat.com> | 2008-01-07 08:05:25 -0500 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2008-01-30 06:50:06 -0500 |
commit | d0953d42c3445a120299fac9ad70e672d77898e9 (patch) | |
tree | a631abb2c154bec66cec05508423da705d02f35b /drivers/lguest | |
parent | 4dcc53da49c2387078fe8ceb7a420d125e027fc6 (diff) |
lguest: per-cpu run guest
This patch makes the run_guest() routine use the lg_cpu struct.
This is required since in a smp guest environment, there's no
more the notion of "running the guest", but rather, it is "running the vcpu"
Signed-off-by: Glauber de Oliveira Costa <gcosta@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'drivers/lguest')
-rw-r--r-- | drivers/lguest/core.c | 6 | ||||
-rw-r--r-- | drivers/lguest/lg.h | 4 | ||||
-rw-r--r-- | drivers/lguest/lguest_user.c | 12 | ||||
-rw-r--r-- | drivers/lguest/x86/core.c | 14 |
4 files changed, 25 insertions, 11 deletions
diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c index c1069bceba11..75b38f2c778a 100644 --- a/drivers/lguest/core.c +++ b/drivers/lguest/core.c | |||
@@ -174,8 +174,10 @@ void __lgwrite(struct lguest *lg, unsigned long addr, const void *b, | |||
174 | /*H:030 Let's jump straight to the the main loop which runs the Guest. | 174 | /*H:030 Let's jump straight to the the main loop which runs the Guest. |
175 | * Remember, this is called by the Launcher reading /dev/lguest, and we keep | 175 | * Remember, this is called by the Launcher reading /dev/lguest, and we keep |
176 | * going around and around until something interesting happens. */ | 176 | * going around and around until something interesting happens. */ |
177 | int run_guest(struct lguest *lg, unsigned long __user *user) | 177 | int run_guest(struct lg_cpu *cpu, unsigned long __user *user) |
178 | { | 178 | { |
179 | struct lguest *lg = cpu->lg; | ||
180 | |||
179 | /* We stop running once the Guest is dead. */ | 181 | /* We stop running once the Guest is dead. */ |
180 | while (!lg->dead) { | 182 | while (!lg->dead) { |
181 | /* First we run any hypercalls the Guest wants done. */ | 183 | /* First we run any hypercalls the Guest wants done. */ |
@@ -226,7 +228,7 @@ int run_guest(struct lguest *lg, unsigned long __user *user) | |||
226 | local_irq_disable(); | 228 | local_irq_disable(); |
227 | 229 | ||
228 | /* Actually run the Guest until something happens. */ | 230 | /* Actually run the Guest until something happens. */ |
229 | lguest_arch_run_guest(lg); | 231 | lguest_arch_run_guest(cpu); |
230 | 232 | ||
231 | /* Now we're ready to be interrupted or moved to other CPUs */ | 233 | /* Now we're ready to be interrupted or moved to other CPUs */ |
232 | local_irq_enable(); | 234 | local_irq_enable(); |
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h index 5f73ddff0e3d..bfca2716ad11 100644 --- a/drivers/lguest/lg.h +++ b/drivers/lguest/lg.h | |||
@@ -126,7 +126,7 @@ void __lgwrite(struct lguest *, unsigned long, const void *, unsigned); | |||
126 | } while(0) | 126 | } while(0) |
127 | /* (end of memory access helper routines) :*/ | 127 | /* (end of memory access helper routines) :*/ |
128 | 128 | ||
129 | int run_guest(struct lguest *lg, unsigned long __user *user); | 129 | int run_guest(struct lg_cpu *cpu, unsigned long __user *user); |
130 | 130 | ||
131 | /* Helper macros to obtain the first 12 or the last 20 bits, this is only the | 131 | /* Helper macros to obtain the first 12 or the last 20 bits, this is only the |
132 | * first step in the migration to the kernel types. pte_pfn is already defined | 132 | * first step in the migration to the kernel types. pte_pfn is already defined |
@@ -177,7 +177,7 @@ void page_table_guest_data_init(struct lguest *lg); | |||
177 | /* <arch>/core.c: */ | 177 | /* <arch>/core.c: */ |
178 | void lguest_arch_host_init(void); | 178 | void lguest_arch_host_init(void); |
179 | void lguest_arch_host_fini(void); | 179 | void lguest_arch_host_fini(void); |
180 | void lguest_arch_run_guest(struct lguest *lg); | 180 | void lguest_arch_run_guest(struct lg_cpu *cpu); |
181 | void lguest_arch_handle_trap(struct lguest *lg); | 181 | void lguest_arch_handle_trap(struct lguest *lg); |
182 | int lguest_arch_init_hypercalls(struct lguest *lg); | 182 | int lguest_arch_init_hypercalls(struct lguest *lg); |
183 | int lguest_arch_do_hcall(struct lguest *lg, struct hcall_args *args); | 183 | int lguest_arch_do_hcall(struct lguest *lg, struct hcall_args *args); |
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c index c4bfe5a2b6b7..9f0a44329947 100644 --- a/drivers/lguest/lguest_user.c +++ b/drivers/lguest/lguest_user.c | |||
@@ -55,11 +55,19 @@ static int user_send_irq(struct lguest *lg, const unsigned long __user *input) | |||
55 | static ssize_t read(struct file *file, char __user *user, size_t size,loff_t*o) | 55 | static ssize_t read(struct file *file, char __user *user, size_t size,loff_t*o) |
56 | { | 56 | { |
57 | struct lguest *lg = file->private_data; | 57 | struct lguest *lg = file->private_data; |
58 | struct lg_cpu *cpu; | ||
59 | unsigned int cpu_id = *o; | ||
58 | 60 | ||
59 | /* You must write LHREQ_INITIALIZE first! */ | 61 | /* You must write LHREQ_INITIALIZE first! */ |
60 | if (!lg) | 62 | if (!lg) |
61 | return -EINVAL; | 63 | return -EINVAL; |
62 | 64 | ||
65 | /* Watch out for arbitrary vcpu indexes! */ | ||
66 | if (cpu_id >= lg->nr_cpus) | ||
67 | return -EINVAL; | ||
68 | |||
69 | cpu = &lg->cpus[cpu_id]; | ||
70 | |||
63 | /* If you're not the task which owns the Guest, go away. */ | 71 | /* If you're not the task which owns the Guest, go away. */ |
64 | if (current != lg->tsk) | 72 | if (current != lg->tsk) |
65 | return -EPERM; | 73 | return -EPERM; |
@@ -85,7 +93,7 @@ static ssize_t read(struct file *file, char __user *user, size_t size,loff_t*o) | |||
85 | lg->pending_notify = 0; | 93 | lg->pending_notify = 0; |
86 | 94 | ||
87 | /* Run the Guest until something interesting happens. */ | 95 | /* Run the Guest until something interesting happens. */ |
88 | return run_guest(lg, (unsigned long __user *)user); | 96 | return run_guest(cpu, (unsigned long __user *)user); |
89 | } | 97 | } |
90 | 98 | ||
91 | static int lg_cpu_start(struct lg_cpu *cpu, unsigned id, unsigned long start_ip) | 99 | static int lg_cpu_start(struct lg_cpu *cpu, unsigned id, unsigned long start_ip) |
@@ -147,7 +155,7 @@ static int initialize(struct file *file, const unsigned long __user *input) | |||
147 | lg->pfn_limit = args[1]; | 155 | lg->pfn_limit = args[1]; |
148 | 156 | ||
149 | /* This is the first cpu */ | 157 | /* This is the first cpu */ |
150 | err = cpu_start(&lg->cpus[0], 0, args[3]); | 158 | err = lg_cpu_start(&lg->cpus[0], 0, args[3]); |
151 | if (err) | 159 | if (err) |
152 | goto release_guest; | 160 | goto release_guest; |
153 | 161 | ||
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c index 96d0fd07c57d..3d2131e169fd 100644 --- a/drivers/lguest/x86/core.c +++ b/drivers/lguest/x86/core.c | |||
@@ -73,8 +73,9 @@ static DEFINE_PER_CPU(struct lguest *, last_guest); | |||
73 | * since it last ran. We saw this set in interrupts_and_traps.c and | 73 | * since it last ran. We saw this set in interrupts_and_traps.c and |
74 | * segments.c. | 74 | * segments.c. |
75 | */ | 75 | */ |
76 | static void copy_in_guest_info(struct lguest *lg, struct lguest_pages *pages) | 76 | static void copy_in_guest_info(struct lg_cpu *cpu, struct lguest_pages *pages) |
77 | { | 77 | { |
78 | struct lguest *lg = cpu->lg; | ||
78 | /* Copying all this data can be quite expensive. We usually run the | 79 | /* Copying all this data can be quite expensive. We usually run the |
79 | * same Guest we ran last time (and that Guest hasn't run anywhere else | 80 | * same Guest we ran last time (and that Guest hasn't run anywhere else |
80 | * meanwhile). If that's not the case, we pretend everything in the | 81 | * meanwhile). If that's not the case, we pretend everything in the |
@@ -113,14 +114,15 @@ static void copy_in_guest_info(struct lguest *lg, struct lguest_pages *pages) | |||
113 | } | 114 | } |
114 | 115 | ||
115 | /* Finally: the code to actually call into the Switcher to run the Guest. */ | 116 | /* Finally: the code to actually call into the Switcher to run the Guest. */ |
116 | static void run_guest_once(struct lguest *lg, struct lguest_pages *pages) | 117 | static void run_guest_once(struct lg_cpu *cpu, struct lguest_pages *pages) |
117 | { | 118 | { |
118 | /* This is a dummy value we need for GCC's sake. */ | 119 | /* This is a dummy value we need for GCC's sake. */ |
119 | unsigned int clobber; | 120 | unsigned int clobber; |
121 | struct lguest *lg = cpu->lg; | ||
120 | 122 | ||
121 | /* Copy the guest-specific information into this CPU's "struct | 123 | /* Copy the guest-specific information into this CPU's "struct |
122 | * lguest_pages". */ | 124 | * lguest_pages". */ |
123 | copy_in_guest_info(lg, pages); | 125 | copy_in_guest_info(cpu, pages); |
124 | 126 | ||
125 | /* Set the trap number to 256 (impossible value). If we fault while | 127 | /* Set the trap number to 256 (impossible value). If we fault while |
126 | * switching to the Guest (bad segment registers or bug), this will | 128 | * switching to the Guest (bad segment registers or bug), this will |
@@ -161,8 +163,10 @@ static void run_guest_once(struct lguest *lg, struct lguest_pages *pages) | |||
161 | 163 | ||
162 | /*H:040 This is the i386-specific code to setup and run the Guest. Interrupts | 164 | /*H:040 This is the i386-specific code to setup and run the Guest. Interrupts |
163 | * are disabled: we own the CPU. */ | 165 | * are disabled: we own the CPU. */ |
164 | void lguest_arch_run_guest(struct lguest *lg) | 166 | void lguest_arch_run_guest(struct lg_cpu *cpu) |
165 | { | 167 | { |
168 | struct lguest *lg = cpu->lg; | ||
169 | |||
166 | /* Remember the awfully-named TS bit? If the Guest has asked to set it | 170 | /* Remember the awfully-named TS bit? If the Guest has asked to set it |
167 | * we set it now, so we can trap and pass that trap to the Guest if it | 171 | * we set it now, so we can trap and pass that trap to the Guest if it |
168 | * uses the FPU. */ | 172 | * uses the FPU. */ |
@@ -180,7 +184,7 @@ void lguest_arch_run_guest(struct lguest *lg) | |||
180 | /* Now we actually run the Guest. It will return when something | 184 | /* Now we actually run the Guest. It will return when something |
181 | * interesting happens, and we can examine its registers to see what it | 185 | * interesting happens, and we can examine its registers to see what it |
182 | * was doing. */ | 186 | * was doing. */ |
183 | run_guest_once(lg, lguest_pages(raw_smp_processor_id())); | 187 | run_guest_once(cpu, lguest_pages(raw_smp_processor_id())); |
184 | 188 | ||
185 | /* Note that the "regs" pointer contains two extra entries which are | 189 | /* Note that the "regs" pointer contains two extra entries which are |
186 | * not really registers: a trap number which says what interrupt or | 190 | * not really registers: a trap number which says what interrupt or |