Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 93184
b: refs/heads/master
c: b77797f
h: refs/heads/master
v: v3
  • Loading branch information
Jeremy Fitzhardinge authored and Ingo Molnar committed Apr 24, 2008
1 parent d5d762b commit ef45144
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 65 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2bd50036b5dfc929390ddc48be7f6314447b2be3
refs/heads/master: b77797fb2bf31bf076e6b69736119bc6a077525b
9 changes: 1 addition & 8 deletions trunk/arch/x86/kernel/entry_32.S
Original file line number Diff line number Diff line change
Expand Up @@ -1044,15 +1044,8 @@ ENTRY(xen_hypervisor_callback)

jmp xen_iret_crit_fixup

1: cmpl $xen_sysexit_start_crit,%eax
jb 2f
cmpl $xen_sysexit_end_crit,%eax
jae 2f

jmp xen_sysexit_crit_fixup

ENTRY(xen_do_upcall)
2: mov %esp, %eax
1: mov %esp, %eax
call xen_evtchn_do_upcall
jmp ret_from_intr
CFI_ENDPROC
Expand Down
70 changes: 14 additions & 56 deletions trunk/arch/x86/xen/xen-asm.S
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,20 @@ ENDPATCH(xen_restore_fl_direct)
ENDPROC(xen_restore_fl_direct)
RELOC(xen_restore_fl_direct, 2b+1)

/*
We can't use sysexit directly, because we're not running in ring0.
But we can easily fake it up using iret. Assuming xen_sysexit
is jumped to with a standard stack frame, we can just strip it
back to a standard iret frame and use iret.
*/
ENTRY(xen_sysexit)
movl PT_EAX(%esp), %eax /* Shouldn't be necessary? */
orl $X86_EFLAGS_IF, PT_EFLAGS(%esp)
lea PT_EIP(%esp), %esp

jmp xen_iret
ENDPROC(xen_sysexit)

/*
This is run where a normal iret would be run, with the same stack setup:
8: eflags
Expand Down Expand Up @@ -276,62 +290,6 @@ ENTRY(xen_iret_crit_fixup)
2: jmp xen_do_upcall


ENTRY(xen_sysexit)
/* Store vcpu_info pointer for easy access. Do it this
way to avoid having to reload %fs */
#ifdef CONFIG_SMP
GET_THREAD_INFO(%eax)
movl TI_cpu(%eax),%eax
movl __per_cpu_offset(,%eax,4),%eax
mov per_cpu__xen_vcpu(%eax),%eax
#else
movl per_cpu__xen_vcpu, %eax
#endif

/* We can't actually use sysexit in a pv guest,
so fake it up with iret */
pushl $__USER_DS /* user stack segment */
pushl %ecx /* user esp */
pushl PT_EFLAGS+2*4(%esp) /* user eflags */
pushl $__USER_CS /* user code segment */
pushl %edx /* user eip */

xen_sysexit_start_crit:
/* Unmask events... */
movb $0, XEN_vcpu_info_mask(%eax)
/* ...and test for pending.
There's a preempt window here, but it doesn't
matter because we're within the critical section. */
testb $0xff, XEN_vcpu_info_pending(%eax)

/* If there's something pending, mask events again so we
can directly inject it back into the kernel. */
jnz 1f

movl PT_EAX+5*4(%esp),%eax
2: iret
1: movb $1, XEN_vcpu_info_mask(%eax)
xen_sysexit_end_crit:
addl $5*4, %esp /* remove iret frame */
/* no need to re-save regs, but need to restore kernel %fs */
mov $__KERNEL_PERCPU, %eax
mov %eax, %fs
jmp xen_do_upcall
.section __ex_table,"a"
.align 4
.long 2b,iret_exc
.previous

.globl xen_sysexit_start_crit, xen_sysexit_end_crit
/*
sysexit fixup is easy, since the old frame is still sitting there
on the stack. We just need to remove the new recursive
interrupt and return.
*/
ENTRY(xen_sysexit_crit_fixup)
addl $PT_OLDESP+5*4, %esp /* remove frame+iret */
jmp xen_do_upcall

/*
Force an event check by making a hypercall,
but preserve regs before making the call.
Expand Down

0 comments on commit ef45144

Please sign in to comment.