aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/lguest
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/lguest')
-rw-r--r--drivers/lguest/core.c14
-rw-r--r--drivers/lguest/hypercalls.c4
-rw-r--r--drivers/lguest/io.c10
-rw-r--r--drivers/lguest/lg.h5
-rw-r--r--drivers/lguest/lguest_user.c17
5 files changed, 13 insertions, 37 deletions
diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c
index eb95860cf098..ca581ef591e8 100644
--- a/drivers/lguest/core.c
+++ b/drivers/lguest/core.c
@@ -47,10 +47,6 @@ static struct {
47DEFINE_MUTEX(lguest_lock); 47DEFINE_MUTEX(lguest_lock);
48static DEFINE_PER_CPU(struct lguest *, last_guest); 48static DEFINE_PER_CPU(struct lguest *, last_guest);
49 49
50/* FIXME: Make dynamic. */
51#define MAX_LGUEST_GUESTS 16
52struct lguest lguests[MAX_LGUEST_GUESTS];
53
54/* Offset from where switcher.S was compiled to where we've copied it */ 50/* Offset from where switcher.S was compiled to where we've copied it */
55static unsigned long switcher_offset(void) 51static unsigned long switcher_offset(void)
56{ 52{
@@ -660,16 +656,6 @@ int run_guest(struct lguest *lg, unsigned long __user *user)
660 * deliver_trap() and demand_page(). After all those, we'll be ready to 656 * deliver_trap() and demand_page(). After all those, we'll be ready to
661 * examine the Switcher, and our philosophical understanding of the Host/Guest 657 * examine the Switcher, and our philosophical understanding of the Host/Guest
662 * duality will be complete. :*/ 658 * duality will be complete. :*/
663
664int find_free_guest(void)
665{
666 unsigned int i;
667 for (i = 0; i < MAX_LGUEST_GUESTS; i++)
668 if (!lguests[i].tsk)
669 return i;
670 return -1;
671}
672
673static void adjust_pge(void *on) 659static void adjust_pge(void *on)
674{ 660{
675 if (on) 661 if (on)
diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
index 02e67b49ea4f..8bde20934f91 100644
--- a/drivers/lguest/hypercalls.c
+++ b/drivers/lguest/hypercalls.c
@@ -225,9 +225,7 @@ static void initialize(struct lguest *lg)
225 /* We tell the Guest that it can't use the top 4MB of virtual 225 /* We tell the Guest that it can't use the top 4MB of virtual
226 * addresses used by the Switcher. */ 226 * addresses used by the Switcher. */
227 || put_user(4U*1024*1024, &lg->lguest_data->reserve_mem) 227 || put_user(4U*1024*1024, &lg->lguest_data->reserve_mem)
228 || put_user(tsc_speed, &lg->lguest_data->tsc_khz) 228 || put_user(tsc_speed, &lg->lguest_data->tsc_khz))
229 /* We also give the Guest a unique id, as used in lguest_net.c. */
230 || put_user(lg->guestid, &lg->lguest_data->guestid))
231 kill_guest(lg, "bad guest page %p", lg->lguest_data); 229 kill_guest(lg, "bad guest page %p", lg->lguest_data);
232 230
233 /* We write the current time into the Guest's data page once now. */ 231 /* We write the current time into the Guest's data page once now. */
diff --git a/drivers/lguest/io.c b/drivers/lguest/io.c
index 3a845335fee8..0e842e9caf68 100644
--- a/drivers/lguest/io.c
+++ b/drivers/lguest/io.c
@@ -212,7 +212,7 @@ int bind_dma(struct lguest *lg,
212 lg->dma[i].num_dmas = numdmas; 212 lg->dma[i].num_dmas = numdmas;
213 lg->dma[i].next_dma = 0; 213 lg->dma[i].next_dma = 0;
214 lg->dma[i].key = key; 214 lg->dma[i].key = key;
215 lg->dma[i].guestid = lg->guestid; 215 lg->dma[i].owner = lg;
216 lg->dma[i].interrupt = interrupt; 216 lg->dma[i].interrupt = interrupt;
217 217
218 /* Now we add it to the hash table: the position 218 /* Now we add it to the hash table: the position
@@ -412,7 +412,7 @@ static int dma_transfer(struct lguest *srclg,
412 412
413 /* From the "struct lguest_dma_info" we found in the hash, grab the 413 /* From the "struct lguest_dma_info" we found in the hash, grab the
414 * Guest. */ 414 * Guest. */
415 dstlg = &lguests[dst->guestid]; 415 dstlg = dst->owner;
416 /* Read in the source "struct lguest_dma" handed to SEND_DMA. */ 416 /* Read in the source "struct lguest_dma" handed to SEND_DMA. */
417 lgread(srclg, &src_dma, udma, sizeof(src_dma)); 417 lgread(srclg, &src_dma, udma, sizeof(src_dma));
418 418
@@ -506,8 +506,8 @@ again:
506 struct lguest_dma_info *i; 506 struct lguest_dma_info *i;
507 /* Look through the hash for other Guests. */ 507 /* Look through the hash for other Guests. */
508 list_for_each_entry(i, &dma_hash[hash(&key)], list) { 508 list_for_each_entry(i, &dma_hash[hash(&key)], list) {
509 /* Don't send to ourselves. */ 509 /* Don't send to ourselves (would deadlock). */
510 if (i->guestid == lg->guestid) 510 if (i->owner->mm == lg->mm)
511 continue; 511 continue;
512 if (!key_eq(&key, &i->key)) 512 if (!key_eq(&key, &i->key))
513 continue; 513 continue;
@@ -594,7 +594,7 @@ unsigned long get_dma_buffer(struct lguest *lg,
594 * send to its own Guest for the moment, so the entry must be for this 594 * send to its own Guest for the moment, so the entry must be for this
595 * Guest) */ 595 * Guest) */
596 list_for_each_entry(i, &dma_hash[hash(&key)], list) { 596 list_for_each_entry(i, &dma_hash[hash(&key)], list) {
597 if (key_eq(&key, &i->key) && i->guestid == lg->guestid) { 597 if (key_eq(&key, &i->key) && i->owner == lg) {
598 unsigned int j; 598 unsigned int j;
599 /* Look through the registered DMA array for an 599 /* Look through the registered DMA array for an
600 * available buffer. */ 600 * available buffer. */
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index 54f2c2472bec..c9d1dc29490d 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -51,9 +51,9 @@ struct lguest_dma_info
51 struct list_head list; 51 struct list_head list;
52 union futex_key key; 52 union futex_key key;
53 unsigned long dmas; 53 unsigned long dmas;
54 struct lguest *owner;
54 u16 next_dma; 55 u16 next_dma;
55 u16 num_dmas; 56 u16 num_dmas;
56 u16 guestid;
57 u8 interrupt; /* 0 when not registered */ 57 u8 interrupt; /* 0 when not registered */
58}; 58};
59 59
@@ -140,7 +140,6 @@ struct lguest
140 struct lguest_data __user *lguest_data; 140 struct lguest_data __user *lguest_data;
141 struct task_struct *tsk; 141 struct task_struct *tsk;
142 struct mm_struct *mm; /* == tsk->mm, but that becomes NULL on exit */ 142 struct mm_struct *mm; /* == tsk->mm, but that becomes NULL on exit */
143 u16 guestid;
144 u32 pfn_limit; 143 u32 pfn_limit;
145 /* This provides the offset to the base of guest-physical 144 /* This provides the offset to the base of guest-physical
146 * memory in the Launcher. */ 145 * memory in the Launcher. */
@@ -195,7 +194,6 @@ struct lguest
195 DECLARE_BITMAP(irqs_pending, LGUEST_IRQS); 194 DECLARE_BITMAP(irqs_pending, LGUEST_IRQS);
196}; 195};
197 196
198extern struct lguest lguests[];
199extern struct mutex lguest_lock; 197extern struct mutex lguest_lock;
200 198
201/* core.c: */ 199/* core.c: */
@@ -203,7 +201,6 @@ u32 lgread_u32(struct lguest *lg, unsigned long addr);
203void lgwrite_u32(struct lguest *lg, unsigned long addr, u32 val); 201void lgwrite_u32(struct lguest *lg, unsigned long addr, u32 val);
204void lgread(struct lguest *lg, void *buf, unsigned long addr, unsigned len); 202void lgread(struct lguest *lg, void *buf, unsigned long addr, unsigned len);
205void lgwrite(struct lguest *lg, unsigned long, const void *buf, unsigned len); 203void lgwrite(struct lguest *lg, unsigned long, const void *buf, unsigned len);
206int find_free_guest(void);
207int lguest_address_ok(const struct lguest *lg, 204int lguest_address_ok(const struct lguest *lg,
208 unsigned long addr, unsigned long len); 205 unsigned long addr, unsigned long len);
209int run_guest(struct lguest *lg, unsigned long __user *user); 206int run_guest(struct lguest *lg, unsigned long __user *user);
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
index 816d4d12a801..5632ed82798a 100644
--- a/drivers/lguest/lguest_user.c
+++ b/drivers/lguest/lguest_user.c
@@ -167,11 +167,11 @@ static int initialize(struct file *file, const u32 __user *input)
167 /* "struct lguest" contains everything we (the Host) know about a 167 /* "struct lguest" contains everything we (the Host) know about a
168 * Guest. */ 168 * Guest. */
169 struct lguest *lg; 169 struct lguest *lg;
170 int err, i; 170 int err;
171 u32 args[5]; 171 u32 args[5];
172 172
173 /* We grab the Big Lguest lock, which protects the global array 173 /* We grab the Big Lguest lock, which protects against multiple
174 * "lguests" and multiple simultaneous initializations. */ 174 * simultaneous initializations. */
175 mutex_lock(&lguest_lock); 175 mutex_lock(&lguest_lock);
176 /* You can't initialize twice! Close the device and start again... */ 176 /* You can't initialize twice! Close the device and start again... */
177 if (file->private_data) { 177 if (file->private_data) {
@@ -184,18 +184,13 @@ static int initialize(struct file *file, const u32 __user *input)
184 goto unlock; 184 goto unlock;
185 } 185 }
186 186
187 /* Find an unused guest. */ 187 lg = kzalloc(sizeof(*lg), GFP_KERNEL);
188 i = find_free_guest(); 188 if (!lg) {
189 if (i < 0) { 189 err = -ENOMEM;
190 err = -ENOSPC;
191 goto unlock; 190 goto unlock;
192 } 191 }
193 /* OK, we have an index into the "lguest" array: "lg" is a convenient
194 * pointer. */
195 lg = &lguests[i];
196 192
197 /* Populate the easy fields of our "struct lguest" */ 193 /* Populate the easy fields of our "struct lguest" */
198 lg->guestid = i;
199 lg->mem_base = (void __user *)(long)args[0]; 194 lg->mem_base = (void __user *)(long)args[0];
200 lg->pfn_limit = args[1]; 195 lg->pfn_limit = args[1];
201 lg->page_offset = args[4]; 196 lg->page_offset = args[4];