#ifndef _PERF_SYS_H #define _PERF_SYS_H #include #include #include #include #include #include #include #if defined(__i386__) #define cpu_relax() asm volatile("rep; nop" ::: "memory"); #define CPUINFO_PROC {"model name"} #endif #if defined(__x86_64__) #define cpu_relax() asm volatile("rep; nop" ::: "memory"); #define CPUINFO_PROC {"model name"} #endif #ifdef __powerpc__ #define CPUINFO_PROC {"cpu"} #endif #ifdef __s390__ #define CPUINFO_PROC {"vendor_id"} #endif #ifdef __sh__ #define CPUINFO_PROC {"cpu type"} #endif #ifdef __hppa__ #define CPUINFO_PROC {"cpu"} #endif #ifdef __sparc__ #define CPUINFO_PROC {"cpu"} #endif #ifdef __alpha__ #define CPUINFO_PROC {"cpu model"} #endif #ifdef __ia64__ #define cpu_relax() asm volatile ("hint @pause" ::: "memory") #define CPUINFO_PROC {"model name"} #endif #ifdef __arm__ #define CPUINFO_PROC {"model name", "Processor"} #endif #ifdef __aarch64__ #define cpu_relax() asm volatile("yield" ::: "memory") #endif #ifdef __mips__ #define CPUINFO_PROC {"cpu model"} #endif #ifdef __arc__ #define CPUINFO_PROC {"Processor"} #endif #ifdef __metag__ #define CPUINFO_PROC {"CPU"} #endif #ifdef __xtensa__ #define CPUINFO_PROC {"core ID"} #endif #ifdef __tile__ #define cpu_relax() asm volatile ("mfspr zero, PASS" ::: "memory") #define CPUINFO_PROC {"model name"} #endif #ifndef cpu_relax #define cpu_relax() barrier() #endif static inline int sys_perf_event_open(struct perf_event_attr *attr, pid_t pid, int cpu, int group_fd, unsigned long flags) { int fd; fd = syscall(__NR_perf_event_open, attr, pid, cpu, group_fd, flags); #ifdef HAVE_ATTR_TEST if (unlikely(test_attr__enabled)) test_attr__open(attr, pid, cpu, fd, group_fd, flags); #endif return fd; } #endif /* _PERF_SYS_H */ f656'>commitdiff
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@ozlabs.org>2016-10-11 22:25:47 +1100
committerMichael Ellerman <mpe@ellerman.id.au>2016-10-12 08:31:37 +1100
commit1a34439e5a0b2235e43f96816dbb15ee1154f656 (patch)
treee430a9a021fcfc1a9459cb3e87e5946e3ef01eee
parent7c8cb4b50f3cc6f4a8f7bfddad6fb5a845df3261 (diff)
powerpc/64: Fix incorrect return value from __copy_tofrom_user
Debugging a data corruption issue with virtio-net/vhost-net led to the observation that __copy_tofrom_user was occasionally returning a value 16 larger than it should. Since the return value from __copy_tofrom_user is the number of bytes not copied, this means that __copy_tofrom_user can occasionally return a value larger than the number of bytes it was asked to copy. In turn this can cause higher-level copy functions such as copy_page_to_iter_iovec to corrupt memory by copying data into the wrong memory locations. It turns out that the failing case involves a fault on the store at label 79, and at that point the first unmodified byte of the destination is at R3 + 16. Consequently the exception handler for that store needs to add 16 to R3 before using it to work out how many bytes were not copied, but in this one case it was not adding the offset to R3. To fix it, this moves the label 179 to the point where we add 16 to R3. I have checked manually all the exception handlers for the loads and stores in this code and the rest of them are correct (it would be excellent to have an automated test of all the exception cases). This bug has been present since this code was initially committed in May 2002 to Linux version 2.5.20. Cc: stable@vger.kernel.org Signed-off-by: Paul Mackerras <paulus@ozlabs.org> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>