網(wǎng)絡(luò)營(yíng)銷(xiāo)推廣方案pdf站長(zhǎng)工具seo綜合查詢(xún)
Xen-Trap
xen的虛擬化實(shí)現(xiàn)有一個(gè)很重要的機(jī)制就是tarp,中文可以暫且叫做陷入。在ARMv8中,trap就是異常等級(jí)的一個(gè)切換。
當(dāng)發(fā)生trap的時(shí)候,就會(huì)進(jìn)入設(shè)定好的異常向量表中,硬件自動(dòng)判斷屬于哪種類(lèi)型的異常。
一、異常處理
ARM v8有4個(gè)異常級(jí)別,每一個(gè)異常級(jí)別對(duì)應(yīng)一個(gè) VBAR(Vector Base Address Register) 寄存器,用來(lái)指向異常向量表的基地址,每一個(gè)異常向量表的大小為128個(gè)字節(jié),也即可以存放32條指令(ARM v8指令集里一條指令的位寬是32bit的,而不是64bit);同時(shí)每一個(gè)異常向量表會(huì)分為4組,每一組包含4 種異常,如圖所示:
這里的圖對(duì)應(yīng)上面的hyp_traps_vector
整理了一下,xen對(duì)于發(fā)生的異常,最后會(huì)調(diào)用如下函數(shù)進(jìn)行處理:
function | action |
---|---|
do_trap_hyp_sync | brk指令處理、當(dāng)前異常等級(jí)產(chǎn)生的數(shù)據(jù)abort(用于由數(shù)據(jù)訪問(wèn)產(chǎn)生的 MMU 故障、由堆棧指針未對(duì)齊引起的對(duì)齊故障以及同步外部中止,包括同步奇偶校驗(yàn)或 ECC 錯(cuò)誤)、當(dāng)前異常等級(jí)產(chǎn)生的指令abort(用于指令訪問(wèn)和同步外部中止生成的 MMU 故障) |
do_trap_hyp_serror | 在EL2,發(fā)生了Serror是不安全的,直接輸出panic信息 |
do_trap_guest_sync | WFI/WFE指令、cp15/cp14/cp10協(xié)處理訪問(wèn)、SVE相關(guān)指令、SMC指令、HVC指令、訪問(wèn)系統(tǒng)寄存器、從低異常等級(jí)產(chǎn)生的數(shù)據(jù)&指令abort |
do_trap_guest_serror | 通過(guò)置位HCR_EL2的VSE(bit 8)來(lái)產(chǎn)生Virtual SError interrupt,由EL1的異常向量表做進(jìn)一步處理 |
do_trap_irq | 處理中斷 |
二、trap處理的事情(挑重點(diǎn))
1. guest os的同步異常 — do_trap_guest_sync(關(guān)注點(diǎn))
①SMC調(diào)用
function | action |
---|---|
do_trap_smc: | 處理來(lái)自EL1的SMC指令(由于xen修改了dom的dts,所以os的開(kāi)核方式不是使用smc) |
monitor_smc | |
vsmccc_handle_call(handle SMC/HVC call according to ARM SMCCC) | handle_existing_apis —> do_vpsci_0_1_call |
handle_sssc —> do_vpsci_0_2_call |
②HVC調(diào)用
function | action |
---|---|
do_trap_hvc_smccc: | 執(zhí)行vsmccc_handle_call(handle SMC/HVC call according to ARM SMCCC),xen修改了dts,讓每個(gè)dom的psci開(kāi)核方法為hvc:method = “hvc”; |
handle_existing_apis | do_vpsci_0_1_call |
handle_arch | |
handle_hypervisor | |
handle_sssc | do_vpsci_0_2_call:PSCI_0_2_FN64_CPU_ON |
platform_smc | |
do_trap_hypercall: | |
do_memory_op | XENMEM_increase_reservation對(duì)應(yīng)balloon的放氣,增加guest的內(nèi)存 |
XENMEM_decrease_reservation對(duì)應(yīng)balloon的吹氣,減少guest的內(nèi)存 | |
XENMEM_populate_physmap,給page分配mfn | |
XENMEM_exchange,內(nèi)存交換 | |
XENMEM_maximum_ram_page,獲取最大的頁(yè)數(shù) | |
XENMEM_current_reservation,獲取當(dāng)前預(yù)留內(nèi)存總頁(yè)數(shù) | |
XENMEM_maximum_reservation,獲取預(yù)留內(nèi)存最大總頁(yè)數(shù) | |
XENMEM_maximum_gpfn,獲取最大guest pfn數(shù) | |
XENMEM_add_to_physmap,增加頁(yè)面映射 | |
XENMEM_add_to_physmap_batch,增加頁(yè)面映射,不支持iommu? | |
XENMEM_remove_from_physmap,刪除頁(yè)面映射 | |
XENMEM_access_op,內(nèi)存訪問(wèn)權(quán)限設(shè)置&獲取 | |
XENMEM_claim_pages,檢查頁(yè)的權(quán)限等信息 | |
XENMEM_get_vnumainfo,獲取vNUMA的拓?fù)湫畔?/td> | |
XENMEM_reserved_device_memory_map,獲取外設(shè)預(yù)留的內(nèi)存情況?看代碼arm并沒(méi)有實(shí)現(xiàn)相關(guān)的函數(shù) | |
XENMEM_acquire_resource,獲取內(nèi)存資源情況 | |
do_domctl | XEN_DOMCTL_setvcpucontext,設(shè)置vcpu的上下文 |
XEN_DOMCTL_pausedomain,暫停domain,調(diào)用domain_pause | |
XEN_DOMCTL_unpausedomain,取消暫停domain,調(diào)用domain_unpause | |
XEN_DOMCTL_resumedomain,恢復(fù)domain,也會(huì)調(diào)用domain_pause和domain_unpause,涉及vcpu的操作 | |
XEN_DOMCTL_createdomain,創(chuàng)建domain | |
XEN_DOMCTL_max_vcpus,設(shè)置vcpu數(shù)量為max_vcpus | |
XEN_DOMCTL_soft_reset,domain軟復(fù)位 | |
XEN_DOMCTL_destroydomain,銷(xiāo)毀domain | |
XEN_DOMCTL_setnodeaffinity,設(shè)置與guest具有親和力的 NUMA 節(jié)點(diǎn) | |
XEN_DOMCTL_getnodeaffinity,獲取與guest具有親和力的 NUMA 節(jié)點(diǎn) | |
XEN_DOMCTL_setvcpuaffinity,設(shè)置vpu的親和度 | |
XEN_DOMCTL_getvcpuaffinity,獲取vcpu的親和度 | |
XEN_DOMCTL_scheduler_op,調(diào)整domain的調(diào)度參數(shù) | |
XEN_DOMCTL_getdomaininfo,獲取domain的相關(guān)信息 | |
XEN_DOMCTL_getvcpucontext,獲取vcpu的上下文信息 | |
XEN_DOMCTL_getvcpuinfo,獲取vcpu的信息 | |
XEN_DOMCTL_max_mem,設(shè)置max_pages最大內(nèi)存數(shù) | |
XEN_DOMCTL_setdomainhandle,設(shè)置domain操作句柄 | |
XEN_DOMCTL_setdebugging,設(shè)置debugger_attached標(biāo)志位,判斷guest是否被dom0調(diào)試中 | |
XEN_DOMCTL_irq_permission,設(shè)置domain對(duì)于給定irq的訪問(wèn)權(quán)限 | |
XEN_DOMCTL_iomem_permission,設(shè)置domain對(duì)應(yīng)給定io內(nèi)存的訪問(wèn)權(quán)限 | |
XEN_DOMCTL_memory_mapping,映射memory | |
XEN_DOMCTL_settimeoffset,設(shè)置domain的timeoffset(CNTVOFF_EL2?) | |
XEN_DOMCTL_set_target,設(shè)置該guest對(duì)給定guest的特權(quán) | |
XEN_DOMCTL_subscribe,設(shè)置suspend_evtchn | |
XEN_DOMCTL_set_access_required,設(shè)置p2m表的訪問(wèn)權(quán)限 | |
XEN_DOMCTL_set_virq_handler,設(shè)置虛擬中斷的中斷服務(wù)函數(shù) | |
XEN_DOMCTL_setvnumainfo,設(shè)置vNUMA的拓?fù)湫畔?/td> | |
XEN_DOMCTL_monitor_op,啟用/禁用監(jiān)視各種 VM 事件 | |
do_sched_op | 調(diào)度相關(guān)的操作(yeiled、shutdown等操作),這里不一一列舉了,直接看代碼 |
do_console_io | CONSOLEIO_write,guest對(duì)于console的寫(xiě)操作 |
CONSOLEIO_read,guest對(duì)于console的讀操作 | |
do_xen_version | 獲取xen版本 |
do_xsm_op | xen的Xen Security Modules(安全模塊)相關(guān)操作,是個(gè)鉤子 |
do_event_channel_op | xen事件通道的相關(guān)操作 |
do_physdev_op | 這是是對(duì)于一些物理外設(shè)的具體操作,目前只實(shí)現(xiàn)了pci_physdev_op:pci_device_add、pci_device_remove |
do_sysctl | XEN_SYSCTL_readconsole,讀取console |
XEN_SYSCTL_tbuf_op,trace buffers上的 sysctl 操作 | |
XEN_SYSCTL_sched_id,獲取當(dāng)前調(diào)度程序的 ID | |
XEN_SYSCTL_getdomaininfolist,獲取所有domain的信息 | |
XEN_SYSCTL_debug_keys,設(shè)置debug_key,模擬在xen按下按鍵,產(chǎn)生對(duì)應(yīng)的調(diào)試信息 | |
XEN_SYSCTL_getcpuinfo,獲取cpu信息 | |
XEN_SYSCTL_availheap,獲取可用的heap內(nèi)存信息 | |
XEN_SYSCTL_page_offline_op,設(shè)置page的狀態(tài),online或者offline | |
XEN_SYSCTL_cpupool_op,做 cpupool 相關(guān)的 sysctl 操作 | |
XEN_SYSCTL_scheduler_op,調(diào)度相關(guān)的sysctl操作 | |
XEN_SYSCTL_physinfo,獲取當(dāng)前的一些物理信息:cpu數(shù)量、內(nèi)存node數(shù)量、總頁(yè)數(shù)等等 | |
XEN_SYSCTL_numainfo,獲取numa的相關(guān)信息 | |
XEN_SYSCTL_cputopoinfo,獲取xen_sysctl_cputopo結(jié)構(gòu)體信息 | |
XEN_SYSCTL_coverage_op,@TODO,沒(méi)看懂 | |
XEN_SYSCTL_livepatch_op,@TODO,沒(méi)看懂 | |
XEN_SYSCTL_overlay,在給定的設(shè)備樹(shù)目標(biāo)節(jié)點(diǎn)做add或者remove節(jié)點(diǎn)操作 | |
do_hvm_op | HVMOP_set_param,設(shè)置xen_hvm_param結(jié)構(gòu)體參數(shù) |
HVMOP_get_param,獲取xen_hvm_param結(jié)構(gòu)體參數(shù) | |
do_grant_table_op (Xen通過(guò)提供grant_table_op一系列hypercall以供DomU使用來(lái)實(shí)現(xiàn)內(nèi)存共享) | GNTTABOP_map_grant_ref,映射一個(gè)gref |
GNTTABOP_unmap_grant_ref,取消gref的映射 | |
GNTTABOP_unmap_and_replace,撤銷(xiāo)對(duì)gref的映射,并替換為其他的映射 | |
GNTTABOP_setup_table,建立grant table | |
GNTTABOP_transfer,移交一個(gè)頁(yè) | |
GNTTABOP_copy,拷貝一些頁(yè)/gref對(duì)應(yīng)的頁(yè) | |
GNTTABOP_query_size,查詢(xún)grant table的當(dāng)前/最大大小 | |
GNTTABOP_set_version,設(shè)置grant table的版本 | |
GNTTABOP_get_status_frames,獲取用于存儲(chǔ)dom授權(quán)狀態(tài)的幀列表 | |
GNTTABOP_get_version,獲取grant table的版本 | |
GNTTABOP_swap_grant_ref,交換gref | |
GNTTABOP_cache_flush,刷cache(gref對(duì)應(yīng)的mfn) | |
do_multicall | 調(diào)用arch_do_multicall_call來(lái)執(zhí)行多次hypcall |
do_platform_op | 目前只實(shí)現(xiàn)了XENPF_settime64,設(shè)置墻上時(shí)鐘(wall clock) |
do_vcpu_op | VCPUOP_initialise,初始化vcpu |
VCPUOP_up,上線vcpu | |
VCPUOP_down,下線vpcu | |
VCPUOP_is_up,判斷vpcu是否上線 | |
VCPUOP_get_runstate_info,獲取vcpu的運(yùn)行狀態(tài)信息 | |
VCPUOP_set_periodic_timer,設(shè)置周期定時(shí)器 | |
VCPUOP_stop_periodic_timer,停止周期定時(shí)器 | |
VCPUOP_set_singleshot_timer,設(shè)置單次定時(shí)器 | |
VCPUOP_stop_singleshot_timer,停止單次定時(shí)器 | |
VCPUOP_register_vcpu_info,在客戶(hù)地址空間中為vcpu_info結(jié)構(gòu)注冊(cè)一個(gè)內(nèi)存位置 | |
VCPUOP_register_runstate_memory_area,注冊(cè)一個(gè)共享內(nèi)存區(qū)域 |
③訪問(wèn)系統(tǒng)寄存器
function | action |
---|---|
do_sysreg | HSR_SYSREG_ACTLR_EL1:EL1階段訪問(wèn)ACTLR_EL1寄存器 |
HSR_SYSREG_DCISW:EL1階段訪問(wèn)DCISW、DCCSW、DCCISW寄存器(三個(gè)都是和cache相關(guān)的) | |
EL1階段訪問(wèn)SCTLR_EL1、TTBR0_EL1、TTBR1_EL1、TCR_EL1、ESR_EL1、FAR_EL1、AFSR0_EL1、AFSR1_EL1、MAIR_EL1、AMAIR_EL1、CONTEXTIDR_EL1寄存器 | |
HSR_SYSREG_MDRAR_EL1:EL1階段訪問(wèn)MDRAR_EL1寄存器:Monitor Debug ROM Address Register | |
HSR_SYSREG_OSLAR_EL1:EL1階段訪問(wèn)OSLAR_EL1寄存器:OS Lock Access Register | |
HSR_SYSREG_OSDLR_EL1:EL1階段訪問(wèn)OSDLR_EL1寄存器:OS Double Lock Register | |
HSR_SYSREG_OSLSR_EL1:EL1階段訪問(wèn)OSLSR_EL1寄存器:OS Lock Status Register | |
HSR_SYSREG_MDSCR_EL1:EL1階段訪問(wèn)MDSCR_EL1寄存器:Monitor Debug System Control Register | |
HSR_SYSREG_MDCCSR_EL0:EL0階段訪問(wèn)MDCCSR_EL0寄存器:Monitor DCC Status Register | |
下面是關(guān)于性能監(jiān)視器相關(guān)的寄存器: | |
HSR_SYSREG_PMINTENSET_EL1:EL1階段訪問(wèn)PMINTENSET_EL1寄存器:Performance Monitors Interrupt Enable Set register | |
HSR_SYSREG_PMINTENCLR_EL1:EL1階段訪問(wèn)PMINTENCLR_EL1寄存器:Performance Monitors Interrupt Enable Clear register | |
HSR_SYSREG_PMUSERENR_EL0:EL0階段訪問(wèn)PMUSERENR_EL0寄存器:Performance Monitors User Enable Register | |
HSR_SYSREG_PMCR_EL0:EL0階段訪問(wèn)PMCR_EL0寄存器:Performance Monitors Control Register | |
HSR_SYSREG_PMCNTENSET_EL0:EL0階段訪問(wèn)PMCNTENSET_EL0寄存器:Performance Monitors Count Enable Set register | |
HSR_SYSREG_PMCNTENCLR_EL0:EL0階段訪問(wèn)PMCNTENCLR_EL0寄存器:Performance Monitors Count Enable Clear register | |
HSR_SYSREG_PMOVSCLR_EL0:EL0階段訪問(wèn)PMOVSCLR_EL0寄存器:Performance Monitors Overflow Flag Status Clear Register | |
HSR_SYSREG_PMSWINC_EL0:EL0階段訪問(wèn)PMSWINC_EL0寄存器:Performance Monitors Software Increment register | |
HSR_SYSREG_PMSELR_EL0:EL0階段訪問(wèn)PMSELR_EL0寄存器:Performance Monitors Event Counter Selection Register | |
HSR_SYSREG_PMCEID0_EL0:EL0階段訪問(wèn)PMCEID0_EL0寄存器:Performance Monitors Common Event Identification register 0 | |
HSR_SYSREG_PMCEID1_EL0:EL0階段訪問(wèn)PMCEID1_EL0寄存器:Performance Monitors Common Event Identification register 1 | |
HSR_SYSREG_PMCCNTR_EL0:EL0階段訪問(wèn)PMCCNTR_EL0寄存器:Performance Monitors Cycle Count Register | |
HSR_SYSREG_PMXEVTYPER_EL0:EL0階段訪問(wèn)PMXEVTYPER_EL0寄存器:Performance Monitors Selected Event Type Register | |
HSR_SYSREG_PMXEVCNTR_EL0:EL0階段訪問(wèn)PMXEVCNTR_EL0寄存器:Performance Monitors Selected Event Count Register | |
HSR_SYSREG_PMOVSSET_EL0:EL0階段訪問(wèn)PMOVSSET_EL0寄存器:Performance Monitors Overflow Flag Status Set register | |
下面是和定時(shí)器相關(guān)的寄存器: | |
HSR_SYSREG_CNTP_CTL_EL0:EL0階段訪問(wèn)CNTP_CTL_EL0寄存器:Counter-timer Physical Timer Control register | |
HSR_SYSREG_CNTP_TVAL_EL0:EL0階段訪問(wèn)CNTP_TVAL_EL0寄存器:Counter-timer Physical Timer TimerValue register | |
HSR_SYSREG_CNTP_CVAL_EL0:EL0階段訪問(wèn)CNTP_CVAL_EL0寄存器:Counter-timer Physical Timer CompareValue register | |
下面是和GIC中斷控制器相關(guān)的寄存器: | |
HSR_SYSREG_ICC_SGI1R_EL1:EL1階段訪問(wèn)ICC_SGI1R_EL1寄存器:Interrupt Controller Software Generated Interrupt Group 1 Register Generates Group 1 SGIs for the current Security state | |
HSR_SYSREG_ICC_ASGI1R_EL1:EL1階段訪問(wèn)ICC_ASGI1R_EL1寄存器:Interrupt Controller Alias Software Generated Interrupt Group 1 Generates Group 1 SGIs for the Security state that is not the current Security state | |
HSR_SYSREG_ICC_SGI0R_EL1:EL1階段訪問(wèn)ICC_SGI0R_EL1寄存器:Interrupt Controller Software Generated Interrupt Group 0 Register Generates Secure Group 0 SGIs | |
HSR_SYSREG_ICC_SRE_EL1:EL1階段訪問(wèn)ICC_SRE_EL1寄存器:Interrupt Controller System Register Enable register (EL1) | |
下面是guest os用來(lái)識(shí)別處理器功能的大多數(shù)Identification寄存器: | |
ID_PFR0_EL1 ~ ID_PFR2_EL1:AArch32 Processor Feature Register 0、1、2 | |
ID_DFR0_EL1、ID_DFR1_EL1:AArch32 Debug Feature Register 0、1 | |
ID_AFR0_EL1:AArch32 Auxiliary Feature Register 0 | |
ID_MMFR0_EL1 ~ ID_MMFR5_EL1:AArch32 Memory Model Feature Register 0、1、2、3、4、5 | |
ID_ISAR0_EL1 ~ ID_ISAR6_EL1:AArch32 Instruction Set Attribute Register 0、1、2、3、4、5、6 | |
MVFR0_EL1 ~ MVFR2_EL1: AArch32 Media and VFP Feature Register 0、1、2 | |
ID_AA64PFR0_EL1、ID_AA64PFR1_EL1:AArch64 Processor Feature Register 0、1 | |
ID_AA64DFR0_EL1、ID_AA64DFR1_EL1:AArch64 Debug Feature Register 0、1 | |
ID_AA64ISAR0_EL1、ID_AA64ISAR1_EL1:AArch64 Instruction Set Attribute Register 0、1 | |
ID_AA64MMFR0_EL1 ~ ID_AA64MMFR2_EL1:AArch64 Memory Model Feature Register 0、1、2 | |
ID_AA64AFR0_EL1、ID_AA64AFR1_EL1:AArch64 Auxiliary Feature Register 0 | |
ID_AA64ZFR0_EL1:AArch64 SVE Feature ID register 0 | |
EL1訪問(wèn) group 3 ID registers: | |
④低異常等級(jí)產(chǎn)生的數(shù)據(jù)&指令abort
function | action |
---|---|
do_trap_stage2_abort_guest(數(shù)據(jù)&指令abort都是調(diào)用這個(gè)函數(shù)) | FSC_FLT_PERM:0b0011xx:L1/L2/L3頁(yè)表訪問(wèn)權(quán)限錯(cuò)誤 |
p2m_mem_access_check,這里會(huì)去配置頁(yè)表項(xiàng),設(shè)置權(quán)限位 | |
FSC_FLT_TRANS:0b0001xx:L0/L1/L2/L3頁(yè)表翻譯錯(cuò)誤,IPA —> PA的頁(yè)表沒(méi)有正確配置(VA —> IPA的翻譯已經(jīng)在guest os的EL1處理了) | |
check_p2m —> p2m_resolve_translation_faul或者try_map_mmio | |
try_decode_instruction —> 指令abort | |
try_handle_mmio(IO trap or Device emulation,解決多個(gè)guest os訪問(wèn)一個(gè)外設(shè)的情況) |
2. hypervisor同步異常 — do_trap_hyp_sync
function | action |
---|---|
do_trap_hyp_sync | HSR_EC_BRK:斷點(diǎn)指令異常,調(diào)試用 |
HSR_EC_DATA_ABORT_CURR_EL:同異常等級(jí)產(chǎn)生的數(shù)據(jù)abort:dump_hyp_walk。xen的頁(yè)表錯(cuò)誤 | |
HSR_EC_INSTR_ABORT_CURR_EL:同異常等級(jí)產(chǎn)生的指令abort:dump_hyp_walk |