|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 6/6] mini-os/x86-64 entry: check against nested events and try to fix up
On 03/08/2013 01:30 PM, Xu Zhang wrote:
> +# [How we do the fixup]. We want to merge the current stack frame with the
> +# just-interrupted frame. How we do this depends on where in the critical
> +# region the interrupted handler was executing, and so how many saved
> +# registers are in each frame. We do this quickly using the lookup table
> +# 'critical_fixup_table'. For each byte offset in the critical region, it
> +# provides the number of bytes which have already been popped from the
> +# interrupted stack frame. This is the number of bytes from the current stack
> +# that we need to copy at the end of the previous activation frame so that
> +# we can continue as if we've never even reached 11 running in the old
> +# activation frame.
> +critical_region_fixup:
> + addq $critical_fixup_table - scrit, %rax
> + movzbq (%rax),%rax # %rax contains num bytes popped
> + mov %rsp,%rsi
> + add %rax,%rsi # %esi points at end of src region
> +
> + movq RSP(%rsp),%rdi # acquire interrupted %rsp from current
> stack frame
> + # %edi points at end of dst region
> + mov %rax,%rcx
> + shr $3,%rcx # convert bytes into count of 64-bit
> entities
> + je 16f # skip loop if nothing to copy
> +15: subq $8,%rsi # pre-decrementing copy loop
> + subq $8,%rdi
> + movq (%rsi),%rax
> + movq %rax,(%rdi)
> + loop 15b
> +16: movq %rdi,%rsp # final %rdi is top of merged stack
> + andb $KERNEL_CS_MASK,CS(%rsp) # CS on stack might have
> changed
> + jmp 11b
> +
> +
> +/* Nested event fixup look-up table*/
> +critical_fixup_table:
> + .byte 0x00,0x00,0x00 # XEN_TEST_PENDING(%rsi)
> + .byte 0x00,0x00,0x00,0x00,0x00,0x00 # jnz 14f
> + .byte 0x00,0x00,0x00,0x00 # mov (%rsp),%r15
> + .byte 0x00,0x00,0x00,0x00,0x00 # mov 0x8(%rsp),%r14
> + .byte 0x00,0x00,0x00,0x00,0x00 # mov 0x10(%rsp),%r13
> + .byte 0x00,0x00,0x00,0x00,0x00 # mov 0x18(%rsp),%r12
> + .byte 0x00,0x00,0x00,0x00,0x00 # mov 0x20(%rsp),%rbp
> + .byte 0x00,0x00,0x00,0x00,0x00 # mov 0x28(%rsp),%rbx
> + .byte 0x00,0x00,0x00,0x00 # add $0x30,%rsp
> + .byte 0x30,0x30,0x30,0x30 # mov (%rsp),%r11
> + .byte 0x30,0x30,0x30,0x30,0x30 # mov 0x8(%rsp),%r10
> + .byte 0x30,0x30,0x30,0x30,0x30 # mov 0x10(%rsp),%r9
> + .byte 0x30,0x30,0x30,0x30,0x30 # mov 0x18(%rsp),%r8
> + .byte 0x30,0x30,0x30,0x30,0x30 # mov 0x20(%rsp),%rax
> + .byte 0x30,0x30,0x30,0x30,0x30 # mov 0x28(%rsp),%rcx
> + .byte 0x30,0x30,0x30,0x30,0x30 # mov 0x30(%rsp),%rdx
> + .byte 0x30,0x30,0x30,0x30,0x30 # mov 0x38(%rsp),%rsi
> + .byte 0x30,0x30,0x30,0x30,0x30 # mov 0x40(%rsp),%rdi
> + .byte 0x30,0x30,0x30,0x30 # add $0x50,%rsp
> + .byte 0x80,0x80,0x80,0x80 # testl $NMI_MASK,2*8(%rsp)
> + .byte 0x80,0x80,0x80,0x80
> + .byte 0x80,0x80 # jnz 2f
> + .byte 0x80,0x80,0x80,0x80 # testb
> $1,(xen_features+XENFEAT_supervisor_mode_kernel)
> + .byte 0x80,0x80,0x80,0x80
> + .byte 0x80,0x80 # jnz 1f
> + .byte 0x80,0x80,0x80,0x80,0x80 # orb $3,1*8(%rsp)
> + .byte 0x80,0x80,0x80,0x80,0x80 # orb $3,4*8(%rsp)
> + .byte 0x80,0x80 # iretq
> + .byte 0x80,0x80,0x80,0x80 # andl $~NMI_MASK, 16(%rsp)
> + .byte 0x80,0x80,0x80,0x80
> + .byte 0x80,0x80 # pushq $\flag
> + .byte 0x78,0x78,0x78,0x78,0x78 # jmp hypercall_page +
> (__HYPERVISOR_iret * 32)
> + .byte 0x00,0x00,0x00,0x00 # XEN_LOCKED_BLOCK_EVENTS(%rsi)
> + .byte 0x00,0x00,0x00 # mov %rsp,%rdi
> + .byte 0x00,0x00,0x00,0x00,0x00 # jmp 11b
This looks super-fragile. The original Xen-linux kernel code had a
similar kind of fixup table, but I went to some lengths to make it as
simple and robust as possible in the pvops kernels. See the comment in
xen-asm_32.S:
* Because the nested interrupt handler needs to deal with the current
* stack state in whatever form its in, we keep things simple by only
* using a single register which is pushed/popped on the stack.
64-bit pvops Linux always uses the iret hypercall, so the issue is moot
there. (In principle a nested kernel interrupt could avoid the iret,
but it wasn't obvious that the extra complexity was worth it.)
J
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |