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

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

?? pci-amd-iommu.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 <asm/amd-iommu.h>#include <asm/hvm/svm/amd-iommu-proto.h>#include <xen/sched.h>#include <asm/mm.h>#include "pci-direct.h"#include "pci_regs.h"struct list_head amd_iommu_head;long amd_iommu_poll_comp_wait = COMPLETION_WAIT_DEFAULT_POLLING_COUNT;static long amd_iommu_cmd_buffer_entries = IOMMU_CMD_BUFFER_DEFAULT_ENTRIES;int nr_amd_iommus = 0;/* will set if amd-iommu HW is found */int amd_iommu_enabled = 0;static int enable_amd_iommu = 0;boolean_param("enable_amd_iommu", enable_amd_iommu);static void deallocate_domain_page_tables(struct hvm_iommu *hd){    if ( hd->root_table )        free_xenheap_page(hd->root_table);}static void deallocate_domain_resources(struct hvm_iommu *hd){    deallocate_domain_page_tables(hd);}static void __init init_cleanup(void){    struct amd_iommu *iommu;    dprintk(XENLOG_ERR, "AMD IOMMU: %s()\n", __FUNCTION__);    for_each_amd_iommu(iommu) {        unmap_iommu_mmio_region(iommu);    }}static void __init deallocate_iommu_table_struct(            struct table_struct *table){    if (table->buffer) {        free_xenheap_pages(table->buffer,            get_order_from_bytes(table->alloc_size));        table->buffer = NULL;    }}static void __init deallocate_iommu_resources(struct amd_iommu *iommu){    deallocate_iommu_table_struct(&iommu->dev_table);    deallocate_iommu_table_struct(&iommu->cmd_buffer);;}static void __init detect_cleanup(void){    struct amd_iommu *iommu;    dprintk(XENLOG_ERR, "AMD IOMMU: %s()\n", __FUNCTION__);    for_each_amd_iommu(iommu) {        list_del(&iommu->list);        deallocate_iommu_resources(iommu);        xfree(iommu);    }}static int requestor_id_from_bdf(int bdf){    /* HACK - HACK */    /* account for possible 'aliasing' by parent device */   return bdf;}static int __init allocate_iommu_table_struct(struct table_struct *table,            const char *name){    table->buffer = (void *) alloc_xenheap_pages(        get_order_from_bytes(table->alloc_size));    if ( !table->buffer ) {        dprintk(XENLOG_ERR, "AMD IOMMU: Error allocating %s\n", name);        return -ENOMEM;    }    memset(table->buffer, 0, table->alloc_size);    return 0;}static int __init allocate_iommu_resources(struct amd_iommu *iommu){    /* allocate 'device table' on a 4K boundary */    iommu->dev_table.alloc_size =        PAGE_ALIGN(((iommu->last_downstream_bus + 1) *        IOMMU_DEV_TABLE_ENTRIES_PER_BUS) *        IOMMU_DEV_TABLE_ENTRY_SIZE);    iommu->dev_table.entries =        iommu->dev_table.alloc_size / IOMMU_DEV_TABLE_ENTRY_SIZE;    if (allocate_iommu_table_struct(&iommu->dev_table,            "Device Table") != 0)        goto error_out;    /* allocate 'command buffer' in power of 2 increments of 4K */    iommu->cmd_buffer_tail = 0;    iommu->cmd_buffer.alloc_size =        PAGE_SIZE << get_order_from_bytes(        PAGE_ALIGN(amd_iommu_cmd_buffer_entries *        IOMMU_CMD_BUFFER_ENTRY_SIZE));   iommu->cmd_buffer.entries =        iommu->cmd_buffer.alloc_size / IOMMU_CMD_BUFFER_ENTRY_SIZE;    if ( allocate_iommu_table_struct(&iommu->cmd_buffer,            "Command Buffer") != 0 )        goto error_out;    return 0;error_out:    deallocate_iommu_resources(iommu);    return -ENOMEM;}int iommu_detect_callback(u8 bus, u8 dev, u8 func, u8 cap_ptr){    struct amd_iommu *iommu;    iommu = (struct amd_iommu *) xmalloc(struct amd_iommu);    if ( !iommu ) {        dprintk(XENLOG_ERR, "AMD IOMMU: Error allocating amd_iommu\n");        return -ENOMEM;    }    memset(iommu, 0, sizeof(struct amd_iommu));    spin_lock_init(&iommu->lock);    /* get capability and topology information */    if ( get_iommu_capabilities(bus, dev, func, cap_ptr, iommu) != 0 )        goto error_out;    if ( get_iommu_last_downstream_bus(iommu) != 0 )        goto error_out;    list_add_tail(&iommu->list, &amd_iommu_head);    /* allocate resources for this IOMMU */    if (allocate_iommu_resources(iommu) != 0)        goto error_out;    return 0;error_out:    xfree(iommu);    return -ENODEV;}static int __init amd_iommu_init(void){    struct amd_iommu *iommu;    unsigned long flags;    for_each_amd_iommu(iommu) {        spin_lock_irqsave(&iommu->lock, flags);        /* register IOMMU data strucures in MMIO space */        if (map_iommu_mmio_region(iommu) != 0)            goto error_out;        register_iommu_dev_table_in_mmio_space(iommu);        register_iommu_cmd_buffer_in_mmio_space(iommu);        /* enable IOMMU translation services */        enable_iommu(iommu);        nr_amd_iommus++;        spin_unlock_irqrestore(&iommu->lock, flags);    }    amd_iommu_enabled = 1;    return 0;error_out:    init_cleanup();    return -ENODEV;}struct amd_iommu *find_iommu_for_device(int bus, int devfn){    struct amd_iommu *iommu;    for_each_amd_iommu(iommu) {        if ( bus == iommu->root_bus ) {            if ( devfn >= iommu->first_devfn &&                devfn <= iommu->last_devfn )                return iommu;        }        else if ( bus <= iommu->last_downstream_bus ) {            if ( iommu->downstream_bus_present[bus] )                return iommu;        }    }    return NULL;}void amd_iommu_setup_domain_device(    struct domain *domain, struct amd_iommu *iommu, int requestor_id){    void *dte;    u64 root_ptr;    unsigned long flags;    struct hvm_iommu *hd = domain_hvm_iommu(domain);    BUG_ON( !hd->root_table||!hd->paging_mode );    root_ptr = (u64)virt_to_maddr(hd->root_table);    dte = iommu->dev_table.buffer +        (requestor_id * IOMMU_DEV_TABLE_ENTRY_SIZE);    spin_lock_irqsave(&iommu->lock, flags);     amd_iommu_set_dev_table_entry((u32 *)dte,        root_ptr, hd->domain_id, hd->paging_mode);    dprintk(XENLOG_INFO, "AMD IOMMU: Set DTE req_id:%x, "            "root_ptr:%"PRIx64", domain_id:%d, paging_mode:%d\n",            requestor_id, root_ptr, hd->domain_id, hd->paging_mode);    spin_unlock_irqrestore(&iommu->lock, flags);}void __init amd_iommu_setup_dom0_devices(void){    struct hvm_iommu *hd = domain_hvm_iommu(dom0);    struct amd_iommu *iommu;    struct pci_dev *pdev;    int bus, dev, func;    u32 l;    int req_id, bdf;    for ( bus = 0; bus < 256; bus++ ) {        for ( dev = 0; dev < 32; dev++ ) {            for ( func = 0; func < 8; func++ ) {                l = read_pci_config(bus, dev, func, PCI_VENDOR_ID);                /* some broken boards return 0 or ~0 if a slot is empty: */                if ( l == 0xffffffff || l == 0x00000000 ||                    l == 0x0000ffff || l == 0xffff0000 )                    continue;                pdev = xmalloc(struct pci_dev);                pdev->bus = bus;                pdev->devfn = PCI_DEVFN(dev, func);                list_add_tail(&pdev->list, &hd->pdev_list);                bdf = (bus << 8) | pdev->devfn;                req_id = requestor_id_from_bdf(bdf);                iommu = find_iommu_for_device(bus, pdev->devfn);                if ( iommu )                    amd_iommu_setup_domain_device(dom0, iommu, req_id);            }        }    }}int amd_iommu_detect(void){    unsigned long i;    if ( !enable_amd_iommu ) {        printk("AMD IOMMU: Disabled\n");        return 0;    }    INIT_LIST_HEAD(&amd_iommu_head);    if ( scan_for_iommu(iommu_detect_callback) != 0 ) {        dprintk(XENLOG_ERR, "AMD IOMMU: Error detection\n");        goto error_out;    }    if ( !iommu_found() ) {        printk("AMD IOMMU: Not found!\n");        return 0;    }    if ( amd_iommu_init() != 0 ) {        dprintk(XENLOG_ERR, "AMD IOMMU: Error initialization\n");        goto error_out;    }    if ( amd_iommu_domain_init(dom0) != 0 )        goto error_out;    /* setup 1:1 page table for dom0 */    for ( i = 0; i < max_page; i++ )        amd_iommu_map_page(dom0, i, i);    amd_iommu_setup_dom0_devices();    return 0;error_out:     detect_cleanup();     return -ENODEV;}static int allocate_domain_resources(struct hvm_iommu *hd){    /* allocate root table */    hd->root_table = (void *)alloc_xenheap_page();    if ( !hd->root_table )        return -ENOMEM;    memset((u8*)hd->root_table, 0, PAGE_SIZE);    return 0;}static int get_paging_mode(unsigned long entries){    int level = 1;    BUG_ON ( !max_page );    if ( entries > max_page )        entries = max_page;    while ( entries > PTE_PER_TABLE_SIZE ) {        entries = PTE_PER_TABLE_ALIGN(entries) >> PTE_PER_TABLE_SHIFT;        ++level;        if ( level > 6 )            return -ENOMEM;    }    dprintk(XENLOG_INFO, "AMD IOMMU: paging mode = %d\n", level);    return level;}int amd_iommu_domain_init(struct domain *domain){    struct hvm_iommu *hd = domain_hvm_iommu(domain);    spin_lock_init(&hd->mapping_lock);    spin_lock_init(&hd->iommu_list_lock);    INIT_LIST_HEAD(&hd->pdev_list);    /* allocate page directroy */    if ( allocate_domain_resources(hd) != 0 ) {        dprintk(XENLOG_ERR, "AMD IOMMU: %s()\n", __FUNCTION__);        goto error_out;    }    if ( is_hvm_domain(domain) )        hd->paging_mode = IOMMU_PAGE_TABLE_LEVEL_4;    else        hd->paging_mode = get_paging_mode(max_page);    hd->domain_id = domain->domain_id;    return 0;error_out:    deallocate_domain_resources(hd);    return -ENOMEM;}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
亚洲免费观看高清在线观看| 久久久久久久久久看片| 成人国产电影网| 奇米色一区二区| 美腿丝袜亚洲色图| 麻豆国产精品一区二区三区| 蜜桃一区二区三区在线| 午夜欧美一区二区三区在线播放| 亚洲国产一区视频| 亚洲一卡二卡三卡四卡无卡久久 | 欧美mv和日韩mv国产网站| 在线亚洲一区二区| 3d动漫精品啪啪| 精品国内片67194| 中国av一区二区三区| 亚洲欧美aⅴ...| 热久久国产精品| 国产高清不卡一区| 99久久99久久精品免费观看| 欧美性色欧美a在线播放| 538在线一区二区精品国产| 欧美一级片免费看| 国产亚洲视频系列| 日韩理论片网站| 午夜在线电影亚洲一区| 久久99精品久久只有精品| 韩国女主播成人在线| 99久久久无码国产精品| 欧美色成人综合| 久久久久久久国产精品影院| 亚洲自拍欧美精品| 九一九一国产精品| 91豆麻精品91久久久久久| 日韩午夜三级在线| 亚洲天堂2014| 国产一区 二区 三区一级| 色婷婷国产精品综合在线观看| 宅男在线国产精品| 久久久影视传媒| 亚洲午夜久久久久久久久久久| 麻豆91精品91久久久的内涵| 91在线码无精品| 久久香蕉国产线看观看99| 亚洲综合免费观看高清在线观看| 国产一区二区三区蝌蚪| 欧美日韩免费在线视频| 国产欧美一区二区精品婷婷 | 精品在线一区二区| 日本高清成人免费播放| 精品电影一区二区| 亚洲高清免费视频| 91网上在线视频| 久久久欧美精品sm网站| 日韩精品电影一区亚洲| 一本到不卡免费一区二区| 国产亚洲一区二区在线观看| 日本特黄久久久高潮| 色狠狠一区二区三区香蕉| 国产精品美女久久久久久久久久久| 日本欧美一区二区三区| 欧美裸体一区二区三区| 一区二区三区免费看视频| www.av精品| 国产精品久久久久久久浪潮网站 | 亚洲日本韩国一区| 国产精品资源在线观看| 久久综合色天天久久综合图片| 午夜一区二区三区在线观看| 在线视频欧美区| 亚洲精品国产一区二区精华液 | 91丨九色porny丨蝌蚪| 欧美激情一区不卡| 国产精品一区二区视频| 久久综合久久久久88| 国产激情视频一区二区三区欧美 | 欧美一区二区三区视频免费| 亚洲第一久久影院| 欧美网站一区二区| 亚洲成av人综合在线观看| 欧美日韩精品是欧美日韩精品| 亚洲免费观看高清完整版在线观看 | 中文字幕日韩一区二区| 97se亚洲国产综合自在线| 国产精品毛片a∨一区二区三区| 不卡av免费在线观看| 亚洲人成伊人成综合网小说| 色婷婷av久久久久久久| 亚洲国产aⅴ天堂久久| 51精品秘密在线观看| 韩国成人在线视频| 欧美激情一区三区| 欧洲精品一区二区| 男女激情视频一区| 国产色一区二区| 色婷婷综合久久久久中文一区二区| 一区二区欧美视频| 日韩一区二区在线观看视频| 国产一区视频导航| 亚洲免费电影在线| 日韩女优电影在线观看| 成人免费电影视频| 五月激情丁香一区二区三区| 在线播放国产精品二区一二区四区| 免费不卡在线观看| 成人欧美一区二区三区1314| 欧美精品1区2区3区| 狠狠色狠狠色合久久伊人| 国产精品萝li| 欧美一区二区三区人| 成人综合婷婷国产精品久久蜜臀| 亚洲猫色日本管| 精品国产91乱码一区二区三区| 99视频国产精品| 麻豆91精品视频| 亚洲精品高清视频在线观看| 精品国产精品一区二区夜夜嗨| 99久久99久久精品国产片果冻| 日本欧美一区二区在线观看| 亚洲天堂成人网| 国产午夜精品一区二区三区嫩草| 欧美这里有精品| 成人午夜在线免费| 蜜臀av亚洲一区中文字幕| 亚洲精品国产一区二区精华液| 久久久www成人免费无遮挡大片| 欧美色欧美亚洲另类二区| 成人黄页毛片网站| 日韩精品电影在线观看| 亚洲一区欧美一区| 欧美极品aⅴ影院| 精品少妇一区二区三区免费观看| 欧美日韩免费视频| 94色蜜桃网一区二区三区| 高清不卡一区二区在线| 紧缚奴在线一区二区三区| 五月天一区二区三区| 一区二区免费视频| 亚洲女人小视频在线观看| 国产欧美日韩一区二区三区在线观看| 欧美一区二区视频免费观看| 欧美在线免费观看亚洲| 99精品欧美一区二区三区小说 | 色婷婷久久综合| 99热精品一区二区| av成人免费在线| 成人激情小说网站| av一本久道久久综合久久鬼色| 国产成人综合亚洲网站| 激情文学综合网| 极品尤物av久久免费看| 蜜臀av在线播放一区二区三区 | 成人精品视频网站| 粉嫩13p一区二区三区| 粉嫩欧美一区二区三区高清影视| 精彩视频一区二区| 丁香六月久久综合狠狠色| 高清不卡在线观看| 91浏览器入口在线观看| 色综合久久综合网| 欧美色网一区二区| 日韩一区二区在线看片| www精品美女久久久tv| 国产丝袜欧美中文另类| 椎名由奈av一区二区三区| 亚洲精品视频观看| 日韩影院精彩在线| 国产乱子轮精品视频| 99久久精品国产毛片| 欧美午夜精品电影| 欧美电影免费观看高清完整版| 久久夜色精品国产噜噜av| 国产精品素人视频| 亚洲嫩草精品久久| 日本午夜一本久久久综合| 国产精一区二区三区| 97久久久精品综合88久久| 欧美区一区二区三区| 久久久久久久性| 亚洲综合男人的天堂| 精品一区二区三区香蕉蜜桃 | 奇米888四色在线精品| 国产在线日韩欧美| 日本福利一区二区| 日韩欧美精品三级| 国产精品久久久久久久岛一牛影视| 亚洲欧美韩国综合色| 久草热8精品视频在线观看| 成人免费观看视频| 在线播放欧美女士性生活| 国产精品视频一二| 天天色 色综合| www.欧美亚洲| 欧美成人精品高清在线播放| 亚洲天堂av一区| 国产在线麻豆精品观看| 欧美在线观看视频一区二区三区| 久久久久久久久久久电影| 视频一区国产视频| 99综合电影在线视频| 精品免费一区二区三区|