sparc: Fix syscall fallback bugs in VDSO.
First, the trap number for 32-bit syscalls is 0x10. Also, only negate the return value when syscall error is indicated by the carry bit being set. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
c343db455e
commit
776ca1543b
2 changed files with 16 additions and 1 deletions
|
@ -33,9 +33,19 @@
|
||||||
#define TICK_PRIV_BIT (1ULL << 63)
|
#define TICK_PRIV_BIT (1ULL << 63)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_SPARC64
|
||||||
#define SYSCALL_STRING \
|
#define SYSCALL_STRING \
|
||||||
"ta 0x6d;" \
|
"ta 0x6d;" \
|
||||||
"sub %%g0, %%o0, %%o0;" \
|
"bcs,a 1f;" \
|
||||||
|
" sub %%g0, %%o0, %%o0;" \
|
||||||
|
"1:"
|
||||||
|
#else
|
||||||
|
#define SYSCALL_STRING \
|
||||||
|
"ta 0x10;" \
|
||||||
|
"bcs,a 1f;" \
|
||||||
|
" sub %%g0, %%o0, %%o0;" \
|
||||||
|
"1:"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define SYSCALL_CLOBBERS \
|
#define SYSCALL_CLOBBERS \
|
||||||
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
|
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
|
||||||
|
|
|
@ -1081,6 +1081,7 @@ void *cpu_map_data__alloc(struct cpu_map *map, size_t *size, u16 *type, int *max
|
||||||
}
|
}
|
||||||
|
|
||||||
*size += sizeof(struct cpu_map_data);
|
*size += sizeof(struct cpu_map_data);
|
||||||
|
*size = PERF_ALIGN(*size, sizeof(u64));
|
||||||
return zalloc(*size);
|
return zalloc(*size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1560,7 +1561,9 @@ struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
try_again:
|
try_again:
|
||||||
|
#endif
|
||||||
al->map = map_groups__find(mg, al->addr);
|
al->map = map_groups__find(mg, al->addr);
|
||||||
if (al->map == NULL) {
|
if (al->map == NULL) {
|
||||||
/*
|
/*
|
||||||
|
@ -1572,6 +1575,7 @@ struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,
|
||||||
* "[vdso]" dso, but for now lets use the old trick of looking
|
* "[vdso]" dso, but for now lets use the old trick of looking
|
||||||
* in the whole kernel symbol list.
|
* in the whole kernel symbol list.
|
||||||
*/
|
*/
|
||||||
|
#if 0
|
||||||
if (cpumode == PERF_RECORD_MISC_USER && machine &&
|
if (cpumode == PERF_RECORD_MISC_USER && machine &&
|
||||||
mg != &machine->kmaps &&
|
mg != &machine->kmaps &&
|
||||||
machine__kernel_ip(machine, al->addr)) {
|
machine__kernel_ip(machine, al->addr)) {
|
||||||
|
@ -1579,6 +1583,7 @@ struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,
|
||||||
load_map = true;
|
load_map = true;
|
||||||
goto try_again;
|
goto try_again;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* Kernel maps might be changed when loading symbols so loading
|
* Kernel maps might be changed when loading symbols so loading
|
||||||
|
|
Loading…
Reference in a new issue