diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2007-10-21 21:03:27 -0400 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2007-10-23 01:49:51 -0400 |
commit | 48245cc0708d49d1d0566b9fa617ad6c5f4c6934 (patch) | |
tree | b396fd2d1ab185aab20894570e7e84bd4f656355 | |
parent | 3c6b5bfa3cf3b4057788e08482a468cc3bc00780 (diff) |
Remove fixed limit on number of guests, and lguests array.
Back when we had all the Guest state in the switcher, we had a fixed
array of them. This is no longer necessary.
If we switch the network code to using random_ether_addr (46 bits is
enough to avoid clashes), we can get rid of the concept of "guest id"
altogether.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
-rw-r--r-- | drivers/lguest/core.c | 14 | ||||
-rw-r--r-- | drivers/lguest/hypercalls.c | 4 | ||||
-rw-r--r-- | drivers/lguest/io.c | 10 | ||||
-rw-r--r-- | drivers/lguest/lg.h | 5 | ||||
-rw-r--r-- | drivers/lguest/lguest_user.c | 17 | ||||
-rw-r--r-- | drivers/net/lguest_net.c | 7 | ||||
-rw-r--r-- | include/linux/lguest.h | 2 |
7 files changed, 14 insertions, 45 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 { | |||
47 | DEFINE_MUTEX(lguest_lock); | 47 | DEFINE_MUTEX(lguest_lock); |
48 | static DEFINE_PER_CPU(struct lguest *, last_guest); | 48 | static DEFINE_PER_CPU(struct lguest *, last_guest); |
49 | 49 | ||
50 | /* FIXME: Make dynamic. */ | ||
51 | #define MAX_LGUEST_GUESTS 16 | ||
52 | struct 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 */ |
55 | static unsigned long switcher_offset(void) | 51 | static 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 | |||
664 | int 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 | |||
673 | static void adjust_pge(void *on) | 659 | static 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 | ||
198 | extern struct lguest lguests[]; | ||
199 | extern struct mutex lguest_lock; | 197 | extern 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); | |||
203 | void lgwrite_u32(struct lguest *lg, unsigned long addr, u32 val); | 201 | void lgwrite_u32(struct lguest *lg, unsigned long addr, u32 val); |
204 | void lgread(struct lguest *lg, void *buf, unsigned long addr, unsigned len); | 202 | void lgread(struct lguest *lg, void *buf, unsigned long addr, unsigned len); |
205 | void lgwrite(struct lguest *lg, unsigned long, const void *buf, unsigned len); | 203 | void lgwrite(struct lguest *lg, unsigned long, const void *buf, unsigned len); |
206 | int find_free_guest(void); | ||
207 | int lguest_address_ok(const struct lguest *lg, | 204 | int lguest_address_ok(const struct lguest *lg, |
208 | unsigned long addr, unsigned long len); | 205 | unsigned long addr, unsigned long len); |
209 | int run_guest(struct lguest *lg, unsigned long __user *user); | 206 | int 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]; |
diff --git a/drivers/net/lguest_net.c b/drivers/net/lguest_net.c index abce2ee8430a..e255476f224f 100644 --- a/drivers/net/lguest_net.c +++ b/drivers/net/lguest_net.c | |||
@@ -463,12 +463,7 @@ static int lguestnet_probe(struct lguest_device *lgdev) | |||
463 | /* Ethernet defaults with some changes */ | 463 | /* Ethernet defaults with some changes */ |
464 | ether_setup(dev); | 464 | ether_setup(dev); |
465 | dev->set_mac_address = NULL; | 465 | dev->set_mac_address = NULL; |
466 | 466 | random_ether_addr(dev->dev_addr); | |
467 | dev->dev_addr[0] = 0x02; /* set local assignment bit (IEEE802) */ | ||
468 | dev->dev_addr[1] = 0x00; | ||
469 | memcpy(&dev->dev_addr[2], &lguest_data.guestid, 2); | ||
470 | dev->dev_addr[4] = 0x00; | ||
471 | dev->dev_addr[5] = 0x00; | ||
472 | 467 | ||
473 | dev->open = lguestnet_open; | 468 | dev->open = lguestnet_open; |
474 | dev->stop = lguestnet_close; | 469 | dev->stop = lguestnet_close; |
diff --git a/include/linux/lguest.h b/include/linux/lguest.h index d4d94a127f35..8e959deed412 100644 --- a/include/linux/lguest.h +++ b/include/linux/lguest.h | |||
@@ -41,8 +41,6 @@ struct lguest_data | |||
41 | /* Fields initialized by the Host at boot: */ | 41 | /* Fields initialized by the Host at boot: */ |
42 | /* Memory not to try to access */ | 42 | /* Memory not to try to access */ |
43 | unsigned long reserve_mem; | 43 | unsigned long reserve_mem; |
44 | /* ID of this Guest (used by network driver to set ethernet address) */ | ||
45 | u16 guestid; | ||
46 | /* KHz for the TSC clock. */ | 44 | /* KHz for the TSC clock. */ |
47 | u32 tsc_khz; | 45 | u32 tsc_khz; |
48 | 46 | ||