More code cleanups, mainly to do_iret() implementations.
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 11 Jan 2006 18:44:54 +0000 (19:44 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 11 Jan 2006 18:44:54 +0000 (19:44 +0100)
Signed-off-by: Keir Fraser <keir@xensource.com>
xen/arch/x86/domain.c
xen/arch/x86/mm.c
xen/arch/x86/traps.c
xen/arch/x86/x86_32/traps.c
xen/arch/x86/x86_64/traps.c
xen/include/asm-x86/domain.h

index e1485ed1a08e1e68ade53c0a0f5edf22b44e8aa9..19c29d084c1007140b22425b5ce349945c3e6fc5 100644 (file)
@@ -480,14 +480,6 @@ void new_thread(struct vcpu *d,
 
 #ifdef __x86_64__
 
-void toggle_guest_mode(struct vcpu *v)
-{
-    v->arch.flags ^= TF_kernel_mode;
-    __asm__ __volatile__ ( "swapgs" );
-    update_pagetables(v);
-    write_ptbase(v);
-}
-
 #define loadsegment(seg,value) ({               \
     int __r = 1;                                \
     __asm__ __volatile__ (                      \
index f15ebb4d9cfda986accfe55e67a367f62a5eb7af..a9dba3ef6687cbe8335b334f0f9276ba90325e5d 100644 (file)
@@ -297,7 +297,6 @@ int map_ldt_shadow_page(unsigned int off)
 
 #if defined(__x86_64__)
     /* If in user mode, switch to kernel mode just to read LDT mapping. */
-    extern void toggle_guest_mode(struct vcpu *);
     int user_mode = !(v->arch.flags & TF_kernel_mode);
 #define TOGGLE_MODE() if ( user_mode ) toggle_guest_mode(v)
 #elif defined(__i386__)
@@ -2971,7 +2970,6 @@ void ptwr_flush(struct domain *d, const int which)
 
 #ifdef CONFIG_X86_64
     struct vcpu *v = current;
-    extern void toggle_guest_mode(struct vcpu *);
     int user_mode = !(v->arch.flags & TF_kernel_mode);
 #endif
 
index 4458b70636523062ded2c9c18109c3da2a873894..9929722fab14c5986eacfbab945029fa874bba6c 100644 (file)
@@ -596,7 +596,6 @@ static inline int guest_io_okay(
     u16 x;
 #if defined(__x86_64__)
     /* If in user mode, switch to kernel mode just to read I/O bitmap. */
-    extern void toggle_guest_mode(struct vcpu *);
     int user_mode = !(v->arch.flags & TF_kernel_mode);
 #define TOGGLE_MODE() if ( user_mode ) toggle_guest_mode(v)
 #elif defined(__i386__)
index 2c896bce2a75919503a821e189ed774ea727378c..6f7fb83640fa9566d22f1de14cce586d24f7fbc6 100644 (file)
@@ -157,38 +157,37 @@ asmlinkage void do_double_fault(void)
         __asm__ __volatile__ ( "hlt" );
 }
 
+static inline void pop_from_guest_stack(
+    void *dst, struct cpu_user_regs *regs, unsigned int bytes)
+{
+    if ( unlikely(copy_from_user(dst, (void __user *)regs->esp, bytes)) )
+        domain_crash_synchronous();
+    regs->esp += bytes;
+}
+
 asmlinkage unsigned long do_iret(void)
 {
     struct cpu_user_regs *regs = guest_cpu_user_regs();
 
-    /* Restore EAX (clobbered by hypercall). */
-    if ( copy_from_user(&regs->eax, (void __user *)regs->esp, 4) )
-        domain_crash_synchronous();
-    regs->esp += 4;
+    /* Pop and restore EAX (clobbered by hypercall). */
+    pop_from_guest_stack(&regs->eax, regs, 4);
 
-    /* Restore EFLAGS, CS and EIP. */
-    if ( copy_from_user(&regs->eip, (void __user *)regs->esp, 12) )
-        domain_crash_synchronous();
+    /* Pop and restore EFLAGS, CS and EIP. */
+    pop_from_guest_stack(&regs->eip, regs, 12);
 
     if ( VM86_MODE(regs) )
     {
-        /* Return to VM86 mode: restore ESP,SS,ES,DS,FS and GS. */
-        if(copy_from_user(&regs->esp, (void __user *)(regs->esp+12), 24))
-            domain_crash_synchronous();
+        /* Return to VM86 mode: pop and restore ESP,SS,ES,DS,FS and GS. */
+        pop_from_guest_stack(&regs->esp, regs, 24);
     }
     else if ( RING_0(regs) )
     {
         domain_crash_synchronous();
     }
-    else if ( RING_1(regs) ) {
-        /* Return to ring 1: pop EFLAGS,CS and EIP. */
-        regs->esp += 12;
-    }
-    else
+    else if ( !RING_1(regs) )
     {
-        /* Return to ring 2/3: restore ESP and SS. */
-        if ( copy_from_user(&regs->esp, (void __user *)(regs->esp+12), 8) )
-            domain_crash_synchronous();
+        /* Return to ring 2/3: pop and restore ESP and SS. */
+        pop_from_guest_stack(&regs->esp, regs, 8);
     }
 
     /* Fixup EFLAGS. */
index af2f55e29a1d042db61ac150bcf6c8f3cbd1c746..9756c545891cddead59c741ef766e9c982ba8c81 100644 (file)
@@ -114,7 +114,13 @@ asmlinkage void do_double_fault(struct cpu_user_regs *regs)
         __asm__ __volatile__ ( "hlt" );
 }
 
-extern void toggle_guest_mode(struct vcpu *);
+void toggle_guest_mode(struct vcpu *v)
+{
+    v->arch.flags ^= TF_kernel_mode;
+    __asm__ __volatile__ ( "swapgs" );
+    update_pagetables(v);
+    write_ptbase(v);
+}
 
 long do_iret(void)
 {
@@ -122,13 +128,17 @@ long do_iret(void)
     struct iret_context iret_saved;
     struct vcpu *v = current;
 
-    if ( unlikely(copy_from_user(&iret_saved, (void *)regs->rsp, sizeof(iret_saved))) ||
-         unlikely(pagetable_get_paddr(v->arch.guest_table_user) == 0) )
-        return -EFAULT;
+    if ( unlikely(copy_from_user(&iret_saved, (void *)regs->rsp,
+                                 sizeof(iret_saved))) )
+        domain_crash_synchronous();
 
-    /* Returning to user mode. */
-    if ( (iret_saved.cs & 0x03) == 3 )
+    /* Returning to user mode? */
+    if ( (iret_saved.cs & 3) == 3 )
+    {
+        if ( unlikely(pagetable_get_paddr(v->arch.guest_table_user) == 0) )
+            return -EFAULT;
         toggle_guest_mode(v);
+    }
 
     regs->rip    = iret_saved.rip;
     regs->cs     = iret_saved.cs | 3; /* force guest privilege */
index a713b898866266fe17237ef4077a7fb18ee443af..6438757d67c3ee53c1bacda4b762472a08c0c846 100644 (file)
@@ -46,7 +46,10 @@ struct mapcache {
     struct vcpu_maphash vcpu_maphash[MAX_VIRT_CPUS];
 };
 
-extern void mapcache_init(struct domain *d);
+extern void mapcache_init(struct domain *);
+
+/* x86/64: toggle guest between kernel and user modes. */
+extern void toggle_guest_mode(struct vcpu *);
 
 struct arch_domain
 {