xen: add configurable max domain size
[linux-3.10.git] / arch / x86 / xen / xen-asm.S
index 1ac0808..2497a30 100644 (file)
@@ -108,6 +108,20 @@ ENDPATCH(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
              4: cs
@@ -223,9 +237,7 @@ hyper_iret:
         ds             }  SAVE_ALL state
         eax            }
          :             :
-        ebx            }
-       ----------------
-        return addr     <- esp
+        ebx            }<- esp
        ----------------
 
    In order to deliver the nested exception properly, we need to shift
@@ -240,10 +252,8 @@ hyper_iret:
    it's usermode state which we eventually need to restore.
  */
 ENTRY(xen_iret_crit_fixup)
-       /* offsets +4 for return address */
-
        /*
-          Paranoia: Make sure we're really coming from userspace.
+          Paranoia: Make sure we're really coming from kernel space.
           One could imagine a case where userspace jumps into the
           critical range address, but just before the CPU delivers a GP,
           it decides to deliver an interrupt instead.  Unlikely?
@@ -252,89 +262,33 @@ ENTRY(xen_iret_crit_fixup)
           jump instruction itself, not the destination, but some virtual
           environments get this wrong.
         */
-       movl PT_CS+4(%esp), %ecx
+       movl PT_CS(%esp), %ecx
        andl $SEGMENT_RPL_MASK, %ecx
        cmpl $USER_RPL, %ecx
        je 2f
 
-       lea PT_ORIG_EAX+4(%esp), %esi
-       lea PT_EFLAGS+4(%esp), %edi
+       lea PT_ORIG_EAX(%esp), %esi
+       lea PT_EFLAGS(%esp), %edi
 
        /* If eip is before iret_restore_end then stack
           hasn't been restored yet. */
        cmp $iret_restore_end, %eax
        jae 1f
 
-       movl 0+4(%edi),%eax             /* copy EAX */
-       movl %eax, PT_EAX+4(%esp)
+       movl 0+4(%edi),%eax             /* copy EAX (just above top of frame) */
+       movl %eax, PT_EAX(%esp)
 
        lea ESP_OFFSET(%edi),%edi       /* move dest up over saved regs */
 
        /* set up the copy */
 1:     std
-       mov $(PT_EIP+4) / 4, %ecx       /* copy ret+saved regs up to orig_eax */
+       mov $PT_EIP / 4, %ecx           /* saved regs up to orig_eax */
        rep movsl
        cld
 
        lea 4(%edi),%esp                /* point esp to new frame */
-2:     ret
-
-
-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)
+2:     jmp xen_do_upcall
 
-       /* 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,