|
|
1.1 ! root 1: /* ! 2: * Copyright (C) 2006-2009 Free Software Foundation ! 3: * ! 4: * This program is free software ; you can redistribute it and/or modify ! 5: * it under the terms of the GNU General Public License as published by ! 6: * the Free Software Foundation ; either version 2 of the License, or ! 7: * (at your option) any later version. ! 8: * ! 9: * This program is distributed in the hope that it will be useful, ! 10: * but WITHOUT ANY WARRANTY ; without even the implied warranty of ! 11: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 12: * GNU General Public License for more details. ! 13: * ! 14: * You should have received a copy of the GNU General Public License ! 15: * along with the program ; if not, write to the Free Software ! 16: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ! 17: */ ! 18: ! 19: #include <sys/types.h> ! 20: #include <mach/vm_param.h> ! 21: #include <machine/spl.h> ! 22: #include <vm/pmap.h> ! 23: #include <vm/vm_map.h> ! 24: #include <vm/vm_kern.h> ! 25: #include "grant.h" ! 26: ! 27: #define NR_RESERVED_ENTRIES 8 ! 28: #define NR_GRANT_PAGES 4 ! 29: ! 30: decl_simple_lock_data(static,lock); ! 31: static struct grant_entry *grants; ! 32: static vm_map_entry_t grants_map_entry; ! 33: static int last_grant = NR_RESERVED_ENTRIES; ! 34: ! 35: static grant_ref_t free_grants = -1; ! 36: ! 37: static grant_ref_t grant_alloc(void) { ! 38: grant_ref_t grant; ! 39: if (free_grants != -1) { ! 40: grant = free_grants; ! 41: free_grants = grants[grant].frame; ! 42: } else { ! 43: grant = last_grant++; ! 44: if (grant == (NR_GRANT_PAGES * PAGE_SIZE)/sizeof(*grants)) ! 45: panic("not enough grant entries, increase NR_GRANT_PAGES"); ! 46: } ! 47: return grant; ! 48: } ! 49: ! 50: static void grant_free(grant_ref_t grant) { ! 51: grants[grant].frame = free_grants; ! 52: free_grants = grant; ! 53: } ! 54: ! 55: static grant_ref_t grant_set(domid_t domid, unsigned long mfn, uint16_t flags) { ! 56: spl_t spl = splhigh(); ! 57: simple_lock(&lock); ! 58: ! 59: grant_ref_t grant = grant_alloc(); ! 60: grants[grant].domid = domid; ! 61: grants[grant].frame = mfn; ! 62: wmb(); ! 63: grants[grant].flags = flags; ! 64: ! 65: simple_unlock(&lock); ! 66: splx(spl); ! 67: return grant; ! 68: } ! 69: ! 70: grant_ref_t hyp_grant_give(domid_t domid, unsigned long frame, int readonly) { ! 71: return grant_set(domid, pfn_to_mfn(frame), ! 72: GTF_permit_access | (readonly ? GTF_readonly : 0)); ! 73: } ! 74: ! 75: grant_ref_t hyp_grant_accept_transfer(domid_t domid, unsigned long frame) { ! 76: return grant_set(domid, frame, GTF_accept_transfer); ! 77: } ! 78: ! 79: unsigned long hyp_grant_finish_transfer(grant_ref_t grant) { ! 80: unsigned long frame; ! 81: spl_t spl = splhigh(); ! 82: simple_lock(&lock); ! 83: ! 84: if (!(grants[grant].flags & GTF_transfer_committed)) ! 85: panic("grant transfer %x not committed\n", grant); ! 86: while (!(grants[grant].flags & GTF_transfer_completed)) ! 87: machine_relax(); ! 88: rmb(); ! 89: frame = grants[grant].frame; ! 90: grant_free(grant); ! 91: ! 92: simple_unlock(&lock); ! 93: splx(spl); ! 94: return frame; ! 95: } ! 96: ! 97: void hyp_grant_takeback(grant_ref_t grant) { ! 98: spl_t spl = splhigh(); ! 99: simple_lock(&lock); ! 100: ! 101: if (grants[grant].flags & (GTF_reading|GTF_writing)) ! 102: panic("grant %d still in use (%lx)\n", grant, grants[grant].flags); ! 103: ! 104: /* Note: this is not safe, a cmpxchg is needed, see grant_table.h */ ! 105: grants[grant].flags = 0; ! 106: wmb(); ! 107: ! 108: grant_free(grant); ! 109: ! 110: simple_unlock(&lock); ! 111: splx(spl); ! 112: } ! 113: ! 114: void *hyp_grant_address(grant_ref_t grant) { ! 115: return &grants[grant]; ! 116: } ! 117: ! 118: void hyp_grant_init(void) { ! 119: struct gnttab_setup_table setup; ! 120: unsigned long frame[NR_GRANT_PAGES]; ! 121: long ret; ! 122: int i; ! 123: vm_offset_t addr; ! 124: ! 125: setup.dom = DOMID_SELF; ! 126: setup.nr_frames = NR_GRANT_PAGES; ! 127: setup.frame_list = (void*) kvtolin(frame); ! 128: ! 129: ret = hyp_grant_table_op(GNTTABOP_setup_table, kvtolin(&setup), 1); ! 130: if (ret) ! 131: panic("setup grant table error %d", ret); ! 132: if (setup.status) ! 133: panic("setup grant table: %d\n", setup.status); ! 134: ! 135: simple_lock_init(&lock); ! 136: vm_map_find_entry(kernel_map, &addr, NR_GRANT_PAGES * PAGE_SIZE, ! 137: (vm_offset_t) 0, kernel_object, &grants_map_entry); ! 138: grants = (void*) addr; ! 139: ! 140: for (i = 0; i < NR_GRANT_PAGES; i++) ! 141: pmap_map_mfn((void *)grants + i * PAGE_SIZE, frame[i]); ! 142: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.