Annotation of Gnu-Mach/xen/grant.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.