Commit 48245cc0 authored by Rusty Russell's avatar Rusty Russell

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: default avatarRusty Russell <rusty@rustcorp.com.au>
parent 3c6b5bfa
...@@ -47,10 +47,6 @@ static struct { ...@@ -47,10 +47,6 @@ static struct {
DEFINE_MUTEX(lguest_lock); DEFINE_MUTEX(lguest_lock);
static DEFINE_PER_CPU(struct lguest *, last_guest); static DEFINE_PER_CPU(struct lguest *, last_guest);
/* FIXME: Make dynamic. */
#define MAX_LGUEST_GUESTS 16
struct lguest lguests[MAX_LGUEST_GUESTS];
/* Offset from where switcher.S was compiled to where we've copied it */ /* Offset from where switcher.S was compiled to where we've copied it */
static unsigned long switcher_offset(void) static unsigned long switcher_offset(void)
{ {
...@@ -660,16 +656,6 @@ int run_guest(struct lguest *lg, unsigned long __user *user) ...@@ -660,16 +656,6 @@ int run_guest(struct lguest *lg, unsigned long __user *user)
* deliver_trap() and demand_page(). After all those, we'll be ready to * deliver_trap() and demand_page(). After all those, we'll be ready to
* examine the Switcher, and our philosophical understanding of the Host/Guest * examine the Switcher, and our philosophical understanding of the Host/Guest
* duality will be complete. :*/ * duality will be complete. :*/
int find_free_guest(void)
{
unsigned int i;
for (i = 0; i < MAX_LGUEST_GUESTS; i++)
if (!lguests[i].tsk)
return i;
return -1;
}
static void adjust_pge(void *on) static void adjust_pge(void *on)
{ {
if (on) if (on)
......
...@@ -225,9 +225,7 @@ static void initialize(struct lguest *lg) ...@@ -225,9 +225,7 @@ static void initialize(struct lguest *lg)
/* We tell the Guest that it can't use the top 4MB of virtual /* We tell the Guest that it can't use the top 4MB of virtual
* addresses used by the Switcher. */ * addresses used by the Switcher. */
|| put_user(4U*1024*1024, &lg->lguest_data->reserve_mem) || put_user(4U*1024*1024, &lg->lguest_data->reserve_mem)
|| put_user(tsc_speed, &lg->lguest_data->tsc_khz) || put_user(tsc_speed, &lg->lguest_data->tsc_khz))
/* We also give the Guest a unique id, as used in lguest_net.c. */
|| put_user(lg->guestid, &lg->lguest_data->guestid))
kill_guest(lg, "bad guest page %p", lg->lguest_data); kill_guest(lg, "bad guest page %p", lg->lguest_data);
/* We write the current time into the Guest's data page once now. */ /* We write the current time into the Guest's data page once now. */
......
...@@ -212,7 +212,7 @@ int bind_dma(struct lguest *lg, ...@@ -212,7 +212,7 @@ int bind_dma(struct lguest *lg,
lg->dma[i].num_dmas = numdmas; lg->dma[i].num_dmas = numdmas;
lg->dma[i].next_dma = 0; lg->dma[i].next_dma = 0;
lg->dma[i].key = key; lg->dma[i].key = key;
lg->dma[i].guestid = lg->guestid; lg->dma[i].owner = lg;
lg->dma[i].interrupt = interrupt; lg->dma[i].interrupt = interrupt;
/* Now we add it to the hash table: the position /* Now we add it to the hash table: the position
...@@ -412,7 +412,7 @@ static int dma_transfer(struct lguest *srclg, ...@@ -412,7 +412,7 @@ static int dma_transfer(struct lguest *srclg,
/* From the "struct lguest_dma_info" we found in the hash, grab the /* From the "struct lguest_dma_info" we found in the hash, grab the
* Guest. */ * Guest. */
dstlg = &lguests[dst->guestid]; dstlg = dst->owner;
/* Read in the source "struct lguest_dma" handed to SEND_DMA. */ /* Read in the source "struct lguest_dma" handed to SEND_DMA. */
lgread(srclg, &src_dma, udma, sizeof(src_dma)); lgread(srclg, &src_dma, udma, sizeof(src_dma));
...@@ -506,8 +506,8 @@ again: ...@@ -506,8 +506,8 @@ again:
struct lguest_dma_info *i; struct lguest_dma_info *i;
/* Look through the hash for other Guests. */ /* Look through the hash for other Guests. */
list_for_each_entry(i, &dma_hash[hash(&key)], list) { list_for_each_entry(i, &dma_hash[hash(&key)], list) {
/* Don't send to ourselves. */ /* Don't send to ourselves (would deadlock). */
if (i->guestid == lg->guestid) if (i->owner->mm == lg->mm)
continue; continue;
if (!key_eq(&key, &i->key)) if (!key_eq(&key, &i->key))
continue; continue;
...@@ -594,7 +594,7 @@ unsigned long get_dma_buffer(struct lguest *lg, ...@@ -594,7 +594,7 @@ unsigned long get_dma_buffer(struct lguest *lg,
* send to its own Guest for the moment, so the entry must be for this * send to its own Guest for the moment, so the entry must be for this
* Guest) */ * Guest) */
list_for_each_entry(i, &dma_hash[hash(&key)], list) { list_for_each_entry(i, &dma_hash[hash(&key)], list) {
if (key_eq(&key, &i->key) && i->guestid == lg->guestid) { if (key_eq(&key, &i->key) && i->owner == lg) {
unsigned int j; unsigned int j;
/* Look through the registered DMA array for an /* Look through the registered DMA array for an
* available buffer. */ * available buffer. */
......
...@@ -51,9 +51,9 @@ struct lguest_dma_info ...@@ -51,9 +51,9 @@ struct lguest_dma_info
struct list_head list; struct list_head list;
union futex_key key; union futex_key key;
unsigned long dmas; unsigned long dmas;
struct lguest *owner;
u16 next_dma; u16 next_dma;
u16 num_dmas; u16 num_dmas;
u16 guestid;
u8 interrupt; /* 0 when not registered */ u8 interrupt; /* 0 when not registered */
}; };
...@@ -140,7 +140,6 @@ struct lguest ...@@ -140,7 +140,6 @@ struct lguest
struct lguest_data __user *lguest_data; struct lguest_data __user *lguest_data;
struct task_struct *tsk; struct task_struct *tsk;
struct mm_struct *mm; /* == tsk->mm, but that becomes NULL on exit */ struct mm_struct *mm; /* == tsk->mm, but that becomes NULL on exit */
u16 guestid;
u32 pfn_limit; u32 pfn_limit;
/* This provides the offset to the base of guest-physical /* This provides the offset to the base of guest-physical
* memory in the Launcher. */ * memory in the Launcher. */
...@@ -195,7 +194,6 @@ struct lguest ...@@ -195,7 +194,6 @@ struct lguest
DECLARE_BITMAP(irqs_pending, LGUEST_IRQS); DECLARE_BITMAP(irqs_pending, LGUEST_IRQS);
}; };
extern struct lguest lguests[];
extern struct mutex lguest_lock; extern struct mutex lguest_lock;
/* core.c: */ /* core.c: */
...@@ -203,7 +201,6 @@ u32 lgread_u32(struct lguest *lg, unsigned long addr); ...@@ -203,7 +201,6 @@ u32 lgread_u32(struct lguest *lg, unsigned long addr);
void lgwrite_u32(struct lguest *lg, unsigned long addr, u32 val); void lgwrite_u32(struct lguest *lg, unsigned long addr, u32 val);
void lgread(struct lguest *lg, void *buf, unsigned long addr, unsigned len); void lgread(struct lguest *lg, void *buf, unsigned long addr, unsigned len);
void lgwrite(struct lguest *lg, unsigned long, const void *buf, unsigned len); void lgwrite(struct lguest *lg, unsigned long, const void *buf, unsigned len);
int find_free_guest(void);
int lguest_address_ok(const struct lguest *lg, int lguest_address_ok(const struct lguest *lg,
unsigned long addr, unsigned long len); unsigned long addr, unsigned long len);
int run_guest(struct lguest *lg, unsigned long __user *user); int run_guest(struct lguest *lg, unsigned long __user *user);
......
...@@ -167,11 +167,11 @@ static int initialize(struct file *file, const u32 __user *input) ...@@ -167,11 +167,11 @@ static int initialize(struct file *file, const u32 __user *input)
/* "struct lguest" contains everything we (the Host) know about a /* "struct lguest" contains everything we (the Host) know about a
* Guest. */ * Guest. */
struct lguest *lg; struct lguest *lg;
int err, i; int err;
u32 args[5]; u32 args[5];
/* We grab the Big Lguest lock, which protects the global array /* We grab the Big Lguest lock, which protects against multiple
* "lguests" and multiple simultaneous initializations. */ * simultaneous initializations. */
mutex_lock(&lguest_lock); mutex_lock(&lguest_lock);
/* You can't initialize twice! Close the device and start again... */ /* You can't initialize twice! Close the device and start again... */
if (file->private_data) { if (file->private_data) {
...@@ -184,18 +184,13 @@ static int initialize(struct file *file, const u32 __user *input) ...@@ -184,18 +184,13 @@ static int initialize(struct file *file, const u32 __user *input)
goto unlock; goto unlock;
} }
/* Find an unused guest. */ lg = kzalloc(sizeof(*lg), GFP_KERNEL);
i = find_free_guest(); if (!lg) {
if (i < 0) { err = -ENOMEM;
err = -ENOSPC;
goto unlock; goto unlock;
} }
/* OK, we have an index into the "lguest" array: "lg" is a convenient
* pointer. */
lg = &lguests[i];
/* Populate the easy fields of our "struct lguest" */ /* Populate the easy fields of our "struct lguest" */
lg->guestid = i;
lg->mem_base = (void __user *)(long)args[0]; lg->mem_base = (void __user *)(long)args[0];
lg->pfn_limit = args[1]; lg->pfn_limit = args[1];
lg->page_offset = args[4]; lg->page_offset = args[4];
......
...@@ -463,12 +463,7 @@ static int lguestnet_probe(struct lguest_device *lgdev) ...@@ -463,12 +463,7 @@ static int lguestnet_probe(struct lguest_device *lgdev)
/* Ethernet defaults with some changes */ /* Ethernet defaults with some changes */
ether_setup(dev); ether_setup(dev);
dev->set_mac_address = NULL; dev->set_mac_address = NULL;
random_ether_addr(dev->dev_addr);
dev->dev_addr[0] = 0x02; /* set local assignment bit (IEEE802) */
dev->dev_addr[1] = 0x00;
memcpy(&dev->dev_addr[2], &lguest_data.guestid, 2);
dev->dev_addr[4] = 0x00;
dev->dev_addr[5] = 0x00;
dev->open = lguestnet_open; dev->open = lguestnet_open;
dev->stop = lguestnet_close; dev->stop = lguestnet_close;
......
...@@ -41,8 +41,6 @@ struct lguest_data ...@@ -41,8 +41,6 @@ struct lguest_data
/* Fields initialized by the Host at boot: */ /* Fields initialized by the Host at boot: */
/* Memory not to try to access */ /* Memory not to try to access */
unsigned long reserve_mem; unsigned long reserve_mem;
/* ID of this Guest (used by network driver to set ethernet address) */
u16 guestid;
/* KHz for the TSC clock. */ /* KHz for the TSC clock. */
u32 tsc_khz; u32 tsc_khz;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment