超级调用swi 82的最初流程



xen/arch/arm/kernel/entry-armv.S

__vectors_start:

swi SYS_ERROR0 /* Reset */

b vector_undefined_instruction + stubs_offset

ldr pc, .LCvswi + stubs_offset

b vector_prefetch_abort + stubs_offset

b vector_data_abort + stubs_offset

b vector_addrexcptn + stubs_offset

b vector_irq + stubs_offset

b vector_fiq + stubs_offset

.globl __vectors_end

__vectors_end:

/*

 * We group all the following data together to optimise

 * for CPUs with separate I & D caches.

 */

.align 5

.LCvswi:

.word vector_swi

--------------
xen/arch/arm/hypervisor/hypervisor.S


ENTRY(vector_swi)

sub sp, sp, #S_FRAME_SIZE

stmia sp, {r0 - r12}

add r8, sp, #S_PC

stmdb r8, {sp, lr}^

mrs r8, spsr

str lr, [sp, #S_PC]

str r8, [sp, #S_PSR]

vcpu r8

add r8, r8, #(OFFSET_ARCH_VCPU + OFFSET_GUEST_CONTEXT)

ldr r9, [r8, #(OFFSET_SYS_REGS+OFFSET_VPSR)]

ldr r10, [sp, #S_SP]

cmp r9, #PSR_MODE_USR

streq   r10, [r8, #(OFFSET_SYS_REGS+OFFSET_VUSP)]

strne   r10, [r8, #(OFFSET_SYS_REGS+OFFSET_VKSP)]

ldr     r8, [sp, #S_PSR]

bic     r8, r8, #PSR_MODE_MASK

orr     r8, r8, r9

str     r8, [sp, #S_PSR]

ldr r10, [lr, #-4]

bic r10, r10, #0xff000000

cmp r10, #HYPERCALL_VECTOR_NO

moveq r12, #0x18

movne r12, #0x08

str r12, [sp, #S_CONTEXT]

beq process_hypercalls  //BEQ  也就是条件跳转 当r10与 82比较,相等的时候,就跳转到process_hypercalls标号处

b do_upcall                     //这个do_upcall和evtchn_do_upcall好相似,实际上也是的。

process_hypercalls:

enable_irq

adr lr, ret_from_hypercall

adr tbl, hypercall_table

add tbl, tbl, scno, lsl #2

ldr pc, [tbl]

ENTRY(hypercall_table)

__hypercall_start:

.long do_set_trap_table     /*  0 */

.long do_mmu_update

.long do_ni_hypercall

.long do_stack_switch

.long do_set_callbacks

.long do_fpu_taskswitch     /*  5 */

.long do_sched_op_compat

.long do_domctl

.long do_set_debugreg

.long do_get_debugreg

.long do_update_descriptor  /* 10 */

.long do_ni_hypercall

.long do_memory_op

.long do_multicall

.long do_update_va_mapping

.long do_set_timer_op       /* 15 */

.long do_event_channel_op

。。。。。。
-------------


看一下do_upcall的定义:

xen/arch/arm/kernel/entry-common.S

/*

 * Send event to guest domain

 */

ENTRY(do_upcall)

vcpu    r10

ldr r11, [r10, #OFFSET_VCPU_INFO]

add r10, r10, #(OFFSET_ARCH_VCPU + OFFSET_GUEST_CONTEXT)

ldr lr, [r10, #OFFSET_HYPERVISOR_CALLBACK]

cmp lr, #0

beq restore

@DRE_start

@ldrb r9, [r11, #OFFSET_EVTCHN_UPCALL_MASK]

@cmp r9, #1

@beq restore

@DRE_end

mov r9, #0x01

strb r9, [r11, #OFFSET_EVTCHN_UPCALL_MASK]

mov r4, #PSR_MODE_SVC

str r4, [r10, #(OFFSET_SYS_REGS + OFFSET_VPSR)]

@ Load virtual kernel stack pointer

ldr r11, [r10, #(OFFSET_SYS_REGS + OFFSET_VKSP)]

@ Align VKSP in 8-byte boundary

sub r12, r11, #S_FRAME_SIZE

tst r12, #4

bicne r12, r12, #4

tst r12, #4

1:

bne 1b

@ Update effective virtual kernel stack pointer.

str r12, [r10, #(OFFSET_SYS_REGS + OFFSET_VKSP)]

@ Create bounce frame in guest stack

ldmia sp!, {r0-r8}

stmia r12!, {r0-r8}

ldmia sp!, {r0-r8}

stmia r12!, {r0-r8}

sub r12, r12, #S_FRAME_SIZE

ldr r0, =.LCupcall

stmia r0, {r12,lr}

ldmia r0, {sp, lr}^

ldr r0, [r12, #S_CONTEXT]

ldr r1, [r12, #S_PSR]

ldr r2, [r10, #(OFFSET_SYS_REGS + OFFSET_VFAR)]

ldr r3, [r10, #(OFFSET_SYS_REGS + OFFSET_VFSR)]

mov r7, #PSR_MODE_USR

msr spsr, r7

ldr r5, =DOMAIN_KERNEL_VALUE

mcr     p15, 0, r5, c3, c0, 0   @ Load DAC

movs pc, lr

.LCupcall:

.long 0

.long 0


评论

此博客中的热门博文

Linux/ARM Page Table Entry 属性设置分析

提交了30次才AC ---【附】POJ 2488解题报告

笔记