X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Flguest%2Fio.c;h=0e842e9caf6881f6e3c131ce04045f321dbad08c;hb=0ca49ca946409f87a8cd0b14d5acb6dea58de6f3;hp=da288128e44f8df314ecbc4954064b7ab029edd5;hpb=dde797899ac17ebb812b7566044124d785e98dc7;p=linux-2.6 diff --git a/drivers/lguest/io.c b/drivers/lguest/io.c index da288128e4..0e842e9caf 100644 --- a/drivers/lguest/io.c +++ b/drivers/lguest/io.c @@ -186,7 +186,7 @@ int bind_dma(struct lguest *lg, * we're doing this. */ mutex_lock(&lguest_lock); down_read(fshared); - if (get_futex_key((u32 __user *)ukey, fshared, &key) != 0) { + if (get_futex_key(lg->mem_base + ukey, fshared, &key) != 0) { kill_guest(lg, "bad dma key %#lx", ukey); goto unlock; } @@ -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 @@ -247,7 +247,8 @@ static int lgread_other(struct lguest *lg, void *buf, u32 addr, unsigned bytes) { if (!lguest_address_ok(lg, addr, bytes) - || access_process_vm(lg->tsk, addr, buf, bytes, 0) != bytes) { + || access_process_vm(lg->tsk, (unsigned long)lg->mem_base + addr, + buf, bytes, 0) != bytes) { memset(buf, 0, bytes); kill_guest(lg, "bad address in registered DMA struct"); return 0; @@ -261,8 +262,8 @@ static int lgwrite_other(struct lguest *lg, u32 addr, const void *buf, unsigned bytes) { if (!lguest_address_ok(lg, addr, bytes) - || (access_process_vm(lg->tsk, addr, (void *)buf, bytes, 1) - != bytes)) { + || access_process_vm(lg->tsk, (unsigned long)lg->mem_base + addr, + (void *)buf, bytes, 1) != bytes) { kill_guest(lg, "bad address writing to registered DMA"); return 0; } @@ -318,7 +319,7 @@ static u32 copy_data(struct lguest *srclg, * copy_to_user_page(), and some arch's seem to need special * flushes. x86 is fine. */ if (copy_from_user(maddr + (dst->addr[di] + dstoff)%PAGE_SIZE, - (void __user *)src->addr[si], len) != 0) { + srclg->mem_base+src->addr[si], len) != 0) { /* If a copy failed, it's the source's fault. */ kill_guest(srclg, "bad address in sending DMA"); totlen = 0; @@ -377,7 +378,8 @@ static u32 do_dma(struct lguest *srclg, const struct lguest_dma *src, * number of pages. Note that we're holding the destination's * mmap_sem, as get_user_pages() requires. */ if (get_user_pages(dstlg->tsk, dstlg->mm, - dst->addr[i], 1, 1, 1, pages+i, NULL) + (unsigned long)dstlg->mem_base+dst->addr[i], + 1, 1, 1, pages+i, NULL) != 1) { /* This means the destination gave us a bogus buffer */ kill_guest(dstlg, "Error mapping DMA pages"); @@ -410,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)); @@ -493,7 +495,7 @@ again: mutex_lock(&lguest_lock); down_read(fshared); /* Get the futex key for the key the Guest gave us */ - if (get_futex_key((u32 __user *)ukey, fshared, &key) != 0) { + if (get_futex_key(lg->mem_base + ukey, fshared, &key) != 0) { kill_guest(lg, "bad sending DMA key"); goto unlock; } @@ -504,8 +506,8 @@ again: 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; @@ -553,6 +555,16 @@ void release_all_dma(struct lguest *lg) up_read(&lg->mm->mmap_sem); } +/*M:007 We only return a single DMA buffer to the Launcher, but it would be + * more efficient to return a pointer to the entire array of DMA buffers, which + * it can cache and choose one whenever it wants. + * + * Currently the Launcher uses a write to /dev/lguest, and the return value is + * the address of the DMA structure with the interrupt number placed in + * dma->used_len. If we wanted to return the entire array, we need to return + * the address, array size and interrupt number: this seems to require an + * ioctl(). :*/ + /*L:320 This routine looks for a DMA buffer registered by the Guest on the * given key (using the BIND_DMA hypercall). */ unsigned long get_dma_buffer(struct lguest *lg, @@ -574,7 +586,7 @@ unsigned long get_dma_buffer(struct lguest *lg, /* This can fail if it's not a valid address, or if the address is not * divisible by 4 (the futex code needs that, we don't really). */ - if (get_futex_key((u32 __user *)ukey, fshared, &key) != 0) { + if (get_futex_key(lg->mem_base + ukey, fshared, &key) != 0) { kill_guest(lg, "bad registered DMA buffer"); goto unlock; } @@ -582,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. */