bitkeeper revision 1.1108 (40faa786-NQDR74N9ltmfUON6lXTWw)

Merge scramble.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into scramble.cl.cam.ac.uk:/local/scratch/kaf24/xeno
This commit is contained in:
kaf24@scramble.cl.cam.ac.uk committed 2004-07-18 16:38:30 +00:00
commit e17fa59f09
8 files changed
+170 -162

No files matched your search

+1 -1
View File
@@ -80,7 +80,6 @@
3e5a4e65ibVQmwlOn0j3sVH_j_6hAg linux-2.4.26-xen-sparse/arch/xen/kernel/evtchn.c
3e5a4e65Hy_1iUvMTPsNqGNXd9uFpg linux-2.4.26-xen-sparse/arch/xen/kernel/head.S
3e5a4e65RMGcuA-HCn3-wNx3fFQwdg linux-2.4.26-xen-sparse/arch/xen/kernel/i386_ksyms.c
3e5a4e65MEvZhlr070sK5JsfAQlv7Q linux-2.4.26-xen-sparse/arch/xen/kernel/ioport.c
3e5a4e653U6cELGv528IxOLHvCq8iA linux-2.4.26-xen-sparse/arch/xen/kernel/irq.c
3e5a4e65muT6SU3ck47IP87Q7Ti5hA linux-2.4.26-xen-sparse/arch/xen/kernel/ldt.c
4051db84bZeRX7a_Kh6VyyDuT5FOIg linux-2.4.26-xen-sparse/arch/xen/kernel/pci-dma.c
@@ -164,6 +163,7 @@
40f56238xFQe9T7M_U_FItM-bZIpLw linux-2.6.7-xen-sparse/arch/xen/i386/kernel/evtchn.c
40f56238bnvciAuyzAiMkdzGErYt1A linux-2.6.7-xen-sparse/arch/xen/i386/kernel/head.S
40f58a0d31M2EkuPbG94ns_nOi0PVA linux-2.6.7-xen-sparse/arch/xen/i386/kernel/i386_ksyms.c
40faa751_zbZlAmLyQgCXdYekVFdWA linux-2.6.7-xen-sparse/arch/xen/i386/kernel/ioport.c
40f562382aC3_Gt4RG-4ZsfvDRUg3Q linux-2.6.7-xen-sparse/arch/xen/i386/kernel/irq.c
40f56238ue3YRsK52HG7iccNzP1AwQ linux-2.6.7-xen-sparse/arch/xen/i386/kernel/ldt.c
40f56238a8iOVDEoostsbun_sy2i4g linux-2.6.7-xen-sparse/arch/xen/i386/kernel/process.c
@@ -1,48 +0,0 @@
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/stddef.h>
#include <asm/hypervisor-ifs/dom0_ops.h>
asmlinkage int sys_iopl(unsigned int new_io_pl)
{
unsigned int old_io_pl = current->thread.io_pl;
dom0_op_t op;
if ( !(start_info.flags & SIF_PRIVILEGED) )
return -EPERM;
if ( new_io_pl > 3 )
return -EINVAL;
/* Need "raw I/O" privileges for direct port access. */
if ( (new_io_pl > old_io_pl) && !capable(CAP_SYS_RAWIO) )
return -EPERM;
/* Maintain OS privileges even if user attempts to relinquish them. */
if ( (new_io_pl == 0) && (start_info.flags & SIF_PRIVILEGED) )
new_io_pl = 1;
/* Change our version of the privilege levels. */
current->thread.io_pl = new_io_pl;
/* Force the change at ring 0. */
op.cmd = DOM0_IOPL;
op.u.iopl.domain = DOMID_SELF;
op.u.iopl.iopl = new_io_pl;
HYPERVISOR_dom0_op(&op);
return 0;
}
asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int turn_on)
{
printk(KERN_INFO "ioperm not fully supported - %s\n",
turn_on ? "set iopl to 3" : "ignore resource release");
return turn_on ? sys_iopl(3) : 0;
}
+1
View File
@@ -209,6 +209,7 @@ ln -sf ../../i386/kernel/pci-i386.h
ln -sf ../../i386/kernel/ptrace.c
ln -sf ../../i386/kernel/semaphore.c
ln -sf ../../i386/kernel/sys_i386.c
ln -sf ../../../${LINUX_26}/arch/xen/i386/kernel/ioport.c
cd ../lib
ln -sf ../../i386/lib/checksum.S
ln -sf ../../i386/lib/dec_and_lock.c
@@ -0,0 +1,49 @@
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/ioport.h>
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/slab.h>
#include <asm/hypervisor-ifs/dom0_ops.h>
asmlinkage long sys_iopl(unsigned int new_io_pl)
{
unsigned int old_io_pl = current->thread.io_pl;
dom0_op_t op;
if (!(start_info.flags & SIF_PRIVILEGED))
return -EPERM;
if (new_io_pl > 3)
return -EINVAL;
/* Need "raw I/O" privileges for direct port access. */
if ((new_io_pl > old_io_pl) && !capable(CAP_SYS_RAWIO))
return -EPERM;
/* Maintain OS privileges even if user attempts to relinquish them. */
if (new_io_pl == 0)
new_io_pl = 1;
/* Change our version of the privilege levels. */
current->thread.io_pl = new_io_pl;
/* Force the change at ring 0. */
op.cmd = DOM0_IOPL;
op.u.iopl.domain = DOMID_SELF;
op.u.iopl.iopl = new_io_pl;
HYPERVISOR_dom0_op(&op);
return 0;
}
asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
{
printk(KERN_INFO "ioperm not fully supported - %s\n",
turn_on ? "set iopl to 3" : "ignore resource release");
return turn_on ? sys_iopl(3) : 0;
}
@@ -338,6 +338,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
struct pt_regs * childregs;
struct task_struct *tsk;
int err;
unsigned long eflags;
childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
struct_cpy(childregs, regs);
@@ -386,6 +387,10 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
desc->b = LDT_entry_b(&info);
}
__asm__ __volatile__ ( "pushfl; popl %0" : "=r" (eflags) : );
p->thread.io_pl = (eflags >> 12) & 3;
err = 0;
out:
if (err && p->thread.io_bitmap_ptr)
@@ -532,6 +537,14 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas
*/
load_TLS(next, cpu);
if (start_info.flags & SIF_PRIVILEGED) {
dom0_op_t op;
op.cmd = DOM0_IOPL;
op.u.iopl.domain = DOMID_SELF;
op.u.iopl.iopl = next->io_pl;
HYPERVISOR_dom0_op(&op);
}
local_irq_restore(flags);
/*
@@ -1206,6 +1206,17 @@ void __init setup_arch(char **cmdline_p)
conswitchp = &dummy_con;
#endif
#endif
/* If we are a privileged guest OS then we should request IO privs. */
if (start_info.flags & SIF_PRIVILEGED) {
dom0_op_t op;
op.cmd = DOM0_IOPL;
op.u.iopl.domain = DOMID_SELF;
op.u.iopl.iopl = 1;
if (HYPERVISOR_dom0_op(&op) != 0)
panic("Unable to obtain IOPL, despite SIF_PRIVILEGED");
current->thread.io_pl = 1;
}
}
#include "setup_arch_post.h"
@@ -422,6 +422,7 @@ struct thread_struct {
unsigned long esp;
unsigned long fs;
unsigned long gs;
unsigned int io_pl;
/* Hardware debugging registers */
unsigned long debugreg[8]; /* %%db0-7 debug registers */
/* fault info */
+94 -113
View File
@@ -30,6 +30,15 @@
#include <xen/perfc.h>
#include <asm/processor.h>
/*
* Obtain the base and limit associated with the given segment selector.
* The selector must identify a 32-bit code or data segment. Any segment that
* appears to be truncated to not overlap with Xen is assumed to be a truncated
* 4GB segment, and the returned limit reflects this.
* @seg (IN) : Segment selector to decode.
* @base (OUT): Decoded linear base address.
* @limit (OUT): Decoded segment limit, in bytes. 0 == unlimited (4GB).
*/
int get_baselimit(u16 seg, unsigned long *base, unsigned long *limit)
{
struct domain *d = current;
@@ -80,6 +89,7 @@ int get_baselimit(u16 seg, unsigned long *base, unsigned long *limit)
return 0;
}
/* Turn a segment+offset into a linear address. */
int linearise_address(u16 seg, unsigned long off, unsigned long *linear)
{
unsigned long base, limit;
@@ -95,6 +105,7 @@ int linearise_address(u16 seg, unsigned long off, unsigned long *linear)
return 1;
}
/* Decode Reg field of a ModRM byte: return a pointer into a register block. */
void *decode_reg(struct pt_regs *regs, u8 b)
{
switch ( b & 7 )
@@ -120,6 +131,9 @@ void *decode_reg(struct pt_regs *regs, u8 b)
* @pseg (IN) : address in pt_regs block of the override segment.
* @regs (IN) : addrress of the the pt_regs block.
*/
#define DECODE_EA_FAILED 0
#define DECODE_EA_FIXME 1
#define DECODE_EA_SUCCESS 2
int decode_effective_address(u8 **ppb, void **preg, void **pmem,
unsigned int *pseg, struct pt_regs *regs)
{
@@ -132,7 +146,7 @@ int decode_effective_address(u8 **ppb, void **preg, void **pmem,
if ( get_user(modrm, pb) )
{
DPRINTK("Fault while extracting modrm byte\n");
return 0;
return DECODE_EA_FAILED;
}
pb++;
@@ -144,7 +158,7 @@ int decode_effective_address(u8 **ppb, void **preg, void **pmem,
if ( rm == 4 )
{
DPRINTK("FIXME: Add decoding for the SIB byte.\n");
return 0;
return DECODE_EA_FIXME;
}
/* Decode Reg and R/M fields. */
@@ -164,7 +178,7 @@ int decode_effective_address(u8 **ppb, void **preg, void **pmem,
if ( get_user(disp32, (u32 *)pb) )
{
DPRINTK("Fault while extracting <disp8>.\n");
return 0;
return DECODE_EA_FAILED;
}
pb += 4;
}
@@ -176,7 +190,7 @@ int decode_effective_address(u8 **ppb, void **preg, void **pmem,
if ( get_user(disp8, pb) )
{
DPRINTK("Fault while extracting <disp8>.\n");
return 0;
return DECODE_EA_FAILED;
}
pb++;
disp32 = (disp8 & 0x80) ? (disp8 | ~0xff) : disp8;;
@@ -188,22 +202,22 @@ int decode_effective_address(u8 **ppb, void **preg, void **pmem,
if ( get_user(disp32, (u32 *)pb) )
{
DPRINTK("Fault while extracting <disp8>.\n");
return 0;
return DECODE_EA_FAILED;
}
pb += 4;
break;
case 3:
DPRINTK("Not a memory operand!\n");
return 0;
return DECODE_EA_FAILED;
}
if ( !get_baselimit((u16)(*pseg), &ea, &limit) )
return 0;
return DECODE_EA_FAILED;
if ( limit != 0 )
{
DPRINTK("Bailing: not a 4GB data segment.\n");
return 0;
return DECODE_EA_FAILED;
}
offset = disp32;
@@ -212,23 +226,42 @@ int decode_effective_address(u8 **ppb, void **preg, void **pmem,
if ( (offset & 0xf0000000) != 0xf0000000 )
{
DPRINTK("Bailing: not a -ve offset into 4GB segment.\n");
return 0;
return DECODE_EA_FAILED;
}
ea += offset;
if ( ea > (PAGE_OFFSET - PAGE_SIZE) )
{
DPRINTK("!!!! DISALLOWING UNSAFE ACCESS !!!!\n");
return 0;
return DECODE_EA_FAILED;
}
*ppb = pb;
*preg = regreg;
*pmem = (void *)ea;
return 1;
return DECODE_EA_SUCCESS;
}
#define GET_IMM8 \
if ( get_user(ib, (u8 *)pb) ) { \
DPRINTK("Fault while extracting imm8\n"); \
return 0; \
} \
pb += 1;
#define GET_IMM16 \
if ( get_user(iw, (u8 *)pb) ) { \
DPRINTK("Fault while extracting imm16\n"); \
return 0; \
} \
pb += 2;
#define GET_IMM32 \
if ( get_user(il, (u32 *)pb) ) { \
DPRINTK("Fault while extracting imm32\n"); \
return 0; \
} \
pb += 4;
/*
* Called from the general-protection fault handler to attempt to decode
* and emulate an instruction that depends on 4GB segments. At this point
@@ -239,15 +272,18 @@ int gpf_emulate_4gb(struct pt_regs *regs)
{
struct domain *d = current;
trap_info_t *ti;
u8 *eip, *nextbyte, b, mb, rb;
u16 mw, rw;
u32 ml, rl, eflags;
unsigned int *pseg = NULL;
int i;
int opsz_override = 0;
void *reg, *mem;
struct guest_trap_bounce *gtb;
u8 *eip; /* ptr to instruction start */
u8 *pb, b; /* ptr into instr. / current instr. byte */
u8 ib, mb, rb; /* byte operand from imm/register/memory */
u16 iw, mw, rw; /* word operand from imm/register/memory */
u32 il, ml, rl; /* long operand from imm/register/memory */
void *reg, *mem; /* ptr to register/memory operand */
unsigned int *pseg = NULL; /* segment for memory operand (NULL=default) */
u32 eflags;
int opsz_override = 0;
if ( !linearise_address((u16)regs->xcs, regs->eip, (unsigned long *)&eip) )
{
DPRINTK("Cannot linearise %04x:%08lx\n", regs->xcs, regs->eip);
@@ -255,11 +291,11 @@ int gpf_emulate_4gb(struct pt_regs *regs)
}
/* Parse prefix bytes. We're basically looking for segment override. */
for ( i = 0; i < 4; i++ )
for ( pb = eip; (pb - eip) < 4; pb++ )
{
if ( get_user(b, &eip[i]) )
if ( get_user(b, pb) )
{
DPRINTK("Fault while accessing byte %d of instruction\n", i);
DPRINTK("Fault while accessing byte %d of instruction\n", pb-eip);
return 0;
}
@@ -298,141 +334,94 @@ int gpf_emulate_4gb(struct pt_regs *regs)
}
done_prefix:
nextbyte = &eip[i+1];
if ( !decode_effective_address(&nextbyte, &reg, &mem, pseg, regs) )
pb++; /* skip opcode byte */
switch ( decode_effective_address(&pb, &reg, &mem, pseg, regs) )
{
case DECODE_EA_FAILED:
return 0;
case DECODE_EA_FIXME:
goto undecodeable;
}
/* Only handle single-byte opcodes right now. Sufficient for MOV. */
/*
* XXX Now I see how this decode routine is panning out, it needs
* refactoring. Lots of duplicated cruft in here...
*/
switch ( b )
{
case 0x88: /* movb r,r/m */
if ( __put_user(*(u8 *)reg, (u8 *)mem) )
goto page_fault_w;
regs->eip += nextbyte - eip;
break;
case 0x89: /* movl r,r/m */
if ( opsz_override )
{
if ( __put_user(*(u16 *)reg, (u16 *)mem) )
goto page_fault_w;
}
else
{
if ( __put_user(*(u32 *)reg, (u32 *)mem) )
goto page_fault_w;
}
regs->eip += nextbyte - eip;
if ( opsz_override ? __put_user(*(u16 *)reg, (u16 *)mem)
: __put_user(*(u32 *)reg, (u32 *)mem) )
goto page_fault_w;
break;
case 0x8a: /* movb r/m,r */
if ( __get_user(*(u8 *)reg, (u8 *)mem) )
goto page_fault_r;
regs->eip += nextbyte - eip;
break;
case 0x8b: /* movl r/m,r */
if ( opsz_override )
{
if ( __get_user(*(u16 *)reg, (u16 *)mem) )
goto page_fault_r;
}
else
{
if ( __get_user(*(u32 *)reg, (u32 *)mem) )
goto page_fault_r;
}
regs->eip += nextbyte - eip;
if ( opsz_override ? __get_user(*(u16 *)reg, (u16 *)mem)
: __get_user(*(u32 *)reg, (u32 *)mem) )
goto page_fault_r;
break;
case 0xc6: /* movb imm,r/m */
if ( reg != &regs->eax ) /* Reg == /0 */
goto undecodeable;
if ( get_user(rb, nextbyte) )
{
DPRINTK("Fault while extracting immediate byte\n");
return 0;
}
if ( __put_user(rb, (u8 *)mem) )
GET_IMM8;
if ( __put_user(ib, (u8 *)mem) )
goto page_fault_w;
regs->eip += nextbyte - eip + 1;
break;
case 0xc7: /* movl imm,r/m */
if ( reg != &regs->eax ) /* Reg == /0 */
goto undecodeable;
if ( opsz_override )
{
if ( get_user(rw, (u16 *)nextbyte) )
{
DPRINTK("Fault while extracting immediate word\n");
return 0;
}
if ( __put_user(rw, (u16 *)mem) )
GET_IMM16;
if ( __put_user(iw, (u16 *)mem) )
goto page_fault_w;
regs->eip += nextbyte - eip + 2;
}
else
{
if ( get_user(rl, (u32 *)nextbyte) )
{
DPRINTK("Fault while extracting immediate longword\n");
return 0;
}
if ( __put_user(rl, (u32 *)mem) )
GET_IMM32;
if ( __put_user(il, (u32 *)mem) )
goto page_fault_w;
regs->eip += nextbyte - eip + 4;
}
break;
case 0x80: /* cmpb imm8,r/m */
if ( reg != &regs->edi ) /* Reg == /7 */
goto undecodeable;
if ( get_user(rb, nextbyte) )
{
DPRINTK("Fault while extracting immediate byte\n");
return 0;
}
GET_IMM8;
if ( __get_user(mb, (u8 *)mem) )
goto page_fault_r;
__asm__ __volatile__ (
"cmpb %b1,%b2 ; pushf ; popl %0"
: "=a" (eflags)
: "0" (rb), "b" (mb) );
: "0" (ib), "b" (mb) );
regs->eflags &= ~0x8d5; /* OF,SF,ZF,AF,PF,CF */
regs->eflags |= eflags & 0x8d5;
regs->eip += nextbyte - eip + 1;
break;
case 0x81: /* cmpl imm32,r/m */
if ( reg != &regs->edi ) /* Reg == /7 */
goto undecodeable;
if ( opsz_override )
{
if ( get_user(rw, (u16 *)nextbyte) )
{
DPRINTK("Fault while extracting immediate word\n");
return 0;
}
GET_IMM16;
if ( __get_user(mw, (u16 *)mem) )
goto page_fault_r;
__asm__ __volatile__ (
"cmpw %w1,%w2 ; pushf ; popl %0"
: "=a" (eflags)
: "0" (rw), "b" (mw) );
regs->eip += nextbyte - eip + 2;
: "0" (iw), "b" (mw) );
}
else
{
if ( get_user(rl, (u32 *)nextbyte) )
{
DPRINTK("Fault while extracting immediate longword\n");
return 0;
}
GET_IMM32;
if ( __get_user(ml, (u32 *)mem) )
goto page_fault_r;
__asm__ __volatile__ (
"cmpl %1,%2 ; pushf ; popl %0"
: "=a" (eflags)
: "0" (rl), "b" (ml) );
regs->eip += nextbyte - eip + 4;
: "0" (il), "b" (ml) );
}
regs->eflags &= ~0x8d5; /* OF,SF,ZF,AF,PF,CF */
regs->eflags |= eflags & 0x8d5;
@@ -440,35 +429,29 @@ int gpf_emulate_4gb(struct pt_regs *regs)
case 0x83: /* cmpl imm8,r/m */
if ( reg != &regs->edi ) /* Reg == /7 */
goto undecodeable;
if ( get_user(rb, nextbyte) )
{
DPRINTK("Fault while extracting immediate byte\n");
return 0;
}
GET_IMM8;
if ( opsz_override )
{
rw = (rb & 0x80) ? (rb | ~0xff) : rb;
iw = (u16)(s16)(s8)ib;
if ( __get_user(mw, (u16 *)mem) )
goto page_fault_r;
__asm__ __volatile__ (
"cmpw %w1,%w2 ; pushf ; popl %0"
: "=a" (eflags)
: "0" (rw), "b" (mw) );
regs->eip += nextbyte - eip + 2;
: "0" (iw), "b" (mw) );
}
else
{
rl = (rb & 0x80) ? (rb | ~0xff) : rb;
il = (u32)(s32)(s8)ib;
if ( __get_user(ml, (u32 *)mem) )
goto page_fault_r;
__asm__ __volatile__ (
"cmpl %1,%2 ; pushf ; popl %0"
: "=a" (eflags)
: "0" (rl), "b" (ml) );
: "0" (il), "b" (ml) );
}
regs->eflags &= ~0x8d5; /* OF,SF,ZF,AF,PF,CF */
regs->eflags |= eflags & 0x8d5;
regs->eip += nextbyte - eip + 1;
break;
case 0x38: /* cmpb r,r/m */
case 0x3a: /* cmpb r/m,r */
@@ -481,7 +464,6 @@ int gpf_emulate_4gb(struct pt_regs *regs)
: "0" ((b==0x38)?rb:mb), "b" ((b==0x38)?mb:rb) );
regs->eflags &= ~0x8d5; /* OF,SF,ZF,AF,PF,CF */
regs->eflags |= eflags & 0x8d5;
regs->eip += nextbyte - eip;
break;
case 0x39: /* cmpl r,r/m */
case 0x3b: /* cmpl r/m,r */
@@ -507,24 +489,23 @@ int gpf_emulate_4gb(struct pt_regs *regs)
}
regs->eflags &= ~0x8d5; /* OF,SF,ZF,AF,PF,CF */
regs->eflags |= eflags & 0x8d5;
regs->eip += nextbyte - eip;
break;
default:
DPRINTK("Unhandleable opcode byte %02x\n", b);
goto undecodeable;
}
perfc_incrc(emulations);
/* Success! */
regs->eip += pb - eip;
perfc_incrc(emulations);
return 1;
undecodeable:
printk("Undecodable instruction %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x "
"caused GPF(0) at %04x:%08lx\n",
eip[0], eip[1], eip[2], eip[3],
eip[4], eip[5], eip[6], eip[7],
regs->xcs, regs->eip);
DPRINTK("Undecodable instruction %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x "
"caused GPF(0) at %04x:%08lx\n",
eip[0], eip[1], eip[2], eip[3],
eip[4], eip[5], eip[6], eip[7],
regs->xcs, regs->eip);
return 0;
page_fault_w:
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.