mirror of
https://github.com/golang/go
synced 2024-11-24 13:10:11 -07:00
runtime: SysMap uses MAP_FIXED if needed on 64-bit Linux
This change was adapted from gccgo's libgo/runtime/mem.c at Ian Taylor's suggestion. It fixes all.bash failing with "address space conflict: map() =" on amd64 Linux with kernel version 2.6.32.8-grsec-2.1.14-modsign-xeon-64. With this change, SysMap will use MAP_FIXED to allocate its desired address space, after first calling mincore to check that there is nothing else mapped there. R=iant, dave, n13m3y3r, rsc CC=golang-dev https://golang.org/cl/4438091
This commit is contained in:
parent
bac24da2ac
commit
ddde52ae56
@ -47,6 +47,14 @@ TEXT runtime·setitimer(SB),7,$0-24
|
||||
INT $0x80
|
||||
RET
|
||||
|
||||
TEXT runtime·mincore(SB),7,$0-24
|
||||
MOVL $218, AX // syscall - mincore
|
||||
MOVL 4(SP), BX
|
||||
MOVL 8(SP), CX
|
||||
MOVL 12(SP), DX
|
||||
INT $0x80
|
||||
RET
|
||||
|
||||
TEXT runtime·gettime(SB), 7, $32
|
||||
MOVL $78, AX // syscall - gettimeofday
|
||||
LEAL 8(SP), BX
|
||||
|
@ -53,6 +53,14 @@ TEXT runtime·setitimer(SB),7,$0-24
|
||||
SYSCALL
|
||||
RET
|
||||
|
||||
TEXT runtime·mincore(SB),7,$0-24
|
||||
MOVQ 8(SP), DI
|
||||
MOVQ 16(SP), SI
|
||||
MOVQ 24(SP), DX
|
||||
MOVL $27, AX // syscall entry
|
||||
SYSCALL
|
||||
RET
|
||||
|
||||
TEXT runtime·gettime(SB), 7, $32
|
||||
LEAQ 8(SP), DI
|
||||
MOVQ $0, SI
|
||||
|
@ -26,6 +26,7 @@
|
||||
#define SYS_exit_group (SYS_BASE + 248)
|
||||
#define SYS_munmap (SYS_BASE + 91)
|
||||
#define SYS_setitimer (SYS_BASE + 104)
|
||||
#define SYS_mincore (SYS_BASE + 219)
|
||||
#define SYS_gettid (SYS_BASE + 224)
|
||||
#define SYS_tkill (SYS_BASE + 238)
|
||||
|
||||
@ -91,6 +92,14 @@ TEXT runtime·setitimer(SB),7,$0
|
||||
SWI $0
|
||||
RET
|
||||
|
||||
TEXT runtime·mincore(SB),7,$0
|
||||
MOVW 0(FP), R0
|
||||
MOVW 4(FP), R1
|
||||
MOVW 8(FP), R2
|
||||
MOVW $SYS_mincore, R7
|
||||
SWI $0
|
||||
RET
|
||||
|
||||
TEXT runtime·gettime(SB),7,$32
|
||||
/* dummy version - return 0,0 */
|
||||
MOVW $0, R1
|
||||
|
@ -3,6 +3,30 @@
|
||||
#include "os.h"
|
||||
#include "malloc.h"
|
||||
|
||||
enum
|
||||
{
|
||||
ENOMEM = 12,
|
||||
};
|
||||
|
||||
static int32
|
||||
addrspace_free(void *v, uintptr n)
|
||||
{
|
||||
uintptr page_size = 4096;
|
||||
uintptr off;
|
||||
int8 one_byte;
|
||||
|
||||
for(off = 0; off < n; off += page_size) {
|
||||
int32 errval = runtime·mincore((int8 *)v + off, page_size, (void *)&one_byte);
|
||||
// errval is 0 if success, or -(error_code) if error.
|
||||
if (errval == 0 || errval != -ENOMEM)
|
||||
return 0;
|
||||
}
|
||||
USED(v);
|
||||
USED(n);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void*
|
||||
runtime·SysAlloc(uintptr n)
|
||||
{
|
||||
@ -54,11 +78,6 @@ runtime·SysReserve(void *v, uintptr n)
|
||||
return p;
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
ENOMEM = 12,
|
||||
};
|
||||
|
||||
void
|
||||
runtime·SysMap(void *v, uintptr n)
|
||||
{
|
||||
@ -69,6 +88,11 @@ runtime·SysMap(void *v, uintptr n)
|
||||
// On 64-bit, we don't actually have v reserved, so tread carefully.
|
||||
if(sizeof(void*) == 8) {
|
||||
p = runtime·mmap(v, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, -1, 0);
|
||||
if(p != v && addrspace_free(v, n)) {
|
||||
// On some systems, mmap ignores v without
|
||||
// MAP_FIXED, so retry if the address space is free.
|
||||
p = runtime·mmap(v, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0);
|
||||
}
|
||||
if(p == (void*)ENOMEM)
|
||||
runtime·throw("runtime: out of memory");
|
||||
if(p != v) {
|
||||
|
@ -413,6 +413,7 @@ int32 runtime·gotraceback(void);
|
||||
void runtime·traceback(uint8 *pc, uint8 *sp, uint8 *lr, G* gp);
|
||||
void runtime·tracebackothers(G*);
|
||||
int32 runtime·write(int32, void*, int32);
|
||||
int32 runtime·mincore(void*, uintptr, byte*);
|
||||
bool runtime·cas(uint32*, uint32, uint32);
|
||||
bool runtime·casp(void**, void*, void*);
|
||||
uint32 runtime·xadd(uint32 volatile*, int32);
|
||||
|
Loading…
Reference in New Issue
Block a user