* 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;
}
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
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;
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;
}
* 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;
* 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");
/* 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));
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;
}
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;
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,
/* 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;
}
* 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. */