* copyin/out(), copyin/outstr(), s/fubyte() et al protection fixes,

including COW support, using code based on that from Wolfgang Solfrank and
Christoph Robitschko.

* user segment descriptors fixed to disallow access to user area.

* bde's boot >= 1MB fixes.
This commit is contained in:
andrew 1993-07-18 08:22:59 +00:00
parent aa381d0e73
commit 297f54dd01
4 changed files with 582 additions and 376 deletions

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)locore.s 7.3 (Berkeley) 5/13/91
* $Id: locore.s,v 1.22 1993/07/04 05:49:17 andrew Exp $
* $Id: locore.s,v 1.23 1993/07/18 08:22:59 andrew Exp $
*/
@ -117,15 +117,14 @@
.set PPDROFF,0x3F6
.set PPTEOFF,0x400-UPAGES # 0x3FE
#define ENTRY(name) \
.globl _/**/name; ALIGN_TEXT; _/**/name:
#define ALTENTRY(name) ENTRY(name)
#define ENTRY(name) .globl _/**/name; ALIGN_TEXT; _/**/name:
#define ALTENTRY(name) .globl _/**/name; _/**/name:
/*
* Initialization
*/
.data
.globl _cpu,_cold,_boothowto,_bootdev,_cyloffset,_atdevbase,_atdevphys
.globl _cpu,_cold,_boothowto,_bootdev,_cyloffset,_atdevbase
_cpu: .long 0 # are we 386, 386sx, or 486
_cold: .long 1 # cold till we are not
_atdevbase: .long 0 # location of start of iomem in virtual
@ -265,7 +264,10 @@ start: movw $0x1234,%ax
movl %esi,%ecx # this much memory,
shrl $ PGSHIFT,%ecx # for this many pte s
addl $ UPAGES+4,%ecx # including our early context
movl $0xa0,%ecx # XXX - cover debugger pages
cmpl $0xa0,%ecx # XXX - cover debugger pages
jae 1f
movl $0xa0,%ecx
1:
movl $PG_V|PG_KW,%eax # having these bits set,
lea (4*NBPG)(%esi),%ebx # physical address of KPT in proc 0,
movl %ebx,_KPTphys-SYSTEM # in the kernel page table,
@ -357,19 +359,15 @@ start: movw $0x1234,%ax
addl $2*6,%esp
popal
/* load base of page directory, and enable mapping */
movl %esi,%eax # phys address of ptd in proc 0
orl $ I386_CR3PAT,%eax
movl %eax,%cr3 # load ptd addr into mmu
movl %cr0,%eax # get control word
#ifdef USE_486_WRITE_PROTECT
orl $CR0_PE|CR0_PG|CR0_WP,%eax # and let s page!
#else
orl $CR0_PE|CR0_PG,%eax # and let s page!
#endif
movl %eax,%cr0 # NOW!
/* load base of page directory and enable mapping */
movl %esi, %eax # phys address of ptd in proc 0
orl $ I386_CR3PAT, %eax
movl %eax, %cr3 # load ptd addr into mmu
movl %cr0, %eax # get control word
orl $ CR0_PE|CR0_PG, %eax # enable paging
movl %eax, %cr0 # and let's page NOW!
pushl $begin # jump to high mem!
pushl $begin # jump to high mem
ret
begin: /* now running relocated at SYSTEM where the system is linked to run */
@ -415,6 +413,19 @@ reloc_gdt:
call _main
popl %esi
#if defined(I486_CPU) || defined(I586_CPU)
/*
* now we've run main() and determined what cpu-type we are, we can
* enable WP mode on i486 cpus and above.
*/
cmpl $ CPUCLASS_386, _cpu_class
je 1f # 386s can't handle WP mode
movl %cr0, %eax # get control word
orl $ CR0_WP, %eax # enable ring 0 Write Protection
movl %eax, %cr0
1:
#endif
.globl __ucodesel,__udatasel
movl __ucodesel,%eax
movl __udatasel,%ecx
@ -444,23 +455,28 @@ lretmsg1:
* If the exec fails, process 1 exits.
*/
ENTRY(icode)
# pushl $argv-_icode # gas fucks up again
movl $argv,%eax
subl $_icode,%eax
pushl %eax
pushl $0 /* envp for execve() */
# pushl $init-_icode
movl $init,%eax
subl $_icode,%eax
pushl %eax
pushl %eax # dummy out rta
# pushl $argv-_icode /* can't do this 'cos gas 1.38 is broken */
movl $ argv, %eax
subl $ _icode, %eax
pushl %eax /* argp for execve() */
movl %esp,%ebp
movl $exec,%eax
# pushl $ (init-_icode)
movl $ init, %eax
subl $ _icode, %eax
pushl %eax /* fname for execve() */
pushl %eax /* dummy return address */
movl %esp, %ebp
movl $ exec, %eax
LCALL(0x7,0x0)
pushl %eax
movl $exit,%eax
pushl %eax # dummy out rta
/* exit if something botches up in the above exec */
pushl %eax /* exit code */
movl $exit, %eax
pushl %eax /* dummy return address */
LCALL(0x7,0x0)
init:
@ -474,7 +490,7 @@ eicode:
.globl _szicode
_szicode:
.long _szicode-_icode
.long eicode-_icode
#if 0 /* before bde */
.globl _sigcode,_esigcode
@ -772,187 +788,550 @@ ENTRY(ffs)
1: xorl %eax,%eax /* clear result */
ret
#ifdef notdef
/*
* copyout() originally written by ws@tools.de, and optimised by
* by Christoph Robitschko <chmr@edvz.tu-graz.ac.at>.
* Minor modifications by Andrew Herbert <andrew@werple.apana.org.au>
*/
ENTRY(copyout)
movl _curpcb, %eax
movl $cpyflt, PCB_ONFAULT(%eax) # in case we page/protection violate
movl $copyout_fault, PCB_ONFAULT(%eax)
pushl %esi
pushl %edi
pushl %ebx
movl 16(%esp), %esi
movl 20(%esp), %edi
movl 24(%esp), %ebx
orl %ebx, %ebx /* anything to do? */
jz done_copyout
/* first, check to see if "write fault" */
1: movl %edi, %eax
#ifdef notyet
shrl $IDXSHIFT, %eax /* fetch pte associated with address */
andb $0xfc, %al
movl _PTmap(%eax), %eax
pushl %es
andb $7, %al /* if we are the one case that won't trap... */
cmpb $5, %al
#if defined(I386_CPU)
#if defined(I486_CPU) || defined(I586_CPU)
cmpl $ CPUCLASS_386, _cpu_class
jne 3f /* fine, we're not a 386 so don't need this stuff */
#endif /* I486_CPU || I586_CPU */
/* we have to check each PTE for (write) permission */
/* compute number of pages */
movl %edi, %ecx
andl $0x0fff, %ecx
addl %ebx, %ecx
decl %ecx
shrl $ IDXSHIFT+2, %ecx
incl %ecx
/* compute PTE offset for start address */
movl %edi, %edx
shrl $ IDXSHIFT, %edx
andb $0xfc, %dl
1: /* check PTE for each page */
movb _PTmap(%edx), %al
andb $0x07, %al /* Pages must be VALID + USERACC + WRITABLE */
cmpb $0x05, %al
jne 2f
/* ... then simulate the trap! */
pushl %edi
/* simulate a trap */
pushl %edx
pushl %ecx
shll $ IDXSHIFT, %edx
pushl %edx
call _trapwrite /* trapwrite(addr) */
popl %edx
popl %ecx
popl %edx
orl %eax, %eax /* if not ok, return EFAULT */
jnz copyout_fault
cmpl $0, %eax /* if not ok, return */
jne cpyflt
/* otherwise, continue with reference */
2:
movl %edi, %eax /* calculate remainder this pass */
andl $0xfffff000, %eax
movl $NBPG, %ecx
subl %eax, %ecx
cmpl %ecx, %ebx
jle 3f
addl $4, %edx
decl %ecx
jnz 1b /* check next page */
#endif /* I386_CPU */
/* If WP bit in CR0 is set (n/a on 386), the hardware does the
* write check. We just have to load the right segment selector
* This is of some use on a 386 too, as it gives us bounds
* limiting.
*/
3:
movl __udatasel, %eax
movl %ax, %es
/* bcopy (%esi, %edi, %ebx) */
cld
movl %ebx, %ecx
3: subl %ecx, %ebx
shrl $2, %ecx
rep
movsl
movb %bl, %cl
andb $3, %cl /* XXX can we trust the rest of %ecx on clones? */
rep
movsb
popl %es
done_copyout:
popl %ebx
popl %edi
popl %esi
xorl %eax, %eax
movl _curpcb, %edx
movl %eax, PCB_ONFAULT(%edx)
ret
copyout_fault:
popl %es
popl %ebx
popl %edi
popl %esi
movl _curpcb, %edx
movl $0, PCB_ONFAULT(%edx)
movl $ EFAULT, %eax
ret
ENTRY(copyin)
movl _curpcb, %eax
movl $copyin_fault, PCB_ONFAULT(%eax)
pushl %esi
pushl %edi
pushl %ebx
movl 16(%esp), %esi
movl 20(%esp), %edi
movl 24(%esp), %ecx
movl %ecx, %edx
#else
movl %ebx, %ecx
movl %ebx, %edx
#endif
pushl %ds
movl __udatasel, %eax /* use the user segment descriptor */
movl %ax, %ds
shrl $2,%ecx /* movem */
shrl $2, %ecx
cld
rep
movsl
movl %edx, %ecx /* don't depend on ecx here! */
andl $3, %ecx
movb %dl, %cl
andb $3, %cl
rep
movsb
#ifdef notyet
cmpl $0, %ebx
jl 1b
#endif
popl %ds
popl %ebx
popl %edi
popl %esi
xorl %eax,%eax
movl _curpcb,%edx
movl %eax,PCB_ONFAULT(%edx)
xorl %eax, %eax
movl _curpcb, %edx
movl %eax, PCB_ONFAULT(%edx)
ret
ENTRY(copyin)
movl _curpcb,%eax
movl $cpyflt,PCB_ONFAULT(%eax) # in case we page/protection violate
pushl %esi
pushl %edi
pushl %ebx # XXX - not used, but affects stack offsets
movl 12(%esp),%esi
movl 16(%esp),%edi
movl 20(%esp),%ecx
shrl $2,%ecx
cld
rep
movsl
movl 20(%esp),%ecx
andl $3,%ecx
rep
movsb
copyin_fault:
popl %ds
popl %ebx
popl %edi
popl %esi
xorl %eax,%eax
movl _curpcb,%edx
movl %eax,PCB_ONFAULT(%edx)
movl _curpcb, %edx
movl $0, PCB_ONFAULT(%edx)
movl $ EFAULT, %eax
ret
ALIGN_TEXT
cpyflt:
popl %ebx
popl %edi
popl %esi
movl _curpcb,%edx
movl $0,PCB_ONFAULT(%edx)
movl $ EFAULT,%eax
ret
#else
ENTRY(copyout)
movl _curpcb,%eax
movl $cpyflt,PCB_ONFAULT(%eax) # in case we page/protection violate
/*
* copyoutstr(from, to, maxlen, int *lencopied)
* copy a string from from to to, stop when a 0 character is reached.
* return ENAMETOOLONG if string is longer than maxlen, and
* EFAULT on protection violations. If lencopied is non-zero,
* return the actual length in *lencopied.
*
* by Christoph Robitschko <chmr@edvz.tu-graz.ac.at>
* with modifications by Andrew Herbert <andrew@werple.apana.org.au>
*/
ENTRY(copyoutstr)
pushl %esi
pushl %edi
movl 12(%esp),%esi
movl 16(%esp),%edi
movl 20(%esp),%ecx
shrl $2,%ecx
cld
rep
movsl
movl 20(%esp),%ecx
andl $3,%ecx
rep
movsb
popl %edi
popl %esi
xorl %eax,%eax
movl _curpcb,%edx
movl %eax,PCB_ONFAULT(%edx)
ret
movl _curpcb, %ecx
movl $copystr_fault, PCB_ONFAULT(%ecx)
ENTRY(copyin)
movl _curpcb,%eax
movl $cpyflt,PCB_ONFAULT(%eax) # in case we page/protection violate
movl 12(%esp), %esi /* %esi = from */
movl 16(%esp), %edi /* %edi = to */
movl 20(%esp), %edx /* %edx = maxlen */
movl __udatasel, %eax
movl %ax, %gs
#if defined(I386_CPU)
#if defined(I486_CPU) || defined(I586_CPU)
cmpl $ CPUCLASS_386, _cpu_class
jne 5f /* fine, we're not a 386 so don't need this stuff */
#endif /* I486_CPU || I586_CPU */
1:
movl %edi, %eax
shrl $ IDXSHIFT, %eax
andb $0xfc, %al
movb _PTmap(%eax), %al
andb $7, %al
cmpb $5, %al
jne 2f
/* simulate trap */
pushl %edx
pushl %edi
call _trapwrite
popl %edi
popl %edx
orl %eax, %eax
jnz copystr_fault
2: /* copy up to end of this page */
movl %edi, %eax
andl $0x0fff, %eax
movl $ NBPG, %ecx
subl %eax, %ecx /* ecx = NBPG - (src % NBPG) */
cmpl %ecx, %edx
jge 3f
movl %edx, %ecx /* ecx = min (ecx, edx) */
3:
orl %ecx, %ecx
jz 4f
decl %ecx
decl %edx
lodsb
gs
stosb
orb %al, %al
jnz 3b
/* Success -- 0 byte reached */
decl %edx
xorl %eax, %eax
jmp 7f
4: /* next page */
orl %edx, %edx
jnz 1b
/* edx is zero -- return ENAMETOOLONG */
movl $ ENAMETOOLONG, %eax
jmp 7f
#endif /* I386_CPU */
#if defined(I486_CPU) || defined(I586_CPU)
5:
incl %edx
1: /* aren't numeric labels wonderful ;-) */
decl %edx
jz 2f
lodsb
gs
stosb
orb %al, %al
jnz 1b
/* Success -- 0 byte reached */
decl %edx
xorl %eax, %eax
jmp 7f
2: /* edx is zero -- return ENAMETOOLONG */
movl $ ENAMETOOLONG, %eax
jmp 7f
#endif /* I486_CPU || I586_CPU */
/*
* copyinstr(from, to, maxlen, int *lencopied)
* copy a string from from to to, stop when a 0 character is reached.
* return ENAMETOOLONG if string is longer than maxlen, and
* EFAULT on protection violations. If lencopied is non-zero,
* return the actual length in *lencopied.
*
* by Christoph Robitschko <chmr@edvz.tu-graz.ac.at>
*/
ENTRY(copyinstr)
pushl %esi
pushl %edi
movl 12(%esp),%esi
movl 16(%esp),%edi
movl 20(%esp),%ecx
shrl $2,%ecx
cld
rep
movsl
movl 20(%esp),%ecx
andl $3,%ecx
rep
movsb
movl _curpcb, %ecx
movl $copystr_fault, PCB_ONFAULT(%ecx)
movl 12(%esp), %esi # %esi = from
movl 16(%esp), %edi # %edi = to
movl 20(%esp), %edx # %edx = maxlen
movl __udatasel, %eax
movl %ax, %gs
incl %edx
1:
decl %edx
jz 4f
gs
lodsb
stosb
orb %al,%al
jnz 1b
/* Success -- 0 byte reached */
decl %edx
xorl %eax, %eax
jmp 7f
4:
/* edx is zero -- return ENAMETOOLONG */
movl $ ENAMETOOLONG, %eax
jmp 7f
copystr_fault:
movl $ EFAULT, %eax
7: /* set *lencopied and return %eax */
movl _curpcb, %ecx
movl $0, PCB_ONFAULT(%ecx)
movl 20(%esp), %ecx
subl %edx, %ecx
movl 24(%esp), %edx
orl %edx, %edx
jz 8f
movl %ecx, (%edx)
8:
popl %edi
popl %esi
xorl %eax,%eax
movl _curpcb,%edx
movl %eax,PCB_ONFAULT(%edx)
ret
ALIGN_TEXT
cpyflt: popl %edi
/*
* copystr(from, to, maxlen, int *lencopied)
*
* by Christoph Robitschko <chmr@edvz.tu-graz.ac.at>
*/
ENTRY(copystr)
pushl %esi
pushl %edi
movl 12(%esp), %esi /* %esi = from */
movl 16(%esp), %edi /* %edi = to */
movl 20(%esp), %edx /* %edx = maxlen */
incl %edx
1:
decl %edx
jz 4f
lodsb
stosb
orb %al,%al
jnz 1b
/* Success -- 0 byte reached */
decl %edx
xorl %eax, %eax
jmp 6f
4:
/* edx is zero -- return ENAMETOOLONG */
movl $ ENAMETOOLONG, %eax
6: /* set *lencopied and return %eax */
movl 20(%esp), %ecx
subl %edx, %ecx
movl 24(%esp), %edx
orl %edx, %edx
jz 7f
movl %ecx, (%edx)
7:
popl %edi
popl %esi
movl _curpcb,%edx
movl $0,PCB_ONFAULT(%edx)
movl $ EFAULT,%eax
ret
/*
* {fu,su},{byte,word} - <ws@tools.de>. Minor modifications - <andrew@werple>
*/
ENTRY(fuword)
ALTENTRY(fuiword)
movl __udatasel, %ax
movl %ax, %gs
movl _curpcb, %ecx
movl $fusufault, PCB_ONFAULT(%ecx)
movl 4(%esp), %edx
gs
movl (%edx), %eax
movl $0, PCB_ONFAULT(%ecx)
ret
ENTRY(fusword)
movl __udatasel, %ax
movl %ax, %gs
movl _curpcb, %ecx
movl $fusufault, PCB_ONFAULT(%ecx)
movl 4(%esp), %edx
gs
movzwl (%edx), %eax
movl $0, PCB_ONFAULT(%ecx)
ret
ENTRY(fubyte)
ALTENTRY(fuibyte)
movl __udatasel, %ax
movl %ax, %gs
movl _curpcb, %ecx
movl $fusufault, PCB_ONFAULT(%ecx)
movl 4(%esp), %edx
gs
movzbl (%edx), %eax
movl $0, PCB_ONFAULT(%ecx)
ret
fusufault:
movl _curpcb, %ecx
xorl %eax, %eax
movl %eax, PCB_ONFAULT(%ecx)
decl %eax
ret
ENTRY(suword)
ALTENTRY(suiword)
movl __udatasel, %ax
movl %ax, %gs
movl _curpcb, %ecx
movl $fusufault, PCB_ONFAULT(%ecx) #in case we page/protection violate
movl 4(%esp), %edx
#if defined(I386_CPU)
#if defined(I486_CPU) || defined(I586_CPU)
cmpl $ CPUCLASS_386, _cpu_class
jne 2f /* fine, we're not a 386 so don't need this stuff */
#endif /* I486_CPU || I586_CPU */
movl %edx, %eax
shrl $IDXSHIFT, %edx /* fetch pte associated with address */
andb $0xfc, %dl
movb _PTmap(%edx), %dl
andb $7, %dl /* if we are the one case that won't trap... */
cmpb $5, %dl
jne 1f
/* ... then simulate the trap! */
pushl %eax
call _trapwrite /* trapwrite(addr) */
addl $4, %esp /* clear parameter from the stack */
movl _curpcb, %ecx # restore trashed registers
orl %eax, %eax /* if not ok, return */
jne fusufault
1:
/* XXX also need to check the following 3 bytes for validity! */
movl 4(%esp), %edx
#endif
# insb(port,addr,cnt)
2:
movl 8(%esp), %eax
gs
movl %eax, (%edx)
xorl %eax, %eax
movl %eax, PCB_ONFAULT(%ecx) #in case we page/protection violate
ret
ENTRY(susword)
movl __udatasel, %eax
movl %ax, %gs
movl _curpcb, %ecx
movl $fusufault, PCB_ONFAULT(%ecx) #in case we page/protection violate
movl 4(%esp), %edx
#if defined(I386_CPU)
#if defined(I486_CPU) || defined(I586_CPU)
cmpl $ CPUCLASS_386, _cpu_class
jne 2f /* fine, we're not a 386 so don't need this stuff */
#endif /* I486_CPU || I586_CPU */
movl %edx, %eax
shrl $IDXSHIFT, %edx /* calculate pte address */
andb $0xfc, %dl
movb _PTmap(%edx), %dl
andb $7, %dl /* if we are the one case that won't trap... */
cmpb $5, %dl
jne 1f
/* ...then simulate the trap! */
pushl %eax
call _trapwrite /* trapwrite(addr) */
addl $4, %esp /* clear parameter from the stack */
movl _curpcb, %ecx /* restore trashed registers */
orl %eax, %eax
jne fusufault
1:
/* XXX also need to check the following byte for validity! */
movl 4(%esp), %edx
#endif
2:
movl 8(%esp), %eax
gs
movw %ax, (%edx)
xorl %eax, %eax
movl %eax, PCB_ONFAULT(%ecx) #in case we page/protection violate
ret
ENTRY(subyte)
ALTENTRY(suibyte)
movl __udatasel, %eax
movl %ax, %gs
movl _curpcb, %ecx
movl $fusufault, PCB_ONFAULT(%ecx)
movl 4(%esp), %edx
#if defined(I386_CPU)
#if defined(I486_CPU) || defined(I586_CPU)
cmpl $ CPUCLASS_386, _cpu_class
jne 2f /* fine, we're not a 386 so don't need this stuff */
#endif /* I486_CPU || I586_CPU */
movl %edx, %eax
shrl $IDXSHIFT, %edx /* calculate pte address */
andb $0xfc, %dl
movb _PTmap(%edx), %dl
andb $7, %dl /* if we are the one case that won't trap... */
cmpb $5, %dl
jne 1f
/* ...then simulate the trap! */
pushl %eax
call _trapwrite /* trapwrite(addr) */
addl $4, %esp /* clear parameter from the stack */
movl _curpcb, %ecx /* restore trashed registers */
orl %eax, %eax
jne fusufault
1:
movl 4(%esp), %edx
#endif
2:
movl 8(%esp), %eax
gs
movb %eax, (%edx)
xorl %eax, %eax
movl %eax, PCB_ONFAULT(%ecx) #in case we page/protection violate
ret
# insb(port, addr, cnt)
ENTRY(insb)
pushl %edi
movw 8(%esp),%dx
movl 12(%esp),%edi
movl 16(%esp),%ecx
movl 8(%esp), %edx
movl 12(%esp), %edi
movl 16(%esp), %ecx
cld
NOP
rep
insb
NOP
movl %edi,%eax
movl %edi, %eax
popl %edi
ret
# insw(port,addr,cnt)
# insw(port, addr, cnt)
ENTRY(insw)
pushl %edi
movw 8(%esp),%dx
movl 12(%esp),%edi
movl 16(%esp),%ecx
movl 8(%esp), %dx
movl 12(%esp), %edi
movl 16(%esp), %ecx
cld
NOP
.byte 0x66,0xf2,0x6d # rep insw
rep
insw
NOP
movl %edi,%eax
popl %edi
@ -966,7 +1345,8 @@ ENTRY(outsw)
movl 16(%esp),%ecx
cld
NOP
.byte 0x66,0xf2,0x6f # rep outsw
rep
outsw
NOP
movl %esi,%eax
popl %esi
@ -996,9 +1376,7 @@ ENTRY(lgdt)
lgdt (%eax)
/* flush the prefetch q */
jmp 1f
#ifdef I386_CPU
nop
#endif
1:
/* reload "stale" selectors */
movl $KDSEL,%eax
@ -1097,134 +1475,6 @@ ENTRY(ssdtosd)
popl %ebx
ret
/*
* {fu,su},{byte,word}
*/
ALTENTRY(fuiword)
ENTRY(fuword)
movl _curpcb,%ecx
movl $fusufault,PCB_ONFAULT(%ecx)
movl 4(%esp),%edx
.byte 0x65 # use gs
movl (%edx),%eax
movl $0,PCB_ONFAULT(%ecx)
ret
ENTRY(fusword)
movl _curpcb,%ecx
movl $fusufault,PCB_ONFAULT(%ecx) #in case we page/protection violate
movl 4(%esp),%edx
.byte 0x65 # use gs
movzwl (%edx),%eax
movl $0,PCB_ONFAULT(%ecx)
ret
ALTENTRY(fuibyte)
ENTRY(fubyte)
movl _curpcb,%ecx
movl $fusufault,PCB_ONFAULT(%ecx) #in case we page/protection violate
movl 4(%esp),%edx
.byte 0x65 # use gs
movzbl (%edx),%eax
movl $0,PCB_ONFAULT(%ecx)
ret
ALIGN_TEXT
fusufault:
movl _curpcb,%ecx
xorl %eax,%eax
movl %eax,PCB_ONFAULT(%ecx) #in case we page/protection violate
decl %eax
ret
ALTENTRY(suiword)
ENTRY(suword)
movl _curpcb,%ecx
movl $fusufault,PCB_ONFAULT(%ecx) #in case we page/protection violate
movl 4(%esp),%edx
movl 8(%esp),%eax
#ifdef notdef
shrl $IDXSHIFT, %edx /* fetch pte associated with address */
andb $0xfc, %dl
movl _PTmap(%edx), %edx
andb $7, %dl /* if we are the one case that won't trap... */
cmpb $5 , %edx
jne 1f
/* ... then simulate the trap! */
pushl %edi
call _trapwrite /* trapwrite(addr) */
popl %edx
cmpl $0, %eax /* if not ok, return */
jne fusufault
movl 8(%esp),%eax /* otherwise, continue with reference */
1:
movl 4(%esp),%edx
#endif
.byte 0x65 # use gs
movl %eax,(%edx)
xorl %eax,%eax
movl %eax,PCB_ONFAULT(%ecx) #in case we page/protection violate
ret
ENTRY(susword)
movl _curpcb,%ecx
movl $fusufault,PCB_ONFAULT(%ecx) #in case we page/protection violate
movl 4(%esp),%edx
movl 8(%esp),%eax
#ifdef notdef
shrl $IDXSHIFT, %edx /* calculate pte address */
andb $0xfc, %dl
movl _PTmap(%edx), %edx
andb $7, %edx /* if we are the one case that won't trap... */
cmpb $5 , %edx
jne 1f
/* ..., then simulate the trap! */
pushl %edi
call _trapwrite /* trapwrite(addr) */
popl %edx
movl _curpcb, %ecx # restore trashed registers
cmpl $0, %eax /* if not ok, return */
jne fusufault
movl 8(%esp),%eax
1: movl 4(%esp),%edx
#endif
.byte 0x65 # use gs
movw %ax,(%edx)
xorl %eax,%eax
movl %eax,PCB_ONFAULT(%ecx) #in case we page/protection violate
ret
ALTENTRY(suibyte)
ENTRY(subyte)
movl _curpcb,%ecx
movl $fusufault,PCB_ONFAULT(%ecx) #in case we page/protection violate
movl 4(%esp),%edx
movl 8(%esp),%eax
#ifdef notdef
shrl $IDXSHIFT, %edx /* calculate pte address */
andb $0xfc, %dl
movl _PTmap(%edx), %edx
andb $7, %edx /* if we are the one case that won't trap... */
cmpb $5 , %edx
jne 1f
/* ..., then simulate the trap! */
pushl %edi
call _trapwrite /* trapwrite(addr) */
popl %edx
movl _curpcb, %ecx # restore trashed registers
cmpl $0, %eax /* if not ok, return */
jne fusufault
movl 8(%esp),%eax
1: movl 4(%esp),%edx
#endif
.byte 0x65 # use gs
movb %eax,(%edx)
xorl %eax,%eax
movl %eax,PCB_ONFAULT(%ecx) #in case we page/protection violate
ret
ENTRY(setjmp)
movl 4(%esp),%eax
movl %ebx, (%eax) # save ebx
@ -1475,7 +1725,7 @@ swfnd:
#if 0
call _splx
#endif
addl $4,%esp
addl $4, %esp
/*
* XXX - 0.0 gets here via swtch_to_inactive(). I think 0.1 gets here in the
* same way. Better return a value.
@ -1484,8 +1734,9 @@ swfnd:
ret
ENTRY(mvesp)
movl %esp,%eax
movl %esp, %eax
ret
/*
* struct proc *swtch_to_inactive(p) ; struct proc *p;
*

View File

@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
* $Id: machdep.c,v 1.39 1993/07/17 16:06:44 mycroft Exp $
* $Id: machdep.c,v 1.40 1993/07/18 08:23:07 andrew Exp $
*/
#include "npx.h"
@ -778,7 +778,6 @@ setregs(p, entry, stack, retval)
* Initialize segments & interrupt table
*/
#define GNULL_SEL 0 /* Null Descriptor */
#define GCODE_SEL 1 /* Kernel Code Descriptor */
#define GDATA_SEL 2 /* Kernel Data Descriptor */
@ -808,15 +807,15 @@ struct i386tss tss, panic_tss;
extern struct user *proc0paddr;
/* software prototypes -- in more palitable form */
/* software prototypes -- in more palatable form */
struct soft_segment_descriptor gdt_segs[] = {
/* Null Descriptor */
{ 0x0, /* segment base address */
0x0, /* length - all address space */
0x0, /* length */
0, /* segment type */
0, /* segment descriptor priority level */
0, /* segment descriptor present */
0,0,
0, 0,
0, /* default 32 vs 16 bit size */
0 /* limit granularity (byte/page units)*/ },
/* Code Descriptor for kernel */
@ -825,7 +824,7 @@ struct soft_segment_descriptor gdt_segs[] = {
SDT_MEMERA, /* segment type */
0, /* segment descriptor priority level */
1, /* segment descriptor present */
0,0,
0, 0,
1, /* default 32 vs 16 bit size */
1 /* limit granularity (byte/page units)*/ },
/* Data Descriptor for kernel */
@ -834,7 +833,7 @@ struct soft_segment_descriptor gdt_segs[] = {
SDT_MEMRWA, /* segment type */
0, /* segment descriptor priority level */
1, /* segment descriptor present */
0,0,
0, 0,
1, /* default 32 vs 16 bit size */
1 /* limit granularity (byte/page units)*/ },
/* LDT Descriptor */
@ -843,16 +842,16 @@ struct soft_segment_descriptor gdt_segs[] = {
SDT_SYSLDT, /* segment type */
0, /* segment descriptor priority level */
1, /* segment descriptor present */
0,0,
0, 0,
0, /* unused - default 32 vs 16 bit size */
0 /* limit granularity (byte/page units)*/ },
/* Null Descriptor - Placeholder */
{ 0x0, /* segment base address */
0x0, /* length - all address space */
0x0, /* length */
0, /* segment type */
0, /* segment descriptor priority level */
0, /* segment descriptor present */
0,0,
0, 0,
0, /* default 32 vs 16 bit size */
0 /* limit granularity (byte/page units)*/ },
/* Panic Tss Descriptor */
@ -861,7 +860,7 @@ struct soft_segment_descriptor gdt_segs[] = {
SDT_SYS386TSS, /* segment type */
0, /* segment descriptor priority level */
1, /* segment descriptor present */
0,0,
0, 0,
0, /* unused - default 32 vs 16 bit size */
0 /* limit granularity (byte/page units)*/ },
/* Proc 0 Tss Descriptor */
@ -870,36 +869,36 @@ struct soft_segment_descriptor gdt_segs[] = {
SDT_SYS386TSS, /* segment type */
0, /* segment descriptor priority level */
1, /* segment descriptor present */
0,0,
0, 0,
0, /* unused - default 32 vs 16 bit size */
0 /* limit granularity (byte/page units)*/ }};
struct soft_segment_descriptor ldt_segs[] = {
/* Null Descriptor - overwritten by call gate */
{ 0x0, /* segment base address */
0x0, /* length - all address space */
0x0, /* length */
0, /* segment type */
0, /* segment descriptor priority level */
0, /* segment descriptor present */
0,0,
0, 0,
0, /* default 32 vs 16 bit size */
0 /* limit granularity (byte/page units)*/ },
/* Null Descriptor - overwritten by call gate */
{ 0x0, /* segment base address */
0x0, /* length - all address space */
0x0, /* length */
0, /* segment type */
0, /* segment descriptor priority level */
0, /* segment descriptor present */
0,0,
0, 0,
0, /* default 32 vs 16 bit size */
0 /* limit granularity (byte/page units)*/ },
/* Null Descriptor - overwritten by call gate */
{ 0x0, /* segment base address */
0x0, /* length - all address space */
0x0, /* length */
0, /* segment type */
0, /* segment descriptor priority level */
0, /* segment descriptor present */
0,0,
0, 0,
0, /* default 32 vs 16 bit size */
0 /* limit granularity (byte/page units)*/ },
/* Code Descriptor for user */
@ -908,7 +907,7 @@ struct soft_segment_descriptor ldt_segs[] = {
SDT_MEMERA, /* segment type */
SEL_UPL, /* segment descriptor priority level */
1, /* segment descriptor present */
0,0,
0, 0,
1, /* default 32 vs 16 bit size */
1 /* limit granularity (byte/page units)*/ },
/* Data Descriptor for user */
@ -917,7 +916,7 @@ struct soft_segment_descriptor ldt_segs[] = {
SDT_MEMRWA, /* segment type */
SEL_UPL, /* segment descriptor priority level */
1, /* segment descriptor present */
0,0,
0, 0,
1, /* default 32 vs 16 bit size */
1 /* limit granularity (byte/page units)*/ } };
@ -974,8 +973,8 @@ init386(first)
for (x=0; x < NGDT; x++) ssdtosd(gdt_segs+x, gdt+x);
/* make ldt memory segments */
ldt_segs[LUCODE_SEL].ssd_limit = btoc(UPT_MIN_ADDRESS);
ldt_segs[LUDATA_SEL].ssd_limit = btoc(UPT_MIN_ADDRESS);
ldt_segs[LUCODE_SEL].ssd_limit = btoc(VM_MAXUSER_ADDRESS) - 1;
ldt_segs[LUDATA_SEL].ssd_limit = btoc(VM_MAXUSER_ADDRESS) - 1;
/* Note. eventually want private ldts per process */
for (x=0; x < 5; x++) ssdtosd(ldt_segs+x, ldt+x);
@ -1072,7 +1071,8 @@ init386(first)
Maxmem = 640/4;
else {
Maxmem = pagesinext + 0x100000/NBPG;
first = 0x100000; /* skip hole */
if (first < 0x100000)
first = 0x100000; /* skip hole */
}
/* This used to explode, since Maxmem used to be 0 for bas CMOS*/
@ -1206,67 +1206,6 @@ _remque(element)
vmunaccess() {}
/*
* Below written in C to allow access to debugging code
*/
copyinstr(fromaddr, toaddr, maxlength, lencopied) u_int *lencopied, maxlength;
void *toaddr, *fromaddr; {
int c,tally;
tally = 0;
while (maxlength--) {
c = fubyte(fromaddr++);
if (c == -1) {
if(lencopied) *lencopied = tally;
return(EFAULT);
}
tally++;
*(char *)toaddr++ = (char) c;
if (c == 0){
if(lencopied) *lencopied = (u_int)tally;
return(0);
}
}
if(lencopied) *lencopied = (u_int)tally;
return(ENAMETOOLONG);
}
copyoutstr(fromaddr, toaddr, maxlength, lencopied) u_int *lencopied, maxlength;
void *fromaddr, *toaddr; {
int c;
int tally;
tally = 0;
while (maxlength--) {
c = subyte(toaddr++, *(char *)fromaddr);
if (c == -1) return(EFAULT);
tally++;
if (*(char *)fromaddr++ == 0){
if(lencopied) *lencopied = tally;
return(0);
}
}
if(lencopied) *lencopied = tally;
return(ENAMETOOLONG);
}
copystr(fromaddr, toaddr, maxlength, lencopied) u_int *lencopied, maxlength;
void *fromaddr, *toaddr; {
u_int tally;
tally = 0;
while (maxlength--) {
*(u_char *)toaddr = *(u_char *)fromaddr++;
tally++;
if (*(u_char *)toaddr++ == 0) {
if(lencopied) *lencopied = tally;
return(0);
}
}
if(lencopied) *lencopied = tally;
return(ENAMETOOLONG);
}
cpu_exec_makecmds(p, epp)
struct proc *p;
struct exec_package *epp;

View File

@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)pmap.c 7.7 (Berkeley) 5/12/91
* $Id: pmap.c,v 1.5 1993/06/27 06:02:54 andrew Exp $
* $Id: pmap.c,v 1.6 1993/07/18 08:23:12 andrew Exp $
*/
/*
@ -454,7 +454,7 @@ pmap_pinit(pmap)
/* install self-referential address mapping entry */
*(int *)(pmap->pm_pdir+PTDPTDI) =
(int)pmap_extract(kernel_pmap, pmap->pm_pdir) | PG_V | PG_URKW;
(int)pmap_extract(kernel_pmap, pmap->pm_pdir) | PG_V | PG_KW;
pmap->pm_count = 1;
simple_lock_init(&pmap->pm_lock);
@ -834,7 +834,9 @@ pmap_protect(pmap, sva, eva, prot)
ix = 0;
i386prot = pte_prot(pmap, prot);
if(va < UPT_MAX_ADDRESS)
if (va < UPT_MAX_ADDRESS) /* see also pmap_enter() */
/* what on earth is this? 2 == PG_RW !!! */
/* andrew@werple.apana.org.au */
i386prot |= 2 /*PG_u*/;
do {
/* clear VAC here if PG_RO? */
@ -1033,10 +1035,19 @@ validate:
npte |= (*(int *)pte & (PG_M|PG_U));
if (wired)
npte |= PG_W;
if(va < UPT_MIN_ADDRESS)
if (va < VM_MAXUSER_ADDRESS) /* i.e. below USRSTACK */
npte |= PG_u;
else if(va < UPT_MAX_ADDRESS)
else if (va < UPT_MAX_ADDRESS)
/* pagetables need to be user RW, for some reason, and the
* user area must be writable too. Anything above
* VM_MAXUSER_ADDRESS is protected from user access by
* the user data and code segment descriptors, so this is OK.
*
* andrew@werple.apana.org.au
*/
npte |= PG_u | PG_RW;
#ifdef DEBUG
if (pmapdebug & PDB_ENTER)
printf("enter: new pte value %x ", npte);

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91
* $Id: vm_machdep.c,v 1.5 1993/06/27 06:02:55 andrew Exp $
* $Id: vm_machdep.c,v 1.6 1993/07/18 08:23:15 andrew Exp $
*/
/*
@ -99,7 +99,12 @@ cpu_fork(p1, p2)
vm_map_pageable(&p2->p_vmspace->vm_map, addr, addr+NBPG, FALSE);
for (i=0; i < UPAGES; i++)
pmap_enter(&p2->p_vmspace->vm_pmap, kstack+i*NBPG,
pmap_extract(kernel_pmap, ((int)p2->p_addr)+i*NBPG), VM_PROT_READ, 1);
pmap_extract(kernel_pmap, ((int)p2->p_addr)+i*NBPG),
VM_PROT_READ | VM_PROT_WRITE, /* must be writable for
* i486 WP support;
* i386 doesn't care
*/
TRUE);
pmap_activate(&p2->p_vmspace->vm_pmap, &up->u_pcb);