亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? amd-iommu-map.c

?? xen 3.2.2 源碼
?? C
字號:
/* * Copyright (C) 2007 Advanced Micro Devices, Inc. * Author: Leo Duran <leo.duran@amd.com> * Author: Wei Wang <wei.wang2@amd.com> - adapted to xen * * 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 * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA */#include <xen/sched.h>#include <asm/hvm/iommu.h>#include <asm/amd-iommu.h>#include <asm/hvm/svm/amd-iommu-proto.h>extern long amd_iommu_poll_comp_wait;static int queue_iommu_command(struct amd_iommu *iommu, u32 cmd[]){    u32 tail, head, *cmd_buffer;    int i;    BUG_ON( !iommu || !cmd );    tail = iommu->cmd_buffer_tail;    if ( ++tail == iommu->cmd_buffer.entries ) {        tail = 0;    }    head = get_field_from_reg_u32(            readl(iommu->mmio_base+IOMMU_CMD_BUFFER_HEAD_OFFSET),            IOMMU_CMD_BUFFER_HEAD_MASK,            IOMMU_CMD_BUFFER_HEAD_SHIFT);    if ( head != tail ) {        cmd_buffer = (u32 *)(iommu->cmd_buffer.buffer +            (iommu->cmd_buffer_tail * IOMMU_CMD_BUFFER_ENTRY_SIZE));        for ( i = 0; i < IOMMU_CMD_BUFFER_U32_PER_ENTRY; ++i ) {            cmd_buffer[i] = cmd[i];        }        iommu->cmd_buffer_tail = tail;        return 1;    }    return 0;}static void commit_iommu_command_buffer(struct amd_iommu *iommu){    u32 tail;    BUG_ON( !iommu );    set_field_in_reg_u32(iommu->cmd_buffer_tail, 0,        IOMMU_CMD_BUFFER_TAIL_MASK,        IOMMU_CMD_BUFFER_TAIL_SHIFT, &tail);    writel(tail, iommu->mmio_base+IOMMU_CMD_BUFFER_TAIL_OFFSET);}int send_iommu_command(struct amd_iommu *iommu, u32 cmd[]){    BUG_ON( !iommu || !cmd );    if ( queue_iommu_command(iommu, cmd) ) {        commit_iommu_command_buffer(iommu);        return 1;    }    return 0;}static void invalidate_iommu_page(struct amd_iommu *iommu,            u64 io_addr, u16 domain_id){    u64 addr_lo, addr_hi;    u32 cmd[4], entry;    addr_lo = io_addr & DMA_32BIT_MASK;    addr_hi = io_addr >> 32;    set_field_in_reg_u32(domain_id, 0,        IOMMU_INV_IOMMU_PAGES_DOMAIN_ID_MASK,        IOMMU_INV_IOMMU_PAGES_DOMAIN_ID_SHIFT, &entry);    set_field_in_reg_u32(IOMMU_CMD_INVALIDATE_IOMMU_PAGES, entry,        IOMMU_CMD_OPCODE_MASK, IOMMU_CMD_OPCODE_SHIFT, &entry);    cmd[1] = entry;    set_field_in_reg_u32(IOMMU_CONTROL_DISABLED, 0,        IOMMU_INV_IOMMU_PAGES_S_FLAG_MASK,        IOMMU_INV_IOMMU_PAGES_S_FLAG_SHIFT, &entry);    set_field_in_reg_u32(IOMMU_CONTROL_DISABLED, entry,        IOMMU_INV_IOMMU_PAGES_PDE_FLAG_MASK,        IOMMU_INV_IOMMU_PAGES_PDE_FLAG_SHIFT, &entry);    set_field_in_reg_u32((u32)addr_lo >> PAGE_SHIFT, entry,        IOMMU_INV_IOMMU_PAGES_ADDR_LOW_MASK,        IOMMU_INV_IOMMU_PAGES_ADDR_LOW_SHIFT, &entry);    cmd[2] = entry;    set_field_in_reg_u32((u32)addr_hi, 0,        IOMMU_INV_IOMMU_PAGES_ADDR_HIGH_MASK,        IOMMU_INV_IOMMU_PAGES_ADDR_HIGH_SHIFT, &entry);    cmd[3] = entry;    cmd[0] = 0;    send_iommu_command(iommu, cmd);}static void flush_command_buffer(struct amd_iommu *iommu){    u32 cmd[4], status;    int loop_count, comp_wait;    /* clear 'ComWaitInt' in status register (WIC) */    set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, 0,        IOMMU_STATUS_COMP_WAIT_INT_MASK,        IOMMU_STATUS_COMP_WAIT_INT_SHIFT, &status);    writel(status, iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET);    /* send an empty COMPLETION_WAIT command to flush command buffer */    cmd[3] = cmd[2] = 0;    set_field_in_reg_u32(IOMMU_CMD_COMPLETION_WAIT, 0,        IOMMU_CMD_OPCODE_MASK,        IOMMU_CMD_OPCODE_SHIFT, &cmd[1]);    set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, 0,        IOMMU_COMP_WAIT_I_FLAG_MASK,        IOMMU_COMP_WAIT_I_FLAG_SHIFT, &cmd[0]);    send_iommu_command(iommu, cmd);    /* wait for 'ComWaitInt' to signal comp#endifletion? */    if ( amd_iommu_poll_comp_wait ) {        loop_count = amd_iommu_poll_comp_wait;        do {            status = readl(iommu->mmio_base +                    IOMMU_STATUS_MMIO_OFFSET);            comp_wait = get_field_from_reg_u32(status,                    IOMMU_STATUS_COMP_WAIT_INT_MASK,                    IOMMU_STATUS_COMP_WAIT_INT_SHIFT);            --loop_count;        } while ( loop_count && !comp_wait );        if ( comp_wait ) {            /* clear 'ComWaitInt' in status register (WIC) */            status &= IOMMU_STATUS_COMP_WAIT_INT_MASK;            writel(status, iommu->mmio_base +                IOMMU_STATUS_MMIO_OFFSET);        } else            dprintk(XENLOG_WARNING, "AMD IOMMU: %s(): Warning:"                " ComWaitInt bit did not assert!\n",                 __FUNCTION__);    }}static void clear_page_table_entry_present(u32 *pte){    set_field_in_reg_u32(IOMMU_CONTROL_DISABLED, pte[0],        IOMMU_PTE_PRESENT_MASK,        IOMMU_PTE_PRESENT_SHIFT, &pte[0]);}static void set_page_table_entry_present(u32 *pte, u64 page_addr,                int iw, int ir){    u64 addr_lo, addr_hi;    u32 entry;    addr_lo = page_addr & DMA_32BIT_MASK;    addr_hi = page_addr >> 32;    set_field_in_reg_u32((u32)addr_hi, 0,        IOMMU_PTE_ADDR_HIGH_MASK,        IOMMU_PTE_ADDR_HIGH_SHIFT, &entry);    set_field_in_reg_u32(iw ? IOMMU_CONTROL_ENABLED :        IOMMU_CONTROL_DISABLED, entry,        IOMMU_PTE_IO_WRITE_PERMISSION_MASK,        IOMMU_PTE_IO_WRITE_PERMISSION_SHIFT, &entry);    set_field_in_reg_u32(ir ? IOMMU_CONTROL_ENABLED :        IOMMU_CONTROL_DISABLED, entry,        IOMMU_PTE_IO_READ_PERMISSION_MASK,        IOMMU_PTE_IO_READ_PERMISSION_SHIFT, &entry);    pte[1] = entry;    set_field_in_reg_u32((u32)addr_lo >> PAGE_SHIFT, 0,        IOMMU_PTE_ADDR_LOW_MASK,        IOMMU_PTE_ADDR_LOW_SHIFT, &entry);    set_field_in_reg_u32(IOMMU_PAGING_MODE_LEVEL_0, entry,        IOMMU_PTE_NEXT_LEVEL_MASK,        IOMMU_PTE_NEXT_LEVEL_SHIFT, &entry);    set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, entry,        IOMMU_PTE_PRESENT_MASK,        IOMMU_PTE_PRESENT_SHIFT, &entry);    pte[0] = entry;}static void amd_iommu_set_page_directory_entry(u32 *pde,             u64 next_ptr, u8 next_level){    u64 addr_lo, addr_hi;    u32 entry;    addr_lo = next_ptr & DMA_32BIT_MASK;    addr_hi = next_ptr >> 32;    /* enable read/write permissions,which will be enforced at the PTE */    set_field_in_reg_u32((u32)addr_hi, 0,        IOMMU_PDE_ADDR_HIGH_MASK, IOMMU_PDE_ADDR_HIGH_SHIFT, &entry);    set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, entry,        IOMMU_PDE_IO_WRITE_PERMISSION_MASK,        IOMMU_PDE_IO_WRITE_PERMISSION_SHIFT, &entry);    set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, entry,        IOMMU_PDE_IO_READ_PERMISSION_MASK,        IOMMU_PDE_IO_READ_PERMISSION_SHIFT, &entry);    pde[1] = entry;    /* mark next level as 'present' */    set_field_in_reg_u32((u32)addr_lo >> PAGE_SHIFT, 0,        IOMMU_PDE_ADDR_LOW_MASK, IOMMU_PDE_ADDR_LOW_SHIFT, &entry);    set_field_in_reg_u32(next_level, entry,        IOMMU_PDE_NEXT_LEVEL_MASK,        IOMMU_PDE_NEXT_LEVEL_SHIFT, &entry);    set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, entry,        IOMMU_PDE_PRESENT_MASK,        IOMMU_PDE_PRESENT_SHIFT, &entry);    pde[0] = entry;}void amd_iommu_set_dev_table_entry(u32 *dte, u64 root_ptr, u16 domain_id,                u8 paging_mode){    u64 addr_hi, addr_lo;    u32 entry;    dte[6] = dte[5] = dte[4] = 0;    set_field_in_reg_u32(IOMMU_DEV_TABLE_SYS_MGT_MSG_FORWARDED, 0,        IOMMU_DEV_TABLE_SYS_MGT_MSG_ENABLE_MASK,        IOMMU_DEV_TABLE_SYS_MGT_MSG_ENABLE_SHIFT, &entry);    dte[3] = entry;    set_field_in_reg_u32(domain_id, 0,        IOMMU_DEV_TABLE_DOMAIN_ID_MASK,        IOMMU_DEV_TABLE_DOMAIN_ID_SHIFT, &entry);    dte[2] = entry;    addr_lo = root_ptr & DMA_32BIT_MASK;    addr_hi = root_ptr >> 32;    set_field_in_reg_u32((u32)addr_hi, 0,        IOMMU_DEV_TABLE_PAGE_TABLE_PTR_HIGH_MASK,        IOMMU_DEV_TABLE_PAGE_TABLE_PTR_HIGH_SHIFT, &entry);    set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, entry,        IOMMU_DEV_TABLE_IO_WRITE_PERMISSION_MASK,        IOMMU_DEV_TABLE_IO_WRITE_PERMISSION_SHIFT, &entry);    set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, entry,        IOMMU_DEV_TABLE_IO_READ_PERMISSION_MASK,        IOMMU_DEV_TABLE_IO_READ_PERMISSION_SHIFT, &entry);    dte[1] = entry;    set_field_in_reg_u32((u32)addr_lo >> PAGE_SHIFT, 0,        IOMMU_DEV_TABLE_PAGE_TABLE_PTR_LOW_MASK,        IOMMU_DEV_TABLE_PAGE_TABLE_PTR_LOW_SHIFT, &entry);    set_field_in_reg_u32(paging_mode, entry,        IOMMU_DEV_TABLE_PAGING_MODE_MASK,        IOMMU_DEV_TABLE_PAGING_MODE_SHIFT, &entry);    set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, entry,        IOMMU_DEV_TABLE_TRANSLATION_VALID_MASK,        IOMMU_DEV_TABLE_TRANSLATION_VALID_SHIFT, &entry);    set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, entry,        IOMMU_DEV_TABLE_VALID_MASK,        IOMMU_DEV_TABLE_VALID_SHIFT, &entry);    dte[0] = entry;}static void *amd_iommu_get_vptr_from_page_table_entry(u32 *entry){    u64 addr_lo, addr_hi, ptr;    addr_lo = get_field_from_reg_u32(entry[0],            IOMMU_DEV_TABLE_PAGE_TABLE_PTR_LOW_MASK,            IOMMU_DEV_TABLE_PAGE_TABLE_PTR_LOW_SHIFT);    addr_hi = get_field_from_reg_u32(entry[1],            IOMMU_DEV_TABLE_PAGE_TABLE_PTR_HIGH_MASK,            IOMMU_DEV_TABLE_PAGE_TABLE_PTR_HIGH_SHIFT);    ptr = (addr_hi << 32) | (addr_lo << PAGE_SHIFT);    return ptr ? maddr_to_virt((unsigned long)ptr) : NULL;}static int amd_iommu_is_pte_present(u32 *entry){    return (get_field_from_reg_u32(entry[0],            IOMMU_PDE_PRESENT_MASK,            IOMMU_PDE_PRESENT_SHIFT));}static void *get_pte_from_page_tables(void *table, int level,        unsigned long io_pfn){    unsigned long offset;    void *pde = 0;    BUG_ON( !table );    while ( level > 0 )    {        void *next_table = 0;        unsigned long next_ptr;        offset = io_pfn >> ((PTE_PER_TABLE_SHIFT *            (level - IOMMU_PAGING_MODE_LEVEL_1)));        offset &= ~PTE_PER_TABLE_MASK;        pde = table + (offset * IOMMU_PAGE_TABLE_ENTRY_SIZE);        if ( level == 1 )            break;        if ( !pde )           return NULL;        if ( !amd_iommu_is_pte_present(pde) ) {            next_table = alloc_xenheap_page();            if ( next_table == NULL )                return NULL;            memset(next_table, 0, PAGE_SIZE);            if ( *(u64*)(pde) == 0 ) {                next_ptr = (u64)virt_to_maddr(next_table);                amd_iommu_set_page_directory_entry((u32 *)pde,                    next_ptr, level - 1);            } else                free_xenheap_page(next_table);        }        table = amd_iommu_get_vptr_from_page_table_entry(pde);        level--;    }    return pde;}int amd_iommu_map_page(struct domain *d, unsigned long gfn,        unsigned long mfn){    void *pte;    unsigned long flags;    u64 maddr;    struct hvm_iommu *hd = domain_hvm_iommu(d);    int iw, ir;    BUG_ON( !hd->root_table );    maddr = (u64)(mfn << PAGE_SHIFT);    iw = IOMMU_IO_WRITE_ENABLED;    ir = IOMMU_IO_READ_ENABLED;    spin_lock_irqsave(&hd->mapping_lock, flags);    pte = get_pte_from_page_tables(hd->root_table, hd->paging_mode, gfn);    if ( pte != 0 ) {        set_page_table_entry_present((u32 *)pte, maddr, iw, ir);        spin_unlock_irqrestore(&hd->mapping_lock, flags);        return 0;    } else {        dprintk(XENLOG_ERR,            "%s() AMD IOMMU: Invalid IO pagetable entry gfn = %lx\n",            __FUNCTION__, gfn);        spin_unlock_irqrestore(&hd->mapping_lock, flags);        return -EIO;    }}int amd_iommu_unmap_page(struct domain *d, unsigned long gfn){    void *pte;    unsigned long flags;    u64 io_addr = gfn;    int requestor_id;    struct amd_iommu *iommu;    struct hvm_iommu *hd = domain_hvm_iommu(d);    BUG_ON( !hd->root_table );    requestor_id = hd->domain_id;    io_addr = (u64)(gfn << PAGE_SHIFT);    spin_lock_irqsave(&hd->mapping_lock, flags);    pte = get_pte_from_page_tables(hd->root_table, hd->paging_mode, gfn);    if ( pte != 0 ) {        /* mark PTE as 'page not present' */        clear_page_table_entry_present((u32 *)pte);        spin_unlock_irqrestore(&hd->mapping_lock, flags);        /* send INVALIDATE_IOMMU_PAGES command */        for_each_amd_iommu(iommu) {            spin_lock_irqsave(&iommu->lock, flags);            invalidate_iommu_page(iommu, io_addr, requestor_id);            flush_command_buffer(iommu);            spin_unlock_irqrestore(&iommu->lock, flags);        }        return 0;    } else {        dprintk(XENLOG_ERR,            "%s() AMD IOMMU: Invalid IO pagetable entry gfn = %lx\n",             __FUNCTION__, gfn);        spin_unlock_irqrestore(&hd->mapping_lock, flags);        return -EIO;    }}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
亚洲卡通欧美制服中文| 国产精品嫩草影院av蜜臀| 久久综合av免费| 国产精品国产三级国产专播品爱网 | 国产精品一区二区三区四区| 日韩精品亚洲一区二区三区免费| 激情久久五月天| 日本韩国一区二区| 精品精品国产高清一毛片一天堂| 亚洲乱码国产乱码精品精小说| 久久影院视频免费| 亚洲日本丝袜连裤袜办公室| 日本欧美一区二区三区乱码| 麻豆成人av在线| 91麻豆国产自产在线观看| 日韩午夜精品视频| 中文一区在线播放| 日本美女一区二区三区视频| 日韩**一区毛片| 色综合天天狠狠| 国产亚洲一区二区三区在线观看| 国产丝袜在线精品| 久久成人羞羞网站| 欧美三区在线观看| 亚洲美女区一区| 国产精品亚洲一区二区三区在线| 欧美日韩精品三区| 亚洲图片激情小说| 天天色图综合网| 欧美三级欧美一级| 亚洲女子a中天字幕| 国产ts人妖一区二区| 69堂亚洲精品首页| 午夜精品福利一区二区三区av| 成人av片在线观看| 亚洲成av人片观看| 亚洲激情av在线| eeuss影院一区二区三区| 欧美日韩国产一级片| 国产午夜亚洲精品不卡| 美女网站在线免费欧美精品| 色国产综合视频| 一区二区三区四区不卡在线| 99视频在线观看一区三区| 国产清纯白嫩初高生在线观看91 | 亚洲午夜视频在线| 91视频www| 亚洲欧美一区二区三区极速播放 | 日韩三级免费观看| 日韩国产一二三区| 91精品国产福利| 五月天丁香久久| 555夜色666亚洲国产免| 亚洲成人你懂的| 色综合久久久久网| 亚洲欧洲成人av每日更新| av成人动漫在线观看| 国产精品护士白丝一区av| 国产成人免费视频精品含羞草妖精 | 国产精品久线观看视频| 成人久久久精品乱码一区二区三区| 中文字幕精品一区二区三区精品| 国产成人av一区二区| 欧美日韩一区精品| 婷婷综合另类小说色区| 欧美一区二区三区啪啪| 极品少妇xxxx偷拍精品少妇| 久久综合九色综合欧美98 | 亚洲国产综合视频在线观看| 欧美日韩国产三级| 久久99最新地址| 精品99999| 成人手机在线视频| 一区二区三区中文在线| 91精品国产综合久久精品麻豆| 亚洲欧美韩国综合色| 欧美区一区二区三区| 国产一区二区三区最好精华液| 中文字幕乱码久久午夜不卡| 色综合婷婷久久| 亚洲动漫第一页| 精品国产3级a| 成人在线视频首页| 一区二区三区不卡视频| 欧美v日韩v国产v| 91免费视频大全| 精品久久久久久亚洲综合网| 粉嫩久久99精品久久久久久夜| 亚洲最大色网站| 国产欧美一区二区三区沐欲| 欧美日韩mp4| 精品免费日韩av| 亚洲图片一区二区| 中文字幕乱码亚洲精品一区 | 国产91精品精华液一区二区三区| 亚洲五码中文字幕| 亚洲精品视频在线看| xfplay精品久久| 欧美日韩精品欧美日韩精品一| 秋霞国产午夜精品免费视频| 亚洲欧洲中文日韩久久av乱码| 欧美成人艳星乳罩| 日韩三级高清在线| 欧美日韩一级视频| 欧美亚洲自拍偷拍| 成人av在线网站| 懂色av一区二区三区免费观看| 五月天婷婷综合| 337p粉嫩大胆色噜噜噜噜亚洲 | 国产精品一卡二| 麻豆精品精品国产自在97香蕉| 亚洲成av人片一区二区三区 | 99这里都是精品| 成人h版在线观看| 国产一区在线看| 国产成a人亚洲精品| 国产在线精品一区在线观看麻豆| 中文字幕一区二区三区不卡| 国产精品成人免费在线| 久久久噜噜噜久久中文字幕色伊伊| 精品免费日韩av| 日韩三级视频在线看| 精品国产一区二区亚洲人成毛片| 777xxx欧美| 精品国产123| 欧美xxxxxxxxx| 日韩午夜激情av| 精品久久久网站| 久久精品欧美日韩| 国产精品入口麻豆原神| 久久久久亚洲蜜桃| 中文字幕的久久| 精品精品国产高清a毛片牛牛 | 亚洲人精品午夜| 26uuu亚洲综合色欧美| 国产亚洲福利社区一区| 久久综合色婷婷| 亚洲欧美日韩中文播放| 一区二区三区中文免费| 日韩精品一级二级 | 亚洲欧美激情小说另类| 亚洲天堂福利av| 亚洲午夜在线视频| 喷白浆一区二区| 国产成人自拍在线| 色婷婷综合久久久久中文一区二区 | 91黄视频在线观看| 欧美日韩极品在线观看一区| 精品少妇一区二区三区免费观看| 亚洲女人的天堂| 免费久久精品视频| 国产经典欧美精品| 在线观看不卡一区| 日韩欧美激情四射| 国产欧美精品区一区二区三区| 亚洲精品ww久久久久久p站| 午夜精品一区二区三区电影天堂 | 中国av一区二区三区| 亚洲国产欧美在线| 精品制服美女久久| 欧洲另类一二三四区| 91麻豆精品91久久久久同性| 国产精品国产三级国产普通话99 | 麻豆一区二区三| 日本欧美久久久久免费播放网| 成人免费高清视频| 欧美日韩在线三级| 中文字幕中文字幕一区二区| 香蕉成人啪国产精品视频综合网| 国产精品资源在线| 欧美日韩国产天堂| 亚洲免费在线电影| 激情五月婷婷综合| 欧美日韩一区成人| 一区在线播放视频| 国产精品小仙女| 在线不卡中文字幕播放| 久久精品这里都是精品| 亚洲福利一区二区| 久久电影网电视剧免费观看| 欧美日韩精品二区第二页| 欧美国产视频在线| 国产成人午夜精品5599| 91.麻豆视频| 日韩精品欧美精品| 97se亚洲国产综合自在线不卡| 国产欧美一区二区三区在线老狼| 亚洲成在人线免费| 欧美亚一区二区| 国产欧美一区二区在线观看| 国产麻豆成人精品| 日韩午夜av一区| 美女www一区二区| 欧美日韩久久不卡| 亚洲丰满少妇videoshd| 99久久er热在这里只有精品66| 国产日韩影视精品| 国产精品1区2区| 久久看人人爽人人| 久久99热狠狠色一区二区|