Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 6985
b: refs/heads/master
c: a520112
h: refs/heads/master
i:
  6983: 0026af6
v: v3
  • Loading branch information
Zachary Amsden authored and Linus Torvalds committed Sep 5, 2005
1 parent f482a40 commit f1e88e5
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 7 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: 0998e4228aca046fbd747c3fed909791d52e88eb
refs/heads/master: a5201129307f414890f9a4410e38da205f5d7359
7 changes: 4 additions & 3 deletions trunk/arch/i386/kernel/ioport.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ asmlinkage long sys_iopl(unsigned long unused)
volatile struct pt_regs * regs = (struct pt_regs *) &unused;
unsigned int level = regs->ebx;
unsigned int old = (regs->eflags >> 12) & 3;
struct thread_struct *t = &current->thread;

if (level > 3)
return -EINVAL;
Expand All @@ -140,8 +141,8 @@ asmlinkage long sys_iopl(unsigned long unused)
if (!capable(CAP_SYS_RAWIO))
return -EPERM;
}
regs->eflags = (regs->eflags &~ 0x3000UL) | (level << 12);
/* Make sure we return the long way (not sysenter) */
set_thread_flag(TIF_IRET);
t->iopl = level << 12;
regs->eflags = (regs->eflags & ~X86_EFLAGS_IOPL) | t->iopl;
set_iopl_mask(t->iopl);
return 0;
}
6 changes: 6 additions & 0 deletions trunk/arch/i386/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,12 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas
if (prev->gs | next->gs)
loadsegment(gs, next->gs);

/*
* Restore IOPL if needed.
*/
if (unlikely(prev->iopl != next->iopl))
set_iopl_mask(next->iopl);

/*
* Now maybe reload the debug registers
*/
Expand Down
16 changes: 16 additions & 0 deletions trunk/include/asm-i386/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ struct thread_struct {
unsigned int saved_fs, saved_gs;
/* IO permissions */
unsigned long *io_bitmap_ptr;
unsigned long iopl;
/* max allowed port in the bitmap, in bytes: */
unsigned long io_bitmap_max;
};
Expand Down Expand Up @@ -511,6 +512,21 @@ static inline void load_esp0(struct tss_struct *tss, struct thread_struct *threa
: /* no output */ \
:"r" (value))

/*
* Set IOPL bits in EFLAGS from given mask
*/
static inline void set_iopl_mask(unsigned mask)
{
unsigned int reg;
__asm__ __volatile__ ("pushfl;"
"popl %0;"
"andl %1, %0;"
"orl %2, %0;"
"pushl %0;"
"popfl"
: "=&r" (reg)
: "i" (~X86_EFLAGS_IOPL), "r" (mask));
}

/* Forward declaration, a strange C thing */
struct task_struct;
Expand Down
4 changes: 1 addition & 3 deletions trunk/include/asm-i386/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,14 @@ extern struct task_struct * FASTCALL(__switch_to(struct task_struct *prev, struc

#define switch_to(prev,next,last) do { \
unsigned long esi,edi; \
asm volatile("pushfl\n\t" \
"pushl %%ebp\n\t" \
asm volatile("pushl %%ebp\n\t" \
"movl %%esp,%0\n\t" /* save ESP */ \
"movl %5,%%esp\n\t" /* restore ESP */ \
"movl $1f,%1\n\t" /* save EIP */ \
"pushl %6\n\t" /* restore EIP */ \
"jmp __switch_to\n" \
"1:\t" \
"popl %%ebp\n\t" \
"popfl" \
:"=m" (prev->thread.esp),"=m" (prev->thread.eip), \
"=a" (last),"=S" (esi),"=D" (edi) \
:"m" (next->thread.esp),"m" (next->thread.eip), \
Expand Down

0 comments on commit f1e88e5

Please sign in to comment.