ia64/xen-unstable

changeset 7766:d916497135ac

When creating exception/interrupt stack frames for a guest,
set saved eflags.IF to !saved_upcall_mask. This allows the
guest to test interrupts-enabled in the interrupted context
in the same way as when running natively.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu Nov 10 15:03:33 2005 +0100 (2005-11-10)
parents c405c0d1b49b
children 4982559d8fde
files linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/traps.c linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c xen/arch/x86/domain.c xen/arch/x86/x86_32/entry.S xen/arch/x86/x86_64/entry.S xen/include/public/arch-x86_32.h xen/include/public/arch-x86_64.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c	Thu Nov 10 12:12:00 2005 +0100
     1.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c	Thu Nov 10 15:03:33 2005 +0100
     1.3 @@ -650,7 +650,7 @@ fastcall void do_int3(struct pt_regs *re
     1.4  
     1.5  static inline void conditional_sti(struct pt_regs *regs)
     1.6  {
     1.7 -	if ((uint8_t)(regs->xcs >> 16) == 0)
     1.8 +	if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
     1.9  		local_irq_enable();
    1.10  }
    1.11  
     2.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c	Thu Nov 10 12:12:00 2005 +0100
     2.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c	Thu Nov 10 15:03:33 2005 +0100
     2.3 @@ -300,9 +300,8 @@ fastcall void do_page_fault(struct pt_re
     2.4  	if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14,
     2.5  					SIGSEGV) == NOTIFY_STOP)
     2.6  		return;
     2.7 -
     2.8  	/* It's safe to allow irq's after cr2 has been saved */
     2.9 -	if ((uint8_t)(regs->xcs >> 16) == 0)
    2.10 +	if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
    2.11  		local_irq_enable();
    2.12  
    2.13  	tsk = current;
     3.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/traps.c	Thu Nov 10 12:12:00 2005 +0100
     3.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/traps.c	Thu Nov 10 15:03:33 2005 +0100
     3.3 @@ -89,7 +89,7 @@ int register_die_notifier(struct notifie
     3.4  
     3.5  static inline void conditional_sti(struct pt_regs *regs)
     3.6  {
     3.7 -	if ((uint8_t)(regs->cs >> 32) == 0)
     3.8 +	if (regs->eflags & X86_EFLAGS_IF)
     3.9  		local_irq_enable();
    3.10  }
    3.11  
     4.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c	Thu Nov 10 12:12:00 2005 +0100
     4.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c	Thu Nov 10 15:03:33 2005 +0100
     4.3 @@ -351,7 +351,7 @@ asmlinkage void do_page_fault(struct pt_
     4.4  					SIGSEGV) == NOTIFY_STOP)
     4.5  		return;
     4.6  
     4.7 -	if (likely((uint8_t)(regs->cs >> 32) == 0))
     4.8 +	if (likely(regs->eflags & X86_EFLAGS_IF))
     4.9  		local_irq_enable();
    4.10  
    4.11  	if (unlikely(page_fault_trace))
     5.1 --- a/xen/arch/x86/domain.c	Thu Nov 10 12:12:00 2005 +0100
     5.2 +++ b/xen/arch/x86/domain.c	Thu Nov 10 15:03:33 2005 +0100
     5.3 @@ -647,7 +647,7 @@ long do_switch_to_user(void)
     5.4  
     5.5      regs->rip    = stu.rip;
     5.6      regs->cs     = stu.cs | 3; /* force guest privilege */
     5.7 -    regs->rflags = stu.rflags;
     5.8 +    regs->rflags = (stu.rflags & ~(EF_IOPL|EF_VM)) | EF_IE;
     5.9      regs->rsp    = stu.rsp;
    5.10      regs->ss     = stu.ss | 3; /* force guest privilege */
    5.11  
     6.1 --- a/xen/arch/x86/x86_32/entry.S	Thu Nov 10 12:12:00 2005 +0100
     6.2 +++ b/xen/arch/x86/x86_32/entry.S	Thu Nov 10 15:03:33 2005 +0100
     6.3 @@ -156,7 +156,7 @@ 1:
     6.4           * By this time, all the setups in the VMCS must be complete.
     6.5           */
     6.6          .if \launch
     6.7 -        /* VMLUANCH */
     6.8 +        /* VMLAUNCH */
     6.9          .byte 0x0f,0x01,0xc2
    6.10          pushf
    6.11          call vm_launch_fail
    6.12 @@ -394,7 +394,12 @@ FLT14:  movl %eax,%gs:(%esi)
    6.13          shll $16,%eax                    # Bits 16-23: saved_upcall_mask
    6.14          movw UREGS_cs+4(%esp),%ax        # Bits  0-15: CS
    6.15  FLT15:  movl %eax,%gs:4(%esi) 
    6.16 +        test $0x00FF0000,%eax            # Bits 16-23: saved_upcall_mask
    6.17 +        setz %ch                         # %ch == !saved_upcall_mask
    6.18          movl UREGS_eflags+4(%esp),%eax
    6.19 +        andl $~X86_EFLAGS_IF,%eax
    6.20 +        shlb $1,%ch                      # Bit 9 (EFLAGS.IF)
    6.21 +        orb  %ch,%ah                     # Fold EFLAGS.IF into %eax
    6.22  FLT16:  movl %eax,%gs:8(%esi)
    6.23          test $TBF_EXCEPTION_ERRCODE,%cl
    6.24          jz   1f
     7.1 --- a/xen/arch/x86/x86_64/entry.S	Thu Nov 10 12:12:00 2005 +0100
     7.2 +++ b/xen/arch/x86/x86_64/entry.S	Thu Nov 10 15:03:33 2005 +0100
     7.3 @@ -352,8 +352,6 @@ 1:      movb  TRAPBOUNCE_flags(%rdx),%cl
     7.4  FLT2:   movq  %rax,32(%rsi)             # SS
     7.5          movq  UREGS_rsp+8(%rsp),%rax
     7.6  FLT3:   movq  %rax,24(%rsi)             # RSP
     7.7 -        movq  UREGS_eflags+8(%rsp),%rax
     7.8 -FLT4:   movq  %rax,16(%rsi)             # RFLAGS
     7.9          movq  VCPU_vcpu_info(%rbx),%rax
    7.10          pushq VCPUINFO_upcall_mask(%rax)
    7.11          testb $TBF_INTERRUPT,%cl
    7.12 @@ -362,7 +360,15 @@ FLT4:   movq  %rax,16(%rsi)             
    7.13          popq  %rax
    7.14          shlq  $32,%rax                  # Bits 32-39: saved_upcall_mask
    7.15          movw  UREGS_cs+8(%rsp),%ax      # Bits  0-15: CS
    7.16 -FLT5:   movq  %rax,8(%rsi)              # CS/saved_upcall_mask
    7.17 +FLT4:   movq  %rax,8(%rsi)              # CS / saved_upcall_mask
    7.18 +        shrq  $32,%rax
    7.19 +        testb $0xFF,%al                 # Bits 0-7: saved_upcall_mask
    7.20 +        setz  %ch                       # %ch == !saved_upcall_mask
    7.21 +        movq  UREGS_eflags+8(%rsp),%rax
    7.22 +        andq  $~X86_EFLAGS_IF,%rax
    7.23 +        shlb  $1,%ch                    # Bit 9 (EFLAGS.IF)
    7.24 +        orb   %ch,%ah                   # Fold EFLAGS.IF into %eax
    7.25 +FLT5:   movq  %rax,16(%rsi)             # RFLAGS
    7.26          movq  UREGS_rip+8(%rsp),%rax
    7.27  FLT6:   movq  %rax,(%rsi)               # RIP
    7.28          testb $TBF_EXCEPTION_ERRCODE,%cl
     8.1 --- a/xen/include/public/arch-x86_32.h	Thu Nov 10 12:12:00 2005 +0100
     8.2 +++ b/xen/include/public/arch-x86_32.h	Thu Nov 10 15:03:33 2005 +0100
     8.3 @@ -90,7 +90,7 @@ typedef struct cpu_user_regs {
     8.4      uint16_t cs;
     8.5      uint8_t  saved_upcall_mask;
     8.6      uint8_t  _pad0;
     8.7 -    uint32_t eflags;
     8.8 +    uint32_t eflags;        /* eflags.IF == !saved_upcall_mask */
     8.9      uint32_t esp;
    8.10      uint16_t ss, _pad1;
    8.11      uint16_t es, _pad2;
     9.1 --- a/xen/include/public/arch-x86_64.h	Thu Nov 10 12:12:00 2005 +0100
     9.2 +++ b/xen/include/public/arch-x86_64.h	Thu Nov 10 15:03:33 2005 +0100
     9.3 @@ -154,7 +154,7 @@ typedef struct cpu_user_regs {
     9.4      uint16_t cs, _pad0[1];
     9.5      uint8_t  saved_upcall_mask;
     9.6      uint8_t  _pad1[3];
     9.7 -    __DECL_REG(flags);
     9.8 +    __DECL_REG(flags);      /* rflags.IF == !saved_upcall_mask */
     9.9      __DECL_REG(sp);
    9.10      uint16_t ss, _pad2[3];
    9.11      uint16_t es, _pad3[3];