Annotation of Gnu-Mach/xen/grant.c, revision 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.