[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] merge two heads
# HG changeset patch # User djm@xxxxxxxxxxxxxxx # Node ID bf3fdeeba48bf3172b938120a95e19e98cd473f3 # Parent 888877bc3d798a0f756a01a45caf2d9b2ada0138 # Parent 21ad2828dbdf9c79f90f82e0a55e227268b23a60 merge two heads diff -r 888877bc3d79 -r bf3fdeeba48b xen/arch/ia64/xen/grant_table.c --- a/xen/arch/ia64/xen/grant_table.c Thu Sep 1 19:01:55 2005 +++ b/xen/arch/ia64/xen/grant_table.c Fri Sep 2 18:31:56 2005 @@ -8,6 +8,8 @@ * * Copyright (c) 2005 Christopher Clark * Copyright (c) 2004 K A Fraser + * Copyright (c) 2005 Andrew Warfield + * Modifications by Geoffrey Lefebvre are (c) Intel Research Cambridge * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,13 +36,18 @@ #include <xen/mm.h> #ifdef __ia64__ #define __addr_ok(a) 1 // FIXME-ia64: a variant of access_ok?? -// FIXME-ia64: need to implement real cmpxchg_user on ia64 -//#define cmpxchg_user(_p,_o,_n) ((*_p == _o) ? ((*_p = _n), 0) : ((_o = *_p), 0)) // FIXME-ia64: these belong in an asm/grant_table.h... PAGE_SIZE different #undef ORDER_GRANT_FRAMES //#undef NUM_GRANT_FRAMES #define ORDER_GRANT_FRAMES 0 //#define NUM_GRANT_FRAMES (1U << ORDER_GRANT_FRAMES) +#endif +#include <acm/acm_hooks.h> + +#if defined(CONFIG_X86_64) +#define GRANT_PTE_FLAGS (_PAGE_PRESENT|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) +#else +#define GRANT_PTE_FLAGS (_PAGE_PRESENT|_PAGE_ACCESSED|_PAGE_DIRTY) #endif #define PIN_FAIL(_lbl, _rc, _f, _a...) \ @@ -55,7 +62,7 @@ grant_table_t *t) { unsigned int h; - if ( unlikely((h = t->maptrack_head) == t->maptrack_limit) ) + if ( unlikely((h = t->maptrack_head) == (t->maptrack_limit - 1)) ) return -1; t->maptrack_head = t->maptrack[h].ref_and_flags >> MAPTRACK_REF_SHIFT; t->map_count++; @@ -73,13 +80,13 @@ static int __gnttab_activate_grant_ref( - struct domain *mapping_d, /* IN */ + struct domain *mapping_d, /* IN */ struct vcpu *mapping_ed, - struct domain *granting_d, - grant_ref_t ref, - u16 dev_hst_ro_flags, - unsigned long host_virt_addr, - unsigned long *pframe ) /* OUT */ + struct domain *granting_d, + grant_ref_t ref, + u16 dev_hst_ro_flags, + u64 addr, + unsigned long *pframe ) /* OUT */ { domid_t sdom; u16 sflags; @@ -100,7 +107,7 @@ * Returns: * . -ve: error * . 1: ok - * . 0: ok and TLB invalidate of host_virt_addr needed. + * . 0: ok and TLB invalidate of host_addr needed. * * On success, *pframe contains mfn. */ @@ -126,6 +133,10 @@ sflags = sha->flags; sdom = sha->domid; + /* This loop attempts to set the access (reading/writing) flags + * in the grant table entry. It tries a cmpxchg on the field + * up to five times, and then fails under the assumption that + * the guest is misbehaving. */ for ( ; ; ) { u32 scombo, prev_scombo, new_scombo; @@ -188,7 +199,7 @@ PIN_FAIL(unlock_out, GNTST_general_error, "Could not pin the granted frame (%lx)!\n", frame); } -#endif +#endif if ( dev_hst_ro_flags & GNTMAP_device_map ) act->pin += (dev_hst_ro_flags & GNTMAP_readonly) ? @@ -266,7 +277,7 @@ /* * At this point: - * act->pin updated to reflect mapping. + * act->pin updated to reference count mappings. * sha->flags updated to indicate to granting domain mapping done. * frame contains the mfn. */ @@ -276,21 +287,25 @@ #ifdef __ia64__ // FIXME-ia64: any error checking need to be done here? #else - if ( (host_virt_addr != 0) && (dev_hst_ro_flags & GNTMAP_host_map) ) + if ( (addr != 0) && (dev_hst_ro_flags & GNTMAP_host_map) ) { /* Write update into the pagetable. */ l1_pgentry_t pte; - pte = l1e_from_pfn(frame, _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY); + pte = l1e_from_pfn(frame, GRANT_PTE_FLAGS); + + if ( (dev_hst_ro_flags & GNTMAP_application_map) ) + l1e_add_flags(pte,_PAGE_USER); if ( !(dev_hst_ro_flags & GNTMAP_readonly) ) l1e_add_flags(pte,_PAGE_RW); - rc = update_grant_va_mapping( host_virt_addr, pte, - mapping_d, mapping_ed ); - - /* - * IMPORTANT: (rc == 0) => must flush / invalidate entry in TLB. - * This is done in the outer gnttab_map_grant_ref. - */ - + + if ( dev_hst_ro_flags & GNTMAP_contains_pte ) + rc = update_grant_pte_mapping(addr, pte, mapping_d, mapping_ed); + else + rc = update_grant_va_mapping(addr, pte, mapping_d, mapping_ed); + + /* IMPORTANT: rc indicates the degree of TLB flush that is required. + * GNTST_flush_one (1) or GNTST_flush_all (2). This is done in the + * outer gnttab_map_grant_ref. */ if ( rc < 0 ) { /* Failure: undo and abort. */ @@ -334,20 +349,24 @@ /* * Returns 0 if TLB flush / invalidate required by caller. * va will indicate the address to be invalidated. + * + * addr is _either_ a host virtual address, or the address of the pte to + * update, as indicated by the GNTMAP_contains_pte flag. */ static int __gnttab_map_grant_ref( gnttab_map_grant_ref_t *uop, unsigned long *va) { - domid_t dom; - grant_ref_t ref; - struct domain *ld, *rd; + domid_t dom; + grant_ref_t ref; + struct domain *ld, *rd; struct vcpu *led; - u16 dev_hst_ro_flags; - int handle; - unsigned long frame = 0, host_virt_addr; - int rc; + u16 dev_hst_ro_flags; + int handle; + u64 addr; + unsigned long frame = 0; + int rc; led = current; ld = led->domain; @@ -355,19 +374,20 @@ /* Bitwise-OR avoids short-circuiting which screws control flow. */ if ( unlikely(__get_user(dom, &uop->dom) | __get_user(ref, &uop->ref) | - __get_user(host_virt_addr, &uop->host_addr) | + __get_user(addr, &uop->host_addr) | __get_user(dev_hst_ro_flags, &uop->flags)) ) { DPRINTK("Fault while reading gnttab_map_grant_ref_t.\n"); return -EFAULT; /* don't set status */ } - - if ( ((host_virt_addr != 0) || (dev_hst_ro_flags & GNTMAP_host_map)) && - unlikely(!__addr_ok(host_virt_addr))) - { - DPRINTK("Bad virtual address (%lx) or flags (%x).\n", - host_virt_addr, dev_hst_ro_flags); + if ( (dev_hst_ro_flags & GNTMAP_host_map) && + ( (addr == 0) || + (!(dev_hst_ro_flags & GNTMAP_contains_pte) && + unlikely(!__addr_ok(addr))) ) ) + { + DPRINTK("Bad virtual address (%"PRIx64") or flags (%"PRIx16").\n", + addr, dev_hst_ro_flags); (void)__put_user(GNTST_bad_virt_addr, &uop->handle); return GNTST_bad_gntref; } @@ -379,6 +399,11 @@ DPRINTK("Bad ref (%d) or flags (%x).\n", ref, dev_hst_ro_flags); (void)__put_user(GNTST_bad_gntref, &uop->handle); return GNTST_bad_gntref; + } + + if (acm_pre_grant_map_ref(dom)) { + (void)__put_user(GNTST_permission_denied, &uop->handle); + return GNTST_permission_denied; } if ( unlikely((rd = find_domain_by_id(dom)) == NULL) || @@ -398,12 +423,20 @@ grant_mapping_t *new_mt; grant_table_t *lgt = ld->grant_table; + if ( (lgt->maptrack_limit << 1) > MAPTRACK_MAX_ENTRIES ) + { + put_domain(rd); + DPRINTK("Maptrack table is at maximum size.\n"); + (void)__put_user(GNTST_no_device_space, &uop->handle); + return GNTST_no_device_space; + } + /* Grow the maptrack table. */ new_mt = alloc_xenheap_pages(lgt->maptrack_order + 1); if ( new_mt == NULL ) { put_domain(rd); - DPRINTK("No more map handles available\n"); + DPRINTK("No more map handles available.\n"); (void)__put_user(GNTST_no_device_space, &uop->handle); return GNTST_no_device_space; } @@ -417,7 +450,7 @@ lgt->maptrack_order += 1; lgt->maptrack_limit <<= 1; - printk("Doubled maptrack size\n"); + DPRINTK("Doubled maptrack size\n"); handle = get_maptrack_handle(ld->grant_table); } @@ -428,7 +461,7 @@ if ( 0 <= ( rc = __gnttab_activate_grant_ref( ld, led, rd, ref, dev_hst_ro_flags, - host_virt_addr, &frame))) + addr, &frame))) { /* * Only make the maptrack live _after_ writing the pte, in case we @@ -440,10 +473,11 @@ = (ref << MAPTRACK_REF_SHIFT) | (dev_hst_ro_flags & MAPTRACK_GNTMAP_MASK); - (void)__put_user(frame, &uop->dev_bus_addr); - - if ( dev_hst_ro_flags & GNTMAP_host_map ) - *va = host_virt_addr; + (void)__put_user((u64)frame << PAGE_SHIFT, &uop->dev_bus_addr); + + if ( ( dev_hst_ro_flags & GNTMAP_host_map ) && + !( dev_hst_ro_flags & GNTMAP_contains_pte) ) + *va = addr; (void)__put_user(handle, &uop->handle); } @@ -461,12 +495,12 @@ gnttab_map_grant_ref( gnttab_map_grant_ref_t *uop, unsigned int count) { - int i, flush = 0; + int i, rc, flush = 0; unsigned long va = 0; for ( i = 0; i < count; i++ ) - if ( __gnttab_map_grant_ref(&uop[i], &va) == 0 ) - flush++; + if ( (rc =__gnttab_map_grant_ref(&uop[i], &va)) >= 0 ) + flush += rc; #ifdef __ia64__ // FIXME-ia64: probably need to do something here to avoid stale mappings? @@ -485,28 +519,30 @@ gnttab_unmap_grant_ref_t *uop, unsigned long *va) { - domid_t dom; - grant_ref_t ref; - u16 handle; - struct domain *ld, *rd; - + domid_t dom; + grant_ref_t ref; + u16 handle; + struct domain *ld, *rd; active_grant_entry_t *act; - grant_entry_t *sha; + grant_entry_t *sha; grant_mapping_t *map; - u16 flags; - s16 rc = 1; - unsigned long frame, virt; + u16 flags; + s16 rc = 1; + u64 addr, dev_bus_addr; + unsigned long frame; ld = current->domain; /* Bitwise-OR avoids short-circuiting which screws control flow. */ - if ( unlikely(__get_user(virt, &uop->host_addr) | - __get_user(frame, &uop->dev_bus_addr) | + if ( unlikely(__get_user(addr, &uop->host_addr) | + __get_user(dev_bus_addr, &uop->dev_bus_addr) | __get_user(handle, &uop->handle)) ) { DPRINTK("Fault while reading gnttab_unmap_grant_ref_t.\n"); return -EFAULT; /* don't set status */ } + + frame = (unsigned long)(dev_bus_addr >> PAGE_SHIFT); map = &ld->grant_table->maptrack[handle]; @@ -561,44 +597,22 @@ /* Frame is now unmapped for device access. */ } - if ( (virt != 0) && + if ( (addr != 0) && (flags & GNTMAP_host_map) && ((act->pin & (GNTPIN_hstw_mask | GNTPIN_hstr_mask)) > 0)) { #ifdef __ia64__ // FIXME-ia64: any error checking need to be done here? #else - l1_pgentry_t *pl1e; - unsigned long _ol1e; - - pl1e = &linear_pg_table[l1_linear_offset(virt)]; - - if ( unlikely(__get_user(_ol1e, (unsigned long *)pl1e) != 0) ) - { - DPRINTK("Could not find PTE entry for address %lx\n", virt); - rc = -EINVAL; - goto unmap_out; - } - - /* - * Check that the virtual address supplied is actually mapped to - * act->frame. - */ - if ( unlikely((_ol1e >> PAGE_SHIFT) != frame )) - { - DPRINTK("PTE entry %lx for address %lx doesn't match frame %lx\n", - _ol1e, virt, frame); - rc = -EINVAL; - goto unmap_out; - } - - /* Delete pagetable entry. */ - if ( unlikely(__put_user(0, (unsigned long *)pl1e))) - { - DPRINTK("Cannot delete PTE entry at %p for virtual address %lx\n", - pl1e, virt); - rc = -EINVAL; - goto unmap_out; + if ( flags & GNTMAP_contains_pte ) + { + if ( (rc = clear_grant_pte_mapping(addr, frame, ld)) < 0 ) + goto unmap_out; + } + else + { + if ( (rc = clear_grant_va_mapping(addr, frame)) < 0 ) + goto unmap_out; } #endif @@ -608,7 +622,8 @@ : GNTPIN_hstw_inc; rc = 0; - *va = virt; + if ( !( flags & GNTMAP_contains_pte) ) + *va = addr; } if ( (map->ref_and_flags & (GNTMAP_device_map|GNTMAP_host_map)) == 0) @@ -637,6 +652,7 @@ if ( act->pin == 0 ) { + act->frame = 0xdeadbeef; clear_bit(_GTF_reading, &sha->flags); put_page(&frame_table[frame]); } @@ -678,7 +694,6 @@ gnttab_setup_table_t op; struct domain *d; int i; - unsigned long addr; if ( count != 1 ) return -EINVAL; @@ -726,7 +741,7 @@ &uop->frame_list[i]); } else { /* IA64 hack - need to map it somewhere */ - addr = (1UL << 40); + unsigned long addr = (1UL << 40); map_domain_page(d, addr, virt_to_phys(d->grant_table->shared)); (void)put_user(addr >> PAGE_SHIFT, &uop->frame_list[0]); } @@ -794,7 +809,7 @@ if ( sha_copy.flags ) { DPRINTK("Grant: dom (%hu) SHARED (%d) flags:(%hx) " - "dom:(%hu) frame:(%lx)\n", + "dom:(%hu) frame:(%x)\n", op.dom, i, sha_copy.flags, sha_copy.domid, sha_copy.frame); } } @@ -835,48 +850,208 @@ } #endif +static long +gnttab_donate(gnttab_donate_t *uop, unsigned int count) +{ + struct domain *d = current->domain; + struct domain *e; + struct pfn_info *page; + u32 _d, _nd, x, y; + int i; + int result = GNTST_okay; + +#ifdef __ia64__ +//FIXME-IA64: not support for now? + return GNTST_general_error; +#else + for (i = 0; i < count; i++) { + gnttab_donate_t *gop = &uop[i]; +#if GRANT_DEBUG + printk("gnttab_donate: i=%d mfn=%lx domid=%d gref=%08x\n", + i, gop->mfn, gop->domid, gop->handle); +#endif + page = &frame_table[gop->mfn]; + + if (unlikely(IS_XEN_HEAP_FRAME(page))) { + printk("gnttab_donate: xen heap frame mfn=%lx\n", + (unsigned long) gop->mfn); + gop->status = GNTST_bad_virt_addr; + continue; + } + if (unlikely(!pfn_valid(page_to_pfn(page)))) { + printk("gnttab_donate: invalid pfn for mfn=%lx\n", + (unsigned long) gop->mfn); + gop->status = GNTST_bad_virt_addr; + continue; + } + if (unlikely((e = find_domain_by_id(gop->domid)) == NULL)) { + printk("gnttab_donate: can't find domain %d\n", gop->domid); + gop->status = GNTST_bad_domain; + continue; + } + + spin_lock(&d->page_alloc_lock); + + /* + * The tricky bit: atomically release ownership while + * there is just one benign reference to the page + * (PGC_allocated). If that reference disappears then the + * deallocation routine will safely spin. + */ + _d = pickle_domptr(d); + _nd = page->u.inuse._domain; + y = page->count_info; + do { + x = y; + if (unlikely((x & (PGC_count_mask|PGC_allocated)) != + (1 | PGC_allocated)) || unlikely(_nd != _d)) { + printk("gnttab_donate: Bad page values %p: ed=%p(%u), sd=%p," + " caf=%08x, taf=%" PRtype_info "\n", + (void *) page_to_pfn(page), + d, d->domain_id, unpickle_domptr(_nd), x, + page->u.inuse.type_info); + spin_unlock(&d->page_alloc_lock); + put_domain(e); + return 0; + } + __asm__ __volatile__( + LOCK_PREFIX "cmpxchg8b %2" + : "=d" (_nd), "=a" (y), + "=m" (*(volatile u64 *)(&page->count_info)) + : "0" (_d), "1" (x), "c" (NULL), "b" (x) ); + } while (unlikely(_nd != _d) || unlikely(y != x)); + + /* + * Unlink from 'd'. At least one reference remains (now + * anonymous), so noone else is spinning to try to delete + * this page from 'd'. + */ + d->tot_pages--; + list_del(&page->list); + + spin_unlock(&d->page_alloc_lock); + + spin_lock(&e->page_alloc_lock); + + /* + * Check that 'e' will accept the page and has reservation + * headroom. Also, a domain mustn't have PGC_allocated + * pages when it is dying. + */ +#ifdef GRANT_DEBUG + if (unlikely(e->tot_pages >= e->max_pages)) { + printk("gnttab_dontate: no headroom tot_pages=%d max_pages=%d\n", + e->tot_pages, e->max_pages); + spin_unlock(&e->page_alloc_lock); + put_domain(e); + result = GNTST_general_error; + break; + } + if (unlikely(test_bit(DOMFLAGS_DYING, &e->domain_flags))) { + printk("gnttab_donate: target domain is dying\n"); + spin_unlock(&e->page_alloc_lock); + put_domain(e); + result = GNTST_general_error; + break; + } + if (unlikely(!gnttab_prepare_for_transfer(e, d, gop->handle))) { + printk("gnttab_donate: gnttab_prepare_for_transfer fails\n"); + spin_unlock(&e->page_alloc_lock); + put_domain(e); + result = GNTST_general_error; + break; + } +#else + ASSERT(e->tot_pages <= e->max_pages); + if (unlikely(test_bit(DOMFLAGS_DYING, &e->domain_flags)) || + unlikely(e->tot_pages == e->max_pages) || + unlikely(!gnttab_prepare_for_transfer(e, d, gop->handle))) { + printk("gnttab_donate: Transferee has no reservation headroom (%d," + "%d) or provided a bad grant ref (%08x) or is dying (%p)\n", + e->tot_pages, e->max_pages, gop->handle, e->d_flags); + spin_unlock(&e->page_alloc_lock); + put_domain(e); + result = GNTST_general_error; + break; + } +#endif + /* Okay, add the page to 'e'. */ + if (unlikely(e->tot_pages++ == 0)) { + get_knownalive_domain(e); + } + list_add_tail(&page->list, &e->page_list); + page_set_owner(page, e); + + spin_unlock(&e->page_alloc_lock); + + /* + * Transfer is all done: tell the guest about its new page + * frame. + */ + gnttab_notify_transfer(e, d, gop->handle, gop->mfn); + + put_domain(e); + + gop->status = GNTST_okay; + } + return result; +#endif +} + long do_grant_table_op( unsigned int cmd, void *uop, unsigned int count) { long rc; - + struct domain *d = current->domain; + if ( count > 512 ) return -EINVAL; - - LOCK_BIGLOCK(current->domain); - + + LOCK_BIGLOCK(d); + +#ifndef __ia64__ + sync_pagetable_state(d); +#endif + rc = -EFAULT; switch ( cmd ) - { - case GNTTABOP_map_grant_ref: - if ( unlikely(!array_access_ok( - uop, count, sizeof(gnttab_map_grant_ref_t))) ) - goto out; - rc = gnttab_map_grant_ref((gnttab_map_grant_ref_t *)uop, count); - break; - case GNTTABOP_unmap_grant_ref: - if ( unlikely(!array_access_ok( - uop, count, sizeof(gnttab_unmap_grant_ref_t))) ) - goto out; - rc = gnttab_unmap_grant_ref((gnttab_unmap_grant_ref_t *)uop, count); - break; - case GNTTABOP_setup_table: - rc = gnttab_setup_table((gnttab_setup_table_t *)uop, count); - break; + { + case GNTTABOP_map_grant_ref: + if ( unlikely(!array_access_ok( + uop, count, sizeof(gnttab_map_grant_ref_t))) ) + goto out; + rc = gnttab_map_grant_ref((gnttab_map_grant_ref_t *)uop, count); + break; + case GNTTABOP_unmap_grant_ref: + if ( unlikely(!array_access_ok( + uop, count, sizeof(gnttab_unmap_grant_ref_t))) ) + goto out; + rc = gnttab_unmap_grant_ref((gnttab_unmap_grant_ref_t *)uop, + count); + break; + case GNTTABOP_setup_table: + rc = gnttab_setup_table((gnttab_setup_table_t *)uop, count); + break; #if GRANT_DEBUG - case GNTTABOP_dump_table: - rc = gnttab_dump_table((gnttab_dump_table_t *)uop); - break; -#endif - default: - rc = -ENOSYS; - break; - } - -out: - UNLOCK_BIGLOCK(current->domain); - + case GNTTABOP_dump_table: + rc = gnttab_dump_table((gnttab_dump_table_t *)uop); + break; +#endif + case GNTTABOP_donate: + if (unlikely(!array_access_ok(uop, count, + sizeof(gnttab_donate_t)))) + goto out; + rc = gnttab_donate(uop, count); + break; + default: + rc = -ENOSYS; + break; + } + + out: + UNLOCK_BIGLOCK(d); + return rc; } @@ -890,103 +1065,101 @@ * Called a _lot_ at domain creation because pages mapped by priv domains * also traverse this. */ - + /* Note: If the same frame is mapped multiple times, and then one of * the ptes is overwritten, which maptrack handle gets invalidated? * Advice: Don't do it. Explicitly unmap. */ - + unsigned int handle, ref, refcount; grant_table_t *lgt, *rgt; active_grant_entry_t *act; grant_mapping_t *map; int found = 0; - + lgt = ld->grant_table; - + #if GRANT_DEBUG_VERBOSE - if ( ld->domain_id != 0 ) - { - DPRINTK("Foreign unref rd(%d) ld(%d) frm(%x) flgs(%x).\n", - rd->domain_id, ld->domain_id, frame, readonly); - } -#endif - + if ( ld->domain_ id != 0 ) { + DPRINTK("Foreign unref rd(%d) ld(%d) frm(%lx) flgs(%x).\n", + rd->domain_id, ld->domain_id, frame, readonly); + } +#endif + /* Fast exit if we're not mapping anything using grant tables */ if ( lgt->map_count == 0 ) return 0; - - if ( get_domain(rd) == 0 ) - { + + if ( get_domain(rd) == 0 ) { DPRINTK("gnttab_check_unmap: couldn't get_domain rd(%d)\n", rd->domain_id); return 0; } - + rgt = rd->grant_table; - - for ( handle = 0; handle < lgt->maptrack_limit; handle++ ) - { + + for ( handle = 0; handle < lgt->maptrack_limit; handle++ ) { + map = &lgt->maptrack[handle]; - + + if ( map->domid != rd->domain_id ) + continue; + if ( ( map->ref_and_flags & MAPTRACK_GNTMAP_MASK ) && - ( readonly ? 1 : (!(map->ref_and_flags & GNTMAP_readonly)))) - { + ( readonly ? 1 : (!(map->ref_and_flags & GNTMAP_readonly)))) { + ref = (map->ref_and_flags >> MAPTRACK_REF_SHIFT); act = &rgt->active[ref]; - + spin_lock(&rgt->lock); - - if ( act->frame != frame ) - { + + if ( act->frame != frame ) { spin_unlock(&rgt->lock); continue; } - + refcount = act->pin & ( readonly ? GNTPIN_hstr_mask - : GNTPIN_hstw_mask ); - if ( refcount == 0 ) - { + : GNTPIN_hstw_mask ); + + if ( refcount == 0 ) { spin_unlock(&rgt->lock); continue; } - + /* gotcha */ DPRINTK("Grant unref rd(%d) ld(%d) frm(%lx) flgs(%x).\n", rd->domain_id, ld->domain_id, frame, readonly); - + if ( readonly ) act->pin -= GNTPIN_hstr_inc; - else - { + else { act->pin -= GNTPIN_hstw_inc; - + /* any more granted writable mappings? */ - if ( (act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) == 0 ) - { + if ( (act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) == 0 ) { clear_bit(_GTF_writing, &rgt->shared[ref].flags); put_page_type(&frame_table[frame]); } } - - if ( act->pin == 0 ) - { + + if ( act->pin == 0 ) { clear_bit(_GTF_reading, &rgt->shared[ref].flags); put_page(&frame_table[frame]); } + spin_unlock(&rgt->lock); - + clear_bit(GNTMAP_host_map, &map->ref_and_flags); - + if ( !(map->ref_and_flags & GNTMAP_device_map) ) put_maptrack_handle(lgt, handle); - + found = 1; break; } } put_domain(rd); - + return found; } @@ -1002,8 +1175,10 @@ int retries = 0; unsigned long target_pfn; +#if GRANT_DEBUG_VERBOSE DPRINTK("gnttab_prepare_for_transfer rd(%hu) ld(%hu) ref(%hu).\n", rd->domain_id, ld->domain_id, ref); +#endif if ( unlikely((rgt = rd->grant_table) == NULL) || unlikely(ref >= NR_GRANT_ENTRIES) ) @@ -1081,8 +1256,10 @@ grant_entry_t *sha; unsigned long pfn; +#if GRANT_DEBUG_VERBOSE DPRINTK("gnttab_notify_transfer rd(%hu) ld(%hu) ref(%hu).\n", rd->domain_id, ld->domain_id, ref); +#endif sha = &rd->grant_table->shared[ref]; diff -r 888877bc3d79 -r bf3fdeeba48b xen/arch/ia64/xen/regionreg.c --- a/xen/arch/ia64/xen/regionreg.c Thu Sep 1 19:01:55 2005 +++ b/xen/arch/ia64/xen/regionreg.c Fri Sep 2 18:31:56 2005 @@ -116,7 +116,7 @@ ridbits = IA64_MIN_IMPL_RID_BITS; // convert to rid_blocks and find one - n_rid_blocks = ridbits - IA64_MIN_IMPL_RID_BITS + 1; + n_rid_blocks = 1UL << (ridbits - IA64_MIN_IMPL_RID_BITS); // skip over block 0, reserved for "meta-physical mappings (and Xen)" for (i = n_rid_blocks; i < MAX_RID_BLOCKS; i += n_rid_blocks) { diff -r 888877bc3d79 -r bf3fdeeba48b xen/arch/ia64/xen/vcpu.c --- a/xen/arch/ia64/xen/vcpu.c Thu Sep 1 19:01:55 2005 +++ b/xen/arch/ia64/xen/vcpu.c Fri Sep 2 18:31:56 2005 @@ -1315,7 +1315,8 @@ /* check 1-entry TLB */ if ((trp = match_dtlb(vcpu,address))) { dtlb_translate_count++; - *pteval = trp->page_flags; + //*pteval = trp->page_flags; + *pteval = vcpu->arch.dtlb_pte; *itir = trp->itir; return IA64_NO_FAULT; } diff -r 888877bc3d79 -r bf3fdeeba48b xen/include/asm-ia64/mm.h --- a/xen/include/asm-ia64/mm.h Thu Sep 1 19:01:55 2005 +++ b/xen/include/asm-ia64/mm.h Fri Sep 2 18:31:56 2005 @@ -33,6 +33,8 @@ * 2. Provide a PFN_ORDER() macro for accessing the order of a free page. */ #define PFN_ORDER(_pfn) ((_pfn)->u.free.order) + +#define PRtype_info "08x" struct page { @@ -210,6 +212,12 @@ #define memguard_unguard_range(_p,_l) ((void)0) #endif +// prototype of misc memory stuff +unsigned long __get_free_pages(unsigned int mask, unsigned int order); +void __free_pages(struct page *page, unsigned int order); +void *pgtable_quicklist_alloc(void); +void pgtable_quicklist_free(void *pgtable_entry); + // FOLLOWING FROM linux-2.6.7/include/mm.h /* diff -r 888877bc3d79 -r bf3fdeeba48b xen/include/asm-ia64/xensystem.h --- a/xen/include/asm-ia64/xensystem.h Thu Sep 1 19:01:55 2005 +++ b/xen/include/asm-ia64/xensystem.h Fri Sep 2 18:31:56 2005 @@ -71,6 +71,10 @@ } while (0) #endif // CONFIG_VTI +#undef switch_to +// FIXME SMP... see system.h, does this need to be different? +#define switch_to(prev,next,last) __switch_to(prev, next, last) + #define __cmpxchg_user(ptr, new, old, _size) \ ({ \ register long __gu_r8 asm ("r8"); \ diff -r 888877bc3d79 -r bf3fdeeba48b xen/include/public/arch-ia64.h --- a/xen/include/public/arch-ia64.h Thu Sep 1 19:01:55 2005 +++ b/xen/include/public/arch-ia64.h Fri Sep 2 18:31:56 2005 @@ -257,6 +257,8 @@ typedef struct { int domain_controller_evtchn; unsigned int flags; + unsigned short store_evtchn; + unsigned long store_mfn; //} arch_shared_info_t; } arch_shared_info_t; // DON'T PACK _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |