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>
This commit is contained in:
parent
3c6b5bfa3c
commit
48245cc070
7 changed files with 14 additions and 45 deletions
|
@ -47,10 +47,6 @@ static struct {
|
|||
DEFINE_MUTEX(lguest_lock);
|
||||
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 */
|
||||
static unsigned long switcher_offset(void)
|
||||
{
|
||||
|
@ -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
|
||||
* examine the Switcher, and our philosophical understanding of the Host/Guest
|
||||
* 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)
|
||||
{
|
||||
if (on)
|
||||
|
|
|
@ -225,9 +225,7 @@ static void initialize(struct lguest *lg)
|
|||
/* We tell the Guest that it can't use the top 4MB of virtual
|
||||
* addresses used by the Switcher. */
|
||||
|| put_user(4U*1024*1024, &lg->lguest_data->reserve_mem)
|
||||
|| 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))
|
||||
|| put_user(tsc_speed, &lg->lguest_data->tsc_khz))
|
||||
kill_guest(lg, "bad guest page %p", lg->lguest_data);
|
||||
|
||||
/* We write the current time into the Guest's data page once now. */
|
||||
|
|
|
@ -212,7 +212,7 @@ int bind_dma(struct lguest *lg,
|
|||
lg->dma[i].num_dmas = numdmas;
|
||||
lg->dma[i].next_dma = 0;
|
||||
lg->dma[i].key = key;
|
||||
lg->dma[i].guestid = lg->guestid;
|
||||
lg->dma[i].owner = lg;
|
||||
lg->dma[i].interrupt = interrupt;
|
||||
|
||||
/* Now we add it to the hash table: the position
|
||||
|
@ -412,7 +412,7 @@ static int dma_transfer(struct lguest *srclg,
|
|||
|
||||
/* From the "struct lguest_dma_info" we found in the hash, grab the
|
||||
* Guest. */
|
||||
dstlg = &lguests[dst->guestid];
|
||||
dstlg = dst->owner;
|
||||
/* Read in the source "struct lguest_dma" handed to SEND_DMA. */
|
||||
lgread(srclg, &src_dma, udma, sizeof(src_dma));
|
||||
|
||||
|
@ -506,8 +506,8 @@ void send_dma(struct lguest *lg, unsigned long ukey, unsigned long udma)
|
|||
struct lguest_dma_info *i;
|
||||
/* Look through the hash for other Guests. */
|
||||
list_for_each_entry(i, &dma_hash[hash(&key)], list) {
|
||||
/* Don't send to ourselves. */
|
||||
if (i->guestid == lg->guestid)
|
||||
/* Don't send to ourselves (would deadlock). */
|
||||
if (i->owner->mm == lg->mm)
|
||||
continue;
|
||||
if (!key_eq(&key, &i->key))
|
||||
continue;
|
||||
|
@ -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
|
||||
* Guest) */
|
||||
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;
|
||||
/* Look through the registered DMA array for an
|
||||
* available buffer. */
|
||||
|
|
|
@ -51,9 +51,9 @@ struct lguest_dma_info
|
|||
struct list_head list;
|
||||
union futex_key key;
|
||||
unsigned long dmas;
|
||||
struct lguest *owner;
|
||||
u16 next_dma;
|
||||
u16 num_dmas;
|
||||
u16 guestid;
|
||||
u8 interrupt; /* 0 when not registered */
|
||||
};
|
||||
|
||||
|
@ -140,7 +140,6 @@ struct lguest
|
|||
struct lguest_data __user *lguest_data;
|
||||
struct task_struct *tsk;
|
||||
struct mm_struct *mm; /* == tsk->mm, but that becomes NULL on exit */
|
||||
u16 guestid;
|
||||
u32 pfn_limit;
|
||||
/* This provides the offset to the base of guest-physical
|
||||
* memory in the Launcher. */
|
||||
|
@ -195,7 +194,6 @@ struct lguest
|
|||
DECLARE_BITMAP(irqs_pending, LGUEST_IRQS);
|
||||
};
|
||||
|
||||
extern struct lguest lguests[];
|
||||
extern struct mutex lguest_lock;
|
||||
|
||||
/* core.c: */
|
||||
|
@ -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 lgread(struct lguest *lg, void *buf, unsigned long addr, 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,
|
||||
unsigned long addr, unsigned long len);
|
||||
int run_guest(struct lguest *lg, unsigned long __user *user);
|
||||
|
|
|
@ -167,11 +167,11 @@ static int initialize(struct file *file, const u32 __user *input)
|
|||
/* "struct lguest" contains everything we (the Host) know about a
|
||||
* Guest. */
|
||||
struct lguest *lg;
|
||||
int err, i;
|
||||
int err;
|
||||
u32 args[5];
|
||||
|
||||
/* We grab the Big Lguest lock, which protects the global array
|
||||
* "lguests" and multiple simultaneous initializations. */
|
||||
/* We grab the Big Lguest lock, which protects against multiple
|
||||
* simultaneous initializations. */
|
||||
mutex_lock(&lguest_lock);
|
||||
/* You can't initialize twice! Close the device and start again... */
|
||||
if (file->private_data) {
|
||||
|
@ -184,18 +184,13 @@ static int initialize(struct file *file, const u32 __user *input)
|
|||
goto unlock;
|
||||
}
|
||||
|
||||
/* Find an unused guest. */
|
||||
i = find_free_guest();
|
||||
if (i < 0) {
|
||||
err = -ENOSPC;
|
||||
lg = kzalloc(sizeof(*lg), GFP_KERNEL);
|
||||
if (!lg) {
|
||||
err = -ENOMEM;
|
||||
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" */
|
||||
lg->guestid = i;
|
||||
lg->mem_base = (void __user *)(long)args[0];
|
||||
lg->pfn_limit = args[1];
|
||||
lg->page_offset = args[4];
|
||||
|
|
|
@ -463,12 +463,7 @@ static int lguestnet_probe(struct lguest_device *lgdev)
|
|||
/* Ethernet defaults with some changes */
|
||||
ether_setup(dev);
|
||||
dev->set_mac_address = NULL;
|
||||
|
||||
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;
|
||||
random_ether_addr(dev->dev_addr);
|
||||
|
||||
dev->open = lguestnet_open;
|
||||
dev->stop = lguestnet_close;
|
||||
|
|
|
@ -41,8 +41,6 @@ struct lguest_data
|
|||
/* Fields initialized by the Host at boot: */
|
||||
/* Memory not to try to access */
|
||||
unsigned long reserve_mem;
|
||||
/* ID of this Guest (used by network driver to set ethernet address) */
|
||||
u16 guestid;
|
||||
/* KHz for the TSC clock. */
|
||||
u32 tsc_khz;
|
||||
|
||||
|
|
Loading…
Reference in a new issue