aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/lguest
diff options
context:
space:
mode:
authorGlauber de Oliveira Costa <gcosta@redhat.com>2008-01-07 08:05:25 -0500
committerRusty Russell <rusty@rustcorp.com.au>2008-01-30 06:50:06 -0500
commitd0953d42c3445a120299fac9ad70e672d77898e9 (patch)
treea631abb2c154bec66cec05508423da705d02f35b /drivers/lguest
parent4dcc53da49c2387078fe8ceb7a420d125e027fc6 (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.c6
-rw-r--r--drivers/lguest/lg.h4
-rw-r--r--drivers/lguest/lguest_user.c12
-rw-r--r--drivers/lguest/x86/core.c14
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. */
177int run_guest(struct lguest *lg, unsigned long __user *user) 177int 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
129int run_guest(struct lguest *lg, unsigned long __user *user); 129int 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: */
178void lguest_arch_host_init(void); 178void lguest_arch_host_init(void);
179void lguest_arch_host_fini(void); 179void lguest_arch_host_fini(void);
180void lguest_arch_run_guest(struct lguest *lg); 180void lguest_arch_run_guest(struct lg_cpu *cpu);
181void lguest_arch_handle_trap(struct lguest *lg); 181void lguest_arch_handle_trap(struct lguest *lg);
182int lguest_arch_init_hypercalls(struct lguest *lg); 182int lguest_arch_init_hypercalls(struct lguest *lg);
183int lguest_arch_do_hcall(struct lguest *lg, struct hcall_args *args); 183int 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)
55static ssize_t read(struct file *file, char __user *user, size_t size,loff_t*o) 55static 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
91static int lg_cpu_start(struct lg_cpu *cpu, unsigned id, unsigned long start_ip) 99static 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 */
76static void copy_in_guest_info(struct lguest *lg, struct lguest_pages *pages) 76static 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. */
116static void run_guest_once(struct lguest *lg, struct lguest_pages *pages) 117static 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. */
164void lguest_arch_run_guest(struct lguest *lg) 166void 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