diff options
author | Andy Shevchenko <andriy.shevchenko@linux.intel.com> | 2017-11-03 07:50:41 -0400 |
---|---|---|
committer | Andy Shevchenko <andriy.shevchenko@linux.intel.com> | 2017-11-03 07:50:41 -0400 |
commit | 7d9a6ef558f6ff375aab9e29f08124cb0daa9bc5 (patch) | |
tree | 3916e6cf9678a41081ae822ef67ec5cae1c1fffa /tools | |
parent | 3fcf2b2a2529e268c537d8ad9dac5987ebc8a2f7 (diff) | |
parent | 0224d45c9d46401b6d7018a96cfe049c5da7d91c (diff) |
Merge branch 'i2c/cht-wc-fusb302-immutable' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c/cht-wc-fusb302-immutable immutable branch from Wolfram Sang:
as discussed before, here is the immutable branch for the i2c-cht-wc
driver, so you can safely apply Hans' patch [1]
"platform/x86: intel_cht_int33fe: Update fusb302 type string, add properties"
on top of this.
[1] http://patchwork.ozlabs.org/patch/824314/
Diffstat (limited to 'tools')
63 files changed, 1773 insertions, 432 deletions
diff --git a/tools/arch/s390/include/uapi/asm/kvm.h b/tools/arch/s390/include/uapi/asm/kvm.h index 69d09c39bbcd..cd7359e23d86 100644 --- a/tools/arch/s390/include/uapi/asm/kvm.h +++ b/tools/arch/s390/include/uapi/asm/kvm.h | |||
@@ -88,6 +88,12 @@ struct kvm_s390_io_adapter_req { | |||
88 | /* kvm attributes for KVM_S390_VM_TOD */ | 88 | /* kvm attributes for KVM_S390_VM_TOD */ |
89 | #define KVM_S390_VM_TOD_LOW 0 | 89 | #define KVM_S390_VM_TOD_LOW 0 |
90 | #define KVM_S390_VM_TOD_HIGH 1 | 90 | #define KVM_S390_VM_TOD_HIGH 1 |
91 | #define KVM_S390_VM_TOD_EXT 2 | ||
92 | |||
93 | struct kvm_s390_vm_tod_clock { | ||
94 | __u8 epoch_idx; | ||
95 | __u64 tod; | ||
96 | }; | ||
91 | 97 | ||
92 | /* kvm attributes for KVM_S390_VM_CPU_MODEL */ | 98 | /* kvm attributes for KVM_S390_VM_CPU_MODEL */ |
93 | /* processor related attributes are r/w */ | 99 | /* processor related attributes are r/w */ |
diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h index 8ea315a11fe0..2519c6c801c9 100644 --- a/tools/arch/x86/include/asm/cpufeatures.h +++ b/tools/arch/x86/include/asm/cpufeatures.h | |||
@@ -196,6 +196,7 @@ | |||
196 | 196 | ||
197 | #define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */ | 197 | #define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */ |
198 | #define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */ | 198 | #define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */ |
199 | #define X86_FEATURE_SME ( 7*32+10) /* AMD Secure Memory Encryption */ | ||
199 | 200 | ||
200 | #define X86_FEATURE_INTEL_PPIN ( 7*32+14) /* Intel Processor Inventory Number */ | 201 | #define X86_FEATURE_INTEL_PPIN ( 7*32+14) /* Intel Processor Inventory Number */ |
201 | #define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */ | 202 | #define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */ |
@@ -287,6 +288,7 @@ | |||
287 | #define X86_FEATURE_PFTHRESHOLD (15*32+12) /* pause filter threshold */ | 288 | #define X86_FEATURE_PFTHRESHOLD (15*32+12) /* pause filter threshold */ |
288 | #define X86_FEATURE_AVIC (15*32+13) /* Virtual Interrupt Controller */ | 289 | #define X86_FEATURE_AVIC (15*32+13) /* Virtual Interrupt Controller */ |
289 | #define X86_FEATURE_V_VMSAVE_VMLOAD (15*32+15) /* Virtual VMSAVE VMLOAD */ | 290 | #define X86_FEATURE_V_VMSAVE_VMLOAD (15*32+15) /* Virtual VMSAVE VMLOAD */ |
291 | #define X86_FEATURE_VGIF (15*32+16) /* Virtual GIF */ | ||
290 | 292 | ||
291 | /* Intel-defined CPU features, CPUID level 0x00000007:0 (ecx), word 16 */ | 293 | /* Intel-defined CPU features, CPUID level 0x00000007:0 (ecx), word 16 */ |
292 | #define X86_FEATURE_AVX512VBMI (16*32+ 1) /* AVX512 Vector Bit Manipulation instructions*/ | 294 | #define X86_FEATURE_AVX512VBMI (16*32+ 1) /* AVX512 Vector Bit Manipulation instructions*/ |
diff --git a/tools/arch/x86/include/asm/disabled-features.h b/tools/arch/x86/include/asm/disabled-features.h index 5dff775af7cd..c10c9128f54e 100644 --- a/tools/arch/x86/include/asm/disabled-features.h +++ b/tools/arch/x86/include/asm/disabled-features.h | |||
@@ -21,11 +21,13 @@ | |||
21 | # define DISABLE_K6_MTRR (1<<(X86_FEATURE_K6_MTRR & 31)) | 21 | # define DISABLE_K6_MTRR (1<<(X86_FEATURE_K6_MTRR & 31)) |
22 | # define DISABLE_CYRIX_ARR (1<<(X86_FEATURE_CYRIX_ARR & 31)) | 22 | # define DISABLE_CYRIX_ARR (1<<(X86_FEATURE_CYRIX_ARR & 31)) |
23 | # define DISABLE_CENTAUR_MCR (1<<(X86_FEATURE_CENTAUR_MCR & 31)) | 23 | # define DISABLE_CENTAUR_MCR (1<<(X86_FEATURE_CENTAUR_MCR & 31)) |
24 | # define DISABLE_PCID 0 | ||
24 | #else | 25 | #else |
25 | # define DISABLE_VME 0 | 26 | # define DISABLE_VME 0 |
26 | # define DISABLE_K6_MTRR 0 | 27 | # define DISABLE_K6_MTRR 0 |
27 | # define DISABLE_CYRIX_ARR 0 | 28 | # define DISABLE_CYRIX_ARR 0 |
28 | # define DISABLE_CENTAUR_MCR 0 | 29 | # define DISABLE_CENTAUR_MCR 0 |
30 | # define DISABLE_PCID (1<<(X86_FEATURE_PCID & 31)) | ||
29 | #endif /* CONFIG_X86_64 */ | 31 | #endif /* CONFIG_X86_64 */ |
30 | 32 | ||
31 | #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS | 33 | #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS |
@@ -49,7 +51,7 @@ | |||
49 | #define DISABLED_MASK1 0 | 51 | #define DISABLED_MASK1 0 |
50 | #define DISABLED_MASK2 0 | 52 | #define DISABLED_MASK2 0 |
51 | #define DISABLED_MASK3 (DISABLE_CYRIX_ARR|DISABLE_CENTAUR_MCR|DISABLE_K6_MTRR) | 53 | #define DISABLED_MASK3 (DISABLE_CYRIX_ARR|DISABLE_CENTAUR_MCR|DISABLE_K6_MTRR) |
52 | #define DISABLED_MASK4 0 | 54 | #define DISABLED_MASK4 (DISABLE_PCID) |
53 | #define DISABLED_MASK5 0 | 55 | #define DISABLED_MASK5 0 |
54 | #define DISABLED_MASK6 0 | 56 | #define DISABLED_MASK6 0 |
55 | #define DISABLED_MASK7 0 | 57 | #define DISABLED_MASK7 0 |
diff --git a/tools/include/asm-generic/hugetlb_encode.h b/tools/include/asm-generic/hugetlb_encode.h new file mode 100644 index 000000000000..e4732d3c2998 --- /dev/null +++ b/tools/include/asm-generic/hugetlb_encode.h | |||
@@ -0,0 +1,34 @@ | |||
1 | #ifndef _ASM_GENERIC_HUGETLB_ENCODE_H_ | ||
2 | #define _ASM_GENERIC_HUGETLB_ENCODE_H_ | ||
3 | |||
4 | /* | ||
5 | * Several system calls take a flag to request "hugetlb" huge pages. | ||
6 | * Without further specification, these system calls will use the | ||
7 | * system's default huge page size. If a system supports multiple | ||
8 | * huge page sizes, the desired huge page size can be specified in | ||
9 | * bits [26:31] of the flag arguments. The value in these 6 bits | ||
10 | * will encode the log2 of the huge page size. | ||
11 | * | ||
12 | * The following definitions are associated with this huge page size | ||
13 | * encoding in flag arguments. System call specific header files | ||
14 | * that use this encoding should include this file. They can then | ||
15 | * provide definitions based on these with their own specific prefix. | ||
16 | * for example: | ||
17 | * #define MAP_HUGE_SHIFT HUGETLB_FLAG_ENCODE_SHIFT | ||
18 | */ | ||
19 | |||
20 | #define HUGETLB_FLAG_ENCODE_SHIFT 26 | ||
21 | #define HUGETLB_FLAG_ENCODE_MASK 0x3f | ||
22 | |||
23 | #define HUGETLB_FLAG_ENCODE_64KB (16 << HUGETLB_FLAG_ENCODE_SHIFT) | ||
24 | #define HUGETLB_FLAG_ENCODE_512KB (19 << HUGETLB_FLAG_ENCODE_SHIFT) | ||
25 | #define HUGETLB_FLAG_ENCODE_1MB (20 << HUGETLB_FLAG_ENCODE_SHIFT) | ||
26 | #define HUGETLB_FLAG_ENCODE_2MB (21 << HUGETLB_FLAG_ENCODE_SHIFT) | ||
27 | #define HUGETLB_FLAG_ENCODE_8MB (23 << HUGETLB_FLAG_ENCODE_SHIFT) | ||
28 | #define HUGETLB_FLAG_ENCODE_16MB (24 << HUGETLB_FLAG_ENCODE_SHIFT) | ||
29 | #define HUGETLB_FLAG_ENCODE_256MB (28 << HUGETLB_FLAG_ENCODE_SHIFT) | ||
30 | #define HUGETLB_FLAG_ENCODE_1GB (30 << HUGETLB_FLAG_ENCODE_SHIFT) | ||
31 | #define HUGETLB_FLAG_ENCODE_2GB (31 << HUGETLB_FLAG_ENCODE_SHIFT) | ||
32 | #define HUGETLB_FLAG_ENCODE_16GB (34 << HUGETLB_FLAG_ENCODE_SHIFT) | ||
33 | |||
34 | #endif /* _ASM_GENERIC_HUGETLB_ENCODE_H_ */ | ||
diff --git a/tools/include/uapi/asm-generic/mman-common.h b/tools/include/uapi/asm-generic/mman-common.h index 8c27db0c5c08..203268f9231e 100644 --- a/tools/include/uapi/asm-generic/mman-common.h +++ b/tools/include/uapi/asm-generic/mman-common.h | |||
@@ -58,20 +58,12 @@ | |||
58 | overrides the coredump filter bits */ | 58 | overrides the coredump filter bits */ |
59 | #define MADV_DODUMP 17 /* Clear the MADV_DONTDUMP flag */ | 59 | #define MADV_DODUMP 17 /* Clear the MADV_DONTDUMP flag */ |
60 | 60 | ||
61 | #define MADV_WIPEONFORK 18 /* Zero memory on fork, child only */ | ||
62 | #define MADV_KEEPONFORK 19 /* Undo MADV_WIPEONFORK */ | ||
63 | |||
61 | /* compatibility flags */ | 64 | /* compatibility flags */ |
62 | #define MAP_FILE 0 | 65 | #define MAP_FILE 0 |
63 | 66 | ||
64 | /* | ||
65 | * When MAP_HUGETLB is set bits [26:31] encode the log2 of the huge page size. | ||
66 | * This gives us 6 bits, which is enough until someone invents 128 bit address | ||
67 | * spaces. | ||
68 | * | ||
69 | * Assume these are all power of twos. | ||
70 | * When 0 use the default page size. | ||
71 | */ | ||
72 | #define MAP_HUGE_SHIFT 26 | ||
73 | #define MAP_HUGE_MASK 0x3f | ||
74 | |||
75 | #define PKEY_DISABLE_ACCESS 0x1 | 67 | #define PKEY_DISABLE_ACCESS 0x1 |
76 | #define PKEY_DISABLE_WRITE 0x2 | 68 | #define PKEY_DISABLE_WRITE 0x2 |
77 | #define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS |\ | 69 | #define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS |\ |
diff --git a/tools/include/uapi/drm/drm.h b/tools/include/uapi/drm/drm.h index 101593ab10ac..97677cd6964d 100644 --- a/tools/include/uapi/drm/drm.h +++ b/tools/include/uapi/drm/drm.h | |||
@@ -700,6 +700,7 @@ struct drm_prime_handle { | |||
700 | 700 | ||
701 | struct drm_syncobj_create { | 701 | struct drm_syncobj_create { |
702 | __u32 handle; | 702 | __u32 handle; |
703 | #define DRM_SYNCOBJ_CREATE_SIGNALED (1 << 0) | ||
703 | __u32 flags; | 704 | __u32 flags; |
704 | }; | 705 | }; |
705 | 706 | ||
@@ -718,6 +719,24 @@ struct drm_syncobj_handle { | |||
718 | __u32 pad; | 719 | __u32 pad; |
719 | }; | 720 | }; |
720 | 721 | ||
722 | #define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL (1 << 0) | ||
723 | #define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT (1 << 1) | ||
724 | struct drm_syncobj_wait { | ||
725 | __u64 handles; | ||
726 | /* absolute timeout */ | ||
727 | __s64 timeout_nsec; | ||
728 | __u32 count_handles; | ||
729 | __u32 flags; | ||
730 | __u32 first_signaled; /* only valid when not waiting all */ | ||
731 | __u32 pad; | ||
732 | }; | ||
733 | |||
734 | struct drm_syncobj_array { | ||
735 | __u64 handles; | ||
736 | __u32 count_handles; | ||
737 | __u32 pad; | ||
738 | }; | ||
739 | |||
721 | #if defined(__cplusplus) | 740 | #if defined(__cplusplus) |
722 | } | 741 | } |
723 | #endif | 742 | #endif |
@@ -840,6 +859,9 @@ extern "C" { | |||
840 | #define DRM_IOCTL_SYNCOBJ_DESTROY DRM_IOWR(0xC0, struct drm_syncobj_destroy) | 859 | #define DRM_IOCTL_SYNCOBJ_DESTROY DRM_IOWR(0xC0, struct drm_syncobj_destroy) |
841 | #define DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD DRM_IOWR(0xC1, struct drm_syncobj_handle) | 860 | #define DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD DRM_IOWR(0xC1, struct drm_syncobj_handle) |
842 | #define DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE DRM_IOWR(0xC2, struct drm_syncobj_handle) | 861 | #define DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE DRM_IOWR(0xC2, struct drm_syncobj_handle) |
862 | #define DRM_IOCTL_SYNCOBJ_WAIT DRM_IOWR(0xC3, struct drm_syncobj_wait) | ||
863 | #define DRM_IOCTL_SYNCOBJ_RESET DRM_IOWR(0xC4, struct drm_syncobj_array) | ||
864 | #define DRM_IOCTL_SYNCOBJ_SIGNAL DRM_IOWR(0xC5, struct drm_syncobj_array) | ||
843 | 865 | ||
844 | /** | 866 | /** |
845 | * Device specific ioctls should only be in their respective headers | 867 | * Device specific ioctls should only be in their respective headers |
diff --git a/tools/include/uapi/drm/i915_drm.h b/tools/include/uapi/drm/i915_drm.h index 7ccbd6a2bbe0..6598fb76d2c2 100644 --- a/tools/include/uapi/drm/i915_drm.h +++ b/tools/include/uapi/drm/i915_drm.h | |||
@@ -260,6 +260,8 @@ typedef struct _drm_i915_sarea { | |||
260 | #define DRM_I915_GEM_CONTEXT_GETPARAM 0x34 | 260 | #define DRM_I915_GEM_CONTEXT_GETPARAM 0x34 |
261 | #define DRM_I915_GEM_CONTEXT_SETPARAM 0x35 | 261 | #define DRM_I915_GEM_CONTEXT_SETPARAM 0x35 |
262 | #define DRM_I915_PERF_OPEN 0x36 | 262 | #define DRM_I915_PERF_OPEN 0x36 |
263 | #define DRM_I915_PERF_ADD_CONFIG 0x37 | ||
264 | #define DRM_I915_PERF_REMOVE_CONFIG 0x38 | ||
263 | 265 | ||
264 | #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) | 266 | #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) |
265 | #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) | 267 | #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) |
@@ -315,6 +317,8 @@ typedef struct _drm_i915_sarea { | |||
315 | #define DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_GETPARAM, struct drm_i915_gem_context_param) | 317 | #define DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_GETPARAM, struct drm_i915_gem_context_param) |
316 | #define DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_SETPARAM, struct drm_i915_gem_context_param) | 318 | #define DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_SETPARAM, struct drm_i915_gem_context_param) |
317 | #define DRM_IOCTL_I915_PERF_OPEN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_OPEN, struct drm_i915_perf_open_param) | 319 | #define DRM_IOCTL_I915_PERF_OPEN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_OPEN, struct drm_i915_perf_open_param) |
320 | #define DRM_IOCTL_I915_PERF_ADD_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_ADD_CONFIG, struct drm_i915_perf_oa_config) | ||
321 | #define DRM_IOCTL_I915_PERF_REMOVE_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_REMOVE_CONFIG, __u64) | ||
318 | 322 | ||
319 | /* Allow drivers to submit batchbuffers directly to hardware, relying | 323 | /* Allow drivers to submit batchbuffers directly to hardware, relying |
320 | * on the security mechanisms provided by hardware. | 324 | * on the security mechanisms provided by hardware. |
@@ -431,6 +435,11 @@ typedef struct drm_i915_irq_wait { | |||
431 | */ | 435 | */ |
432 | #define I915_PARAM_HAS_EXEC_BATCH_FIRST 48 | 436 | #define I915_PARAM_HAS_EXEC_BATCH_FIRST 48 |
433 | 437 | ||
438 | /* Query whether DRM_I915_GEM_EXECBUFFER2 supports supplying an array of | ||
439 | * drm_i915_gem_exec_fence structures. See I915_EXEC_FENCE_ARRAY. | ||
440 | */ | ||
441 | #define I915_PARAM_HAS_EXEC_FENCE_ARRAY 49 | ||
442 | |||
434 | typedef struct drm_i915_getparam { | 443 | typedef struct drm_i915_getparam { |
435 | __s32 param; | 444 | __s32 param; |
436 | /* | 445 | /* |
@@ -812,6 +821,17 @@ struct drm_i915_gem_exec_object2 { | |||
812 | __u64 rsvd2; | 821 | __u64 rsvd2; |
813 | }; | 822 | }; |
814 | 823 | ||
824 | struct drm_i915_gem_exec_fence { | ||
825 | /** | ||
826 | * User's handle for a drm_syncobj to wait on or signal. | ||
827 | */ | ||
828 | __u32 handle; | ||
829 | |||
830 | #define I915_EXEC_FENCE_WAIT (1<<0) | ||
831 | #define I915_EXEC_FENCE_SIGNAL (1<<1) | ||
832 | __u32 flags; | ||
833 | }; | ||
834 | |||
815 | struct drm_i915_gem_execbuffer2 { | 835 | struct drm_i915_gem_execbuffer2 { |
816 | /** | 836 | /** |
817 | * List of gem_exec_object2 structs | 837 | * List of gem_exec_object2 structs |
@@ -826,7 +846,11 @@ struct drm_i915_gem_execbuffer2 { | |||
826 | __u32 DR1; | 846 | __u32 DR1; |
827 | __u32 DR4; | 847 | __u32 DR4; |
828 | __u32 num_cliprects; | 848 | __u32 num_cliprects; |
829 | /** This is a struct drm_clip_rect *cliprects */ | 849 | /** |
850 | * This is a struct drm_clip_rect *cliprects if I915_EXEC_FENCE_ARRAY | ||
851 | * is not set. If I915_EXEC_FENCE_ARRAY is set, then this is a | ||
852 | * struct drm_i915_gem_exec_fence *fences. | ||
853 | */ | ||
830 | __u64 cliprects_ptr; | 854 | __u64 cliprects_ptr; |
831 | #define I915_EXEC_RING_MASK (7<<0) | 855 | #define I915_EXEC_RING_MASK (7<<0) |
832 | #define I915_EXEC_DEFAULT (0<<0) | 856 | #define I915_EXEC_DEFAULT (0<<0) |
@@ -927,7 +951,14 @@ struct drm_i915_gem_execbuffer2 { | |||
927 | * element). | 951 | * element). |
928 | */ | 952 | */ |
929 | #define I915_EXEC_BATCH_FIRST (1<<18) | 953 | #define I915_EXEC_BATCH_FIRST (1<<18) |
930 | #define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_BATCH_FIRST<<1)) | 954 | |
955 | /* Setting I915_FENCE_ARRAY implies that num_cliprects and cliprects_ptr | ||
956 | * define an array of i915_gem_exec_fence structures which specify a set of | ||
957 | * dma fences to wait upon or signal. | ||
958 | */ | ||
959 | #define I915_EXEC_FENCE_ARRAY (1<<19) | ||
960 | |||
961 | #define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_ARRAY<<1)) | ||
931 | 962 | ||
932 | #define I915_EXEC_CONTEXT_ID_MASK (0xffffffff) | 963 | #define I915_EXEC_CONTEXT_ID_MASK (0xffffffff) |
933 | #define i915_execbuffer2_set_context_id(eb2, context) \ | 964 | #define i915_execbuffer2_set_context_id(eb2, context) \ |
@@ -1467,6 +1498,22 @@ enum drm_i915_perf_record_type { | |||
1467 | DRM_I915_PERF_RECORD_MAX /* non-ABI */ | 1498 | DRM_I915_PERF_RECORD_MAX /* non-ABI */ |
1468 | }; | 1499 | }; |
1469 | 1500 | ||
1501 | /** | ||
1502 | * Structure to upload perf dynamic configuration into the kernel. | ||
1503 | */ | ||
1504 | struct drm_i915_perf_oa_config { | ||
1505 | /** String formatted like "%08x-%04x-%04x-%04x-%012x" */ | ||
1506 | char uuid[36]; | ||
1507 | |||
1508 | __u32 n_mux_regs; | ||
1509 | __u32 n_boolean_regs; | ||
1510 | __u32 n_flex_regs; | ||
1511 | |||
1512 | __u64 __user mux_regs_ptr; | ||
1513 | __u64 __user boolean_regs_ptr; | ||
1514 | __u64 __user flex_regs_ptr; | ||
1515 | }; | ||
1516 | |||
1470 | #if defined(__cplusplus) | 1517 | #if defined(__cplusplus) |
1471 | } | 1518 | } |
1472 | #endif | 1519 | #endif |
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 461811e57140..24b35a1fd4d6 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h | |||
@@ -143,12 +143,6 @@ enum bpf_attach_type { | |||
143 | 143 | ||
144 | #define MAX_BPF_ATTACH_TYPE __MAX_BPF_ATTACH_TYPE | 144 | #define MAX_BPF_ATTACH_TYPE __MAX_BPF_ATTACH_TYPE |
145 | 145 | ||
146 | enum bpf_sockmap_flags { | ||
147 | BPF_SOCKMAP_UNSPEC, | ||
148 | BPF_SOCKMAP_STRPARSER, | ||
149 | __MAX_BPF_SOCKMAP_FLAG | ||
150 | }; | ||
151 | |||
152 | /* If BPF_F_ALLOW_OVERRIDE flag is used in BPF_PROG_ATTACH command | 146 | /* If BPF_F_ALLOW_OVERRIDE flag is used in BPF_PROG_ATTACH command |
153 | * to the given target_fd cgroup the descendent cgroup will be able to | 147 | * to the given target_fd cgroup the descendent cgroup will be able to |
154 | * override effective bpf program that was inherited from this cgroup | 148 | * override effective bpf program that was inherited from this cgroup |
@@ -318,7 +312,7 @@ union bpf_attr { | |||
318 | * jump into another BPF program | 312 | * jump into another BPF program |
319 | * @ctx: context pointer passed to next program | 313 | * @ctx: context pointer passed to next program |
320 | * @prog_array_map: pointer to map which type is BPF_MAP_TYPE_PROG_ARRAY | 314 | * @prog_array_map: pointer to map which type is BPF_MAP_TYPE_PROG_ARRAY |
321 | * @index: index inside array that selects specific program to run | 315 | * @index: 32-bit index inside array that selects specific program to run |
322 | * Return: 0 on success or negative error | 316 | * Return: 0 on success or negative error |
323 | * | 317 | * |
324 | * int bpf_clone_redirect(skb, ifindex, flags) | 318 | * int bpf_clone_redirect(skb, ifindex, flags) |
@@ -368,9 +362,20 @@ union bpf_attr { | |||
368 | * int bpf_redirect(ifindex, flags) | 362 | * int bpf_redirect(ifindex, flags) |
369 | * redirect to another netdev | 363 | * redirect to another netdev |
370 | * @ifindex: ifindex of the net device | 364 | * @ifindex: ifindex of the net device |
371 | * @flags: bit 0 - if set, redirect to ingress instead of egress | 365 | * @flags: |
372 | * other bits - reserved | 366 | * cls_bpf: |
373 | * Return: TC_ACT_REDIRECT | 367 | * bit 0 - if set, redirect to ingress instead of egress |
368 | * other bits - reserved | ||
369 | * xdp_bpf: | ||
370 | * all bits - reserved | ||
371 | * Return: cls_bpf: TC_ACT_REDIRECT on success or TC_ACT_SHOT on error | ||
372 | * xdp_bfp: XDP_REDIRECT on success or XDP_ABORT on error | ||
373 | * int bpf_redirect_map(map, key, flags) | ||
374 | * redirect to endpoint in map | ||
375 | * @map: pointer to dev map | ||
376 | * @key: index in map to lookup | ||
377 | * @flags: -- | ||
378 | * Return: XDP_REDIRECT on success or XDP_ABORT on error | ||
374 | * | 379 | * |
375 | * u32 bpf_get_route_realm(skb) | 380 | * u32 bpf_get_route_realm(skb) |
376 | * retrieve a dst's tclassid | 381 | * retrieve a dst's tclassid |
@@ -564,9 +569,10 @@ union bpf_attr { | |||
564 | * @flags: reserved for future use | 569 | * @flags: reserved for future use |
565 | * Return: 0 on success or negative error code | 570 | * Return: 0 on success or negative error code |
566 | * | 571 | * |
567 | * int bpf_sk_redirect_map(map, key, flags) | 572 | * int bpf_sk_redirect_map(skb, map, key, flags) |
568 | * Redirect skb to a sock in map using key as a lookup key for the | 573 | * Redirect skb to a sock in map using key as a lookup key for the |
569 | * sock in map. | 574 | * sock in map. |
575 | * @skb: pointer to skb | ||
570 | * @map: pointer to sockmap | 576 | * @map: pointer to sockmap |
571 | * @key: key to lookup sock in map | 577 | * @key: key to lookup sock in map |
572 | * @flags: reserved for future use | 578 | * @flags: reserved for future use |
@@ -632,7 +638,7 @@ union bpf_attr { | |||
632 | FN(skb_adjust_room), \ | 638 | FN(skb_adjust_room), \ |
633 | FN(redirect_map), \ | 639 | FN(redirect_map), \ |
634 | FN(sk_redirect_map), \ | 640 | FN(sk_redirect_map), \ |
635 | FN(sock_map_update), | 641 | FN(sock_map_update), \ |
636 | 642 | ||
637 | /* integer value in 'imm' field of BPF_CALL instruction selects which helper | 643 | /* integer value in 'imm' field of BPF_CALL instruction selects which helper |
638 | * function eBPF program intends to call | 644 | * function eBPF program intends to call |
@@ -753,20 +759,23 @@ struct bpf_sock { | |||
753 | __u32 family; | 759 | __u32 family; |
754 | __u32 type; | 760 | __u32 type; |
755 | __u32 protocol; | 761 | __u32 protocol; |
762 | __u32 mark; | ||
763 | __u32 priority; | ||
756 | }; | 764 | }; |
757 | 765 | ||
758 | #define XDP_PACKET_HEADROOM 256 | 766 | #define XDP_PACKET_HEADROOM 256 |
759 | 767 | ||
760 | /* User return codes for XDP prog type. | 768 | /* User return codes for XDP prog type. |
761 | * A valid XDP program must return one of these defined values. All other | 769 | * A valid XDP program must return one of these defined values. All other |
762 | * return codes are reserved for future use. Unknown return codes will result | 770 | * return codes are reserved for future use. Unknown return codes will |
763 | * in packet drop. | 771 | * result in packet drops and a warning via bpf_warn_invalid_xdp_action(). |
764 | */ | 772 | */ |
765 | enum xdp_action { | 773 | enum xdp_action { |
766 | XDP_ABORTED = 0, | 774 | XDP_ABORTED = 0, |
767 | XDP_DROP, | 775 | XDP_DROP, |
768 | XDP_PASS, | 776 | XDP_PASS, |
769 | XDP_TX, | 777 | XDP_TX, |
778 | XDP_REDIRECT, | ||
770 | }; | 779 | }; |
771 | 780 | ||
772 | /* user accessible metadata for XDP packet hook | 781 | /* user accessible metadata for XDP packet hook |
diff --git a/tools/include/uapi/linux/kvm.h b/tools/include/uapi/linux/kvm.h index 6cd63c18708a..838887587411 100644 --- a/tools/include/uapi/linux/kvm.h +++ b/tools/include/uapi/linux/kvm.h | |||
@@ -711,7 +711,8 @@ struct kvm_ppc_one_seg_page_size { | |||
711 | struct kvm_ppc_smmu_info { | 711 | struct kvm_ppc_smmu_info { |
712 | __u64 flags; | 712 | __u64 flags; |
713 | __u32 slb_size; | 713 | __u32 slb_size; |
714 | __u32 pad; | 714 | __u16 data_keys; /* # storage keys supported for data */ |
715 | __u16 instr_keys; /* # storage keys supported for instructions */ | ||
715 | struct kvm_ppc_one_seg_page_size sps[KVM_PPC_PAGE_SIZES_MAX_SZ]; | 716 | struct kvm_ppc_one_seg_page_size sps[KVM_PPC_PAGE_SIZES_MAX_SZ]; |
716 | }; | 717 | }; |
717 | 718 | ||
diff --git a/tools/include/uapi/linux/mman.h b/tools/include/uapi/linux/mman.h index 81d8edf11789..a937480d7cd3 100644 --- a/tools/include/uapi/linux/mman.h +++ b/tools/include/uapi/linux/mman.h | |||
@@ -1,7 +1,8 @@ | |||
1 | #ifndef _UAPI_LINUX_MMAN_H | 1 | #ifndef _UAPI_LINUX_MMAN_H |
2 | #define _UAPI_LINUX_MMAN_H | 2 | #define _UAPI_LINUX_MMAN_H |
3 | 3 | ||
4 | #include <uapi/asm/mman.h> | 4 | #include <asm/mman.h> |
5 | #include <asm-generic/hugetlb_encode.h> | ||
5 | 6 | ||
6 | #define MREMAP_MAYMOVE 1 | 7 | #define MREMAP_MAYMOVE 1 |
7 | #define MREMAP_FIXED 2 | 8 | #define MREMAP_FIXED 2 |
@@ -10,4 +11,25 @@ | |||
10 | #define OVERCOMMIT_ALWAYS 1 | 11 | #define OVERCOMMIT_ALWAYS 1 |
11 | #define OVERCOMMIT_NEVER 2 | 12 | #define OVERCOMMIT_NEVER 2 |
12 | 13 | ||
14 | /* | ||
15 | * Huge page size encoding when MAP_HUGETLB is specified, and a huge page | ||
16 | * size other than the default is desired. See hugetlb_encode.h. | ||
17 | * All known huge page size encodings are provided here. It is the | ||
18 | * responsibility of the application to know which sizes are supported on | ||
19 | * the running system. See mmap(2) man page for details. | ||
20 | */ | ||
21 | #define MAP_HUGE_SHIFT HUGETLB_FLAG_ENCODE_SHIFT | ||
22 | #define MAP_HUGE_MASK HUGETLB_FLAG_ENCODE_MASK | ||
23 | |||
24 | #define MAP_HUGE_64KB HUGETLB_FLAG_ENCODE_64KB | ||
25 | #define MAP_HUGE_512KB HUGETLB_FLAG_ENCODE_512KB | ||
26 | #define MAP_HUGE_1MB HUGETLB_FLAG_ENCODE_1MB | ||
27 | #define MAP_HUGE_2MB HUGETLB_FLAG_ENCODE_2MB | ||
28 | #define MAP_HUGE_8MB HUGETLB_FLAG_ENCODE_8MB | ||
29 | #define MAP_HUGE_16MB HUGETLB_FLAG_ENCODE_16MB | ||
30 | #define MAP_HUGE_256MB HUGETLB_FLAG_ENCODE_256MB | ||
31 | #define MAP_HUGE_1GB HUGETLB_FLAG_ENCODE_1GB | ||
32 | #define MAP_HUGE_2GB HUGETLB_FLAG_ENCODE_2GB | ||
33 | #define MAP_HUGE_16GB HUGETLB_FLAG_ENCODE_16GB | ||
34 | |||
13 | #endif /* _UAPI_LINUX_MMAN_H */ | 35 | #endif /* _UAPI_LINUX_MMAN_H */ |
diff --git a/tools/objtool/Documentation/stack-validation.txt b/tools/objtool/Documentation/stack-validation.txt index 6a1af43862df..3995735a878f 100644 --- a/tools/objtool/Documentation/stack-validation.txt +++ b/tools/objtool/Documentation/stack-validation.txt | |||
@@ -194,10 +194,10 @@ they mean, and suggestions for how to fix them. | |||
194 | If it's a GCC-compiled .c file, the error may be because the function | 194 | If it's a GCC-compiled .c file, the error may be because the function |
195 | uses an inline asm() statement which has a "call" instruction. An | 195 | uses an inline asm() statement which has a "call" instruction. An |
196 | asm() statement with a call instruction must declare the use of the | 196 | asm() statement with a call instruction must declare the use of the |
197 | stack pointer in its output operand. For example, on x86_64: | 197 | stack pointer in its output operand. On x86_64, this means adding |
198 | the ASM_CALL_CONSTRAINT as an output constraint: | ||
198 | 199 | ||
199 | register void *__sp asm("rsp"); | 200 | asm volatile("call func" : ASM_CALL_CONSTRAINT); |
200 | asm volatile("call func" : "+r" (__sp)); | ||
201 | 201 | ||
202 | Otherwise the stack frame may not get created before the call. | 202 | Otherwise the stack frame may not get created before the call. |
203 | 203 | ||
diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c index 0e8c8ec4fd4e..34a579f806e3 100644 --- a/tools/objtool/arch/x86/decode.c +++ b/tools/objtool/arch/x86/decode.c | |||
@@ -208,14 +208,14 @@ int arch_decode_instruction(struct elf *elf, struct section *sec, | |||
208 | break; | 208 | break; |
209 | 209 | ||
210 | case 0x89: | 210 | case 0x89: |
211 | if (rex == 0x48 && modrm == 0xe5) { | 211 | if (rex_w && !rex_r && modrm_mod == 3 && modrm_reg == 4) { |
212 | 212 | ||
213 | /* mov %rsp, %rbp */ | 213 | /* mov %rsp, reg */ |
214 | *type = INSN_STACK; | 214 | *type = INSN_STACK; |
215 | op->src.type = OP_SRC_REG; | 215 | op->src.type = OP_SRC_REG; |
216 | op->src.reg = CFI_SP; | 216 | op->src.reg = CFI_SP; |
217 | op->dest.type = OP_DEST_REG; | 217 | op->dest.type = OP_DEST_REG; |
218 | op->dest.reg = CFI_BP; | 218 | op->dest.reg = op_to_cfi_reg[modrm_rm][rex_b]; |
219 | break; | 219 | break; |
220 | } | 220 | } |
221 | 221 | ||
@@ -284,11 +284,16 @@ int arch_decode_instruction(struct elf *elf, struct section *sec, | |||
284 | case 0x8d: | 284 | case 0x8d: |
285 | if (sib == 0x24 && rex_w && !rex_b && !rex_x) { | 285 | if (sib == 0x24 && rex_w && !rex_b && !rex_x) { |
286 | 286 | ||
287 | /* lea disp(%rsp), reg */ | ||
288 | *type = INSN_STACK; | 287 | *type = INSN_STACK; |
289 | op->src.type = OP_SRC_ADD; | 288 | if (!insn.displacement.value) { |
289 | /* lea (%rsp), reg */ | ||
290 | op->src.type = OP_SRC_REG; | ||
291 | } else { | ||
292 | /* lea disp(%rsp), reg */ | ||
293 | op->src.type = OP_SRC_ADD; | ||
294 | op->src.offset = insn.displacement.value; | ||
295 | } | ||
290 | op->src.reg = CFI_SP; | 296 | op->src.reg = CFI_SP; |
291 | op->src.offset = insn.displacement.value; | ||
292 | op->dest.type = OP_DEST_REG; | 297 | op->dest.type = OP_DEST_REG; |
293 | op->dest.reg = op_to_cfi_reg[modrm_reg][rex_r]; | 298 | op->dest.reg = op_to_cfi_reg[modrm_reg][rex_r]; |
294 | 299 | ||
diff --git a/tools/objtool/check.c b/tools/objtool/check.c index f744617c9946..c0e26ad1fa7e 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c | |||
@@ -267,12 +267,13 @@ static int decode_instructions(struct objtool_file *file) | |||
267 | &insn->immediate, | 267 | &insn->immediate, |
268 | &insn->stack_op); | 268 | &insn->stack_op); |
269 | if (ret) | 269 | if (ret) |
270 | return ret; | 270 | goto err; |
271 | 271 | ||
272 | if (!insn->type || insn->type > INSN_LAST) { | 272 | if (!insn->type || insn->type > INSN_LAST) { |
273 | WARN_FUNC("invalid instruction type %d", | 273 | WARN_FUNC("invalid instruction type %d", |
274 | insn->sec, insn->offset, insn->type); | 274 | insn->sec, insn->offset, insn->type); |
275 | return -1; | 275 | ret = -1; |
276 | goto err; | ||
276 | } | 277 | } |
277 | 278 | ||
278 | hash_add(file->insn_hash, &insn->hash, insn->offset); | 279 | hash_add(file->insn_hash, &insn->hash, insn->offset); |
@@ -296,6 +297,10 @@ static int decode_instructions(struct objtool_file *file) | |||
296 | } | 297 | } |
297 | 298 | ||
298 | return 0; | 299 | return 0; |
300 | |||
301 | err: | ||
302 | free(insn); | ||
303 | return ret; | ||
299 | } | 304 | } |
300 | 305 | ||
301 | /* | 306 | /* |
@@ -1203,24 +1208,39 @@ static int update_insn_state(struct instruction *insn, struct insn_state *state) | |||
1203 | switch (op->src.type) { | 1208 | switch (op->src.type) { |
1204 | 1209 | ||
1205 | case OP_SRC_REG: | 1210 | case OP_SRC_REG: |
1206 | if (op->src.reg == CFI_SP && op->dest.reg == CFI_BP) { | 1211 | if (op->src.reg == CFI_SP && op->dest.reg == CFI_BP && |
1212 | cfa->base == CFI_SP && | ||
1213 | regs[CFI_BP].base == CFI_CFA && | ||
1214 | regs[CFI_BP].offset == -cfa->offset) { | ||
1215 | |||
1216 | /* mov %rsp, %rbp */ | ||
1217 | cfa->base = op->dest.reg; | ||
1218 | state->bp_scratch = false; | ||
1219 | } | ||
1207 | 1220 | ||
1208 | if (cfa->base == CFI_SP && | 1221 | else if (op->src.reg == CFI_SP && |
1209 | regs[CFI_BP].base == CFI_CFA && | 1222 | op->dest.reg == CFI_BP && state->drap) { |
1210 | regs[CFI_BP].offset == -cfa->offset) { | ||
1211 | 1223 | ||
1212 | /* mov %rsp, %rbp */ | 1224 | /* drap: mov %rsp, %rbp */ |
1213 | cfa->base = op->dest.reg; | 1225 | regs[CFI_BP].base = CFI_BP; |
1214 | state->bp_scratch = false; | 1226 | regs[CFI_BP].offset = -state->stack_size; |
1215 | } | 1227 | state->bp_scratch = false; |
1228 | } | ||
1216 | 1229 | ||
1217 | else if (state->drap) { | 1230 | else if (op->src.reg == CFI_SP && cfa->base == CFI_SP) { |
1218 | 1231 | ||
1219 | /* drap: mov %rsp, %rbp */ | 1232 | /* |
1220 | regs[CFI_BP].base = CFI_BP; | 1233 | * mov %rsp, %reg |
1221 | regs[CFI_BP].offset = -state->stack_size; | 1234 | * |
1222 | state->bp_scratch = false; | 1235 | * This is needed for the rare case where GCC |
1223 | } | 1236 | * does: |
1237 | * | ||
1238 | * mov %rsp, %rax | ||
1239 | * ... | ||
1240 | * mov %rax, %rsp | ||
1241 | */ | ||
1242 | state->vals[op->dest.reg].base = CFI_CFA; | ||
1243 | state->vals[op->dest.reg].offset = -state->stack_size; | ||
1224 | } | 1244 | } |
1225 | 1245 | ||
1226 | else if (op->dest.reg == cfa->base) { | 1246 | else if (op->dest.reg == cfa->base) { |
diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index 6e9f980a7d26..24460155c82c 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c | |||
@@ -175,19 +175,20 @@ static int read_sections(struct elf *elf) | |||
175 | return -1; | 175 | return -1; |
176 | } | 176 | } |
177 | 177 | ||
178 | sec->data = elf_getdata(s, NULL); | 178 | if (sec->sh.sh_size != 0) { |
179 | if (!sec->data) { | 179 | sec->data = elf_getdata(s, NULL); |
180 | WARN_ELF("elf_getdata"); | 180 | if (!sec->data) { |
181 | return -1; | 181 | WARN_ELF("elf_getdata"); |
182 | } | 182 | return -1; |
183 | 183 | } | |
184 | if (sec->data->d_off != 0 || | 184 | if (sec->data->d_off != 0 || |
185 | sec->data->d_size != sec->sh.sh_size) { | 185 | sec->data->d_size != sec->sh.sh_size) { |
186 | WARN("unexpected data attributes for %s", sec->name); | 186 | WARN("unexpected data attributes for %s", |
187 | return -1; | 187 | sec->name); |
188 | return -1; | ||
189 | } | ||
188 | } | 190 | } |
189 | 191 | sec->len = sec->sh.sh_size; | |
190 | sec->len = sec->data->d_size; | ||
191 | } | 192 | } |
192 | 193 | ||
193 | /* sanity check, one more call to elf_nextscn() should return NULL */ | 194 | /* sanity check, one more call to elf_nextscn() should return NULL */ |
@@ -508,6 +509,7 @@ struct section *elf_create_rela_section(struct elf *elf, struct section *base) | |||
508 | strcat(relaname, base->name); | 509 | strcat(relaname, base->name); |
509 | 510 | ||
510 | sec = elf_create_section(elf, relaname, sizeof(GElf_Rela), 0); | 511 | sec = elf_create_section(elf, relaname, sizeof(GElf_Rela), 0); |
512 | free(relaname); | ||
511 | if (!sec) | 513 | if (!sec) |
512 | return NULL; | 514 | return NULL; |
513 | 515 | ||
@@ -561,6 +563,7 @@ int elf_write(struct elf *elf) | |||
561 | struct section *sec; | 563 | struct section *sec; |
562 | Elf_Scn *s; | 564 | Elf_Scn *s; |
563 | 565 | ||
566 | /* Update section headers for changed sections: */ | ||
564 | list_for_each_entry(sec, &elf->sections, list) { | 567 | list_for_each_entry(sec, &elf->sections, list) { |
565 | if (sec->changed) { | 568 | if (sec->changed) { |
566 | s = elf_getscn(elf->elf, sec->idx); | 569 | s = elf_getscn(elf->elf, sec->idx); |
@@ -568,13 +571,17 @@ int elf_write(struct elf *elf) | |||
568 | WARN_ELF("elf_getscn"); | 571 | WARN_ELF("elf_getscn"); |
569 | return -1; | 572 | return -1; |
570 | } | 573 | } |
571 | if (!gelf_update_shdr (s, &sec->sh)) { | 574 | if (!gelf_update_shdr(s, &sec->sh)) { |
572 | WARN_ELF("gelf_update_shdr"); | 575 | WARN_ELF("gelf_update_shdr"); |
573 | return -1; | 576 | return -1; |
574 | } | 577 | } |
575 | } | 578 | } |
576 | } | 579 | } |
577 | 580 | ||
581 | /* Make sure the new section header entries get updated properly. */ | ||
582 | elf_flagelf(elf->elf, ELF_C_SET, ELF_F_DIRTY); | ||
583 | |||
584 | /* Write all changes to the file. */ | ||
578 | if (elf_update(elf->elf, ELF_C_WRITE) < 0) { | 585 | if (elf_update(elf->elf, ELF_C_WRITE) < 0) { |
579 | WARN_ELF("elf_update"); | 586 | WARN_ELF("elf_update"); |
580 | return -1; | 587 | return -1; |
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index e397453e5a46..63526f4416ea 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt | |||
@@ -8,8 +8,8 @@ perf-record - Run a command and record its profile into perf.data | |||
8 | SYNOPSIS | 8 | SYNOPSIS |
9 | -------- | 9 | -------- |
10 | [verse] | 10 | [verse] |
11 | 'perf record' [-e <EVENT> | --event=EVENT] [-l] [-a] <command> | 11 | 'perf record' [-e <EVENT> | --event=EVENT] [-a] <command> |
12 | 'perf record' [-e <EVENT> | --event=EVENT] [-l] [-a] -- <command> [<options>] | 12 | 'perf record' [-e <EVENT> | --event=EVENT] [-a] -- <command> [<options>] |
13 | 13 | ||
14 | DESCRIPTION | 14 | DESCRIPTION |
15 | ----------- | 15 | ----------- |
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST index 62072822dc85..627b7cada144 100644 --- a/tools/perf/MANIFEST +++ b/tools/perf/MANIFEST | |||
@@ -1,34 +1,8 @@ | |||
1 | tools/perf | 1 | tools/perf |
2 | tools/arch/alpha/include/asm/barrier.h | 2 | tools/arch |
3 | tools/arch/arm/include/asm/barrier.h | ||
4 | tools/arch/arm64/include/asm/barrier.h | ||
5 | tools/arch/ia64/include/asm/barrier.h | ||
6 | tools/arch/mips/include/asm/barrier.h | ||
7 | tools/arch/powerpc/include/asm/barrier.h | ||
8 | tools/arch/s390/include/asm/barrier.h | ||
9 | tools/arch/sh/include/asm/barrier.h | ||
10 | tools/arch/sparc/include/asm/barrier.h | ||
11 | tools/arch/sparc/include/asm/barrier_32.h | ||
12 | tools/arch/sparc/include/asm/barrier_64.h | ||
13 | tools/arch/tile/include/asm/barrier.h | ||
14 | tools/arch/x86/include/asm/barrier.h | ||
15 | tools/arch/x86/include/asm/cmpxchg.h | ||
16 | tools/arch/x86/include/asm/cpufeatures.h | ||
17 | tools/arch/x86/include/asm/disabled-features.h | ||
18 | tools/arch/x86/include/asm/required-features.h | ||
19 | tools/arch/x86/include/uapi/asm/svm.h | ||
20 | tools/arch/x86/include/uapi/asm/vmx.h | ||
21 | tools/arch/x86/include/uapi/asm/kvm.h | ||
22 | tools/arch/x86/include/uapi/asm/kvm_perf.h | ||
23 | tools/arch/x86/lib/memcpy_64.S | ||
24 | tools/arch/x86/lib/memset_64.S | ||
25 | tools/arch/s390/include/uapi/asm/kvm_perf.h | ||
26 | tools/arch/s390/include/uapi/asm/sie.h | ||
27 | tools/arch/xtensa/include/asm/barrier.h | ||
28 | tools/scripts | 3 | tools/scripts |
29 | tools/build | 4 | tools/build |
30 | tools/arch/x86/include/asm/atomic.h | 5 | tools/include |
31 | tools/arch/x86/include/asm/rmwcc.h | ||
32 | tools/lib/traceevent | 6 | tools/lib/traceevent |
33 | tools/lib/api | 7 | tools/lib/api |
34 | tools/lib/bpf | 8 | tools/lib/bpf |
@@ -42,60 +16,3 @@ tools/lib/find_bit.c | |||
42 | tools/lib/bitmap.c | 16 | tools/lib/bitmap.c |
43 | tools/lib/str_error_r.c | 17 | tools/lib/str_error_r.c |
44 | tools/lib/vsprintf.c | 18 | tools/lib/vsprintf.c |
45 | tools/include/asm/alternative-asm.h | ||
46 | tools/include/asm/atomic.h | ||
47 | tools/include/asm/barrier.h | ||
48 | tools/include/asm/bug.h | ||
49 | tools/include/asm-generic/atomic-gcc.h | ||
50 | tools/include/asm-generic/barrier.h | ||
51 | tools/include/asm-generic/bitops/arch_hweight.h | ||
52 | tools/include/asm-generic/bitops/atomic.h | ||
53 | tools/include/asm-generic/bitops/const_hweight.h | ||
54 | tools/include/asm-generic/bitops/__ffs.h | ||
55 | tools/include/asm-generic/bitops/__ffz.h | ||
56 | tools/include/asm-generic/bitops/__fls.h | ||
57 | tools/include/asm-generic/bitops/find.h | ||
58 | tools/include/asm-generic/bitops/fls64.h | ||
59 | tools/include/asm-generic/bitops/fls.h | ||
60 | tools/include/asm-generic/bitops/hweight.h | ||
61 | tools/include/asm-generic/bitops.h | ||
62 | tools/include/linux/atomic.h | ||
63 | tools/include/linux/bitops.h | ||
64 | tools/include/linux/compiler.h | ||
65 | tools/include/linux/compiler-gcc.h | ||
66 | tools/include/linux/coresight-pmu.h | ||
67 | tools/include/linux/bug.h | ||
68 | tools/include/linux/filter.h | ||
69 | tools/include/linux/hash.h | ||
70 | tools/include/linux/kernel.h | ||
71 | tools/include/linux/list.h | ||
72 | tools/include/linux/log2.h | ||
73 | tools/include/uapi/asm-generic/fcntl.h | ||
74 | tools/include/uapi/asm-generic/ioctls.h | ||
75 | tools/include/uapi/asm-generic/mman-common.h | ||
76 | tools/include/uapi/asm-generic/mman.h | ||
77 | tools/include/uapi/drm/drm.h | ||
78 | tools/include/uapi/drm/i915_drm.h | ||
79 | tools/include/uapi/linux/bpf.h | ||
80 | tools/include/uapi/linux/bpf_common.h | ||
81 | tools/include/uapi/linux/fcntl.h | ||
82 | tools/include/uapi/linux/hw_breakpoint.h | ||
83 | tools/include/uapi/linux/kvm.h | ||
84 | tools/include/uapi/linux/mman.h | ||
85 | tools/include/uapi/linux/perf_event.h | ||
86 | tools/include/uapi/linux/sched.h | ||
87 | tools/include/uapi/linux/stat.h | ||
88 | tools/include/uapi/linux/vhost.h | ||
89 | tools/include/uapi/sound/asound.h | ||
90 | tools/include/linux/poison.h | ||
91 | tools/include/linux/rbtree.h | ||
92 | tools/include/linux/rbtree_augmented.h | ||
93 | tools/include/linux/refcount.h | ||
94 | tools/include/linux/string.h | ||
95 | tools/include/linux/stringify.h | ||
96 | tools/include/linux/types.h | ||
97 | tools/include/linux/err.h | ||
98 | tools/include/linux/bitmap.h | ||
99 | tools/include/linux/time64.h | ||
100 | tools/arch/*/include/uapi/asm/mman.h | ||
101 | tools/arch/*/include/uapi/asm/perf_regs.h | ||
diff --git a/tools/perf/arch/s390/util/Build b/tools/perf/arch/s390/util/Build index bd518b623d7a..5bd7b9260cc0 100644 --- a/tools/perf/arch/s390/util/Build +++ b/tools/perf/arch/s390/util/Build | |||
@@ -1,5 +1,4 @@ | |||
1 | libperf-y += header.o | 1 | libperf-y += header.o |
2 | libperf-y += sym-handling.o | ||
3 | libperf-y += kvm-stat.o | 2 | libperf-y += kvm-stat.o |
4 | 3 | ||
5 | libperf-$(CONFIG_DWARF) += dwarf-regs.o | 4 | libperf-$(CONFIG_DWARF) += dwarf-regs.o |
diff --git a/tools/perf/arch/s390/util/sym-handling.c b/tools/perf/arch/s390/util/sym-handling.c deleted file mode 100644 index e103f6e46afe..000000000000 --- a/tools/perf/arch/s390/util/sym-handling.c +++ /dev/null | |||
@@ -1,29 +0,0 @@ | |||
1 | /* | ||
2 | * Architecture specific ELF symbol handling and relocation mapping. | ||
3 | * | ||
4 | * Copyright 2017 IBM Corp. | ||
5 | * Author(s): Thomas Richter <tmricht@linux.vnet.ibm.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License (version 2 only) | ||
9 | * as published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include "symbol.h" | ||
13 | |||
14 | #ifdef HAVE_LIBELF_SUPPORT | ||
15 | bool elf__needs_adjust_symbols(GElf_Ehdr ehdr) | ||
16 | { | ||
17 | if (ehdr.e_type == ET_EXEC) | ||
18 | return false; | ||
19 | return ehdr.e_type == ET_REL || ehdr.e_type == ET_DYN; | ||
20 | } | ||
21 | |||
22 | void arch__adjust_sym_map_offset(GElf_Sym *sym, | ||
23 | GElf_Shdr *shdr __maybe_unused, | ||
24 | struct map *map) | ||
25 | { | ||
26 | if (map->type == MAP__FUNCTION) | ||
27 | sym->st_value += map->start; | ||
28 | } | ||
29 | #endif | ||
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 3d4c3b5e1868..0c977b6e0f8b 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c | |||
@@ -586,7 +586,7 @@ static void print_sample_brstack(struct perf_sample *sample, | |||
586 | thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, to, &alt); | 586 | thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, to, &alt); |
587 | } | 587 | } |
588 | 588 | ||
589 | printf("0x%"PRIx64, from); | 589 | printf(" 0x%"PRIx64, from); |
590 | if (PRINT_FIELD(DSO)) { | 590 | if (PRINT_FIELD(DSO)) { |
591 | printf("("); | 591 | printf("("); |
592 | map__fprintf_dsoname(alf.map, stdout); | 592 | map__fprintf_dsoname(alf.map, stdout); |
@@ -681,7 +681,7 @@ static void print_sample_brstackoff(struct perf_sample *sample, | |||
681 | if (alt.map && !alt.map->dso->adjust_symbols) | 681 | if (alt.map && !alt.map->dso->adjust_symbols) |
682 | to = map__map_ip(alt.map, to); | 682 | to = map__map_ip(alt.map, to); |
683 | 683 | ||
684 | printf("0x%"PRIx64, from); | 684 | printf(" 0x%"PRIx64, from); |
685 | if (PRINT_FIELD(DSO)) { | 685 | if (PRINT_FIELD(DSO)) { |
686 | printf("("); | 686 | printf("("); |
687 | map__fprintf_dsoname(alf.map, stdout); | 687 | map__fprintf_dsoname(alf.map, stdout); |
diff --git a/tools/perf/tests/shell/trace+probe_libc_inet_pton.sh b/tools/perf/tests/shell/trace+probe_libc_inet_pton.sh index 462fc755092e..7a84d73324e3 100755 --- a/tools/perf/tests/shell/trace+probe_libc_inet_pton.sh +++ b/tools/perf/tests/shell/trace+probe_libc_inet_pton.sh | |||
@@ -10,6 +10,9 @@ | |||
10 | 10 | ||
11 | . $(dirname $0)/lib/probe.sh | 11 | . $(dirname $0)/lib/probe.sh |
12 | 12 | ||
13 | ld=$(realpath /lib64/ld*.so.* | uniq) | ||
14 | libc=$(echo $ld | sed 's/ld/libc/g') | ||
15 | |||
13 | trace_libc_inet_pton_backtrace() { | 16 | trace_libc_inet_pton_backtrace() { |
14 | idx=0 | 17 | idx=0 |
15 | expected[0]="PING.*bytes" | 18 | expected[0]="PING.*bytes" |
@@ -18,8 +21,8 @@ trace_libc_inet_pton_backtrace() { | |||
18 | expected[3]=".*packets transmitted.*" | 21 | expected[3]=".*packets transmitted.*" |
19 | expected[4]="rtt min.*" | 22 | expected[4]="rtt min.*" |
20 | expected[5]="[0-9]+\.[0-9]+[[:space:]]+probe_libc:inet_pton:\([[:xdigit:]]+\)" | 23 | expected[5]="[0-9]+\.[0-9]+[[:space:]]+probe_libc:inet_pton:\([[:xdigit:]]+\)" |
21 | expected[6]=".*inet_pton[[:space:]]\(/usr/lib.*/libc-[0-9]+\.[0-9]+\.so\)$" | 24 | expected[6]=".*inet_pton[[:space:]]\($libc\)$" |
22 | expected[7]="getaddrinfo[[:space:]]\(/usr/lib.*/libc-[0-9]+\.[0-9]+\.so\)$" | 25 | expected[7]="getaddrinfo[[:space:]]\($libc\)$" |
23 | expected[8]=".*\(.*/bin/ping.*\)$" | 26 | expected[8]=".*\(.*/bin/ping.*\)$" |
24 | 27 | ||
25 | perf trace --no-syscalls -e probe_libc:inet_pton/max-stack=3/ ping -6 -c 1 ::1 2>&1 | grep -v ^$ | while read line ; do | 28 | perf trace --no-syscalls -e probe_libc:inet_pton/max-stack=3/ ping -6 -c 1 ::1 2>&1 | grep -v ^$ | while read line ; do |
@@ -35,7 +38,7 @@ trace_libc_inet_pton_backtrace() { | |||
35 | } | 38 | } |
36 | 39 | ||
37 | skip_if_no_perf_probe && \ | 40 | skip_if_no_perf_probe && \ |
38 | perf probe -q /lib64/libc-*.so inet_pton && \ | 41 | perf probe -q $libc inet_pton && \ |
39 | trace_libc_inet_pton_backtrace | 42 | trace_libc_inet_pton_backtrace |
40 | err=$? | 43 | err=$? |
41 | rm -f ${file} | 44 | rm -f ${file} |
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index ddb2c6fbdf91..db79017a6e56 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c | |||
@@ -532,7 +532,7 @@ void perf_hpp_list__prepend_sort_field(struct perf_hpp_list *list, | |||
532 | 532 | ||
533 | void perf_hpp__column_unregister(struct perf_hpp_fmt *format) | 533 | void perf_hpp__column_unregister(struct perf_hpp_fmt *format) |
534 | { | 534 | { |
535 | list_del(&format->list); | 535 | list_del_init(&format->list); |
536 | } | 536 | } |
537 | 537 | ||
538 | void perf_hpp__cancel_cumulate(void) | 538 | void perf_hpp__cancel_cumulate(void) |
@@ -606,6 +606,13 @@ next: | |||
606 | 606 | ||
607 | static void fmt_free(struct perf_hpp_fmt *fmt) | 607 | static void fmt_free(struct perf_hpp_fmt *fmt) |
608 | { | 608 | { |
609 | /* | ||
610 | * At this point fmt should be completely | ||
611 | * unhooked, if not it's a bug. | ||
612 | */ | ||
613 | BUG_ON(!list_empty(&fmt->list)); | ||
614 | BUG_ON(!list_empty(&fmt->sort_list)); | ||
615 | |||
609 | if (fmt->free) | 616 | if (fmt->free) |
610 | fmt->free(fmt); | 617 | fmt->free(fmt); |
611 | } | 618 | } |
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 510b513e0f01..a971caf3759d 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c | |||
@@ -65,8 +65,6 @@ static int parse_callchain_mode(const char *value) | |||
65 | callchain_param.mode = CHAIN_FOLDED; | 65 | callchain_param.mode = CHAIN_FOLDED; |
66 | return 0; | 66 | return 0; |
67 | } | 67 | } |
68 | |||
69 | pr_err("Invalid callchain mode: %s\n", value); | ||
70 | return -1; | 68 | return -1; |
71 | } | 69 | } |
72 | 70 | ||
@@ -82,8 +80,6 @@ static int parse_callchain_order(const char *value) | |||
82 | callchain_param.order_set = true; | 80 | callchain_param.order_set = true; |
83 | return 0; | 81 | return 0; |
84 | } | 82 | } |
85 | |||
86 | pr_err("Invalid callchain order: %s\n", value); | ||
87 | return -1; | 83 | return -1; |
88 | } | 84 | } |
89 | 85 | ||
@@ -105,8 +101,6 @@ static int parse_callchain_sort_key(const char *value) | |||
105 | callchain_param.branch_callstack = 1; | 101 | callchain_param.branch_callstack = 1; |
106 | return 0; | 102 | return 0; |
107 | } | 103 | } |
108 | |||
109 | pr_err("Invalid callchain sort key: %s\n", value); | ||
110 | return -1; | 104 | return -1; |
111 | } | 105 | } |
112 | 106 | ||
@@ -124,8 +118,6 @@ static int parse_callchain_value(const char *value) | |||
124 | callchain_param.value = CCVAL_COUNT; | 118 | callchain_param.value = CCVAL_COUNT; |
125 | return 0; | 119 | return 0; |
126 | } | 120 | } |
127 | |||
128 | pr_err("Invalid callchain config key: %s\n", value); | ||
129 | return -1; | 121 | return -1; |
130 | } | 122 | } |
131 | 123 | ||
@@ -319,12 +311,27 @@ int perf_callchain_config(const char *var, const char *value) | |||
319 | 311 | ||
320 | return ret; | 312 | return ret; |
321 | } | 313 | } |
322 | if (!strcmp(var, "print-type")) | 314 | if (!strcmp(var, "print-type")){ |
323 | return parse_callchain_mode(value); | 315 | int ret; |
324 | if (!strcmp(var, "order")) | 316 | ret = parse_callchain_mode(value); |
325 | return parse_callchain_order(value); | 317 | if (ret == -1) |
326 | if (!strcmp(var, "sort-key")) | 318 | pr_err("Invalid callchain mode: %s\n", value); |
327 | return parse_callchain_sort_key(value); | 319 | return ret; |
320 | } | ||
321 | if (!strcmp(var, "order")){ | ||
322 | int ret; | ||
323 | ret = parse_callchain_order(value); | ||
324 | if (ret == -1) | ||
325 | pr_err("Invalid callchain order: %s\n", value); | ||
326 | return ret; | ||
327 | } | ||
328 | if (!strcmp(var, "sort-key")){ | ||
329 | int ret; | ||
330 | ret = parse_callchain_sort_key(value); | ||
331 | if (ret == -1) | ||
332 | pr_err("Invalid callchain sort key: %s\n", value); | ||
333 | return ret; | ||
334 | } | ||
328 | if (!strcmp(var, "threshold")) { | 335 | if (!strcmp(var, "threshold")) { |
329 | callchain_param.min_percent = strtod(value, &endptr); | 336 | callchain_param.min_percent = strtod(value, &endptr); |
330 | if (value == endptr) { | 337 | if (value == endptr) { |
@@ -678,6 +685,8 @@ static enum match_result match_chain(struct callchain_cursor_node *node, | |||
678 | { | 685 | { |
679 | struct symbol *sym = node->sym; | 686 | struct symbol *sym = node->sym; |
680 | u64 left, right; | 687 | u64 left, right; |
688 | struct dso *left_dso = NULL; | ||
689 | struct dso *right_dso = NULL; | ||
681 | 690 | ||
682 | if (callchain_param.key == CCKEY_SRCLINE) { | 691 | if (callchain_param.key == CCKEY_SRCLINE) { |
683 | enum match_result match = match_chain_srcline(node, cnode); | 692 | enum match_result match = match_chain_srcline(node, cnode); |
@@ -689,12 +698,14 @@ static enum match_result match_chain(struct callchain_cursor_node *node, | |||
689 | if (cnode->ms.sym && sym && callchain_param.key == CCKEY_FUNCTION) { | 698 | if (cnode->ms.sym && sym && callchain_param.key == CCKEY_FUNCTION) { |
690 | left = cnode->ms.sym->start; | 699 | left = cnode->ms.sym->start; |
691 | right = sym->start; | 700 | right = sym->start; |
701 | left_dso = cnode->ms.map->dso; | ||
702 | right_dso = node->map->dso; | ||
692 | } else { | 703 | } else { |
693 | left = cnode->ip; | 704 | left = cnode->ip; |
694 | right = node->ip; | 705 | right = node->ip; |
695 | } | 706 | } |
696 | 707 | ||
697 | if (left == right) { | 708 | if (left == right && left_dso == right_dso) { |
698 | if (node->branch) { | 709 | if (node->branch) { |
699 | cnode->branch_count++; | 710 | cnode->branch_count++; |
700 | 711 | ||
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 4bb89373eb52..0dccdb89572c 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -271,12 +271,17 @@ struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx) | |||
271 | return evsel; | 271 | return evsel; |
272 | } | 272 | } |
273 | 273 | ||
274 | static bool perf_event_can_profile_kernel(void) | ||
275 | { | ||
276 | return geteuid() == 0 || perf_event_paranoid() == -1; | ||
277 | } | ||
278 | |||
274 | struct perf_evsel *perf_evsel__new_cycles(bool precise) | 279 | struct perf_evsel *perf_evsel__new_cycles(bool precise) |
275 | { | 280 | { |
276 | struct perf_event_attr attr = { | 281 | struct perf_event_attr attr = { |
277 | .type = PERF_TYPE_HARDWARE, | 282 | .type = PERF_TYPE_HARDWARE, |
278 | .config = PERF_COUNT_HW_CPU_CYCLES, | 283 | .config = PERF_COUNT_HW_CPU_CYCLES, |
279 | .exclude_kernel = geteuid() != 0, | 284 | .exclude_kernel = !perf_event_can_profile_kernel(), |
280 | }; | 285 | }; |
281 | struct perf_evsel *evsel; | 286 | struct perf_evsel *evsel; |
282 | 287 | ||
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index f6257fb4f08c..39b15968eab1 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
@@ -309,10 +309,11 @@ static char *get_config_name(struct list_head *head_terms) | |||
309 | static struct perf_evsel * | 309 | static struct perf_evsel * |
310 | __add_event(struct list_head *list, int *idx, | 310 | __add_event(struct list_head *list, int *idx, |
311 | struct perf_event_attr *attr, | 311 | struct perf_event_attr *attr, |
312 | char *name, struct cpu_map *cpus, | 312 | char *name, struct perf_pmu *pmu, |
313 | struct list_head *config_terms, bool auto_merge_stats) | 313 | struct list_head *config_terms, bool auto_merge_stats) |
314 | { | 314 | { |
315 | struct perf_evsel *evsel; | 315 | struct perf_evsel *evsel; |
316 | struct cpu_map *cpus = pmu ? pmu->cpus : NULL; | ||
316 | 317 | ||
317 | event_attr_init(attr); | 318 | event_attr_init(attr); |
318 | 319 | ||
@@ -323,7 +324,7 @@ __add_event(struct list_head *list, int *idx, | |||
323 | (*idx)++; | 324 | (*idx)++; |
324 | evsel->cpus = cpu_map__get(cpus); | 325 | evsel->cpus = cpu_map__get(cpus); |
325 | evsel->own_cpus = cpu_map__get(cpus); | 326 | evsel->own_cpus = cpu_map__get(cpus); |
326 | evsel->system_wide = !!cpus; | 327 | evsel->system_wide = pmu ? pmu->is_uncore : false; |
327 | evsel->auto_merge_stats = auto_merge_stats; | 328 | evsel->auto_merge_stats = auto_merge_stats; |
328 | 329 | ||
329 | if (name) | 330 | if (name) |
@@ -1233,7 +1234,7 @@ static int __parse_events_add_pmu(struct parse_events_state *parse_state, | |||
1233 | 1234 | ||
1234 | if (!head_config) { | 1235 | if (!head_config) { |
1235 | attr.type = pmu->type; | 1236 | attr.type = pmu->type; |
1236 | evsel = __add_event(list, &parse_state->idx, &attr, NULL, pmu->cpus, NULL, auto_merge_stats); | 1237 | evsel = __add_event(list, &parse_state->idx, &attr, NULL, pmu, NULL, auto_merge_stats); |
1237 | return evsel ? 0 : -ENOMEM; | 1238 | return evsel ? 0 : -ENOMEM; |
1238 | } | 1239 | } |
1239 | 1240 | ||
@@ -1254,7 +1255,7 @@ static int __parse_events_add_pmu(struct parse_events_state *parse_state, | |||
1254 | return -EINVAL; | 1255 | return -EINVAL; |
1255 | 1256 | ||
1256 | evsel = __add_event(list, &parse_state->idx, &attr, | 1257 | evsel = __add_event(list, &parse_state->idx, &attr, |
1257 | get_config_name(head_config), pmu->cpus, | 1258 | get_config_name(head_config), pmu, |
1258 | &config_terms, auto_merge_stats); | 1259 | &config_terms, auto_merge_stats); |
1259 | if (evsel) { | 1260 | if (evsel) { |
1260 | evsel->unit = info.unit; | 1261 | evsel->unit = info.unit; |
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l index c42edeac451f..dcfdafdc2f1c 100644 --- a/tools/perf/util/parse-events.l +++ b/tools/perf/util/parse-events.l | |||
@@ -8,6 +8,9 @@ | |||
8 | 8 | ||
9 | %{ | 9 | %{ |
10 | #include <errno.h> | 10 | #include <errno.h> |
11 | #include <sys/types.h> | ||
12 | #include <sys/stat.h> | ||
13 | #include <unistd.h> | ||
11 | #include "../perf.h" | 14 | #include "../perf.h" |
12 | #include "parse-events.h" | 15 | #include "parse-events.h" |
13 | #include "parse-events-bison.h" | 16 | #include "parse-events-bison.h" |
@@ -53,9 +56,8 @@ static int str(yyscan_t scanner, int token) | |||
53 | return token; | 56 | return token; |
54 | } | 57 | } |
55 | 58 | ||
56 | static bool isbpf(yyscan_t scanner) | 59 | static bool isbpf_suffix(char *text) |
57 | { | 60 | { |
58 | char *text = parse_events_get_text(scanner); | ||
59 | int len = strlen(text); | 61 | int len = strlen(text); |
60 | 62 | ||
61 | if (len < 2) | 63 | if (len < 2) |
@@ -68,6 +70,17 @@ static bool isbpf(yyscan_t scanner) | |||
68 | return false; | 70 | return false; |
69 | } | 71 | } |
70 | 72 | ||
73 | static bool isbpf(yyscan_t scanner) | ||
74 | { | ||
75 | char *text = parse_events_get_text(scanner); | ||
76 | struct stat st; | ||
77 | |||
78 | if (!isbpf_suffix(text)) | ||
79 | return false; | ||
80 | |||
81 | return stat(text, &st) == 0; | ||
82 | } | ||
83 | |||
71 | /* | 84 | /* |
72 | * This function is called when the parser gets two kind of input: | 85 | * This function is called when the parser gets two kind of input: |
73 | * | 86 | * |
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index ac16a9db1fb5..1c4d7b4e4fb5 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c | |||
@@ -470,17 +470,36 @@ static void pmu_read_sysfs(void) | |||
470 | closedir(dir); | 470 | closedir(dir); |
471 | } | 471 | } |
472 | 472 | ||
473 | static struct cpu_map *__pmu_cpumask(const char *path) | ||
474 | { | ||
475 | FILE *file; | ||
476 | struct cpu_map *cpus; | ||
477 | |||
478 | file = fopen(path, "r"); | ||
479 | if (!file) | ||
480 | return NULL; | ||
481 | |||
482 | cpus = cpu_map__read(file); | ||
483 | fclose(file); | ||
484 | return cpus; | ||
485 | } | ||
486 | |||
487 | /* | ||
488 | * Uncore PMUs have a "cpumask" file under sysfs. CPU PMUs (e.g. on arm/arm64) | ||
489 | * may have a "cpus" file. | ||
490 | */ | ||
491 | #define CPUS_TEMPLATE_UNCORE "%s/bus/event_source/devices/%s/cpumask" | ||
492 | #define CPUS_TEMPLATE_CPU "%s/bus/event_source/devices/%s/cpus" | ||
493 | |||
473 | static struct cpu_map *pmu_cpumask(const char *name) | 494 | static struct cpu_map *pmu_cpumask(const char *name) |
474 | { | 495 | { |
475 | struct stat st; | ||
476 | char path[PATH_MAX]; | 496 | char path[PATH_MAX]; |
477 | FILE *file; | ||
478 | struct cpu_map *cpus; | 497 | struct cpu_map *cpus; |
479 | const char *sysfs = sysfs__mountpoint(); | 498 | const char *sysfs = sysfs__mountpoint(); |
480 | const char *templates[] = { | 499 | const char *templates[] = { |
481 | "%s/bus/event_source/devices/%s/cpumask", | 500 | CPUS_TEMPLATE_UNCORE, |
482 | "%s/bus/event_source/devices/%s/cpus", | 501 | CPUS_TEMPLATE_CPU, |
483 | NULL | 502 | NULL |
484 | }; | 503 | }; |
485 | const char **template; | 504 | const char **template; |
486 | 505 | ||
@@ -489,20 +508,25 @@ static struct cpu_map *pmu_cpumask(const char *name) | |||
489 | 508 | ||
490 | for (template = templates; *template; template++) { | 509 | for (template = templates; *template; template++) { |
491 | snprintf(path, PATH_MAX, *template, sysfs, name); | 510 | snprintf(path, PATH_MAX, *template, sysfs, name); |
492 | if (stat(path, &st) == 0) | 511 | cpus = __pmu_cpumask(path); |
493 | break; | 512 | if (cpus) |
513 | return cpus; | ||
494 | } | 514 | } |
495 | 515 | ||
496 | if (!*template) | 516 | return NULL; |
497 | return NULL; | 517 | } |
498 | 518 | ||
499 | file = fopen(path, "r"); | 519 | static bool pmu_is_uncore(const char *name) |
500 | if (!file) | 520 | { |
501 | return NULL; | 521 | char path[PATH_MAX]; |
522 | struct cpu_map *cpus; | ||
523 | const char *sysfs = sysfs__mountpoint(); | ||
502 | 524 | ||
503 | cpus = cpu_map__read(file); | 525 | snprintf(path, PATH_MAX, CPUS_TEMPLATE_UNCORE, sysfs, name); |
504 | fclose(file); | 526 | cpus = __pmu_cpumask(path); |
505 | return cpus; | 527 | cpu_map__put(cpus); |
528 | |||
529 | return !!cpus; | ||
506 | } | 530 | } |
507 | 531 | ||
508 | /* | 532 | /* |
@@ -617,6 +641,8 @@ static struct perf_pmu *pmu_lookup(const char *name) | |||
617 | 641 | ||
618 | pmu->cpus = pmu_cpumask(name); | 642 | pmu->cpus = pmu_cpumask(name); |
619 | 643 | ||
644 | pmu->is_uncore = pmu_is_uncore(name); | ||
645 | |||
620 | INIT_LIST_HEAD(&pmu->format); | 646 | INIT_LIST_HEAD(&pmu->format); |
621 | INIT_LIST_HEAD(&pmu->aliases); | 647 | INIT_LIST_HEAD(&pmu->aliases); |
622 | list_splice(&format, &pmu->format); | 648 | list_splice(&format, &pmu->format); |
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 389e9729331f..fe0de0502ce2 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h | |||
@@ -22,6 +22,7 @@ struct perf_pmu { | |||
22 | char *name; | 22 | char *name; |
23 | __u32 type; | 23 | __u32 type; |
24 | bool selectable; | 24 | bool selectable; |
25 | bool is_uncore; | ||
25 | struct perf_event_attr *default_config; | 26 | struct perf_event_attr *default_config; |
26 | struct cpu_map *cpus; | 27 | struct cpu_map *cpus; |
27 | struct list_head format; /* HEAD struct perf_pmu_format -> list */ | 28 | struct list_head format; /* HEAD struct perf_pmu_format -> list */ |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index a7ebd9fe8e40..76ab0709a20c 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -374,6 +374,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool) | |||
374 | tool->mmap2 = process_event_stub; | 374 | tool->mmap2 = process_event_stub; |
375 | if (tool->comm == NULL) | 375 | if (tool->comm == NULL) |
376 | tool->comm = process_event_stub; | 376 | tool->comm = process_event_stub; |
377 | if (tool->namespaces == NULL) | ||
378 | tool->namespaces = process_event_stub; | ||
377 | if (tool->fork == NULL) | 379 | if (tool->fork == NULL) |
378 | tool->fork = process_event_stub; | 380 | tool->fork = process_event_stub; |
379 | if (tool->exit == NULL) | 381 | if (tool->exit == NULL) |
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 5c39f420111e..9cf781f0d8a2 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c | |||
@@ -810,12 +810,6 @@ static u64 ref_reloc(struct kmap *kmap) | |||
810 | void __weak arch__sym_update(struct symbol *s __maybe_unused, | 810 | void __weak arch__sym_update(struct symbol *s __maybe_unused, |
811 | GElf_Sym *sym __maybe_unused) { } | 811 | GElf_Sym *sym __maybe_unused) { } |
812 | 812 | ||
813 | void __weak arch__adjust_sym_map_offset(GElf_Sym *sym, GElf_Shdr *shdr, | ||
814 | struct map *map __maybe_unused) | ||
815 | { | ||
816 | sym->st_value -= shdr->sh_addr - shdr->sh_offset; | ||
817 | } | ||
818 | |||
819 | int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, | 813 | int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, |
820 | struct symsrc *runtime_ss, int kmodule) | 814 | struct symsrc *runtime_ss, int kmodule) |
821 | { | 815 | { |
@@ -996,7 +990,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, | |||
996 | 990 | ||
997 | /* Adjust symbol to map to file offset */ | 991 | /* Adjust symbol to map to file offset */ |
998 | if (adjust_kernel_syms) | 992 | if (adjust_kernel_syms) |
999 | arch__adjust_sym_map_offset(&sym, &shdr, map); | 993 | sym.st_value -= shdr.sh_addr - shdr.sh_offset; |
1000 | 994 | ||
1001 | if (strcmp(section_name, | 995 | if (strcmp(section_name, |
1002 | (curr_dso->short_name + | 996 | (curr_dso->short_name + |
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 2bd6a1f01a1c..aad99e7e179b 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
@@ -344,9 +344,6 @@ int setup_intlist(struct intlist **list, const char *list_str, | |||
344 | #ifdef HAVE_LIBELF_SUPPORT | 344 | #ifdef HAVE_LIBELF_SUPPORT |
345 | bool elf__needs_adjust_symbols(GElf_Ehdr ehdr); | 345 | bool elf__needs_adjust_symbols(GElf_Ehdr ehdr); |
346 | void arch__sym_update(struct symbol *s, GElf_Sym *sym); | 346 | void arch__sym_update(struct symbol *s, GElf_Sym *sym); |
347 | void arch__adjust_sym_map_offset(GElf_Sym *sym, | ||
348 | GElf_Shdr *shdr __maybe_unused, | ||
349 | struct map *map __maybe_unused); | ||
350 | #endif | 347 | #endif |
351 | 348 | ||
352 | #define SYMBOL_A 0 | 349 | #define SYMBOL_A 0 |
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c index 19e5db90394c..6eea7cff3d4e 100644 --- a/tools/perf/util/syscalltbl.c +++ b/tools/perf/util/syscalltbl.c | |||
@@ -15,9 +15,9 @@ | |||
15 | 15 | ||
16 | #include "syscalltbl.h" | 16 | #include "syscalltbl.h" |
17 | #include <stdlib.h> | 17 | #include <stdlib.h> |
18 | #include <linux/compiler.h> | ||
18 | 19 | ||
19 | #ifdef HAVE_SYSCALL_TABLE | 20 | #ifdef HAVE_SYSCALL_TABLE |
20 | #include <linux/compiler.h> | ||
21 | #include <string.h> | 21 | #include <string.h> |
22 | #include "string2.h" | 22 | #include "string2.h" |
23 | #include "util.h" | 23 | #include "util.h" |
diff --git a/tools/perf/util/xyarray.h b/tools/perf/util/xyarray.h index 4ba726c90870..54af60462130 100644 --- a/tools/perf/util/xyarray.h +++ b/tools/perf/util/xyarray.h | |||
@@ -23,12 +23,12 @@ static inline void *xyarray__entry(struct xyarray *xy, int x, int y) | |||
23 | 23 | ||
24 | static inline int xyarray__max_y(struct xyarray *xy) | 24 | static inline int xyarray__max_y(struct xyarray *xy) |
25 | { | 25 | { |
26 | return xy->max_x; | 26 | return xy->max_y; |
27 | } | 27 | } |
28 | 28 | ||
29 | static inline int xyarray__max_x(struct xyarray *xy) | 29 | static inline int xyarray__max_x(struct xyarray *xy) |
30 | { | 30 | { |
31 | return xy->max_y; | 31 | return xy->max_x; |
32 | } | 32 | } |
33 | 33 | ||
34 | #endif /* _PERF_XYARRAY_H_ */ | 34 | #endif /* _PERF_XYARRAY_H_ */ |
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 0dafba2c1e7d..bd9c6b31a504 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c | |||
@@ -92,7 +92,6 @@ unsigned int do_ring_perf_limit_reasons; | |||
92 | unsigned int crystal_hz; | 92 | unsigned int crystal_hz; |
93 | unsigned long long tsc_hz; | 93 | unsigned long long tsc_hz; |
94 | int base_cpu; | 94 | int base_cpu; |
95 | int do_migrate; | ||
96 | double discover_bclk(unsigned int family, unsigned int model); | 95 | double discover_bclk(unsigned int family, unsigned int model); |
97 | unsigned int has_hwp; /* IA32_PM_ENABLE, IA32_HWP_CAPABILITIES */ | 96 | unsigned int has_hwp; /* IA32_PM_ENABLE, IA32_HWP_CAPABILITIES */ |
98 | /* IA32_HWP_REQUEST, IA32_HWP_STATUS */ | 97 | /* IA32_HWP_REQUEST, IA32_HWP_STATUS */ |
@@ -303,9 +302,6 @@ int for_all_cpus(int (func)(struct thread_data *, struct core_data *, struct pkg | |||
303 | 302 | ||
304 | int cpu_migrate(int cpu) | 303 | int cpu_migrate(int cpu) |
305 | { | 304 | { |
306 | if (!do_migrate) | ||
307 | return 0; | ||
308 | |||
309 | CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set); | 305 | CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set); |
310 | CPU_SET_S(cpu, cpu_affinity_setsize, cpu_affinity_set); | 306 | CPU_SET_S(cpu, cpu_affinity_setsize, cpu_affinity_set); |
311 | if (sched_setaffinity(0, cpu_affinity_setsize, cpu_affinity_set) == -1) | 307 | if (sched_setaffinity(0, cpu_affinity_setsize, cpu_affinity_set) == -1) |
@@ -5007,7 +5003,6 @@ void cmdline(int argc, char **argv) | |||
5007 | {"hide", required_argument, 0, 'H'}, // meh, -h taken by --help | 5003 | {"hide", required_argument, 0, 'H'}, // meh, -h taken by --help |
5008 | {"Joules", no_argument, 0, 'J'}, | 5004 | {"Joules", no_argument, 0, 'J'}, |
5009 | {"list", no_argument, 0, 'l'}, | 5005 | {"list", no_argument, 0, 'l'}, |
5010 | {"migrate", no_argument, 0, 'm'}, | ||
5011 | {"out", required_argument, 0, 'o'}, | 5006 | {"out", required_argument, 0, 'o'}, |
5012 | {"quiet", no_argument, 0, 'q'}, | 5007 | {"quiet", no_argument, 0, 'q'}, |
5013 | {"show", required_argument, 0, 's'}, | 5008 | {"show", required_argument, 0, 's'}, |
@@ -5019,7 +5014,7 @@ void cmdline(int argc, char **argv) | |||
5019 | 5014 | ||
5020 | progname = argv[0]; | 5015 | progname = argv[0]; |
5021 | 5016 | ||
5022 | while ((opt = getopt_long_only(argc, argv, "+C:c:Ddhi:Jmo:qST:v", | 5017 | while ((opt = getopt_long_only(argc, argv, "+C:c:Ddhi:JM:m:o:qST:v", |
5023 | long_options, &option_index)) != -1) { | 5018 | long_options, &option_index)) != -1) { |
5024 | switch (opt) { | 5019 | switch (opt) { |
5025 | case 'a': | 5020 | case 'a': |
@@ -5062,9 +5057,6 @@ void cmdline(int argc, char **argv) | |||
5062 | list_header_only++; | 5057 | list_header_only++; |
5063 | quiet++; | 5058 | quiet++; |
5064 | break; | 5059 | break; |
5065 | case 'm': | ||
5066 | do_migrate = 1; | ||
5067 | break; | ||
5068 | case 'o': | 5060 | case 'o': |
5069 | outf = fopen_or_die(optarg, "w"); | 5061 | outf = fopen_or_die(optarg, "w"); |
5070 | break; | 5062 | break; |
diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c index d20791c3f499..bef419d4266d 100644 --- a/tools/testing/nvdimm/test/nfit.c +++ b/tools/testing/nvdimm/test/nfit.c | |||
@@ -1527,9 +1527,6 @@ static void nfit_test1_setup(struct nfit_test *t) | |||
1527 | set_bit(ND_CMD_ARS_START, &acpi_desc->bus_cmd_force_en); | 1527 | set_bit(ND_CMD_ARS_START, &acpi_desc->bus_cmd_force_en); |
1528 | set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_cmd_force_en); | 1528 | set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_cmd_force_en); |
1529 | set_bit(ND_CMD_CLEAR_ERROR, &acpi_desc->bus_cmd_force_en); | 1529 | set_bit(ND_CMD_CLEAR_ERROR, &acpi_desc->bus_cmd_force_en); |
1530 | set_bit(ND_CMD_GET_CONFIG_SIZE, &acpi_desc->dimm_cmd_force_en); | ||
1531 | set_bit(ND_CMD_GET_CONFIG_DATA, &acpi_desc->dimm_cmd_force_en); | ||
1532 | set_bit(ND_CMD_SET_CONFIG_DATA, &acpi_desc->dimm_cmd_force_en); | ||
1533 | } | 1530 | } |
1534 | 1531 | ||
1535 | static int nfit_test_blk_do_io(struct nd_blk_region *ndbr, resource_size_t dpa, | 1532 | static int nfit_test_blk_do_io(struct nd_blk_region *ndbr, resource_size_t dpa, |
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index 26ce4f7168be..ff805643b5f7 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile | |||
@@ -52,6 +52,10 @@ override LDFLAGS = | |||
52 | override MAKEFLAGS = | 52 | override MAKEFLAGS = |
53 | endif | 53 | endif |
54 | 54 | ||
55 | ifneq ($(KBUILD_SRC),) | ||
56 | override LDFLAGS = | ||
57 | endif | ||
58 | |||
55 | BUILD := $(O) | 59 | BUILD := $(O) |
56 | ifndef BUILD | 60 | ifndef BUILD |
57 | BUILD := $(KBUILD_OUTPUT) | 61 | BUILD := $(KBUILD_OUTPUT) |
@@ -62,32 +66,32 @@ endif | |||
62 | 66 | ||
63 | export BUILD | 67 | export BUILD |
64 | all: | 68 | all: |
65 | for TARGET in $(TARGETS); do \ | 69 | @for TARGET in $(TARGETS); do \ |
66 | BUILD_TARGET=$$BUILD/$$TARGET; \ | 70 | BUILD_TARGET=$$BUILD/$$TARGET; \ |
67 | mkdir $$BUILD_TARGET -p; \ | 71 | mkdir $$BUILD_TARGET -p; \ |
68 | make OUTPUT=$$BUILD_TARGET -C $$TARGET;\ | 72 | make OUTPUT=$$BUILD_TARGET -C $$TARGET;\ |
69 | done; | 73 | done; |
70 | 74 | ||
71 | run_tests: all | 75 | run_tests: all |
72 | for TARGET in $(TARGETS); do \ | 76 | @for TARGET in $(TARGETS); do \ |
73 | BUILD_TARGET=$$BUILD/$$TARGET; \ | 77 | BUILD_TARGET=$$BUILD/$$TARGET; \ |
74 | make OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests;\ | 78 | make OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests;\ |
75 | done; | 79 | done; |
76 | 80 | ||
77 | hotplug: | 81 | hotplug: |
78 | for TARGET in $(TARGETS_HOTPLUG); do \ | 82 | @for TARGET in $(TARGETS_HOTPLUG); do \ |
79 | BUILD_TARGET=$$BUILD/$$TARGET; \ | 83 | BUILD_TARGET=$$BUILD/$$TARGET; \ |
80 | make OUTPUT=$$BUILD_TARGET -C $$TARGET;\ | 84 | make OUTPUT=$$BUILD_TARGET -C $$TARGET;\ |
81 | done; | 85 | done; |
82 | 86 | ||
83 | run_hotplug: hotplug | 87 | run_hotplug: hotplug |
84 | for TARGET in $(TARGETS_HOTPLUG); do \ | 88 | @for TARGET in $(TARGETS_HOTPLUG); do \ |
85 | BUILD_TARGET=$$BUILD/$$TARGET; \ | 89 | BUILD_TARGET=$$BUILD/$$TARGET; \ |
86 | make OUTPUT=$$BUILD_TARGET -C $$TARGET run_full_test;\ | 90 | make OUTPUT=$$BUILD_TARGET -C $$TARGET run_full_test;\ |
87 | done; | 91 | done; |
88 | 92 | ||
89 | clean_hotplug: | 93 | clean_hotplug: |
90 | for TARGET in $(TARGETS_HOTPLUG); do \ | 94 | @for TARGET in $(TARGETS_HOTPLUG); do \ |
91 | BUILD_TARGET=$$BUILD/$$TARGET; \ | 95 | BUILD_TARGET=$$BUILD/$$TARGET; \ |
92 | make OUTPUT=$$BUILD_TARGET -C $$TARGET clean;\ | 96 | make OUTPUT=$$BUILD_TARGET -C $$TARGET clean;\ |
93 | done; | 97 | done; |
@@ -103,7 +107,7 @@ install: | |||
103 | ifdef INSTALL_PATH | 107 | ifdef INSTALL_PATH |
104 | @# Ask all targets to install their files | 108 | @# Ask all targets to install their files |
105 | mkdir -p $(INSTALL_PATH) | 109 | mkdir -p $(INSTALL_PATH) |
106 | for TARGET in $(TARGETS); do \ | 110 | @for TARGET in $(TARGETS); do \ |
107 | BUILD_TARGET=$$BUILD/$$TARGET; \ | 111 | BUILD_TARGET=$$BUILD/$$TARGET; \ |
108 | make OUTPUT=$$BUILD_TARGET -C $$TARGET INSTALL_PATH=$(INSTALL_PATH)/$$TARGET install; \ | 112 | make OUTPUT=$$BUILD_TARGET -C $$TARGET INSTALL_PATH=$(INSTALL_PATH)/$$TARGET install; \ |
109 | done; | 113 | done; |
@@ -128,7 +132,7 @@ else | |||
128 | endif | 132 | endif |
129 | 133 | ||
130 | clean: | 134 | clean: |
131 | for TARGET in $(TARGETS); do \ | 135 | @for TARGET in $(TARGETS); do \ |
132 | BUILD_TARGET=$$BUILD/$$TARGET; \ | 136 | BUILD_TARGET=$$BUILD/$$TARGET; \ |
133 | make OUTPUT=$$BUILD_TARGET -C $$TARGET clean;\ | 137 | make OUTPUT=$$BUILD_TARGET -C $$TARGET clean;\ |
134 | done; | 138 | done; |
diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h index 36fb9161b34a..b2e02bdcd098 100644 --- a/tools/testing/selftests/bpf/bpf_helpers.h +++ b/tools/testing/selftests/bpf/bpf_helpers.h | |||
@@ -65,7 +65,7 @@ static int (*bpf_xdp_adjust_head)(void *ctx, int offset) = | |||
65 | static int (*bpf_setsockopt)(void *ctx, int level, int optname, void *optval, | 65 | static int (*bpf_setsockopt)(void *ctx, int level, int optname, void *optval, |
66 | int optlen) = | 66 | int optlen) = |
67 | (void *) BPF_FUNC_setsockopt; | 67 | (void *) BPF_FUNC_setsockopt; |
68 | static int (*bpf_sk_redirect_map)(void *map, int key, int flags) = | 68 | static int (*bpf_sk_redirect_map)(void *ctx, void *map, int key, int flags) = |
69 | (void *) BPF_FUNC_sk_redirect_map; | 69 | (void *) BPF_FUNC_sk_redirect_map; |
70 | static int (*bpf_sock_map_update)(void *map, void *key, void *value, | 70 | static int (*bpf_sock_map_update)(void *map, void *key, void *value, |
71 | unsigned long long flags) = | 71 | unsigned long long flags) = |
diff --git a/tools/testing/selftests/bpf/bpf_util.h b/tools/testing/selftests/bpf/bpf_util.h index 20ecbaa0d85d..6c53a8906eff 100644 --- a/tools/testing/selftests/bpf/bpf_util.h +++ b/tools/testing/selftests/bpf/bpf_util.h | |||
@@ -12,6 +12,7 @@ static inline unsigned int bpf_num_possible_cpus(void) | |||
12 | unsigned int start, end, possible_cpus = 0; | 12 | unsigned int start, end, possible_cpus = 0; |
13 | char buff[128]; | 13 | char buff[128]; |
14 | FILE *fp; | 14 | FILE *fp; |
15 | int n; | ||
15 | 16 | ||
16 | fp = fopen(fcpu, "r"); | 17 | fp = fopen(fcpu, "r"); |
17 | if (!fp) { | 18 | if (!fp) { |
@@ -20,17 +21,17 @@ static inline unsigned int bpf_num_possible_cpus(void) | |||
20 | } | 21 | } |
21 | 22 | ||
22 | while (fgets(buff, sizeof(buff), fp)) { | 23 | while (fgets(buff, sizeof(buff), fp)) { |
23 | if (sscanf(buff, "%u-%u", &start, &end) == 2) { | 24 | n = sscanf(buff, "%u-%u", &start, &end); |
24 | possible_cpus = start == 0 ? end + 1 : 0; | 25 | if (n == 0) { |
25 | break; | 26 | printf("Failed to retrieve # possible CPUs!\n"); |
27 | exit(1); | ||
28 | } else if (n == 1) { | ||
29 | end = start; | ||
26 | } | 30 | } |
31 | possible_cpus = start == 0 ? end + 1 : 0; | ||
32 | break; | ||
27 | } | 33 | } |
28 | |||
29 | fclose(fp); | 34 | fclose(fp); |
30 | if (!possible_cpus) { | ||
31 | printf("Failed to retrieve # possible CPUs!\n"); | ||
32 | exit(1); | ||
33 | } | ||
34 | 35 | ||
35 | return possible_cpus; | 36 | return possible_cpus; |
36 | } | 37 | } |
diff --git a/tools/testing/selftests/bpf/sockmap_verdict_prog.c b/tools/testing/selftests/bpf/sockmap_verdict_prog.c index 9b99bd10807d..2cd2d552938b 100644 --- a/tools/testing/selftests/bpf/sockmap_verdict_prog.c +++ b/tools/testing/selftests/bpf/sockmap_verdict_prog.c | |||
@@ -61,8 +61,8 @@ int bpf_prog2(struct __sk_buff *skb) | |||
61 | bpf_printk("verdict: data[0] = redir(%u:%u)\n", map, sk); | 61 | bpf_printk("verdict: data[0] = redir(%u:%u)\n", map, sk); |
62 | 62 | ||
63 | if (!map) | 63 | if (!map) |
64 | return bpf_sk_redirect_map(&sock_map_rx, sk, 0); | 64 | return bpf_sk_redirect_map(skb, &sock_map_rx, sk, 0); |
65 | return bpf_sk_redirect_map(&sock_map_tx, sk, 0); | 65 | return bpf_sk_redirect_map(skb, &sock_map_tx, sk, 0); |
66 | } | 66 | } |
67 | 67 | ||
68 | char _license[] SEC("license") = "GPL"; | 68 | char _license[] SEC("license") = "GPL"; |
diff --git a/tools/testing/selftests/bpf/test_maps.c b/tools/testing/selftests/bpf/test_maps.c index fe3a443a1102..50ce52d2013d 100644 --- a/tools/testing/selftests/bpf/test_maps.c +++ b/tools/testing/selftests/bpf/test_maps.c | |||
@@ -466,7 +466,7 @@ static void test_sockmap(int tasks, void *data) | |||
466 | int one = 1, map_fd_rx, map_fd_tx, map_fd_break, s, sc, rc; | 466 | int one = 1, map_fd_rx, map_fd_tx, map_fd_break, s, sc, rc; |
467 | struct bpf_map *bpf_map_rx, *bpf_map_tx, *bpf_map_break; | 467 | struct bpf_map *bpf_map_rx, *bpf_map_tx, *bpf_map_break; |
468 | int ports[] = {50200, 50201, 50202, 50204}; | 468 | int ports[] = {50200, 50201, 50202, 50204}; |
469 | int err, i, fd, sfd[6] = {0xdeadbeef}; | 469 | int err, i, fd, udp, sfd[6] = {0xdeadbeef}; |
470 | u8 buf[20] = {0x0, 0x5, 0x3, 0x2, 0x1, 0x0}; | 470 | u8 buf[20] = {0x0, 0x5, 0x3, 0x2, 0x1, 0x0}; |
471 | int parse_prog, verdict_prog; | 471 | int parse_prog, verdict_prog; |
472 | struct sockaddr_in addr; | 472 | struct sockaddr_in addr; |
@@ -548,6 +548,16 @@ static void test_sockmap(int tasks, void *data) | |||
548 | goto out_sockmap; | 548 | goto out_sockmap; |
549 | } | 549 | } |
550 | 550 | ||
551 | /* Test update with unsupported UDP socket */ | ||
552 | udp = socket(AF_INET, SOCK_DGRAM, 0); | ||
553 | i = 0; | ||
554 | err = bpf_map_update_elem(fd, &i, &udp, BPF_ANY); | ||
555 | if (!err) { | ||
556 | printf("Failed socket SOCK_DGRAM allowed '%i:%i'\n", | ||
557 | i, udp); | ||
558 | goto out_sockmap; | ||
559 | } | ||
560 | |||
551 | /* Test update without programs */ | 561 | /* Test update without programs */ |
552 | for (i = 0; i < 6; i++) { | 562 | for (i = 0; i < 6; i++) { |
553 | err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY); | 563 | err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY); |
diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c index 26f3250bdcd2..64ae21f64489 100644 --- a/tools/testing/selftests/bpf/test_verifier.c +++ b/tools/testing/selftests/bpf/test_verifier.c | |||
@@ -1130,15 +1130,27 @@ static struct bpf_test tests[] = { | |||
1130 | .errstr = "invalid bpf_context access", | 1130 | .errstr = "invalid bpf_context access", |
1131 | }, | 1131 | }, |
1132 | { | 1132 | { |
1133 | "check skb->mark is writeable by SK_SKB", | 1133 | "invalid access of skb->mark for SK_SKB", |
1134 | .insns = { | ||
1135 | BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, | ||
1136 | offsetof(struct __sk_buff, mark)), | ||
1137 | BPF_EXIT_INSN(), | ||
1138 | }, | ||
1139 | .result = REJECT, | ||
1140 | .prog_type = BPF_PROG_TYPE_SK_SKB, | ||
1141 | .errstr = "invalid bpf_context access", | ||
1142 | }, | ||
1143 | { | ||
1144 | "check skb->mark is not writeable by SK_SKB", | ||
1134 | .insns = { | 1145 | .insns = { |
1135 | BPF_MOV64_IMM(BPF_REG_0, 0), | 1146 | BPF_MOV64_IMM(BPF_REG_0, 0), |
1136 | BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, | 1147 | BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, |
1137 | offsetof(struct __sk_buff, mark)), | 1148 | offsetof(struct __sk_buff, mark)), |
1138 | BPF_EXIT_INSN(), | 1149 | BPF_EXIT_INSN(), |
1139 | }, | 1150 | }, |
1140 | .result = ACCEPT, | 1151 | .result = REJECT, |
1141 | .prog_type = BPF_PROG_TYPE_SK_SKB, | 1152 | .prog_type = BPF_PROG_TYPE_SK_SKB, |
1153 | .errstr = "invalid bpf_context access", | ||
1142 | }, | 1154 | }, |
1143 | { | 1155 | { |
1144 | "check skb->tc_index is writeable by SK_SKB", | 1156 | "check skb->tc_index is writeable by SK_SKB", |
@@ -6645,6 +6657,500 @@ static struct bpf_test tests[] = { | |||
6645 | .errstr = "BPF_END uses reserved fields", | 6657 | .errstr = "BPF_END uses reserved fields", |
6646 | .result = REJECT, | 6658 | .result = REJECT, |
6647 | }, | 6659 | }, |
6660 | { | ||
6661 | "arithmetic ops make PTR_TO_CTX unusable", | ||
6662 | .insns = { | ||
6663 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, | ||
6664 | offsetof(struct __sk_buff, data) - | ||
6665 | offsetof(struct __sk_buff, mark)), | ||
6666 | BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, | ||
6667 | offsetof(struct __sk_buff, mark)), | ||
6668 | BPF_EXIT_INSN(), | ||
6669 | }, | ||
6670 | .errstr = "dereference of modified ctx ptr R1 off=68+8, ctx+const is allowed, ctx+const+const is not", | ||
6671 | .result = REJECT, | ||
6672 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | ||
6673 | }, | ||
6674 | { | ||
6675 | "XDP pkt read, pkt_end mangling, bad access 1", | ||
6676 | .insns = { | ||
6677 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
6678 | offsetof(struct xdp_md, data)), | ||
6679 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
6680 | offsetof(struct xdp_md, data_end)), | ||
6681 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
6682 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
6683 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 8), | ||
6684 | BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1), | ||
6685 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), | ||
6686 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
6687 | BPF_EXIT_INSN(), | ||
6688 | }, | ||
6689 | .errstr = "R1 offset is outside of the packet", | ||
6690 | .result = REJECT, | ||
6691 | .prog_type = BPF_PROG_TYPE_XDP, | ||
6692 | }, | ||
6693 | { | ||
6694 | "XDP pkt read, pkt_end mangling, bad access 2", | ||
6695 | .insns = { | ||
6696 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
6697 | offsetof(struct xdp_md, data)), | ||
6698 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
6699 | offsetof(struct xdp_md, data_end)), | ||
6700 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
6701 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
6702 | BPF_ALU64_IMM(BPF_SUB, BPF_REG_3, 8), | ||
6703 | BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1), | ||
6704 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), | ||
6705 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
6706 | BPF_EXIT_INSN(), | ||
6707 | }, | ||
6708 | .errstr = "R1 offset is outside of the packet", | ||
6709 | .result = REJECT, | ||
6710 | .prog_type = BPF_PROG_TYPE_XDP, | ||
6711 | }, | ||
6712 | { | ||
6713 | "XDP pkt read, pkt_data' > pkt_end, good access", | ||
6714 | .insns = { | ||
6715 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
6716 | offsetof(struct xdp_md, data)), | ||
6717 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
6718 | offsetof(struct xdp_md, data_end)), | ||
6719 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
6720 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
6721 | BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1), | ||
6722 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), | ||
6723 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
6724 | BPF_EXIT_INSN(), | ||
6725 | }, | ||
6726 | .result = ACCEPT, | ||
6727 | .prog_type = BPF_PROG_TYPE_XDP, | ||
6728 | }, | ||
6729 | { | ||
6730 | "XDP pkt read, pkt_data' > pkt_end, bad access 1", | ||
6731 | .insns = { | ||
6732 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
6733 | offsetof(struct xdp_md, data)), | ||
6734 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
6735 | offsetof(struct xdp_md, data_end)), | ||
6736 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
6737 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
6738 | BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1), | ||
6739 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4), | ||
6740 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
6741 | BPF_EXIT_INSN(), | ||
6742 | }, | ||
6743 | .errstr = "R1 offset is outside of the packet", | ||
6744 | .result = REJECT, | ||
6745 | .prog_type = BPF_PROG_TYPE_XDP, | ||
6746 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
6747 | }, | ||
6748 | { | ||
6749 | "XDP pkt read, pkt_data' > pkt_end, bad access 2", | ||
6750 | .insns = { | ||
6751 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
6752 | offsetof(struct xdp_md, data)), | ||
6753 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
6754 | offsetof(struct xdp_md, data_end)), | ||
6755 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
6756 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
6757 | BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 0), | ||
6758 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), | ||
6759 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
6760 | BPF_EXIT_INSN(), | ||
6761 | }, | ||
6762 | .errstr = "R1 offset is outside of the packet", | ||
6763 | .result = REJECT, | ||
6764 | .prog_type = BPF_PROG_TYPE_XDP, | ||
6765 | }, | ||
6766 | { | ||
6767 | "XDP pkt read, pkt_end > pkt_data', good access", | ||
6768 | .insns = { | ||
6769 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
6770 | offsetof(struct xdp_md, data)), | ||
6771 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
6772 | offsetof(struct xdp_md, data_end)), | ||
6773 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
6774 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
6775 | BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1), | ||
6776 | BPF_JMP_IMM(BPF_JA, 0, 0, 1), | ||
6777 | BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5), | ||
6778 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
6779 | BPF_EXIT_INSN(), | ||
6780 | }, | ||
6781 | .result = ACCEPT, | ||
6782 | .prog_type = BPF_PROG_TYPE_XDP, | ||
6783 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
6784 | }, | ||
6785 | { | ||
6786 | "XDP pkt read, pkt_end > pkt_data', bad access 1", | ||
6787 | .insns = { | ||
6788 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
6789 | offsetof(struct xdp_md, data)), | ||
6790 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
6791 | offsetof(struct xdp_md, data_end)), | ||
6792 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
6793 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
6794 | BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1), | ||
6795 | BPF_JMP_IMM(BPF_JA, 0, 0, 1), | ||
6796 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), | ||
6797 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
6798 | BPF_EXIT_INSN(), | ||
6799 | }, | ||
6800 | .errstr = "R1 offset is outside of the packet", | ||
6801 | .result = REJECT, | ||
6802 | .prog_type = BPF_PROG_TYPE_XDP, | ||
6803 | }, | ||
6804 | { | ||
6805 | "XDP pkt read, pkt_end > pkt_data', bad access 2", | ||
6806 | .insns = { | ||
6807 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
6808 | offsetof(struct xdp_md, data)), | ||
6809 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
6810 | offsetof(struct xdp_md, data_end)), | ||
6811 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
6812 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
6813 | BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1), | ||
6814 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), | ||
6815 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
6816 | BPF_EXIT_INSN(), | ||
6817 | }, | ||
6818 | .errstr = "R1 offset is outside of the packet", | ||
6819 | .result = REJECT, | ||
6820 | .prog_type = BPF_PROG_TYPE_XDP, | ||
6821 | }, | ||
6822 | { | ||
6823 | "XDP pkt read, pkt_data' < pkt_end, good access", | ||
6824 | .insns = { | ||
6825 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
6826 | offsetof(struct xdp_md, data)), | ||
6827 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
6828 | offsetof(struct xdp_md, data_end)), | ||
6829 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
6830 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
6831 | BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1), | ||
6832 | BPF_JMP_IMM(BPF_JA, 0, 0, 1), | ||
6833 | BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5), | ||
6834 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
6835 | BPF_EXIT_INSN(), | ||
6836 | }, | ||
6837 | .result = ACCEPT, | ||
6838 | .prog_type = BPF_PROG_TYPE_XDP, | ||
6839 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
6840 | }, | ||
6841 | { | ||
6842 | "XDP pkt read, pkt_data' < pkt_end, bad access 1", | ||
6843 | .insns = { | ||
6844 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
6845 | offsetof(struct xdp_md, data)), | ||
6846 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
6847 | offsetof(struct xdp_md, data_end)), | ||
6848 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
6849 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
6850 | BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1), | ||
6851 | BPF_JMP_IMM(BPF_JA, 0, 0, 1), | ||
6852 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), | ||
6853 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
6854 | BPF_EXIT_INSN(), | ||
6855 | }, | ||
6856 | .errstr = "R1 offset is outside of the packet", | ||
6857 | .result = REJECT, | ||
6858 | .prog_type = BPF_PROG_TYPE_XDP, | ||
6859 | }, | ||
6860 | { | ||
6861 | "XDP pkt read, pkt_data' < pkt_end, bad access 2", | ||
6862 | .insns = { | ||
6863 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
6864 | offsetof(struct xdp_md, data)), | ||
6865 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
6866 | offsetof(struct xdp_md, data_end)), | ||
6867 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
6868 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
6869 | BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1), | ||
6870 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), | ||
6871 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
6872 | BPF_EXIT_INSN(), | ||
6873 | }, | ||
6874 | .errstr = "R1 offset is outside of the packet", | ||
6875 | .result = REJECT, | ||
6876 | .prog_type = BPF_PROG_TYPE_XDP, | ||
6877 | }, | ||
6878 | { | ||
6879 | "XDP pkt read, pkt_end < pkt_data', good access", | ||
6880 | .insns = { | ||
6881 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
6882 | offsetof(struct xdp_md, data)), | ||
6883 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
6884 | offsetof(struct xdp_md, data_end)), | ||
6885 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
6886 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
6887 | BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1), | ||
6888 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), | ||
6889 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
6890 | BPF_EXIT_INSN(), | ||
6891 | }, | ||
6892 | .result = ACCEPT, | ||
6893 | .prog_type = BPF_PROG_TYPE_XDP, | ||
6894 | }, | ||
6895 | { | ||
6896 | "XDP pkt read, pkt_end < pkt_data', bad access 1", | ||
6897 | .insns = { | ||
6898 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
6899 | offsetof(struct xdp_md, data)), | ||
6900 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
6901 | offsetof(struct xdp_md, data_end)), | ||
6902 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
6903 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
6904 | BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1), | ||
6905 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4), | ||
6906 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
6907 | BPF_EXIT_INSN(), | ||
6908 | }, | ||
6909 | .errstr = "R1 offset is outside of the packet", | ||
6910 | .result = REJECT, | ||
6911 | .prog_type = BPF_PROG_TYPE_XDP, | ||
6912 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
6913 | }, | ||
6914 | { | ||
6915 | "XDP pkt read, pkt_end < pkt_data', bad access 2", | ||
6916 | .insns = { | ||
6917 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
6918 | offsetof(struct xdp_md, data)), | ||
6919 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
6920 | offsetof(struct xdp_md, data_end)), | ||
6921 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
6922 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
6923 | BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 0), | ||
6924 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), | ||
6925 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
6926 | BPF_EXIT_INSN(), | ||
6927 | }, | ||
6928 | .errstr = "R1 offset is outside of the packet", | ||
6929 | .result = REJECT, | ||
6930 | .prog_type = BPF_PROG_TYPE_XDP, | ||
6931 | }, | ||
6932 | { | ||
6933 | "XDP pkt read, pkt_data' >= pkt_end, good access", | ||
6934 | .insns = { | ||
6935 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
6936 | offsetof(struct xdp_md, data)), | ||
6937 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
6938 | offsetof(struct xdp_md, data_end)), | ||
6939 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
6940 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
6941 | BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1), | ||
6942 | BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5), | ||
6943 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
6944 | BPF_EXIT_INSN(), | ||
6945 | }, | ||
6946 | .result = ACCEPT, | ||
6947 | .prog_type = BPF_PROG_TYPE_XDP, | ||
6948 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
6949 | }, | ||
6950 | { | ||
6951 | "XDP pkt read, pkt_data' >= pkt_end, bad access 1", | ||
6952 | .insns = { | ||
6953 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
6954 | offsetof(struct xdp_md, data)), | ||
6955 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
6956 | offsetof(struct xdp_md, data_end)), | ||
6957 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
6958 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
6959 | BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1), | ||
6960 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), | ||
6961 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
6962 | BPF_EXIT_INSN(), | ||
6963 | }, | ||
6964 | .errstr = "R1 offset is outside of the packet", | ||
6965 | .result = REJECT, | ||
6966 | .prog_type = BPF_PROG_TYPE_XDP, | ||
6967 | }, | ||
6968 | { | ||
6969 | "XDP pkt read, pkt_data' >= pkt_end, bad access 2", | ||
6970 | .insns = { | ||
6971 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
6972 | offsetof(struct xdp_md, data)), | ||
6973 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
6974 | offsetof(struct xdp_md, data_end)), | ||
6975 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
6976 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
6977 | BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 0), | ||
6978 | BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5), | ||
6979 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
6980 | BPF_EXIT_INSN(), | ||
6981 | }, | ||
6982 | .errstr = "R1 offset is outside of the packet", | ||
6983 | .result = REJECT, | ||
6984 | .prog_type = BPF_PROG_TYPE_XDP, | ||
6985 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
6986 | }, | ||
6987 | { | ||
6988 | "XDP pkt read, pkt_end >= pkt_data', good access", | ||
6989 | .insns = { | ||
6990 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
6991 | offsetof(struct xdp_md, data)), | ||
6992 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
6993 | offsetof(struct xdp_md, data_end)), | ||
6994 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
6995 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
6996 | BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1), | ||
6997 | BPF_JMP_IMM(BPF_JA, 0, 0, 1), | ||
6998 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), | ||
6999 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
7000 | BPF_EXIT_INSN(), | ||
7001 | }, | ||
7002 | .result = ACCEPT, | ||
7003 | .prog_type = BPF_PROG_TYPE_XDP, | ||
7004 | }, | ||
7005 | { | ||
7006 | "XDP pkt read, pkt_end >= pkt_data', bad access 1", | ||
7007 | .insns = { | ||
7008 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
7009 | offsetof(struct xdp_md, data)), | ||
7010 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
7011 | offsetof(struct xdp_md, data_end)), | ||
7012 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
7013 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
7014 | BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1), | ||
7015 | BPF_JMP_IMM(BPF_JA, 0, 0, 1), | ||
7016 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4), | ||
7017 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
7018 | BPF_EXIT_INSN(), | ||
7019 | }, | ||
7020 | .errstr = "R1 offset is outside of the packet", | ||
7021 | .result = REJECT, | ||
7022 | .prog_type = BPF_PROG_TYPE_XDP, | ||
7023 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
7024 | }, | ||
7025 | { | ||
7026 | "XDP pkt read, pkt_end >= pkt_data', bad access 2", | ||
7027 | .insns = { | ||
7028 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
7029 | offsetof(struct xdp_md, data)), | ||
7030 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
7031 | offsetof(struct xdp_md, data_end)), | ||
7032 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
7033 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
7034 | BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1), | ||
7035 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), | ||
7036 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
7037 | BPF_EXIT_INSN(), | ||
7038 | }, | ||
7039 | .errstr = "R1 offset is outside of the packet", | ||
7040 | .result = REJECT, | ||
7041 | .prog_type = BPF_PROG_TYPE_XDP, | ||
7042 | }, | ||
7043 | { | ||
7044 | "XDP pkt read, pkt_data' <= pkt_end, good access", | ||
7045 | .insns = { | ||
7046 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
7047 | offsetof(struct xdp_md, data)), | ||
7048 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
7049 | offsetof(struct xdp_md, data_end)), | ||
7050 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
7051 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
7052 | BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1), | ||
7053 | BPF_JMP_IMM(BPF_JA, 0, 0, 1), | ||
7054 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), | ||
7055 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
7056 | BPF_EXIT_INSN(), | ||
7057 | }, | ||
7058 | .result = ACCEPT, | ||
7059 | .prog_type = BPF_PROG_TYPE_XDP, | ||
7060 | }, | ||
7061 | { | ||
7062 | "XDP pkt read, pkt_data' <= pkt_end, bad access 1", | ||
7063 | .insns = { | ||
7064 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
7065 | offsetof(struct xdp_md, data)), | ||
7066 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
7067 | offsetof(struct xdp_md, data_end)), | ||
7068 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
7069 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
7070 | BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1), | ||
7071 | BPF_JMP_IMM(BPF_JA, 0, 0, 1), | ||
7072 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4), | ||
7073 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
7074 | BPF_EXIT_INSN(), | ||
7075 | }, | ||
7076 | .errstr = "R1 offset is outside of the packet", | ||
7077 | .result = REJECT, | ||
7078 | .prog_type = BPF_PROG_TYPE_XDP, | ||
7079 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
7080 | }, | ||
7081 | { | ||
7082 | "XDP pkt read, pkt_data' <= pkt_end, bad access 2", | ||
7083 | .insns = { | ||
7084 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
7085 | offsetof(struct xdp_md, data)), | ||
7086 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
7087 | offsetof(struct xdp_md, data_end)), | ||
7088 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
7089 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
7090 | BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1), | ||
7091 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), | ||
7092 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
7093 | BPF_EXIT_INSN(), | ||
7094 | }, | ||
7095 | .errstr = "R1 offset is outside of the packet", | ||
7096 | .result = REJECT, | ||
7097 | .prog_type = BPF_PROG_TYPE_XDP, | ||
7098 | }, | ||
7099 | { | ||
7100 | "XDP pkt read, pkt_end <= pkt_data', good access", | ||
7101 | .insns = { | ||
7102 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
7103 | offsetof(struct xdp_md, data)), | ||
7104 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
7105 | offsetof(struct xdp_md, data_end)), | ||
7106 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
7107 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
7108 | BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1), | ||
7109 | BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5), | ||
7110 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
7111 | BPF_EXIT_INSN(), | ||
7112 | }, | ||
7113 | .result = ACCEPT, | ||
7114 | .prog_type = BPF_PROG_TYPE_XDP, | ||
7115 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
7116 | }, | ||
7117 | { | ||
7118 | "XDP pkt read, pkt_end <= pkt_data', bad access 1", | ||
7119 | .insns = { | ||
7120 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
7121 | offsetof(struct xdp_md, data)), | ||
7122 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
7123 | offsetof(struct xdp_md, data_end)), | ||
7124 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
7125 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
7126 | BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1), | ||
7127 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), | ||
7128 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
7129 | BPF_EXIT_INSN(), | ||
7130 | }, | ||
7131 | .errstr = "R1 offset is outside of the packet", | ||
7132 | .result = REJECT, | ||
7133 | .prog_type = BPF_PROG_TYPE_XDP, | ||
7134 | }, | ||
7135 | { | ||
7136 | "XDP pkt read, pkt_end <= pkt_data', bad access 2", | ||
7137 | .insns = { | ||
7138 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
7139 | offsetof(struct xdp_md, data)), | ||
7140 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
7141 | offsetof(struct xdp_md, data_end)), | ||
7142 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
7143 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | ||
7144 | BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 0), | ||
7145 | BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5), | ||
7146 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
7147 | BPF_EXIT_INSN(), | ||
7148 | }, | ||
7149 | .errstr = "R1 offset is outside of the packet", | ||
7150 | .result = REJECT, | ||
7151 | .prog_type = BPF_PROG_TYPE_XDP, | ||
7152 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
7153 | }, | ||
6648 | }; | 7154 | }; |
6649 | 7155 | ||
6650 | static int probe_filter_length(const struct bpf_insn *fp) | 7156 | static int probe_filter_length(const struct bpf_insn *fp) |
diff --git a/tools/testing/selftests/breakpoints/Makefile b/tools/testing/selftests/breakpoints/Makefile index 6b214b7b10fb..247b0a1899d7 100644 --- a/tools/testing/selftests/breakpoints/Makefile +++ b/tools/testing/selftests/breakpoints/Makefile | |||
@@ -2,14 +2,14 @@ | |||
2 | uname_M := $(shell uname -m 2>/dev/null || echo not) | 2 | uname_M := $(shell uname -m 2>/dev/null || echo not) |
3 | ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/) | 3 | ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/) |
4 | 4 | ||
5 | TEST_GEN_PROGS := step_after_suspend_test | ||
6 | |||
5 | ifeq ($(ARCH),x86) | 7 | ifeq ($(ARCH),x86) |
6 | TEST_GEN_PROGS := breakpoint_test | 8 | TEST_GEN_PROGS += breakpoint_test |
7 | endif | 9 | endif |
8 | ifneq (,$(filter $(ARCH),aarch64 arm64)) | 10 | ifneq (,$(filter $(ARCH),aarch64 arm64)) |
9 | TEST_GEN_PROGS := breakpoint_test_arm64 | 11 | TEST_GEN_PROGS += breakpoint_test_arm64 |
10 | endif | 12 | endif |
11 | 13 | ||
12 | TEST_GEN_PROGS += step_after_suspend_test | ||
13 | |||
14 | include ../lib.mk | 14 | include ../lib.mk |
15 | 15 | ||
diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/multiple_kprobes.tc b/tools/testing/selftests/ftrace/test.d/kprobe/multiple_kprobes.tc index 2a1cb9908746..a4fd4c851a5b 100644 --- a/tools/testing/selftests/ftrace/test.d/kprobe/multiple_kprobes.tc +++ b/tools/testing/selftests/ftrace/test.d/kprobe/multiple_kprobes.tc | |||
@@ -1,6 +1,8 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | # description: Register/unregister many kprobe events | 2 | # description: Register/unregister many kprobe events |
3 | 3 | ||
4 | [ -f kprobe_events ] || exit_unsupported # this is configurable | ||
5 | |||
4 | # ftrace fentry skip size depends on the machine architecture. | 6 | # ftrace fentry skip size depends on the machine architecture. |
5 | # Currently HAVE_KPROBES_ON_FTRACE defined on x86 and powerpc64le | 7 | # Currently HAVE_KPROBES_ON_FTRACE defined on x86 and powerpc64le |
6 | case `uname -m` in | 8 | case `uname -m` in |
diff --git a/tools/testing/selftests/futex/Makefile b/tools/testing/selftests/futex/Makefile index 7c647f619d63..f0c0369ccb79 100644 --- a/tools/testing/selftests/futex/Makefile +++ b/tools/testing/selftests/futex/Makefile | |||
@@ -7,14 +7,17 @@ TEST_PROGS := run.sh | |||
7 | include ../lib.mk | 7 | include ../lib.mk |
8 | 8 | ||
9 | all: | 9 | all: |
10 | for DIR in $(SUBDIRS); do \ | 10 | @for DIR in $(SUBDIRS); do \ |
11 | BUILD_TARGET=$(OUTPUT)/$$DIR; \ | 11 | BUILD_TARGET=$(OUTPUT)/$$DIR; \ |
12 | mkdir $$BUILD_TARGET -p; \ | 12 | mkdir $$BUILD_TARGET -p; \ |
13 | make OUTPUT=$$BUILD_TARGET -C $$DIR $@;\ | 13 | make OUTPUT=$$BUILD_TARGET -C $$DIR $@;\ |
14 | if [ -e $$DIR/$(TEST_PROGS) ]; then | ||
15 | rsync -a $$DIR/$(TEST_PROGS) $$BUILD_TARGET/; | ||
16 | fi | ||
14 | done | 17 | done |
15 | 18 | ||
16 | override define RUN_TESTS | 19 | override define RUN_TESTS |
17 | $(OUTPUT)/run.sh | 20 | @cd $(OUTPUT); ./run.sh |
18 | endef | 21 | endef |
19 | 22 | ||
20 | override define INSTALL_RULE | 23 | override define INSTALL_RULE |
@@ -33,7 +36,7 @@ override define EMIT_TESTS | |||
33 | endef | 36 | endef |
34 | 37 | ||
35 | override define CLEAN | 38 | override define CLEAN |
36 | for DIR in $(SUBDIRS); do \ | 39 | @for DIR in $(SUBDIRS); do \ |
37 | BUILD_TARGET=$(OUTPUT)/$$DIR; \ | 40 | BUILD_TARGET=$(OUTPUT)/$$DIR; \ |
38 | mkdir $$BUILD_TARGET -p; \ | 41 | mkdir $$BUILD_TARGET -p; \ |
39 | make OUTPUT=$$BUILD_TARGET -C $$DIR $@;\ | 42 | make OUTPUT=$$BUILD_TARGET -C $$DIR $@;\ |
diff --git a/tools/testing/selftests/intel_pstate/Makefile b/tools/testing/selftests/intel_pstate/Makefile index 849a90ffe8dd..a97e24edde39 100644 --- a/tools/testing/selftests/intel_pstate/Makefile +++ b/tools/testing/selftests/intel_pstate/Makefile | |||
@@ -1,7 +1,9 @@ | |||
1 | CFLAGS := $(CFLAGS) -Wall -D_GNU_SOURCE | 1 | CFLAGS := $(CFLAGS) -Wall -D_GNU_SOURCE |
2 | LDLIBS := $(LDLIBS) -lm | 2 | LDLIBS := $(LDLIBS) -lm |
3 | 3 | ||
4 | ifeq (,$(filter $(ARCH),x86)) | ||
4 | TEST_GEN_FILES := msr aperf | 5 | TEST_GEN_FILES := msr aperf |
6 | endif | ||
5 | 7 | ||
6 | TEST_PROGS := run.sh | 8 | TEST_PROGS := run.sh |
7 | 9 | ||
diff --git a/tools/testing/selftests/intel_pstate/run.sh b/tools/testing/selftests/intel_pstate/run.sh index 7868c106b8b1..d3ab48f91cd6 100755 --- a/tools/testing/selftests/intel_pstate/run.sh +++ b/tools/testing/selftests/intel_pstate/run.sh | |||
@@ -29,13 +29,12 @@ | |||
29 | 29 | ||
30 | EVALUATE_ONLY=0 | 30 | EVALUATE_ONLY=0 |
31 | 31 | ||
32 | max_cpus=$(($(nproc)-1)) | 32 | if ! uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ | grep -q x86; then |
33 | echo "$0 # Skipped: Test can only run on x86 architectures." | ||
34 | exit 0 | ||
35 | fi | ||
33 | 36 | ||
34 | # compile programs | 37 | max_cpus=$(($(nproc)-1)) |
35 | gcc aperf.c -Wall -D_GNU_SOURCE -o aperf -lm | ||
36 | [ $? -ne 0 ] && echo "Problem compiling aperf.c." && exit 1 | ||
37 | gcc -o msr msr.c -lm | ||
38 | [ $? -ne 0 ] && echo "Problem compiling msr.c." && exit 1 | ||
39 | 38 | ||
40 | function run_test () { | 39 | function run_test () { |
41 | 40 | ||
diff --git a/tools/testing/selftests/lib.mk b/tools/testing/selftests/lib.mk index 693616651da5..f65886af7c0c 100644 --- a/tools/testing/selftests/lib.mk +++ b/tools/testing/selftests/lib.mk | |||
@@ -6,7 +6,14 @@ ifeq (0,$(MAKELEVEL)) | |||
6 | OUTPUT := $(shell pwd) | 6 | OUTPUT := $(shell pwd) |
7 | endif | 7 | endif |
8 | 8 | ||
9 | # The following are built by lib.mk common compile rules. | ||
10 | # TEST_CUSTOM_PROGS should be used by tests that require | ||
11 | # custom build rule and prevent common build rule use. | ||
12 | # TEST_PROGS are for test shell scripts. | ||
13 | # TEST_CUSTOM_PROGS and TEST_PROGS will be run by common run_tests | ||
14 | # and install targets. Common clean doesn't touch them. | ||
9 | TEST_GEN_PROGS := $(patsubst %,$(OUTPUT)/%,$(TEST_GEN_PROGS)) | 15 | TEST_GEN_PROGS := $(patsubst %,$(OUTPUT)/%,$(TEST_GEN_PROGS)) |
16 | TEST_GEN_PROGS_EXTENDED := $(patsubst %,$(OUTPUT)/%,$(TEST_GEN_PROGS_EXTENDED)) | ||
10 | TEST_GEN_FILES := $(patsubst %,$(OUTPUT)/%,$(TEST_GEN_FILES)) | 17 | TEST_GEN_FILES := $(patsubst %,$(OUTPUT)/%,$(TEST_GEN_FILES)) |
11 | 18 | ||
12 | all: $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES) | 19 | all: $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES) |
@@ -20,17 +27,28 @@ define RUN_TESTS | |||
20 | test_num=`echo $$test_num+1 | bc`; \ | 27 | test_num=`echo $$test_num+1 | bc`; \ |
21 | echo "selftests: $$BASENAME_TEST"; \ | 28 | echo "selftests: $$BASENAME_TEST"; \ |
22 | echo "========================================"; \ | 29 | echo "========================================"; \ |
23 | if [ ! -x $$BASENAME_TEST ]; then \ | 30 | if [ ! -x $$TEST ]; then \ |
24 | echo "selftests: Warning: file $$BASENAME_TEST is not executable, correct this.";\ | 31 | echo "selftests: Warning: file $$BASENAME_TEST is not executable, correct this.";\ |
25 | echo "not ok 1..$$test_num selftests: $$BASENAME_TEST [FAIL]"; \ | 32 | echo "not ok 1..$$test_num selftests: $$BASENAME_TEST [FAIL]"; \ |
26 | else \ | 33 | else \ |
27 | cd `dirname $$TEST` > /dev/null; (./$$BASENAME_TEST && echo "ok 1..$$test_num selftests: $$BASENAME_TEST [PASS]") || echo "not ok 1..$$test_num selftests: $$BASENAME_TEST [FAIL]"; cd - > /dev/null;\ | 34 | cd `dirname $$TEST` > /dev/null; (./$$BASENAME_TEST > /tmp/$$BASENAME_TEST 2>&1 && echo "ok 1..$$test_num selftests: $$BASENAME_TEST [PASS]") || echo "not ok 1..$$test_num selftests: $$BASENAME_TEST [FAIL]"; cd - > /dev/null;\ |
28 | fi; \ | 35 | fi; \ |
29 | done; | 36 | done; |
30 | endef | 37 | endef |
31 | 38 | ||
32 | run_tests: all | 39 | run_tests: all |
33 | $(call RUN_TESTS, $(TEST_GEN_PROGS) $(TEST_PROGS)) | 40 | ifneq ($(KBUILD_SRC),) |
41 | @if [ "X$(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES)" != "X" ]; then | ||
42 | @rsync -aq $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) $(OUTPUT) | ||
43 | fi | ||
44 | @if [ "X$(TEST_PROGS)" != "X" ]; then | ||
45 | $(call RUN_TESTS, $(TEST_GEN_PROGS) $(TEST_CUSTOM_PROGS) $(OUTPUT)/$(TEST_PROGS)) | ||
46 | else | ||
47 | $(call RUN_TESTS, $(TEST_GEN_PROGS) $(TEST_CUSTOM_PROGS)) | ||
48 | fi | ||
49 | else | ||
50 | $(call RUN_TESTS, $(TEST_GEN_PROGS) $(TEST_CUSTOM_PROGS) $(TEST_PROGS)) | ||
51 | endif | ||
34 | 52 | ||
35 | define INSTALL_RULE | 53 | define INSTALL_RULE |
36 | @if [ "X$(TEST_PROGS)$(TEST_PROGS_EXTENDED)$(TEST_FILES)" != "X" ]; then \ | 54 | @if [ "X$(TEST_PROGS)$(TEST_PROGS_EXTENDED)$(TEST_FILES)" != "X" ]; then \ |
@@ -38,10 +56,10 @@ define INSTALL_RULE | |||
38 | echo "rsync -a $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) $(INSTALL_PATH)/"; \ | 56 | echo "rsync -a $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) $(INSTALL_PATH)/"; \ |
39 | rsync -a $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) $(INSTALL_PATH)/; \ | 57 | rsync -a $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) $(INSTALL_PATH)/; \ |
40 | fi | 58 | fi |
41 | @if [ "X$(TEST_GEN_PROGS)$(TEST_GEN_PROGS_EXTENDED)$(TEST_GEN_FILES)" != "X" ]; then \ | 59 | @if [ "X$(TEST_GEN_PROGS)$(TEST_CUSTOM_PROGS)$(TEST_GEN_PROGS_EXTENDED)$(TEST_GEN_FILES)" != "X" ]; then \ |
42 | mkdir -p ${INSTALL_PATH}; \ | 60 | mkdir -p ${INSTALL_PATH}; \ |
43 | echo "rsync -a $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES) $(INSTALL_PATH)/"; \ | 61 | echo "rsync -a $(TEST_GEN_PROGS) $(TEST_CUSTOM_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES) $(INSTALL_PATH)/"; \ |
44 | rsync -a $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES) $(INSTALL_PATH)/; \ | 62 | rsync -a $(TEST_GEN_PROGS) $(TEST_CUSTOM_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES) $(INSTALL_PATH)/; \ |
45 | fi | 63 | fi |
46 | endef | 64 | endef |
47 | 65 | ||
@@ -53,15 +71,20 @@ else | |||
53 | endif | 71 | endif |
54 | 72 | ||
55 | define EMIT_TESTS | 73 | define EMIT_TESTS |
56 | @for TEST in $(TEST_GEN_PROGS) $(TEST_PROGS); do \ | 74 | @for TEST in $(TEST_GEN_PROGS) $(TEST_CUSTOM_PROGS) $(TEST_PROGS); do \ |
57 | BASENAME_TEST=`basename $$TEST`; \ | 75 | BASENAME_TEST=`basename $$TEST`; \ |
58 | echo "(./$$BASENAME_TEST && echo \"selftests: $$BASENAME_TEST [PASS]\") || echo \"selftests: $$BASENAME_TEST [FAIL]\""; \ | 76 | echo "(./$$BASENAME_TEST > /tmp/$$BASENAME_TEST 2>&1 && echo \"selftests: $$BASENAME_TEST [PASS]\") || echo \"selftests: $$BASENAME_TEST [FAIL]\""; \ |
59 | done; | 77 | done; |
60 | endef | 78 | endef |
61 | 79 | ||
62 | emit_tests: | 80 | emit_tests: |
63 | $(EMIT_TESTS) | 81 | $(EMIT_TESTS) |
64 | 82 | ||
83 | # define if isn't already. It is undefined in make O= case. | ||
84 | ifeq ($(RM),) | ||
85 | RM := rm -f | ||
86 | endif | ||
87 | |||
65 | define CLEAN | 88 | define CLEAN |
66 | $(RM) -r $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES) $(EXTRA_CLEAN) | 89 | $(RM) -r $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES) $(EXTRA_CLEAN) |
67 | endef | 90 | endef |
@@ -69,6 +92,15 @@ endef | |||
69 | clean: | 92 | clean: |
70 | $(CLEAN) | 93 | $(CLEAN) |
71 | 94 | ||
95 | # When make O= with kselftest target from main level | ||
96 | # the following aren't defined. | ||
97 | # | ||
98 | ifneq ($(KBUILD_SRC),) | ||
99 | LINK.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) | ||
100 | COMPILE.S = $(CC) $(ASFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c | ||
101 | LINK.S = $(CC) $(ASFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) | ||
102 | endif | ||
103 | |||
72 | $(OUTPUT)/%:%.c | 104 | $(OUTPUT)/%:%.c |
73 | $(LINK.c) $^ $(LDLIBS) -o $@ | 105 | $(LINK.c) $^ $(LDLIBS) -o $@ |
74 | 106 | ||
diff --git a/tools/testing/selftests/memfd/run_tests.sh b/tools/testing/selftests/memfd/run_tests.sh index daabb350697c..daabb350697c 100644..100755 --- a/tools/testing/selftests/memfd/run_tests.sh +++ b/tools/testing/selftests/memfd/run_tests.sh | |||
diff --git a/tools/testing/selftests/mqueue/Makefile b/tools/testing/selftests/mqueue/Makefile index 79a664aeb8d7..152823b6cb21 100644 --- a/tools/testing/selftests/mqueue/Makefile +++ b/tools/testing/selftests/mqueue/Makefile | |||
@@ -5,8 +5,8 @@ TEST_GEN_PROGS := mq_open_tests mq_perf_tests | |||
5 | include ../lib.mk | 5 | include ../lib.mk |
6 | 6 | ||
7 | override define RUN_TESTS | 7 | override define RUN_TESTS |
8 | @./mq_open_tests /test1 || echo "selftests: mq_open_tests [FAIL]" | 8 | @$(OUTPUT)/mq_open_tests /test1 || echo "selftests: mq_open_tests [FAIL]" |
9 | @./mq_perf_tests || echo "selftests: mq_perf_tests [FAIL]" | 9 | @$(OUTPUT)/mq_perf_tests || echo "selftests: mq_perf_tests [FAIL]" |
10 | endef | 10 | endef |
11 | 11 | ||
12 | override define EMIT_TESTS | 12 | override define EMIT_TESTS |
diff --git a/tools/testing/selftests/net/.gitignore b/tools/testing/selftests/net/.gitignore index 9801253e4802..c612d6e38c62 100644 --- a/tools/testing/selftests/net/.gitignore +++ b/tools/testing/selftests/net/.gitignore | |||
@@ -6,3 +6,4 @@ reuseport_bpf | |||
6 | reuseport_bpf_cpu | 6 | reuseport_bpf_cpu |
7 | reuseport_bpf_numa | 7 | reuseport_bpf_numa |
8 | reuseport_dualstack | 8 | reuseport_dualstack |
9 | reuseaddr_conflict | ||
diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile index de1f5772b878..d86bca991f45 100644 --- a/tools/testing/selftests/net/Makefile +++ b/tools/testing/selftests/net/Makefile | |||
@@ -5,9 +5,9 @@ CFLAGS += -I../../../../usr/include/ | |||
5 | 5 | ||
6 | TEST_PROGS := run_netsocktests run_afpackettests test_bpf.sh netdevice.sh rtnetlink.sh | 6 | TEST_PROGS := run_netsocktests run_afpackettests test_bpf.sh netdevice.sh rtnetlink.sh |
7 | TEST_GEN_FILES = socket | 7 | TEST_GEN_FILES = socket |
8 | TEST_GEN_FILES += psock_fanout psock_tpacket | 8 | TEST_GEN_FILES += psock_fanout psock_tpacket msg_zerocopy |
9 | TEST_GEN_FILES += reuseport_bpf reuseport_bpf_cpu reuseport_bpf_numa | 9 | TEST_GEN_PROGS = reuseport_bpf reuseport_bpf_cpu reuseport_bpf_numa |
10 | TEST_GEN_FILES += reuseport_dualstack msg_zerocopy | 10 | TEST_GEN_PROGS += reuseport_dualstack reuseaddr_conflict |
11 | 11 | ||
12 | include ../lib.mk | 12 | include ../lib.mk |
13 | 13 | ||
diff --git a/tools/testing/selftests/net/msg_zerocopy.c b/tools/testing/selftests/net/msg_zerocopy.c index 40232af5b023..3ab6ec403905 100644 --- a/tools/testing/selftests/net/msg_zerocopy.c +++ b/tools/testing/selftests/net/msg_zerocopy.c | |||
@@ -55,7 +55,7 @@ | |||
55 | #include <unistd.h> | 55 | #include <unistd.h> |
56 | 56 | ||
57 | #ifndef SO_EE_ORIGIN_ZEROCOPY | 57 | #ifndef SO_EE_ORIGIN_ZEROCOPY |
58 | #define SO_EE_ORIGIN_ZEROCOPY SO_EE_ORIGIN_UPAGE | 58 | #define SO_EE_ORIGIN_ZEROCOPY 5 |
59 | #endif | 59 | #endif |
60 | 60 | ||
61 | #ifndef SO_ZEROCOPY | 61 | #ifndef SO_ZEROCOPY |
diff --git a/tools/testing/selftests/net/netdevice.sh b/tools/testing/selftests/net/netdevice.sh index 4e00568d70c2..90cb903c3381 100755 --- a/tools/testing/selftests/net/netdevice.sh +++ b/tools/testing/selftests/net/netdevice.sh | |||
@@ -178,7 +178,7 @@ if [ "$(id -u)" -ne 0 ];then | |||
178 | exit 0 | 178 | exit 0 |
179 | fi | 179 | fi |
180 | 180 | ||
181 | ip -Version 2>/dev/null >/dev/null | 181 | ip link show 2>/dev/null >/dev/null |
182 | if [ $? -ne 0 ];then | 182 | if [ $? -ne 0 ];then |
183 | echo "SKIP: Could not run test without the ip tool" | 183 | echo "SKIP: Could not run test without the ip tool" |
184 | exit 0 | 184 | exit 0 |
diff --git a/tools/testing/selftests/net/reuseaddr_conflict.c b/tools/testing/selftests/net/reuseaddr_conflict.c new file mode 100644 index 000000000000..7c5b12664b03 --- /dev/null +++ b/tools/testing/selftests/net/reuseaddr_conflict.c | |||
@@ -0,0 +1,114 @@ | |||
1 | /* | ||
2 | * Test for the regression introduced by | ||
3 | * | ||
4 | * b9470c27607b ("inet: kill smallest_size and smallest_port") | ||
5 | * | ||
6 | * If we open an ipv4 socket on a port with reuseaddr we shouldn't reset the tb | ||
7 | * when we open the ipv6 conterpart, which is what was happening previously. | ||
8 | */ | ||
9 | #include <errno.h> | ||
10 | #include <error.h> | ||
11 | #include <arpa/inet.h> | ||
12 | #include <netinet/in.h> | ||
13 | #include <stdbool.h> | ||
14 | #include <stdio.h> | ||
15 | #include <sys/socket.h> | ||
16 | #include <sys/types.h> | ||
17 | #include <unistd.h> | ||
18 | |||
19 | #define PORT 9999 | ||
20 | |||
21 | int open_port(int ipv6, int any) | ||
22 | { | ||
23 | int fd = -1; | ||
24 | int reuseaddr = 1; | ||
25 | int v6only = 1; | ||
26 | int addrlen; | ||
27 | int ret = -1; | ||
28 | struct sockaddr *addr; | ||
29 | int family = ipv6 ? AF_INET6 : AF_INET; | ||
30 | |||
31 | struct sockaddr_in6 addr6 = { | ||
32 | .sin6_family = AF_INET6, | ||
33 | .sin6_port = htons(PORT), | ||
34 | .sin6_addr = in6addr_any | ||
35 | }; | ||
36 | struct sockaddr_in addr4 = { | ||
37 | .sin_family = AF_INET, | ||
38 | .sin_port = htons(PORT), | ||
39 | .sin_addr.s_addr = any ? htonl(INADDR_ANY) : inet_addr("127.0.0.1"), | ||
40 | }; | ||
41 | |||
42 | |||
43 | if (ipv6) { | ||
44 | addr = (struct sockaddr*)&addr6; | ||
45 | addrlen = sizeof(addr6); | ||
46 | } else { | ||
47 | addr = (struct sockaddr*)&addr4; | ||
48 | addrlen = sizeof(addr4); | ||
49 | } | ||
50 | |||
51 | if ((fd = socket(family, SOCK_STREAM, IPPROTO_TCP)) < 0) { | ||
52 | perror("socket"); | ||
53 | goto out; | ||
54 | } | ||
55 | |||
56 | if (ipv6 && setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&v6only, | ||
57 | sizeof(v6only)) < 0) { | ||
58 | perror("setsockopt IPV6_V6ONLY"); | ||
59 | goto out; | ||
60 | } | ||
61 | |||
62 | if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, | ||
63 | sizeof(reuseaddr)) < 0) { | ||
64 | perror("setsockopt SO_REUSEADDR"); | ||
65 | goto out; | ||
66 | } | ||
67 | |||
68 | if (bind(fd, addr, addrlen) < 0) { | ||
69 | perror("bind"); | ||
70 | goto out; | ||
71 | } | ||
72 | |||
73 | if (any) | ||
74 | return fd; | ||
75 | |||
76 | if (listen(fd, 1) < 0) { | ||
77 | perror("listen"); | ||
78 | goto out; | ||
79 | } | ||
80 | return fd; | ||
81 | out: | ||
82 | close(fd); | ||
83 | return ret; | ||
84 | } | ||
85 | |||
86 | int main(void) | ||
87 | { | ||
88 | int listenfd; | ||
89 | int fd1, fd2; | ||
90 | |||
91 | fprintf(stderr, "Opening 127.0.0.1:%d\n", PORT); | ||
92 | listenfd = open_port(0, 0); | ||
93 | if (listenfd < 0) | ||
94 | error(1, errno, "Couldn't open listen socket"); | ||
95 | fprintf(stderr, "Opening INADDR_ANY:%d\n", PORT); | ||
96 | fd1 = open_port(0, 1); | ||
97 | if (fd1 >= 0) | ||
98 | error(1, 0, "Was allowed to create an ipv4 reuseport on a already bound non-reuseport socket"); | ||
99 | fprintf(stderr, "Opening in6addr_any:%d\n", PORT); | ||
100 | fd1 = open_port(1, 1); | ||
101 | if (fd1 < 0) | ||
102 | error(1, errno, "Couldn't open ipv6 reuseport"); | ||
103 | fprintf(stderr, "Opening INADDR_ANY:%d\n", PORT); | ||
104 | fd2 = open_port(0, 1); | ||
105 | if (fd2 >= 0) | ||
106 | error(1, 0, "Was allowed to create an ipv4 reuseport on a already bound non-reuseport socket"); | ||
107 | close(fd1); | ||
108 | fprintf(stderr, "Opening INADDR_ANY:%d after closing ipv6 socket\n", PORT); | ||
109 | fd1 = open_port(0, 1); | ||
110 | if (fd1 >= 0) | ||
111 | error(1, 0, "Was allowed to create an ipv4 reuseport on an already bound non-reuseport socket with no ipv6"); | ||
112 | fprintf(stderr, "Success"); | ||
113 | return 0; | ||
114 | } | ||
diff --git a/tools/testing/selftests/networking/timestamping/rxtimestamp.c b/tools/testing/selftests/networking/timestamping/rxtimestamp.c index 00f286661dcd..dd4162fc0419 100644 --- a/tools/testing/selftests/networking/timestamping/rxtimestamp.c +++ b/tools/testing/selftests/networking/timestamping/rxtimestamp.c | |||
@@ -341,7 +341,7 @@ int main(int argc, char **argv) | |||
341 | return 0; | 341 | return 0; |
342 | case 'n': | 342 | case 'n': |
343 | t = atoi(optarg); | 343 | t = atoi(optarg); |
344 | if (t > ARRAY_SIZE(test_cases)) | 344 | if (t >= ARRAY_SIZE(test_cases)) |
345 | error(1, 0, "Invalid test case: %d", t); | 345 | error(1, 0, "Invalid test case: %d", t); |
346 | all_tests = false; | 346 | all_tests = false; |
347 | test_cases[t].enabled = true; | 347 | test_cases[t].enabled = true; |
diff --git a/tools/testing/selftests/seccomp/Makefile b/tools/testing/selftests/seccomp/Makefile index aeb0c805f3ca..553d870b4ca9 100644 --- a/tools/testing/selftests/seccomp/Makefile +++ b/tools/testing/selftests/seccomp/Makefile | |||
@@ -1,8 +1,16 @@ | |||
1 | TEST_GEN_PROGS := seccomp_bpf | 1 | all: |
2 | CFLAGS += -Wl,-no-as-needed -Wall | ||
3 | LDFLAGS += -lpthread | ||
4 | 2 | ||
5 | include ../lib.mk | 3 | include ../lib.mk |
6 | 4 | ||
7 | $(TEST_GEN_PROGS): seccomp_bpf.c ../kselftest_harness.h | 5 | .PHONY: all clean |
8 | $(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ | 6 | |
7 | BINARIES := seccomp_bpf seccomp_benchmark | ||
8 | CFLAGS += -Wl,-no-as-needed -Wall | ||
9 | |||
10 | seccomp_bpf: seccomp_bpf.c ../kselftest_harness.h | ||
11 | $(CC) $(CFLAGS) $(LDFLAGS) -lpthread $< -o $@ | ||
12 | |||
13 | TEST_PROGS += $(BINARIES) | ||
14 | EXTRA_CLEAN := $(BINARIES) | ||
15 | |||
16 | all: $(BINARIES) | ||
diff --git a/tools/testing/selftests/seccomp/seccomp_benchmark.c b/tools/testing/selftests/seccomp/seccomp_benchmark.c new file mode 100644 index 000000000000..5838c8697ec3 --- /dev/null +++ b/tools/testing/selftests/seccomp/seccomp_benchmark.c | |||
@@ -0,0 +1,99 @@ | |||
1 | /* | ||
2 | * Strictly speaking, this is not a test. But it can report during test | ||
3 | * runs so relative performace can be measured. | ||
4 | */ | ||
5 | #define _GNU_SOURCE | ||
6 | #include <assert.h> | ||
7 | #include <stdio.h> | ||
8 | #include <stdlib.h> | ||
9 | #include <time.h> | ||
10 | #include <unistd.h> | ||
11 | #include <linux/filter.h> | ||
12 | #include <linux/seccomp.h> | ||
13 | #include <sys/prctl.h> | ||
14 | #include <sys/syscall.h> | ||
15 | #include <sys/types.h> | ||
16 | |||
17 | #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) | ||
18 | |||
19 | unsigned long long timing(clockid_t clk_id, unsigned long long samples) | ||
20 | { | ||
21 | pid_t pid, ret; | ||
22 | unsigned long long i; | ||
23 | struct timespec start, finish; | ||
24 | |||
25 | pid = getpid(); | ||
26 | assert(clock_gettime(clk_id, &start) == 0); | ||
27 | for (i = 0; i < samples; i++) { | ||
28 | ret = syscall(__NR_getpid); | ||
29 | assert(pid == ret); | ||
30 | } | ||
31 | assert(clock_gettime(clk_id, &finish) == 0); | ||
32 | |||
33 | i = finish.tv_sec - start.tv_sec; | ||
34 | i *= 1000000000; | ||
35 | i += finish.tv_nsec - start.tv_nsec; | ||
36 | |||
37 | printf("%lu.%09lu - %lu.%09lu = %llu\n", | ||
38 | finish.tv_sec, finish.tv_nsec, | ||
39 | start.tv_sec, start.tv_nsec, | ||
40 | i); | ||
41 | |||
42 | return i; | ||
43 | } | ||
44 | |||
45 | unsigned long long calibrate(void) | ||
46 | { | ||
47 | unsigned long long i; | ||
48 | |||
49 | printf("Calibrating reasonable sample size...\n"); | ||
50 | |||
51 | for (i = 5; ; i++) { | ||
52 | unsigned long long samples = 1 << i; | ||
53 | |||
54 | /* Find something that takes more than 5 seconds to run. */ | ||
55 | if (timing(CLOCK_REALTIME, samples) / 1000000000ULL > 5) | ||
56 | return samples; | ||
57 | } | ||
58 | } | ||
59 | |||
60 | int main(int argc, char *argv[]) | ||
61 | { | ||
62 | struct sock_filter filter[] = { | ||
63 | BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW), | ||
64 | }; | ||
65 | struct sock_fprog prog = { | ||
66 | .len = (unsigned short)ARRAY_SIZE(filter), | ||
67 | .filter = filter, | ||
68 | }; | ||
69 | long ret; | ||
70 | unsigned long long samples; | ||
71 | unsigned long long native, filtered; | ||
72 | |||
73 | if (argc > 1) | ||
74 | samples = strtoull(argv[1], NULL, 0); | ||
75 | else | ||
76 | samples = calibrate(); | ||
77 | |||
78 | printf("Benchmarking %llu samples...\n", samples); | ||
79 | |||
80 | native = timing(CLOCK_PROCESS_CPUTIME_ID, samples) / samples; | ||
81 | printf("getpid native: %llu ns\n", native); | ||
82 | |||
83 | ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); | ||
84 | assert(ret == 0); | ||
85 | |||
86 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog); | ||
87 | assert(ret == 0); | ||
88 | |||
89 | filtered = timing(CLOCK_PROCESS_CPUTIME_ID, samples) / samples; | ||
90 | printf("getpid RET_ALLOW: %llu ns\n", filtered); | ||
91 | |||
92 | printf("Estimated seccomp overhead per syscall: %llu ns\n", | ||
93 | filtered - native); | ||
94 | |||
95 | if (filtered == native) | ||
96 | printf("Trying running again with more samples.\n"); | ||
97 | |||
98 | return 0; | ||
99 | } | ||
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c index 4d6f92a9df6b..24dbf634e2dd 100644 --- a/tools/testing/selftests/seccomp/seccomp_bpf.c +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c | |||
@@ -6,10 +6,18 @@ | |||
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include <sys/types.h> | 8 | #include <sys/types.h> |
9 | #include <asm/siginfo.h> | 9 | |
10 | #define __have_siginfo_t 1 | 10 | /* |
11 | #define __have_sigval_t 1 | 11 | * glibc 2.26 and later have SIGSYS in siginfo_t. Before that, |
12 | #define __have_sigevent_t 1 | 12 | * we need to use the kernel's siginfo.h file and trick glibc |
13 | * into accepting it. | ||
14 | */ | ||
15 | #if !__GLIBC_PREREQ(2, 26) | ||
16 | # include <asm/siginfo.h> | ||
17 | # define __have_siginfo_t 1 | ||
18 | # define __have_sigval_t 1 | ||
19 | # define __have_sigevent_t 1 | ||
20 | #endif | ||
13 | 21 | ||
14 | #include <errno.h> | 22 | #include <errno.h> |
15 | #include <linux/filter.h> | 23 | #include <linux/filter.h> |
@@ -68,17 +76,7 @@ | |||
68 | #define SECCOMP_MODE_FILTER 2 | 76 | #define SECCOMP_MODE_FILTER 2 |
69 | #endif | 77 | #endif |
70 | 78 | ||
71 | #ifndef SECCOMP_RET_KILL | 79 | #ifndef SECCOMP_RET_ALLOW |
72 | #define SECCOMP_RET_KILL 0x00000000U /* kill the task immediately */ | ||
73 | #define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */ | ||
74 | #define SECCOMP_RET_ERRNO 0x00050000U /* returns an errno */ | ||
75 | #define SECCOMP_RET_TRACE 0x7ff00000U /* pass to a tracer or disallow */ | ||
76 | #define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */ | ||
77 | |||
78 | /* Masks for the return value sections. */ | ||
79 | #define SECCOMP_RET_ACTION 0x7fff0000U | ||
80 | #define SECCOMP_RET_DATA 0x0000ffffU | ||
81 | |||
82 | struct seccomp_data { | 80 | struct seccomp_data { |
83 | int nr; | 81 | int nr; |
84 | __u32 arch; | 82 | __u32 arch; |
@@ -87,6 +85,70 @@ struct seccomp_data { | |||
87 | }; | 85 | }; |
88 | #endif | 86 | #endif |
89 | 87 | ||
88 | #ifndef SECCOMP_RET_KILL_PROCESS | ||
89 | #define SECCOMP_RET_KILL_PROCESS 0x80000000U /* kill the process */ | ||
90 | #define SECCOMP_RET_KILL_THREAD 0x00000000U /* kill the thread */ | ||
91 | #endif | ||
92 | #ifndef SECCOMP_RET_KILL | ||
93 | #define SECCOMP_RET_KILL SECCOMP_RET_KILL_THREAD | ||
94 | #define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */ | ||
95 | #define SECCOMP_RET_ERRNO 0x00050000U /* returns an errno */ | ||
96 | #define SECCOMP_RET_TRACE 0x7ff00000U /* pass to a tracer or disallow */ | ||
97 | #define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */ | ||
98 | #endif | ||
99 | #ifndef SECCOMP_RET_LOG | ||
100 | #define SECCOMP_RET_LOG 0x7ffc0000U /* allow after logging */ | ||
101 | #endif | ||
102 | |||
103 | #ifndef __NR_seccomp | ||
104 | # if defined(__i386__) | ||
105 | # define __NR_seccomp 354 | ||
106 | # elif defined(__x86_64__) | ||
107 | # define __NR_seccomp 317 | ||
108 | # elif defined(__arm__) | ||
109 | # define __NR_seccomp 383 | ||
110 | # elif defined(__aarch64__) | ||
111 | # define __NR_seccomp 277 | ||
112 | # elif defined(__hppa__) | ||
113 | # define __NR_seccomp 338 | ||
114 | # elif defined(__powerpc__) | ||
115 | # define __NR_seccomp 358 | ||
116 | # elif defined(__s390__) | ||
117 | # define __NR_seccomp 348 | ||
118 | # else | ||
119 | # warning "seccomp syscall number unknown for this architecture" | ||
120 | # define __NR_seccomp 0xffff | ||
121 | # endif | ||
122 | #endif | ||
123 | |||
124 | #ifndef SECCOMP_SET_MODE_STRICT | ||
125 | #define SECCOMP_SET_MODE_STRICT 0 | ||
126 | #endif | ||
127 | |||
128 | #ifndef SECCOMP_SET_MODE_FILTER | ||
129 | #define SECCOMP_SET_MODE_FILTER 1 | ||
130 | #endif | ||
131 | |||
132 | #ifndef SECCOMP_GET_ACTION_AVAIL | ||
133 | #define SECCOMP_GET_ACTION_AVAIL 2 | ||
134 | #endif | ||
135 | |||
136 | #ifndef SECCOMP_FILTER_FLAG_TSYNC | ||
137 | #define SECCOMP_FILTER_FLAG_TSYNC 1 | ||
138 | #endif | ||
139 | |||
140 | #ifndef SECCOMP_FILTER_FLAG_LOG | ||
141 | #define SECCOMP_FILTER_FLAG_LOG 2 | ||
142 | #endif | ||
143 | |||
144 | #ifndef seccomp | ||
145 | int seccomp(unsigned int op, unsigned int flags, void *args) | ||
146 | { | ||
147 | errno = 0; | ||
148 | return syscall(__NR_seccomp, op, flags, args); | ||
149 | } | ||
150 | #endif | ||
151 | |||
90 | #if __BYTE_ORDER == __LITTLE_ENDIAN | 152 | #if __BYTE_ORDER == __LITTLE_ENDIAN |
91 | #define syscall_arg(_n) (offsetof(struct seccomp_data, args[_n])) | 153 | #define syscall_arg(_n) (offsetof(struct seccomp_data, args[_n])) |
92 | #elif __BYTE_ORDER == __BIG_ENDIAN | 154 | #elif __BYTE_ORDER == __BIG_ENDIAN |
@@ -136,7 +198,7 @@ TEST(no_new_privs_support) | |||
136 | } | 198 | } |
137 | } | 199 | } |
138 | 200 | ||
139 | /* Tests kernel support by checking for a copy_from_user() fault on * NULL. */ | 201 | /* Tests kernel support by checking for a copy_from_user() fault on NULL. */ |
140 | TEST(mode_filter_support) | 202 | TEST(mode_filter_support) |
141 | { | 203 | { |
142 | long ret; | 204 | long ret; |
@@ -342,6 +404,28 @@ TEST(empty_prog) | |||
342 | EXPECT_EQ(EINVAL, errno); | 404 | EXPECT_EQ(EINVAL, errno); |
343 | } | 405 | } |
344 | 406 | ||
407 | TEST(log_all) | ||
408 | { | ||
409 | struct sock_filter filter[] = { | ||
410 | BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_LOG), | ||
411 | }; | ||
412 | struct sock_fprog prog = { | ||
413 | .len = (unsigned short)ARRAY_SIZE(filter), | ||
414 | .filter = filter, | ||
415 | }; | ||
416 | long ret; | ||
417 | pid_t parent = getppid(); | ||
418 | |||
419 | ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); | ||
420 | ASSERT_EQ(0, ret); | ||
421 | |||
422 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog); | ||
423 | ASSERT_EQ(0, ret); | ||
424 | |||
425 | /* getppid() should succeed and be logged (no check for logging) */ | ||
426 | EXPECT_EQ(parent, syscall(__NR_getppid)); | ||
427 | } | ||
428 | |||
345 | TEST_SIGNAL(unknown_ret_is_kill_inside, SIGSYS) | 429 | TEST_SIGNAL(unknown_ret_is_kill_inside, SIGSYS) |
346 | { | 430 | { |
347 | struct sock_filter filter[] = { | 431 | struct sock_filter filter[] = { |
@@ -520,6 +604,117 @@ TEST_SIGNAL(KILL_one_arg_six, SIGSYS) | |||
520 | close(fd); | 604 | close(fd); |
521 | } | 605 | } |
522 | 606 | ||
607 | /* This is a thread task to die via seccomp filter violation. */ | ||
608 | void *kill_thread(void *data) | ||
609 | { | ||
610 | bool die = (bool)data; | ||
611 | |||
612 | if (die) { | ||
613 | prctl(PR_GET_SECCOMP, 0, 0, 0, 0); | ||
614 | return (void *)SIBLING_EXIT_FAILURE; | ||
615 | } | ||
616 | |||
617 | return (void *)SIBLING_EXIT_UNKILLED; | ||
618 | } | ||
619 | |||
620 | /* Prepare a thread that will kill itself or both of us. */ | ||
621 | void kill_thread_or_group(struct __test_metadata *_metadata, bool kill_process) | ||
622 | { | ||
623 | pthread_t thread; | ||
624 | void *status; | ||
625 | /* Kill only when calling __NR_prctl. */ | ||
626 | struct sock_filter filter_thread[] = { | ||
627 | BPF_STMT(BPF_LD|BPF_W|BPF_ABS, | ||
628 | offsetof(struct seccomp_data, nr)), | ||
629 | BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_prctl, 0, 1), | ||
630 | BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL_THREAD), | ||
631 | BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW), | ||
632 | }; | ||
633 | struct sock_fprog prog_thread = { | ||
634 | .len = (unsigned short)ARRAY_SIZE(filter_thread), | ||
635 | .filter = filter_thread, | ||
636 | }; | ||
637 | struct sock_filter filter_process[] = { | ||
638 | BPF_STMT(BPF_LD|BPF_W|BPF_ABS, | ||
639 | offsetof(struct seccomp_data, nr)), | ||
640 | BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_prctl, 0, 1), | ||
641 | BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL_PROCESS), | ||
642 | BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW), | ||
643 | }; | ||
644 | struct sock_fprog prog_process = { | ||
645 | .len = (unsigned short)ARRAY_SIZE(filter_process), | ||
646 | .filter = filter_process, | ||
647 | }; | ||
648 | |||
649 | ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { | ||
650 | TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!"); | ||
651 | } | ||
652 | |||
653 | ASSERT_EQ(0, seccomp(SECCOMP_SET_MODE_FILTER, 0, | ||
654 | kill_process ? &prog_process : &prog_thread)); | ||
655 | |||
656 | /* | ||
657 | * Add the KILL_THREAD rule again to make sure that the KILL_PROCESS | ||
658 | * flag cannot be downgraded by a new filter. | ||
659 | */ | ||
660 | ASSERT_EQ(0, seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog_thread)); | ||
661 | |||
662 | /* Start a thread that will exit immediately. */ | ||
663 | ASSERT_EQ(0, pthread_create(&thread, NULL, kill_thread, (void *)false)); | ||
664 | ASSERT_EQ(0, pthread_join(thread, &status)); | ||
665 | ASSERT_EQ(SIBLING_EXIT_UNKILLED, (unsigned long)status); | ||
666 | |||
667 | /* Start a thread that will die immediately. */ | ||
668 | ASSERT_EQ(0, pthread_create(&thread, NULL, kill_thread, (void *)true)); | ||
669 | ASSERT_EQ(0, pthread_join(thread, &status)); | ||
670 | ASSERT_NE(SIBLING_EXIT_FAILURE, (unsigned long)status); | ||
671 | |||
672 | /* | ||
673 | * If we get here, only the spawned thread died. Let the parent know | ||
674 | * the whole process didn't die (i.e. this thread, the spawner, | ||
675 | * stayed running). | ||
676 | */ | ||
677 | exit(42); | ||
678 | } | ||
679 | |||
680 | TEST(KILL_thread) | ||
681 | { | ||
682 | int status; | ||
683 | pid_t child_pid; | ||
684 | |||
685 | child_pid = fork(); | ||
686 | ASSERT_LE(0, child_pid); | ||
687 | if (child_pid == 0) { | ||
688 | kill_thread_or_group(_metadata, false); | ||
689 | _exit(38); | ||
690 | } | ||
691 | |||
692 | ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0)); | ||
693 | |||
694 | /* If only the thread was killed, we'll see exit 42. */ | ||
695 | ASSERT_TRUE(WIFEXITED(status)); | ||
696 | ASSERT_EQ(42, WEXITSTATUS(status)); | ||
697 | } | ||
698 | |||
699 | TEST(KILL_process) | ||
700 | { | ||
701 | int status; | ||
702 | pid_t child_pid; | ||
703 | |||
704 | child_pid = fork(); | ||
705 | ASSERT_LE(0, child_pid); | ||
706 | if (child_pid == 0) { | ||
707 | kill_thread_or_group(_metadata, true); | ||
708 | _exit(38); | ||
709 | } | ||
710 | |||
711 | ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0)); | ||
712 | |||
713 | /* If the entire process was killed, we'll see SIGSYS. */ | ||
714 | ASSERT_TRUE(WIFSIGNALED(status)); | ||
715 | ASSERT_EQ(SIGSYS, WTERMSIG(status)); | ||
716 | } | ||
717 | |||
523 | /* TODO(wad) add 64-bit versus 32-bit arg tests. */ | 718 | /* TODO(wad) add 64-bit versus 32-bit arg tests. */ |
524 | TEST(arg_out_of_range) | 719 | TEST(arg_out_of_range) |
525 | { | 720 | { |
@@ -541,26 +736,30 @@ TEST(arg_out_of_range) | |||
541 | EXPECT_EQ(EINVAL, errno); | 736 | EXPECT_EQ(EINVAL, errno); |
542 | } | 737 | } |
543 | 738 | ||
739 | #define ERRNO_FILTER(name, errno) \ | ||
740 | struct sock_filter _read_filter_##name[] = { \ | ||
741 | BPF_STMT(BPF_LD|BPF_W|BPF_ABS, \ | ||
742 | offsetof(struct seccomp_data, nr)), \ | ||
743 | BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_read, 0, 1), \ | ||
744 | BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ERRNO | errno), \ | ||
745 | BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW), \ | ||
746 | }; \ | ||
747 | struct sock_fprog prog_##name = { \ | ||
748 | .len = (unsigned short)ARRAY_SIZE(_read_filter_##name), \ | ||
749 | .filter = _read_filter_##name, \ | ||
750 | } | ||
751 | |||
752 | /* Make sure basic errno values are correctly passed through a filter. */ | ||
544 | TEST(ERRNO_valid) | 753 | TEST(ERRNO_valid) |
545 | { | 754 | { |
546 | struct sock_filter filter[] = { | 755 | ERRNO_FILTER(valid, E2BIG); |
547 | BPF_STMT(BPF_LD|BPF_W|BPF_ABS, | ||
548 | offsetof(struct seccomp_data, nr)), | ||
549 | BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_read, 0, 1), | ||
550 | BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ERRNO | E2BIG), | ||
551 | BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW), | ||
552 | }; | ||
553 | struct sock_fprog prog = { | ||
554 | .len = (unsigned short)ARRAY_SIZE(filter), | ||
555 | .filter = filter, | ||
556 | }; | ||
557 | long ret; | 756 | long ret; |
558 | pid_t parent = getppid(); | 757 | pid_t parent = getppid(); |
559 | 758 | ||
560 | ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); | 759 | ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); |
561 | ASSERT_EQ(0, ret); | 760 | ASSERT_EQ(0, ret); |
562 | 761 | ||
563 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog); | 762 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog_valid); |
564 | ASSERT_EQ(0, ret); | 763 | ASSERT_EQ(0, ret); |
565 | 764 | ||
566 | EXPECT_EQ(parent, syscall(__NR_getppid)); | 765 | EXPECT_EQ(parent, syscall(__NR_getppid)); |
@@ -568,26 +767,17 @@ TEST(ERRNO_valid) | |||
568 | EXPECT_EQ(E2BIG, errno); | 767 | EXPECT_EQ(E2BIG, errno); |
569 | } | 768 | } |
570 | 769 | ||
770 | /* Make sure an errno of zero is correctly handled by the arch code. */ | ||
571 | TEST(ERRNO_zero) | 771 | TEST(ERRNO_zero) |
572 | { | 772 | { |
573 | struct sock_filter filter[] = { | 773 | ERRNO_FILTER(zero, 0); |
574 | BPF_STMT(BPF_LD|BPF_W|BPF_ABS, | ||
575 | offsetof(struct seccomp_data, nr)), | ||
576 | BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_read, 0, 1), | ||
577 | BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ERRNO | 0), | ||
578 | BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW), | ||
579 | }; | ||
580 | struct sock_fprog prog = { | ||
581 | .len = (unsigned short)ARRAY_SIZE(filter), | ||
582 | .filter = filter, | ||
583 | }; | ||
584 | long ret; | 774 | long ret; |
585 | pid_t parent = getppid(); | 775 | pid_t parent = getppid(); |
586 | 776 | ||
587 | ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); | 777 | ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); |
588 | ASSERT_EQ(0, ret); | 778 | ASSERT_EQ(0, ret); |
589 | 779 | ||
590 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog); | 780 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog_zero); |
591 | ASSERT_EQ(0, ret); | 781 | ASSERT_EQ(0, ret); |
592 | 782 | ||
593 | EXPECT_EQ(parent, syscall(__NR_getppid)); | 783 | EXPECT_EQ(parent, syscall(__NR_getppid)); |
@@ -595,26 +785,21 @@ TEST(ERRNO_zero) | |||
595 | EXPECT_EQ(0, read(0, NULL, 0)); | 785 | EXPECT_EQ(0, read(0, NULL, 0)); |
596 | } | 786 | } |
597 | 787 | ||
788 | /* | ||
789 | * The SECCOMP_RET_DATA mask is 16 bits wide, but errno is smaller. | ||
790 | * This tests that the errno value gets capped correctly, fixed by | ||
791 | * 580c57f10768 ("seccomp: cap SECCOMP_RET_ERRNO data to MAX_ERRNO"). | ||
792 | */ | ||
598 | TEST(ERRNO_capped) | 793 | TEST(ERRNO_capped) |
599 | { | 794 | { |
600 | struct sock_filter filter[] = { | 795 | ERRNO_FILTER(capped, 4096); |
601 | BPF_STMT(BPF_LD|BPF_W|BPF_ABS, | ||
602 | offsetof(struct seccomp_data, nr)), | ||
603 | BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_read, 0, 1), | ||
604 | BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ERRNO | 4096), | ||
605 | BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW), | ||
606 | }; | ||
607 | struct sock_fprog prog = { | ||
608 | .len = (unsigned short)ARRAY_SIZE(filter), | ||
609 | .filter = filter, | ||
610 | }; | ||
611 | long ret; | 796 | long ret; |
612 | pid_t parent = getppid(); | 797 | pid_t parent = getppid(); |
613 | 798 | ||
614 | ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); | 799 | ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); |
615 | ASSERT_EQ(0, ret); | 800 | ASSERT_EQ(0, ret); |
616 | 801 | ||
617 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog); | 802 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog_capped); |
618 | ASSERT_EQ(0, ret); | 803 | ASSERT_EQ(0, ret); |
619 | 804 | ||
620 | EXPECT_EQ(parent, syscall(__NR_getppid)); | 805 | EXPECT_EQ(parent, syscall(__NR_getppid)); |
@@ -622,6 +807,37 @@ TEST(ERRNO_capped) | |||
622 | EXPECT_EQ(4095, errno); | 807 | EXPECT_EQ(4095, errno); |
623 | } | 808 | } |
624 | 809 | ||
810 | /* | ||
811 | * Filters are processed in reverse order: last applied is executed first. | ||
812 | * Since only the SECCOMP_RET_ACTION mask is tested for return values, the | ||
813 | * SECCOMP_RET_DATA mask results will follow the most recently applied | ||
814 | * matching filter return (and not the lowest or highest value). | ||
815 | */ | ||
816 | TEST(ERRNO_order) | ||
817 | { | ||
818 | ERRNO_FILTER(first, 11); | ||
819 | ERRNO_FILTER(second, 13); | ||
820 | ERRNO_FILTER(third, 12); | ||
821 | long ret; | ||
822 | pid_t parent = getppid(); | ||
823 | |||
824 | ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); | ||
825 | ASSERT_EQ(0, ret); | ||
826 | |||
827 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog_first); | ||
828 | ASSERT_EQ(0, ret); | ||
829 | |||
830 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog_second); | ||
831 | ASSERT_EQ(0, ret); | ||
832 | |||
833 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog_third); | ||
834 | ASSERT_EQ(0, ret); | ||
835 | |||
836 | EXPECT_EQ(parent, syscall(__NR_getppid)); | ||
837 | EXPECT_EQ(-1, read(0, NULL, 0)); | ||
838 | EXPECT_EQ(12, errno); | ||
839 | } | ||
840 | |||
625 | FIXTURE_DATA(TRAP) { | 841 | FIXTURE_DATA(TRAP) { |
626 | struct sock_fprog prog; | 842 | struct sock_fprog prog; |
627 | }; | 843 | }; |
@@ -676,7 +892,7 @@ TEST_F_SIGNAL(TRAP, ign, SIGSYS) | |||
676 | syscall(__NR_getpid); | 892 | syscall(__NR_getpid); |
677 | } | 893 | } |
678 | 894 | ||
679 | static struct siginfo TRAP_info; | 895 | static siginfo_t TRAP_info; |
680 | static volatile int TRAP_nr; | 896 | static volatile int TRAP_nr; |
681 | static void TRAP_action(int nr, siginfo_t *info, void *void_context) | 897 | static void TRAP_action(int nr, siginfo_t *info, void *void_context) |
682 | { | 898 | { |
@@ -735,6 +951,7 @@ TEST_F(TRAP, handler) | |||
735 | 951 | ||
736 | FIXTURE_DATA(precedence) { | 952 | FIXTURE_DATA(precedence) { |
737 | struct sock_fprog allow; | 953 | struct sock_fprog allow; |
954 | struct sock_fprog log; | ||
738 | struct sock_fprog trace; | 955 | struct sock_fprog trace; |
739 | struct sock_fprog error; | 956 | struct sock_fprog error; |
740 | struct sock_fprog trap; | 957 | struct sock_fprog trap; |
@@ -746,6 +963,13 @@ FIXTURE_SETUP(precedence) | |||
746 | struct sock_filter allow_insns[] = { | 963 | struct sock_filter allow_insns[] = { |
747 | BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW), | 964 | BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW), |
748 | }; | 965 | }; |
966 | struct sock_filter log_insns[] = { | ||
967 | BPF_STMT(BPF_LD|BPF_W|BPF_ABS, | ||
968 | offsetof(struct seccomp_data, nr)), | ||
969 | BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 1, 0), | ||
970 | BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW), | ||
971 | BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_LOG), | ||
972 | }; | ||
749 | struct sock_filter trace_insns[] = { | 973 | struct sock_filter trace_insns[] = { |
750 | BPF_STMT(BPF_LD|BPF_W|BPF_ABS, | 974 | BPF_STMT(BPF_LD|BPF_W|BPF_ABS, |
751 | offsetof(struct seccomp_data, nr)), | 975 | offsetof(struct seccomp_data, nr)), |
@@ -782,6 +1006,7 @@ FIXTURE_SETUP(precedence) | |||
782 | memcpy(self->_x.filter, &_x##_insns, sizeof(_x##_insns)); \ | 1006 | memcpy(self->_x.filter, &_x##_insns, sizeof(_x##_insns)); \ |
783 | self->_x.len = (unsigned short)ARRAY_SIZE(_x##_insns) | 1007 | self->_x.len = (unsigned short)ARRAY_SIZE(_x##_insns) |
784 | FILTER_ALLOC(allow); | 1008 | FILTER_ALLOC(allow); |
1009 | FILTER_ALLOC(log); | ||
785 | FILTER_ALLOC(trace); | 1010 | FILTER_ALLOC(trace); |
786 | FILTER_ALLOC(error); | 1011 | FILTER_ALLOC(error); |
787 | FILTER_ALLOC(trap); | 1012 | FILTER_ALLOC(trap); |
@@ -792,6 +1017,7 @@ FIXTURE_TEARDOWN(precedence) | |||
792 | { | 1017 | { |
793 | #define FILTER_FREE(_x) if (self->_x.filter) free(self->_x.filter) | 1018 | #define FILTER_FREE(_x) if (self->_x.filter) free(self->_x.filter) |
794 | FILTER_FREE(allow); | 1019 | FILTER_FREE(allow); |
1020 | FILTER_FREE(log); | ||
795 | FILTER_FREE(trace); | 1021 | FILTER_FREE(trace); |
796 | FILTER_FREE(error); | 1022 | FILTER_FREE(error); |
797 | FILTER_FREE(trap); | 1023 | FILTER_FREE(trap); |
@@ -809,6 +1035,8 @@ TEST_F(precedence, allow_ok) | |||
809 | 1035 | ||
810 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow); | 1036 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow); |
811 | ASSERT_EQ(0, ret); | 1037 | ASSERT_EQ(0, ret); |
1038 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log); | ||
1039 | ASSERT_EQ(0, ret); | ||
812 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace); | 1040 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace); |
813 | ASSERT_EQ(0, ret); | 1041 | ASSERT_EQ(0, ret); |
814 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error); | 1042 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error); |
@@ -833,6 +1061,8 @@ TEST_F_SIGNAL(precedence, kill_is_highest, SIGSYS) | |||
833 | 1061 | ||
834 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow); | 1062 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow); |
835 | ASSERT_EQ(0, ret); | 1063 | ASSERT_EQ(0, ret); |
1064 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log); | ||
1065 | ASSERT_EQ(0, ret); | ||
836 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace); | 1066 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace); |
837 | ASSERT_EQ(0, ret); | 1067 | ASSERT_EQ(0, ret); |
838 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error); | 1068 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error); |
@@ -864,6 +1094,8 @@ TEST_F_SIGNAL(precedence, kill_is_highest_in_any_order, SIGSYS) | |||
864 | ASSERT_EQ(0, ret); | 1094 | ASSERT_EQ(0, ret); |
865 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error); | 1095 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error); |
866 | ASSERT_EQ(0, ret); | 1096 | ASSERT_EQ(0, ret); |
1097 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log); | ||
1098 | ASSERT_EQ(0, ret); | ||
867 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace); | 1099 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace); |
868 | ASSERT_EQ(0, ret); | 1100 | ASSERT_EQ(0, ret); |
869 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trap); | 1101 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trap); |
@@ -885,6 +1117,8 @@ TEST_F_SIGNAL(precedence, trap_is_second, SIGSYS) | |||
885 | 1117 | ||
886 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow); | 1118 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow); |
887 | ASSERT_EQ(0, ret); | 1119 | ASSERT_EQ(0, ret); |
1120 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log); | ||
1121 | ASSERT_EQ(0, ret); | ||
888 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace); | 1122 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace); |
889 | ASSERT_EQ(0, ret); | 1123 | ASSERT_EQ(0, ret); |
890 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error); | 1124 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error); |
@@ -910,6 +1144,8 @@ TEST_F_SIGNAL(precedence, trap_is_second_in_any_order, SIGSYS) | |||
910 | ASSERT_EQ(0, ret); | 1144 | ASSERT_EQ(0, ret); |
911 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trap); | 1145 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trap); |
912 | ASSERT_EQ(0, ret); | 1146 | ASSERT_EQ(0, ret); |
1147 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log); | ||
1148 | ASSERT_EQ(0, ret); | ||
913 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace); | 1149 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace); |
914 | ASSERT_EQ(0, ret); | 1150 | ASSERT_EQ(0, ret); |
915 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error); | 1151 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error); |
@@ -931,6 +1167,8 @@ TEST_F(precedence, errno_is_third) | |||
931 | 1167 | ||
932 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow); | 1168 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow); |
933 | ASSERT_EQ(0, ret); | 1169 | ASSERT_EQ(0, ret); |
1170 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log); | ||
1171 | ASSERT_EQ(0, ret); | ||
934 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace); | 1172 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace); |
935 | ASSERT_EQ(0, ret); | 1173 | ASSERT_EQ(0, ret); |
936 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error); | 1174 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error); |
@@ -949,6 +1187,8 @@ TEST_F(precedence, errno_is_third_in_any_order) | |||
949 | ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); | 1187 | ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); |
950 | ASSERT_EQ(0, ret); | 1188 | ASSERT_EQ(0, ret); |
951 | 1189 | ||
1190 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log); | ||
1191 | ASSERT_EQ(0, ret); | ||
952 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error); | 1192 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error); |
953 | ASSERT_EQ(0, ret); | 1193 | ASSERT_EQ(0, ret); |
954 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace); | 1194 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace); |
@@ -971,6 +1211,8 @@ TEST_F(precedence, trace_is_fourth) | |||
971 | 1211 | ||
972 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow); | 1212 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow); |
973 | ASSERT_EQ(0, ret); | 1213 | ASSERT_EQ(0, ret); |
1214 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log); | ||
1215 | ASSERT_EQ(0, ret); | ||
974 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace); | 1216 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace); |
975 | ASSERT_EQ(0, ret); | 1217 | ASSERT_EQ(0, ret); |
976 | /* Should work just fine. */ | 1218 | /* Should work just fine. */ |
@@ -992,12 +1234,54 @@ TEST_F(precedence, trace_is_fourth_in_any_order) | |||
992 | ASSERT_EQ(0, ret); | 1234 | ASSERT_EQ(0, ret); |
993 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow); | 1235 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow); |
994 | ASSERT_EQ(0, ret); | 1236 | ASSERT_EQ(0, ret); |
1237 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log); | ||
1238 | ASSERT_EQ(0, ret); | ||
995 | /* Should work just fine. */ | 1239 | /* Should work just fine. */ |
996 | EXPECT_EQ(parent, syscall(__NR_getppid)); | 1240 | EXPECT_EQ(parent, syscall(__NR_getppid)); |
997 | /* No ptracer */ | 1241 | /* No ptracer */ |
998 | EXPECT_EQ(-1, syscall(__NR_getpid)); | 1242 | EXPECT_EQ(-1, syscall(__NR_getpid)); |
999 | } | 1243 | } |
1000 | 1244 | ||
1245 | TEST_F(precedence, log_is_fifth) | ||
1246 | { | ||
1247 | pid_t mypid, parent; | ||
1248 | long ret; | ||
1249 | |||
1250 | mypid = getpid(); | ||
1251 | parent = getppid(); | ||
1252 | ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); | ||
1253 | ASSERT_EQ(0, ret); | ||
1254 | |||
1255 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow); | ||
1256 | ASSERT_EQ(0, ret); | ||
1257 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log); | ||
1258 | ASSERT_EQ(0, ret); | ||
1259 | /* Should work just fine. */ | ||
1260 | EXPECT_EQ(parent, syscall(__NR_getppid)); | ||
1261 | /* Should also work just fine */ | ||
1262 | EXPECT_EQ(mypid, syscall(__NR_getpid)); | ||
1263 | } | ||
1264 | |||
1265 | TEST_F(precedence, log_is_fifth_in_any_order) | ||
1266 | { | ||
1267 | pid_t mypid, parent; | ||
1268 | long ret; | ||
1269 | |||
1270 | mypid = getpid(); | ||
1271 | parent = getppid(); | ||
1272 | ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); | ||
1273 | ASSERT_EQ(0, ret); | ||
1274 | |||
1275 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log); | ||
1276 | ASSERT_EQ(0, ret); | ||
1277 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow); | ||
1278 | ASSERT_EQ(0, ret); | ||
1279 | /* Should work just fine. */ | ||
1280 | EXPECT_EQ(parent, syscall(__NR_getppid)); | ||
1281 | /* Should also work just fine */ | ||
1282 | EXPECT_EQ(mypid, syscall(__NR_getpid)); | ||
1283 | } | ||
1284 | |||
1001 | #ifndef PTRACE_O_TRACESECCOMP | 1285 | #ifndef PTRACE_O_TRACESECCOMP |
1002 | #define PTRACE_O_TRACESECCOMP 0x00000080 | 1286 | #define PTRACE_O_TRACESECCOMP 0x00000080 |
1003 | #endif | 1287 | #endif |
@@ -1262,6 +1546,13 @@ TEST_F(TRACE_poke, getpid_runs_normally) | |||
1262 | # error "Do not know how to find your architecture's registers and syscalls" | 1546 | # error "Do not know how to find your architecture's registers and syscalls" |
1263 | #endif | 1547 | #endif |
1264 | 1548 | ||
1549 | /* When the syscall return can't be changed, stub out the tests for it. */ | ||
1550 | #ifdef SYSCALL_NUM_RET_SHARE_REG | ||
1551 | # define EXPECT_SYSCALL_RETURN(val, action) EXPECT_EQ(-1, action) | ||
1552 | #else | ||
1553 | # define EXPECT_SYSCALL_RETURN(val, action) EXPECT_EQ(val, action) | ||
1554 | #endif | ||
1555 | |||
1265 | /* Use PTRACE_GETREGS and PTRACE_SETREGS when available. This is useful for | 1556 | /* Use PTRACE_GETREGS and PTRACE_SETREGS when available. This is useful for |
1266 | * architectures without HAVE_ARCH_TRACEHOOK (e.g. User-mode Linux). | 1557 | * architectures without HAVE_ARCH_TRACEHOOK (e.g. User-mode Linux). |
1267 | */ | 1558 | */ |
@@ -1357,7 +1648,7 @@ void change_syscall(struct __test_metadata *_metadata, | |||
1357 | #ifdef SYSCALL_NUM_RET_SHARE_REG | 1648 | #ifdef SYSCALL_NUM_RET_SHARE_REG |
1358 | TH_LOG("Can't modify syscall return on this architecture"); | 1649 | TH_LOG("Can't modify syscall return on this architecture"); |
1359 | #else | 1650 | #else |
1360 | regs.SYSCALL_RET = 1; | 1651 | regs.SYSCALL_RET = EPERM; |
1361 | #endif | 1652 | #endif |
1362 | 1653 | ||
1363 | #ifdef HAVE_GETREGS | 1654 | #ifdef HAVE_GETREGS |
@@ -1426,6 +1717,8 @@ void tracer_ptrace(struct __test_metadata *_metadata, pid_t tracee, | |||
1426 | 1717 | ||
1427 | if (nr == __NR_getpid) | 1718 | if (nr == __NR_getpid) |
1428 | change_syscall(_metadata, tracee, __NR_getppid); | 1719 | change_syscall(_metadata, tracee, __NR_getppid); |
1720 | if (nr == __NR_open) | ||
1721 | change_syscall(_metadata, tracee, -1); | ||
1429 | } | 1722 | } |
1430 | 1723 | ||
1431 | FIXTURE_DATA(TRACE_syscall) { | 1724 | FIXTURE_DATA(TRACE_syscall) { |
@@ -1480,6 +1773,28 @@ FIXTURE_TEARDOWN(TRACE_syscall) | |||
1480 | free(self->prog.filter); | 1773 | free(self->prog.filter); |
1481 | } | 1774 | } |
1482 | 1775 | ||
1776 | TEST_F(TRACE_syscall, ptrace_syscall_redirected) | ||
1777 | { | ||
1778 | /* Swap SECCOMP_RET_TRACE tracer for PTRACE_SYSCALL tracer. */ | ||
1779 | teardown_trace_fixture(_metadata, self->tracer); | ||
1780 | self->tracer = setup_trace_fixture(_metadata, tracer_ptrace, NULL, | ||
1781 | true); | ||
1782 | |||
1783 | /* Tracer will redirect getpid to getppid. */ | ||
1784 | EXPECT_NE(self->mypid, syscall(__NR_getpid)); | ||
1785 | } | ||
1786 | |||
1787 | TEST_F(TRACE_syscall, ptrace_syscall_dropped) | ||
1788 | { | ||
1789 | /* Swap SECCOMP_RET_TRACE tracer for PTRACE_SYSCALL tracer. */ | ||
1790 | teardown_trace_fixture(_metadata, self->tracer); | ||
1791 | self->tracer = setup_trace_fixture(_metadata, tracer_ptrace, NULL, | ||
1792 | true); | ||
1793 | |||
1794 | /* Tracer should skip the open syscall, resulting in EPERM. */ | ||
1795 | EXPECT_SYSCALL_RETURN(EPERM, syscall(__NR_open)); | ||
1796 | } | ||
1797 | |||
1483 | TEST_F(TRACE_syscall, syscall_allowed) | 1798 | TEST_F(TRACE_syscall, syscall_allowed) |
1484 | { | 1799 | { |
1485 | long ret; | 1800 | long ret; |
@@ -1520,13 +1835,8 @@ TEST_F(TRACE_syscall, syscall_dropped) | |||
1520 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog, 0, 0); | 1835 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog, 0, 0); |
1521 | ASSERT_EQ(0, ret); | 1836 | ASSERT_EQ(0, ret); |
1522 | 1837 | ||
1523 | #ifdef SYSCALL_NUM_RET_SHARE_REG | ||
1524 | /* gettid has been skipped */ | ||
1525 | EXPECT_EQ(-1, syscall(__NR_gettid)); | ||
1526 | #else | ||
1527 | /* gettid has been skipped and an altered return value stored. */ | 1838 | /* gettid has been skipped and an altered return value stored. */ |
1528 | EXPECT_EQ(1, syscall(__NR_gettid)); | 1839 | EXPECT_SYSCALL_RETURN(EPERM, syscall(__NR_gettid)); |
1529 | #endif | ||
1530 | EXPECT_NE(self->mytid, syscall(__NR_gettid)); | 1840 | EXPECT_NE(self->mytid, syscall(__NR_gettid)); |
1531 | } | 1841 | } |
1532 | 1842 | ||
@@ -1557,6 +1867,7 @@ TEST_F(TRACE_syscall, skip_after_RET_TRACE) | |||
1557 | ASSERT_EQ(0, ret); | 1867 | ASSERT_EQ(0, ret); |
1558 | 1868 | ||
1559 | /* Tracer will redirect getpid to getppid, and we should see EPERM. */ | 1869 | /* Tracer will redirect getpid to getppid, and we should see EPERM. */ |
1870 | errno = 0; | ||
1560 | EXPECT_EQ(-1, syscall(__NR_getpid)); | 1871 | EXPECT_EQ(-1, syscall(__NR_getpid)); |
1561 | EXPECT_EQ(EPERM, errno); | 1872 | EXPECT_EQ(EPERM, errno); |
1562 | } | 1873 | } |
@@ -1654,47 +1965,6 @@ TEST_F_SIGNAL(TRACE_syscall, kill_after_ptrace, SIGSYS) | |||
1654 | EXPECT_NE(self->mypid, syscall(__NR_getpid)); | 1965 | EXPECT_NE(self->mypid, syscall(__NR_getpid)); |
1655 | } | 1966 | } |
1656 | 1967 | ||
1657 | #ifndef __NR_seccomp | ||
1658 | # if defined(__i386__) | ||
1659 | # define __NR_seccomp 354 | ||
1660 | # elif defined(__x86_64__) | ||
1661 | # define __NR_seccomp 317 | ||
1662 | # elif defined(__arm__) | ||
1663 | # define __NR_seccomp 383 | ||
1664 | # elif defined(__aarch64__) | ||
1665 | # define __NR_seccomp 277 | ||
1666 | # elif defined(__hppa__) | ||
1667 | # define __NR_seccomp 338 | ||
1668 | # elif defined(__powerpc__) | ||
1669 | # define __NR_seccomp 358 | ||
1670 | # elif defined(__s390__) | ||
1671 | # define __NR_seccomp 348 | ||
1672 | # else | ||
1673 | # warning "seccomp syscall number unknown for this architecture" | ||
1674 | # define __NR_seccomp 0xffff | ||
1675 | # endif | ||
1676 | #endif | ||
1677 | |||
1678 | #ifndef SECCOMP_SET_MODE_STRICT | ||
1679 | #define SECCOMP_SET_MODE_STRICT 0 | ||
1680 | #endif | ||
1681 | |||
1682 | #ifndef SECCOMP_SET_MODE_FILTER | ||
1683 | #define SECCOMP_SET_MODE_FILTER 1 | ||
1684 | #endif | ||
1685 | |||
1686 | #ifndef SECCOMP_FILTER_FLAG_TSYNC | ||
1687 | #define SECCOMP_FILTER_FLAG_TSYNC 1 | ||
1688 | #endif | ||
1689 | |||
1690 | #ifndef seccomp | ||
1691 | int seccomp(unsigned int op, unsigned int flags, void *args) | ||
1692 | { | ||
1693 | errno = 0; | ||
1694 | return syscall(__NR_seccomp, op, flags, args); | ||
1695 | } | ||
1696 | #endif | ||
1697 | |||
1698 | TEST(seccomp_syscall) | 1968 | TEST(seccomp_syscall) |
1699 | { | 1969 | { |
1700 | struct sock_filter filter[] = { | 1970 | struct sock_filter filter[] = { |
@@ -1783,6 +2053,67 @@ TEST(seccomp_syscall_mode_lock) | |||
1783 | } | 2053 | } |
1784 | } | 2054 | } |
1785 | 2055 | ||
2056 | /* | ||
2057 | * Test detection of known and unknown filter flags. Userspace needs to be able | ||
2058 | * to check if a filter flag is supported by the current kernel and a good way | ||
2059 | * of doing that is by attempting to enter filter mode, with the flag bit in | ||
2060 | * question set, and a NULL pointer for the _args_ parameter. EFAULT indicates | ||
2061 | * that the flag is valid and EINVAL indicates that the flag is invalid. | ||
2062 | */ | ||
2063 | TEST(detect_seccomp_filter_flags) | ||
2064 | { | ||
2065 | unsigned int flags[] = { SECCOMP_FILTER_FLAG_TSYNC, | ||
2066 | SECCOMP_FILTER_FLAG_LOG }; | ||
2067 | unsigned int flag, all_flags; | ||
2068 | int i; | ||
2069 | long ret; | ||
2070 | |||
2071 | /* Test detection of known-good filter flags */ | ||
2072 | for (i = 0, all_flags = 0; i < ARRAY_SIZE(flags); i++) { | ||
2073 | flag = flags[i]; | ||
2074 | ret = seccomp(SECCOMP_SET_MODE_FILTER, flag, NULL); | ||
2075 | ASSERT_NE(ENOSYS, errno) { | ||
2076 | TH_LOG("Kernel does not support seccomp syscall!"); | ||
2077 | } | ||
2078 | EXPECT_EQ(-1, ret); | ||
2079 | EXPECT_EQ(EFAULT, errno) { | ||
2080 | TH_LOG("Failed to detect that a known-good filter flag (0x%X) is supported!", | ||
2081 | flag); | ||
2082 | } | ||
2083 | |||
2084 | all_flags |= flag; | ||
2085 | } | ||
2086 | |||
2087 | /* Test detection of all known-good filter flags */ | ||
2088 | ret = seccomp(SECCOMP_SET_MODE_FILTER, all_flags, NULL); | ||
2089 | EXPECT_EQ(-1, ret); | ||
2090 | EXPECT_EQ(EFAULT, errno) { | ||
2091 | TH_LOG("Failed to detect that all known-good filter flags (0x%X) are supported!", | ||
2092 | all_flags); | ||
2093 | } | ||
2094 | |||
2095 | /* Test detection of an unknown filter flag */ | ||
2096 | flag = -1; | ||
2097 | ret = seccomp(SECCOMP_SET_MODE_FILTER, flag, NULL); | ||
2098 | EXPECT_EQ(-1, ret); | ||
2099 | EXPECT_EQ(EINVAL, errno) { | ||
2100 | TH_LOG("Failed to detect that an unknown filter flag (0x%X) is unsupported!", | ||
2101 | flag); | ||
2102 | } | ||
2103 | |||
2104 | /* | ||
2105 | * Test detection of an unknown filter flag that may simply need to be | ||
2106 | * added to this test | ||
2107 | */ | ||
2108 | flag = flags[ARRAY_SIZE(flags) - 1] << 1; | ||
2109 | ret = seccomp(SECCOMP_SET_MODE_FILTER, flag, NULL); | ||
2110 | EXPECT_EQ(-1, ret); | ||
2111 | EXPECT_EQ(EINVAL, errno) { | ||
2112 | TH_LOG("Failed to detect that an unknown filter flag (0x%X) is unsupported! Does a new flag need to be added to this test?", | ||
2113 | flag); | ||
2114 | } | ||
2115 | } | ||
2116 | |||
1786 | TEST(TSYNC_first) | 2117 | TEST(TSYNC_first) |
1787 | { | 2118 | { |
1788 | struct sock_filter filter[] = { | 2119 | struct sock_filter filter[] = { |
@@ -2421,6 +2752,99 @@ TEST(syscall_restart) | |||
2421 | _metadata->passed = 0; | 2752 | _metadata->passed = 0; |
2422 | } | 2753 | } |
2423 | 2754 | ||
2755 | TEST_SIGNAL(filter_flag_log, SIGSYS) | ||
2756 | { | ||
2757 | struct sock_filter allow_filter[] = { | ||
2758 | BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW), | ||
2759 | }; | ||
2760 | struct sock_filter kill_filter[] = { | ||
2761 | BPF_STMT(BPF_LD|BPF_W|BPF_ABS, | ||
2762 | offsetof(struct seccomp_data, nr)), | ||
2763 | BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 0, 1), | ||
2764 | BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL), | ||
2765 | BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW), | ||
2766 | }; | ||
2767 | struct sock_fprog allow_prog = { | ||
2768 | .len = (unsigned short)ARRAY_SIZE(allow_filter), | ||
2769 | .filter = allow_filter, | ||
2770 | }; | ||
2771 | struct sock_fprog kill_prog = { | ||
2772 | .len = (unsigned short)ARRAY_SIZE(kill_filter), | ||
2773 | .filter = kill_filter, | ||
2774 | }; | ||
2775 | long ret; | ||
2776 | pid_t parent = getppid(); | ||
2777 | |||
2778 | ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); | ||
2779 | ASSERT_EQ(0, ret); | ||
2780 | |||
2781 | /* Verify that the FILTER_FLAG_LOG flag isn't accepted in strict mode */ | ||
2782 | ret = seccomp(SECCOMP_SET_MODE_STRICT, SECCOMP_FILTER_FLAG_LOG, | ||
2783 | &allow_prog); | ||
2784 | ASSERT_NE(ENOSYS, errno) { | ||
2785 | TH_LOG("Kernel does not support seccomp syscall!"); | ||
2786 | } | ||
2787 | EXPECT_NE(0, ret) { | ||
2788 | TH_LOG("Kernel accepted FILTER_FLAG_LOG flag in strict mode!"); | ||
2789 | } | ||
2790 | EXPECT_EQ(EINVAL, errno) { | ||
2791 | TH_LOG("Kernel returned unexpected errno for FILTER_FLAG_LOG flag in strict mode!"); | ||
2792 | } | ||
2793 | |||
2794 | /* Verify that a simple, permissive filter can be added with no flags */ | ||
2795 | ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, &allow_prog); | ||
2796 | EXPECT_EQ(0, ret); | ||
2797 | |||
2798 | /* See if the same filter can be added with the FILTER_FLAG_LOG flag */ | ||
2799 | ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_LOG, | ||
2800 | &allow_prog); | ||
2801 | ASSERT_NE(EINVAL, errno) { | ||
2802 | TH_LOG("Kernel does not support the FILTER_FLAG_LOG flag!"); | ||
2803 | } | ||
2804 | EXPECT_EQ(0, ret); | ||
2805 | |||
2806 | /* Ensure that the kill filter works with the FILTER_FLAG_LOG flag */ | ||
2807 | ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_LOG, | ||
2808 | &kill_prog); | ||
2809 | EXPECT_EQ(0, ret); | ||
2810 | |||
2811 | EXPECT_EQ(parent, syscall(__NR_getppid)); | ||
2812 | /* getpid() should never return. */ | ||
2813 | EXPECT_EQ(0, syscall(__NR_getpid)); | ||
2814 | } | ||
2815 | |||
2816 | TEST(get_action_avail) | ||
2817 | { | ||
2818 | __u32 actions[] = { SECCOMP_RET_KILL_THREAD, SECCOMP_RET_TRAP, | ||
2819 | SECCOMP_RET_ERRNO, SECCOMP_RET_TRACE, | ||
2820 | SECCOMP_RET_LOG, SECCOMP_RET_ALLOW }; | ||
2821 | __u32 unknown_action = 0x10000000U; | ||
2822 | int i; | ||
2823 | long ret; | ||
2824 | |||
2825 | ret = seccomp(SECCOMP_GET_ACTION_AVAIL, 0, &actions[0]); | ||
2826 | ASSERT_NE(ENOSYS, errno) { | ||
2827 | TH_LOG("Kernel does not support seccomp syscall!"); | ||
2828 | } | ||
2829 | ASSERT_NE(EINVAL, errno) { | ||
2830 | TH_LOG("Kernel does not support SECCOMP_GET_ACTION_AVAIL operation!"); | ||
2831 | } | ||
2832 | EXPECT_EQ(ret, 0); | ||
2833 | |||
2834 | for (i = 0; i < ARRAY_SIZE(actions); i++) { | ||
2835 | ret = seccomp(SECCOMP_GET_ACTION_AVAIL, 0, &actions[i]); | ||
2836 | EXPECT_EQ(ret, 0) { | ||
2837 | TH_LOG("Expected action (0x%X) not available!", | ||
2838 | actions[i]); | ||
2839 | } | ||
2840 | } | ||
2841 | |||
2842 | /* Check that an unknown action is handled properly (EOPNOTSUPP) */ | ||
2843 | ret = seccomp(SECCOMP_GET_ACTION_AVAIL, 0, &unknown_action); | ||
2844 | EXPECT_EQ(ret, -1); | ||
2845 | EXPECT_EQ(errno, EOPNOTSUPP); | ||
2846 | } | ||
2847 | |||
2424 | /* | 2848 | /* |
2425 | * TODO: | 2849 | * TODO: |
2426 | * - add microbenchmarks | 2850 | * - add microbenchmarks |
@@ -2429,6 +2853,8 @@ TEST(syscall_restart) | |||
2429 | * - endianness checking when appropriate | 2853 | * - endianness checking when appropriate |
2430 | * - 64-bit arg prodding | 2854 | * - 64-bit arg prodding |
2431 | * - arch value testing (x86 modes especially) | 2855 | * - arch value testing (x86 modes especially) |
2856 | * - verify that FILTER_FLAG_LOG filters generate log messages | ||
2857 | * - verify that RET_LOG generates log messages | ||
2432 | * - ... | 2858 | * - ... |
2433 | */ | 2859 | */ |
2434 | 2860 | ||
diff --git a/tools/testing/selftests/sigaltstack/sas.c b/tools/testing/selftests/sigaltstack/sas.c index 7d406c3973ba..97bb150837df 100644 --- a/tools/testing/selftests/sigaltstack/sas.c +++ b/tools/testing/selftests/sigaltstack/sas.c | |||
@@ -39,7 +39,11 @@ void my_usr1(int sig, siginfo_t *si, void *u) | |||
39 | stack_t stk; | 39 | stack_t stk; |
40 | struct stk_data *p; | 40 | struct stk_data *p; |
41 | 41 | ||
42 | #if __s390x__ | ||
43 | register unsigned long sp asm("%15"); | ||
44 | #else | ||
42 | register unsigned long sp asm("sp"); | 45 | register unsigned long sp asm("sp"); |
46 | #endif | ||
43 | 47 | ||
44 | if (sp < (unsigned long)sstack || | 48 | if (sp < (unsigned long)sstack || |
45 | sp >= (unsigned long)sstack + SIGSTKSZ) { | 49 | sp >= (unsigned long)sstack + SIGSTKSZ) { |
diff --git a/tools/testing/selftests/sync/Makefile b/tools/testing/selftests/sync/Makefile index 4981c6b6d050..8e04d0afcbd7 100644 --- a/tools/testing/selftests/sync/Makefile +++ b/tools/testing/selftests/sync/Makefile | |||
@@ -2,12 +2,16 @@ CFLAGS += -O2 -g -std=gnu89 -pthread -Wall -Wextra | |||
2 | CFLAGS += -I../../../../usr/include/ | 2 | CFLAGS += -I../../../../usr/include/ |
3 | LDFLAGS += -pthread | 3 | LDFLAGS += -pthread |
4 | 4 | ||
5 | TEST_PROGS = sync_test | 5 | .PHONY: all clean |
6 | |||
7 | all: $(TEST_PROGS) | ||
8 | 6 | ||
9 | include ../lib.mk | 7 | include ../lib.mk |
10 | 8 | ||
9 | # lib.mk TEST_CUSTOM_PROGS var is for custom tests that need special | ||
10 | # build rules. lib.mk will run and install them. | ||
11 | |||
12 | TEST_CUSTOM_PROGS := $(OUTPUT)/sync_test | ||
13 | all: $(TEST_CUSTOM_PROGS) | ||
14 | |||
11 | OBJS = sync_test.o sync.o | 15 | OBJS = sync_test.o sync.o |
12 | 16 | ||
13 | TESTS += sync_alloc.o | 17 | TESTS += sync_alloc.o |
@@ -18,6 +22,16 @@ TESTS += sync_stress_parallelism.o | |||
18 | TESTS += sync_stress_consumer.o | 22 | TESTS += sync_stress_consumer.o |
19 | TESTS += sync_stress_merge.o | 23 | TESTS += sync_stress_merge.o |
20 | 24 | ||
21 | sync_test: $(OBJS) $(TESTS) | 25 | OBJS := $(patsubst %,$(OUTPUT)/%,$(OBJS)) |
26 | TESTS := $(patsubst %,$(OUTPUT)/%,$(TESTS)) | ||
27 | |||
28 | $(TEST_CUSTOM_PROGS): $(TESTS) $(OBJS) | ||
29 | $(CC) -o $(TEST_CUSTOM_PROGS) $(OBJS) $(TESTS) $(CFLAGS) $(LDFLAGS) | ||
30 | |||
31 | $(OBJS): $(OUTPUT)/%.o: %.c | ||
32 | $(CC) -c $^ -o $@ | ||
33 | |||
34 | $(TESTS): $(OUTPUT)/%.o: %.c | ||
35 | $(CC) -c $^ -o $@ | ||
22 | 36 | ||
23 | EXTRA_CLEAN := sync_test $(OBJS) $(TESTS) | 37 | EXTRA_CLEAN := $(TEST_CUSTOM_PROGS) $(OBJS) $(TESTS) |
diff --git a/tools/testing/selftests/timers/set-timer-lat.c b/tools/testing/selftests/timers/set-timer-lat.c index 9c92b7bd5641..50da45437daa 100644 --- a/tools/testing/selftests/timers/set-timer-lat.c +++ b/tools/testing/selftests/timers/set-timer-lat.c | |||
@@ -143,7 +143,8 @@ int setup_timer(int clock_id, int flags, int interval, timer_t *tm1) | |||
143 | printf("%-22s %s missing CAP_WAKE_ALARM? : [UNSUPPORTED]\n", | 143 | printf("%-22s %s missing CAP_WAKE_ALARM? : [UNSUPPORTED]\n", |
144 | clockstring(clock_id), | 144 | clockstring(clock_id), |
145 | flags ? "ABSTIME":"RELTIME"); | 145 | flags ? "ABSTIME":"RELTIME"); |
146 | return 0; | 146 | /* Indicate timer isn't set, so caller doesn't wait */ |
147 | return 1; | ||
147 | } | 148 | } |
148 | printf("%s - timer_create() failed\n", clockstring(clock_id)); | 149 | printf("%s - timer_create() failed\n", clockstring(clock_id)); |
149 | return -1; | 150 | return -1; |
@@ -213,8 +214,9 @@ int do_timer(int clock_id, int flags) | |||
213 | int err; | 214 | int err; |
214 | 215 | ||
215 | err = setup_timer(clock_id, flags, interval, &tm1); | 216 | err = setup_timer(clock_id, flags, interval, &tm1); |
217 | /* Unsupported case - return 0 to not fail the test */ | ||
216 | if (err) | 218 | if (err) |
217 | return err; | 219 | return err == 1 ? 0 : err; |
218 | 220 | ||
219 | while (alarmcount < 5) | 221 | while (alarmcount < 5) |
220 | sleep(1); | 222 | sleep(1); |
@@ -228,18 +230,17 @@ int do_timer_oneshot(int clock_id, int flags) | |||
228 | timer_t tm1; | 230 | timer_t tm1; |
229 | const int interval = 0; | 231 | const int interval = 0; |
230 | struct timeval timeout; | 232 | struct timeval timeout; |
231 | fd_set fds; | ||
232 | int err; | 233 | int err; |
233 | 234 | ||
234 | err = setup_timer(clock_id, flags, interval, &tm1); | 235 | err = setup_timer(clock_id, flags, interval, &tm1); |
236 | /* Unsupported case - return 0 to not fail the test */ | ||
235 | if (err) | 237 | if (err) |
236 | return err; | 238 | return err == 1 ? 0 : err; |
237 | 239 | ||
238 | memset(&timeout, 0, sizeof(timeout)); | 240 | memset(&timeout, 0, sizeof(timeout)); |
239 | timeout.tv_sec = 5; | 241 | timeout.tv_sec = 5; |
240 | FD_ZERO(&fds); | ||
241 | do { | 242 | do { |
242 | err = select(FD_SETSIZE, &fds, NULL, NULL, &timeout); | 243 | err = select(0, NULL, NULL, NULL, &timeout); |
243 | } while (err == -1 && errno == EINTR); | 244 | } while (err == -1 && errno == EINTR); |
244 | 245 | ||
245 | timer_delete(tm1); | 246 | timer_delete(tm1); |
diff --git a/tools/testing/selftests/vm/userfaultfd.c b/tools/testing/selftests/vm/userfaultfd.c index a2c53a3d223d..de2f9ec8a87f 100644 --- a/tools/testing/selftests/vm/userfaultfd.c +++ b/tools/testing/selftests/vm/userfaultfd.c | |||
@@ -397,7 +397,7 @@ static void retry_copy_page(int ufd, struct uffdio_copy *uffdio_copy, | |||
397 | } | 397 | } |
398 | } | 398 | } |
399 | 399 | ||
400 | static int copy_page(int ufd, unsigned long offset) | 400 | static int __copy_page(int ufd, unsigned long offset, bool retry) |
401 | { | 401 | { |
402 | struct uffdio_copy uffdio_copy; | 402 | struct uffdio_copy uffdio_copy; |
403 | 403 | ||
@@ -418,7 +418,7 @@ static int copy_page(int ufd, unsigned long offset) | |||
418 | fprintf(stderr, "UFFDIO_COPY unexpected copy %Ld\n", | 418 | fprintf(stderr, "UFFDIO_COPY unexpected copy %Ld\n", |
419 | uffdio_copy.copy), exit(1); | 419 | uffdio_copy.copy), exit(1); |
420 | } else { | 420 | } else { |
421 | if (test_uffdio_copy_eexist) { | 421 | if (test_uffdio_copy_eexist && retry) { |
422 | test_uffdio_copy_eexist = false; | 422 | test_uffdio_copy_eexist = false; |
423 | retry_copy_page(ufd, &uffdio_copy, offset); | 423 | retry_copy_page(ufd, &uffdio_copy, offset); |
424 | } | 424 | } |
@@ -427,6 +427,16 @@ static int copy_page(int ufd, unsigned long offset) | |||
427 | return 0; | 427 | return 0; |
428 | } | 428 | } |
429 | 429 | ||
430 | static int copy_page_retry(int ufd, unsigned long offset) | ||
431 | { | ||
432 | return __copy_page(ufd, offset, true); | ||
433 | } | ||
434 | |||
435 | static int copy_page(int ufd, unsigned long offset) | ||
436 | { | ||
437 | return __copy_page(ufd, offset, false); | ||
438 | } | ||
439 | |||
430 | static void *uffd_poll_thread(void *arg) | 440 | static void *uffd_poll_thread(void *arg) |
431 | { | 441 | { |
432 | unsigned long cpu = (unsigned long) arg; | 442 | unsigned long cpu = (unsigned long) arg; |
@@ -544,7 +554,7 @@ static void *background_thread(void *arg) | |||
544 | for (page_nr = cpu * nr_pages_per_cpu; | 554 | for (page_nr = cpu * nr_pages_per_cpu; |
545 | page_nr < (cpu+1) * nr_pages_per_cpu; | 555 | page_nr < (cpu+1) * nr_pages_per_cpu; |
546 | page_nr++) | 556 | page_nr++) |
547 | copy_page(uffd, page_nr * page_size); | 557 | copy_page_retry(uffd, page_nr * page_size); |
548 | 558 | ||
549 | return NULL; | 559 | return NULL; |
550 | } | 560 | } |
@@ -779,7 +789,7 @@ static void retry_uffdio_zeropage(int ufd, | |||
779 | } | 789 | } |
780 | } | 790 | } |
781 | 791 | ||
782 | static int uffdio_zeropage(int ufd, unsigned long offset) | 792 | static int __uffdio_zeropage(int ufd, unsigned long offset, bool retry) |
783 | { | 793 | { |
784 | struct uffdio_zeropage uffdio_zeropage; | 794 | struct uffdio_zeropage uffdio_zeropage; |
785 | int ret; | 795 | int ret; |
@@ -814,7 +824,7 @@ static int uffdio_zeropage(int ufd, unsigned long offset) | |||
814 | fprintf(stderr, "UFFDIO_ZEROPAGE unexpected %Ld\n", | 824 | fprintf(stderr, "UFFDIO_ZEROPAGE unexpected %Ld\n", |
815 | uffdio_zeropage.zeropage), exit(1); | 825 | uffdio_zeropage.zeropage), exit(1); |
816 | } else { | 826 | } else { |
817 | if (test_uffdio_zeropage_eexist) { | 827 | if (test_uffdio_zeropage_eexist && retry) { |
818 | test_uffdio_zeropage_eexist = false; | 828 | test_uffdio_zeropage_eexist = false; |
819 | retry_uffdio_zeropage(ufd, &uffdio_zeropage, | 829 | retry_uffdio_zeropage(ufd, &uffdio_zeropage, |
820 | offset); | 830 | offset); |
@@ -830,6 +840,11 @@ static int uffdio_zeropage(int ufd, unsigned long offset) | |||
830 | return 0; | 840 | return 0; |
831 | } | 841 | } |
832 | 842 | ||
843 | static int uffdio_zeropage(int ufd, unsigned long offset) | ||
844 | { | ||
845 | return __uffdio_zeropage(ufd, offset, false); | ||
846 | } | ||
847 | |||
833 | /* exercise UFFDIO_ZEROPAGE */ | 848 | /* exercise UFFDIO_ZEROPAGE */ |
834 | static int userfaultfd_zeropage_test(void) | 849 | static int userfaultfd_zeropage_test(void) |
835 | { | 850 | { |
diff --git a/tools/testing/selftests/watchdog/Makefile b/tools/testing/selftests/watchdog/Makefile index f863c664e3d1..ee068511fd0b 100644 --- a/tools/testing/selftests/watchdog/Makefile +++ b/tools/testing/selftests/watchdog/Makefile | |||
@@ -1,8 +1,3 @@ | |||
1 | TEST_PROGS := watchdog-test | 1 | TEST_GEN_PROGS := watchdog-test |
2 | |||
3 | all: $(TEST_PROGS) | ||
4 | 2 | ||
5 | include ../lib.mk | 3 | include ../lib.mk |
6 | |||
7 | clean: | ||
8 | rm -fr $(TEST_PROGS) | ||
diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile index 97f187e2663f..0a74a20ca32b 100644 --- a/tools/testing/selftests/x86/Makefile +++ b/tools/testing/selftests/x86/Makefile | |||
@@ -20,7 +20,7 @@ BINARIES_64 := $(TARGETS_C_64BIT_ALL:%=%_64) | |||
20 | BINARIES_32 := $(patsubst %,$(OUTPUT)/%,$(BINARIES_32)) | 20 | BINARIES_32 := $(patsubst %,$(OUTPUT)/%,$(BINARIES_32)) |
21 | BINARIES_64 := $(patsubst %,$(OUTPUT)/%,$(BINARIES_64)) | 21 | BINARIES_64 := $(patsubst %,$(OUTPUT)/%,$(BINARIES_64)) |
22 | 22 | ||
23 | CFLAGS := -O2 -g -std=gnu99 -pthread -Wall | 23 | CFLAGS := -O2 -g -std=gnu99 -pthread -Wall -no-pie |
24 | 24 | ||
25 | UNAME_M := $(shell uname -m) | 25 | UNAME_M := $(shell uname -m) |
26 | CAN_BUILD_I386 := $(shell ./check_cc.sh $(CC) trivial_32bit_program.c -m32) | 26 | CAN_BUILD_I386 := $(shell ./check_cc.sh $(CC) trivial_32bit_program.c -m32) |