aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-04-10 09:13:06 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-04-10 09:13:06 -0400
commit523aa3586ffb1fc11a9bf88f77ebaf71a15eb998 (patch)
tree1fe96f54e8f1e667798a49ae4b3f951feb136ae0 /tools
parentfd0f50db2eb72555ef8f70af14c1e3ee2079b32c (diff)
parent39da7c509acff13fc8cb12ec1bb20337c988ed36 (diff)
Merge 4.11-rc6 into driver-core-next
We want the fixes in here as well for testing. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'tools')
-rw-r--r--tools/include/linux/filter.h10
-rw-r--r--tools/testing/selftests/bpf/Makefile9
-rw-r--r--tools/testing/selftests/bpf/test_verifier.c290
-rw-r--r--tools/testing/selftests/powerpc/Makefile10
4 files changed, 308 insertions, 11 deletions
diff --git a/tools/include/linux/filter.h b/tools/include/linux/filter.h
index 122153b16ea4..390d7c9685fd 100644
--- a/tools/include/linux/filter.h
+++ b/tools/include/linux/filter.h
@@ -168,6 +168,16 @@
168 .off = OFF, \ 168 .off = OFF, \
169 .imm = 0 }) 169 .imm = 0 })
170 170
171/* Atomic memory add, *(uint *)(dst_reg + off16) += src_reg */
172
173#define BPF_STX_XADD(SIZE, DST, SRC, OFF) \
174 ((struct bpf_insn) { \
175 .code = BPF_STX | BPF_SIZE(SIZE) | BPF_XADD, \
176 .dst_reg = DST, \
177 .src_reg = SRC, \
178 .off = OFF, \
179 .imm = 0 })
180
171/* Memory store, *(uint *) (dst_reg + off16) = imm32 */ 181/* Memory store, *(uint *) (dst_reg + off16) = imm32 */
172 182
173#define BPF_ST_MEM(SIZE, DST, OFF, IMM) \ 183#define BPF_ST_MEM(SIZE, DST, OFF, IMM) \
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 6a1ad58cb66f..9af09e8099c0 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -1,7 +1,14 @@
1LIBDIR := ../../../lib 1LIBDIR := ../../../lib
2BPFDIR := $(LIBDIR)/bpf 2BPFDIR := $(LIBDIR)/bpf
3APIDIR := ../../../include/uapi
4GENDIR := ../../../../include/generated
5GENHDR := $(GENDIR)/autoconf.h
3 6
4CFLAGS += -Wall -O2 -I../../../include/uapi -I$(LIBDIR) 7ifneq ($(wildcard $(GENHDR)),)
8 GENFLAGS := -DHAVE_GENHDR
9endif
10
11CFLAGS += -Wall -O2 -I$(APIDIR) -I$(LIBDIR) -I$(GENDIR) $(GENFLAGS)
5LDLIBS += -lcap 12LDLIBS += -lcap
6 13
7TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map 14TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map
diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c
index d1555e4240c0..c848e90b6421 100644
--- a/tools/testing/selftests/bpf/test_verifier.c
+++ b/tools/testing/selftests/bpf/test_verifier.c
@@ -30,6 +30,14 @@
30 30
31#include <bpf/bpf.h> 31#include <bpf/bpf.h>
32 32
33#ifdef HAVE_GENHDR
34# include "autoconf.h"
35#else
36# if defined(__i386) || defined(__x86_64) || defined(__s390x__) || defined(__aarch64__)
37# define CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 1
38# endif
39#endif
40
33#include "../../../include/linux/filter.h" 41#include "../../../include/linux/filter.h"
34 42
35#ifndef ARRAY_SIZE 43#ifndef ARRAY_SIZE
@@ -39,6 +47,8 @@
39#define MAX_INSNS 512 47#define MAX_INSNS 512
40#define MAX_FIXUPS 8 48#define MAX_FIXUPS 8
41 49
50#define F_NEEDS_EFFICIENT_UNALIGNED_ACCESS (1 << 0)
51
42struct bpf_test { 52struct bpf_test {
43 const char *descr; 53 const char *descr;
44 struct bpf_insn insns[MAX_INSNS]; 54 struct bpf_insn insns[MAX_INSNS];
@@ -53,6 +63,7 @@ struct bpf_test {
53 REJECT 63 REJECT
54 } result, result_unpriv; 64 } result, result_unpriv;
55 enum bpf_prog_type prog_type; 65 enum bpf_prog_type prog_type;
66 uint8_t flags;
56}; 67};
57 68
58/* Note we want this to be 64 bit aligned so that the end of our array is 69/* Note we want this to be 64 bit aligned so that the end of our array is
@@ -2432,6 +2443,30 @@ static struct bpf_test tests[] = {
2432 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2443 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2433 }, 2444 },
2434 { 2445 {
2446 "direct packet access: test15 (spill with xadd)",
2447 .insns = {
2448 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2449 offsetof(struct __sk_buff, data)),
2450 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2451 offsetof(struct __sk_buff, data_end)),
2452 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2453 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
2454 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
2455 BPF_MOV64_IMM(BPF_REG_5, 4096),
2456 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
2457 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
2458 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
2459 BPF_STX_XADD(BPF_DW, BPF_REG_4, BPF_REG_5, 0),
2460 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
2461 BPF_STX_MEM(BPF_W, BPF_REG_2, BPF_REG_5, 0),
2462 BPF_MOV64_IMM(BPF_REG_0, 0),
2463 BPF_EXIT_INSN(),
2464 },
2465 .errstr = "R2 invalid mem access 'inv'",
2466 .result = REJECT,
2467 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2468 },
2469 {
2435 "helper access to packet: test1, valid packet_ptr range", 2470 "helper access to packet: test1, valid packet_ptr range",
2436 .insns = { 2471 .insns = {
2437 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 2472 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
@@ -2934,6 +2969,7 @@ static struct bpf_test tests[] = {
2934 .errstr_unpriv = "R0 pointer arithmetic prohibited", 2969 .errstr_unpriv = "R0 pointer arithmetic prohibited",
2935 .result_unpriv = REJECT, 2970 .result_unpriv = REJECT,
2936 .result = ACCEPT, 2971 .result = ACCEPT,
2972 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
2937 }, 2973 },
2938 { 2974 {
2939 "valid map access into an array with a variable", 2975 "valid map access into an array with a variable",
@@ -2957,6 +2993,7 @@ static struct bpf_test tests[] = {
2957 .errstr_unpriv = "R0 pointer arithmetic prohibited", 2993 .errstr_unpriv = "R0 pointer arithmetic prohibited",
2958 .result_unpriv = REJECT, 2994 .result_unpriv = REJECT,
2959 .result = ACCEPT, 2995 .result = ACCEPT,
2996 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
2960 }, 2997 },
2961 { 2998 {
2962 "valid map access into an array with a signed variable", 2999 "valid map access into an array with a signed variable",
@@ -2984,6 +3021,7 @@ static struct bpf_test tests[] = {
2984 .errstr_unpriv = "R0 pointer arithmetic prohibited", 3021 .errstr_unpriv = "R0 pointer arithmetic prohibited",
2985 .result_unpriv = REJECT, 3022 .result_unpriv = REJECT,
2986 .result = ACCEPT, 3023 .result = ACCEPT,
3024 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
2987 }, 3025 },
2988 { 3026 {
2989 "invalid map access into an array with a constant", 3027 "invalid map access into an array with a constant",
@@ -3025,6 +3063,7 @@ static struct bpf_test tests[] = {
3025 .errstr = "R0 min value is outside of the array range", 3063 .errstr = "R0 min value is outside of the array range",
3026 .result_unpriv = REJECT, 3064 .result_unpriv = REJECT,
3027 .result = REJECT, 3065 .result = REJECT,
3066 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
3028 }, 3067 },
3029 { 3068 {
3030 "invalid map access into an array with a variable", 3069 "invalid map access into an array with a variable",
@@ -3048,6 +3087,7 @@ static struct bpf_test tests[] = {
3048 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.", 3087 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
3049 .result_unpriv = REJECT, 3088 .result_unpriv = REJECT,
3050 .result = REJECT, 3089 .result = REJECT,
3090 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
3051 }, 3091 },
3052 { 3092 {
3053 "invalid map access into an array with no floor check", 3093 "invalid map access into an array with no floor check",
@@ -3074,6 +3114,7 @@ static struct bpf_test tests[] = {
3074 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.", 3114 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
3075 .result_unpriv = REJECT, 3115 .result_unpriv = REJECT,
3076 .result = REJECT, 3116 .result = REJECT,
3117 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
3077 }, 3118 },
3078 { 3119 {
3079 "invalid map access into an array with a invalid max check", 3120 "invalid map access into an array with a invalid max check",
@@ -3100,6 +3141,7 @@ static struct bpf_test tests[] = {
3100 .errstr = "invalid access to map value, value_size=48 off=44 size=8", 3141 .errstr = "invalid access to map value, value_size=48 off=44 size=8",
3101 .result_unpriv = REJECT, 3142 .result_unpriv = REJECT,
3102 .result = REJECT, 3143 .result = REJECT,
3144 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
3103 }, 3145 },
3104 { 3146 {
3105 "invalid map access into an array with a invalid max check", 3147 "invalid map access into an array with a invalid max check",
@@ -3129,6 +3171,7 @@ static struct bpf_test tests[] = {
3129 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.", 3171 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
3130 .result_unpriv = REJECT, 3172 .result_unpriv = REJECT,
3131 .result = REJECT, 3173 .result = REJECT,
3174 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
3132 }, 3175 },
3133 { 3176 {
3134 "multiple registers share map_lookup_elem result", 3177 "multiple registers share map_lookup_elem result",
@@ -3252,6 +3295,7 @@ static struct bpf_test tests[] = {
3252 .result = REJECT, 3295 .result = REJECT,
3253 .errstr_unpriv = "R0 pointer arithmetic prohibited", 3296 .errstr_unpriv = "R0 pointer arithmetic prohibited",
3254 .result_unpriv = REJECT, 3297 .result_unpriv = REJECT,
3298 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
3255 }, 3299 },
3256 { 3300 {
3257 "constant register |= constant should keep constant type", 3301 "constant register |= constant should keep constant type",
@@ -3418,6 +3462,26 @@ static struct bpf_test tests[] = {
3418 .prog_type = BPF_PROG_TYPE_LWT_XMIT, 3462 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
3419 }, 3463 },
3420 { 3464 {
3465 "overlapping checks for direct packet access",
3466 .insns = {
3467 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
3468 offsetof(struct __sk_buff, data)),
3469 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
3470 offsetof(struct __sk_buff, data_end)),
3471 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
3472 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
3473 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 4),
3474 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
3475 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
3476 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
3477 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_2, 6),
3478 BPF_MOV64_IMM(BPF_REG_0, 0),
3479 BPF_EXIT_INSN(),
3480 },
3481 .result = ACCEPT,
3482 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
3483 },
3484 {
3421 "invalid access of tc_classid for LWT_IN", 3485 "invalid access of tc_classid for LWT_IN",
3422 .insns = { 3486 .insns = {
3423 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 3487 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
@@ -3961,7 +4025,208 @@ static struct bpf_test tests[] = {
3961 .result_unpriv = REJECT, 4025 .result_unpriv = REJECT,
3962 }, 4026 },
3963 { 4027 {
3964 "map element value (adjusted) is preserved across register spilling", 4028 "map element value or null is marked on register spilling",
4029 .insns = {
4030 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4031 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4032 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4033 BPF_LD_MAP_FD(BPF_REG_1, 0),
4034 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4035 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4036 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -152),
4037 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
4038 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
4039 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
4040 BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
4041 BPF_EXIT_INSN(),
4042 },
4043 .fixup_map2 = { 3 },
4044 .errstr_unpriv = "R0 leaks addr",
4045 .result = ACCEPT,
4046 .result_unpriv = REJECT,
4047 },
4048 {
4049 "map element value store of cleared call register",
4050 .insns = {
4051 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4052 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4053 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4054 BPF_LD_MAP_FD(BPF_REG_1, 0),
4055 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4056 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
4057 BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
4058 BPF_EXIT_INSN(),
4059 },
4060 .fixup_map2 = { 3 },
4061 .errstr_unpriv = "R1 !read_ok",
4062 .errstr = "R1 !read_ok",
4063 .result = REJECT,
4064 .result_unpriv = REJECT,
4065 },
4066 {
4067 "map element value with unaligned store",
4068 .insns = {
4069 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4070 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4071 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4072 BPF_LD_MAP_FD(BPF_REG_1, 0),
4073 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4074 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 17),
4075 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 3),
4076 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
4077 BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 43),
4078 BPF_ST_MEM(BPF_DW, BPF_REG_0, -2, 44),
4079 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
4080 BPF_ST_MEM(BPF_DW, BPF_REG_8, 0, 32),
4081 BPF_ST_MEM(BPF_DW, BPF_REG_8, 2, 33),
4082 BPF_ST_MEM(BPF_DW, BPF_REG_8, -2, 34),
4083 BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, 5),
4084 BPF_ST_MEM(BPF_DW, BPF_REG_8, 0, 22),
4085 BPF_ST_MEM(BPF_DW, BPF_REG_8, 4, 23),
4086 BPF_ST_MEM(BPF_DW, BPF_REG_8, -7, 24),
4087 BPF_MOV64_REG(BPF_REG_7, BPF_REG_8),
4088 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 3),
4089 BPF_ST_MEM(BPF_DW, BPF_REG_7, 0, 22),
4090 BPF_ST_MEM(BPF_DW, BPF_REG_7, 4, 23),
4091 BPF_ST_MEM(BPF_DW, BPF_REG_7, -4, 24),
4092 BPF_EXIT_INSN(),
4093 },
4094 .fixup_map2 = { 3 },
4095 .errstr_unpriv = "R0 pointer arithmetic prohibited",
4096 .result = ACCEPT,
4097 .result_unpriv = REJECT,
4098 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
4099 },
4100 {
4101 "map element value with unaligned load",
4102 .insns = {
4103 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4104 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4105 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4106 BPF_LD_MAP_FD(BPF_REG_1, 0),
4107 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4108 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
4109 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4110 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES, 9),
4111 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 3),
4112 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
4113 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 2),
4114 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
4115 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_8, 0),
4116 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_8, 2),
4117 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 5),
4118 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
4119 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 4),
4120 BPF_EXIT_INSN(),
4121 },
4122 .fixup_map2 = { 3 },
4123 .errstr_unpriv = "R0 pointer arithmetic prohibited",
4124 .result = ACCEPT,
4125 .result_unpriv = REJECT,
4126 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
4127 },
4128 {
4129 "map element value illegal alu op, 1",
4130 .insns = {
4131 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4132 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4133 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4134 BPF_LD_MAP_FD(BPF_REG_1, 0),
4135 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4136 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
4137 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 8),
4138 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
4139 BPF_EXIT_INSN(),
4140 },
4141 .fixup_map2 = { 3 },
4142 .errstr_unpriv = "R0 pointer arithmetic prohibited",
4143 .errstr = "invalid mem access 'inv'",
4144 .result = REJECT,
4145 .result_unpriv = REJECT,
4146 },
4147 {
4148 "map element value illegal alu op, 2",
4149 .insns = {
4150 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4151 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4152 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4153 BPF_LD_MAP_FD(BPF_REG_1, 0),
4154 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4155 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
4156 BPF_ALU32_IMM(BPF_ADD, BPF_REG_0, 0),
4157 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
4158 BPF_EXIT_INSN(),
4159 },
4160 .fixup_map2 = { 3 },
4161 .errstr_unpriv = "R0 pointer arithmetic prohibited",
4162 .errstr = "invalid mem access 'inv'",
4163 .result = REJECT,
4164 .result_unpriv = REJECT,
4165 },
4166 {
4167 "map element value illegal alu op, 3",
4168 .insns = {
4169 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4170 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4171 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4172 BPF_LD_MAP_FD(BPF_REG_1, 0),
4173 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4174 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
4175 BPF_ALU64_IMM(BPF_DIV, BPF_REG_0, 42),
4176 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
4177 BPF_EXIT_INSN(),
4178 },
4179 .fixup_map2 = { 3 },
4180 .errstr_unpriv = "R0 pointer arithmetic prohibited",
4181 .errstr = "invalid mem access 'inv'",
4182 .result = REJECT,
4183 .result_unpriv = REJECT,
4184 },
4185 {
4186 "map element value illegal alu op, 4",
4187 .insns = {
4188 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4189 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4190 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4191 BPF_LD_MAP_FD(BPF_REG_1, 0),
4192 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4193 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
4194 BPF_ENDIAN(BPF_FROM_BE, BPF_REG_0, 64),
4195 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
4196 BPF_EXIT_INSN(),
4197 },
4198 .fixup_map2 = { 3 },
4199 .errstr_unpriv = "R0 pointer arithmetic prohibited",
4200 .errstr = "invalid mem access 'inv'",
4201 .result = REJECT,
4202 .result_unpriv = REJECT,
4203 },
4204 {
4205 "map element value illegal alu op, 5",
4206 .insns = {
4207 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4208 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4209 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4210 BPF_LD_MAP_FD(BPF_REG_1, 0),
4211 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4212 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
4213 BPF_MOV64_IMM(BPF_REG_3, 4096),
4214 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4215 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4216 BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
4217 BPF_STX_XADD(BPF_DW, BPF_REG_2, BPF_REG_3, 0),
4218 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 0),
4219 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22),
4220 BPF_EXIT_INSN(),
4221 },
4222 .fixup_map2 = { 3 },
4223 .errstr_unpriv = "R0 invalid mem access 'inv'",
4224 .errstr = "R0 invalid mem access 'inv'",
4225 .result = REJECT,
4226 .result_unpriv = REJECT,
4227 },
4228 {
4229 "map element value is preserved across register spilling",
3965 .insns = { 4230 .insns = {
3966 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 4231 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3967 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 4232 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
@@ -3983,6 +4248,7 @@ static struct bpf_test tests[] = {
3983 .errstr_unpriv = "R0 pointer arithmetic prohibited", 4248 .errstr_unpriv = "R0 pointer arithmetic prohibited",
3984 .result = ACCEPT, 4249 .result = ACCEPT,
3985 .result_unpriv = REJECT, 4250 .result_unpriv = REJECT,
4251 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
3986 }, 4252 },
3987 { 4253 {
3988 "helper access to variable memory: stack, bitwise AND + JMP, correct bounds", 4254 "helper access to variable memory: stack, bitwise AND + JMP, correct bounds",
@@ -4421,6 +4687,7 @@ static struct bpf_test tests[] = {
4421 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.", 4687 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
4422 .result = REJECT, 4688 .result = REJECT,
4423 .result_unpriv = REJECT, 4689 .result_unpriv = REJECT,
4690 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
4424 }, 4691 },
4425 { 4692 {
4426 "invalid range check", 4693 "invalid range check",
@@ -4452,6 +4719,7 @@ static struct bpf_test tests[] = {
4452 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.", 4719 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
4453 .result = REJECT, 4720 .result = REJECT,
4454 .result_unpriv = REJECT, 4721 .result_unpriv = REJECT,
4722 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
4455 } 4723 }
4456}; 4724};
4457 4725
@@ -4530,11 +4798,11 @@ static void do_test_fixup(struct bpf_test *test, struct bpf_insn *prog,
4530static void do_test_single(struct bpf_test *test, bool unpriv, 4798static void do_test_single(struct bpf_test *test, bool unpriv,
4531 int *passes, int *errors) 4799 int *passes, int *errors)
4532{ 4800{
4801 int fd_prog, expected_ret, reject_from_alignment;
4533 struct bpf_insn *prog = test->insns; 4802 struct bpf_insn *prog = test->insns;
4534 int prog_len = probe_filter_length(prog); 4803 int prog_len = probe_filter_length(prog);
4535 int prog_type = test->prog_type; 4804 int prog_type = test->prog_type;
4536 int fd_f1 = -1, fd_f2 = -1, fd_f3 = -1; 4805 int fd_f1 = -1, fd_f2 = -1, fd_f3 = -1;
4537 int fd_prog, expected_ret;
4538 const char *expected_err; 4806 const char *expected_err;
4539 4807
4540 do_test_fixup(test, prog, &fd_f1, &fd_f2, &fd_f3); 4808 do_test_fixup(test, prog, &fd_f1, &fd_f2, &fd_f3);
@@ -4547,8 +4815,19 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
4547 test->result_unpriv : test->result; 4815 test->result_unpriv : test->result;
4548 expected_err = unpriv && test->errstr_unpriv ? 4816 expected_err = unpriv && test->errstr_unpriv ?
4549 test->errstr_unpriv : test->errstr; 4817 test->errstr_unpriv : test->errstr;
4818
4819 reject_from_alignment = fd_prog < 0 &&
4820 (test->flags & F_NEEDS_EFFICIENT_UNALIGNED_ACCESS) &&
4821 strstr(bpf_vlog, "Unknown alignment.");
4822#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
4823 if (reject_from_alignment) {
4824 printf("FAIL\nFailed due to alignment despite having efficient unaligned access: '%s'!\n",
4825 strerror(errno));
4826 goto fail_log;
4827 }
4828#endif
4550 if (expected_ret == ACCEPT) { 4829 if (expected_ret == ACCEPT) {
4551 if (fd_prog < 0) { 4830 if (fd_prog < 0 && !reject_from_alignment) {
4552 printf("FAIL\nFailed to load prog '%s'!\n", 4831 printf("FAIL\nFailed to load prog '%s'!\n",
4553 strerror(errno)); 4832 strerror(errno));
4554 goto fail_log; 4833 goto fail_log;
@@ -4558,14 +4837,15 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
4558 printf("FAIL\nUnexpected success to load!\n"); 4837 printf("FAIL\nUnexpected success to load!\n");
4559 goto fail_log; 4838 goto fail_log;
4560 } 4839 }
4561 if (!strstr(bpf_vlog, expected_err)) { 4840 if (!strstr(bpf_vlog, expected_err) && !reject_from_alignment) {
4562 printf("FAIL\nUnexpected error message!\n"); 4841 printf("FAIL\nUnexpected error message!\n");
4563 goto fail_log; 4842 goto fail_log;
4564 } 4843 }
4565 } 4844 }
4566 4845
4567 (*passes)++; 4846 (*passes)++;
4568 printf("OK\n"); 4847 printf("OK%s\n", reject_from_alignment ?
4848 " (NOTE: reject due to unknown alignment)" : "");
4569close_fds: 4849close_fds:
4570 close(fd_prog); 4850 close(fd_prog);
4571 close(fd_f1); 4851 close(fd_f1);
diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile
index 1c5d0575802e..bf13fc2297aa 100644
--- a/tools/testing/selftests/powerpc/Makefile
+++ b/tools/testing/selftests/powerpc/Makefile
@@ -34,34 +34,34 @@ endif
34all: $(SUB_DIRS) 34all: $(SUB_DIRS)
35 35
36$(SUB_DIRS): 36$(SUB_DIRS):
37 BUILD_TARGET=$$OUTPUT/$@; mkdir -p $$BUILD_TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -k -C $@ all 37 BUILD_TARGET=$(OUTPUT)/$@; mkdir -p $$BUILD_TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -k -C $@ all
38 38
39include ../lib.mk 39include ../lib.mk
40 40
41override define RUN_TESTS 41override define RUN_TESTS
42 @for TARGET in $(SUB_DIRS); do \ 42 @for TARGET in $(SUB_DIRS); do \
43 BUILD_TARGET=$$OUTPUT/$$TARGET; \ 43 BUILD_TARGET=$(OUTPUT)/$$TARGET; \
44 $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests;\ 44 $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests;\
45 done; 45 done;
46endef 46endef
47 47
48override define INSTALL_RULE 48override define INSTALL_RULE
49 @for TARGET in $(SUB_DIRS); do \ 49 @for TARGET in $(SUB_DIRS); do \
50 BUILD_TARGET=$$OUTPUT/$$TARGET; \ 50 BUILD_TARGET=$(OUTPUT)/$$TARGET; \
51 $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install;\ 51 $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install;\
52 done; 52 done;
53endef 53endef
54 54
55override define EMIT_TESTS 55override define EMIT_TESTS
56 @for TARGET in $(SUB_DIRS); do \ 56 @for TARGET in $(SUB_DIRS); do \
57 BUILD_TARGET=$$OUTPUT/$$TARGET; \ 57 BUILD_TARGET=$(OUTPUT)/$$TARGET; \
58 $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests;\ 58 $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests;\
59 done; 59 done;
60endef 60endef
61 61
62clean: 62clean:
63 @for TARGET in $(SUB_DIRS); do \ 63 @for TARGET in $(SUB_DIRS); do \
64 BUILD_TARGET=$$OUTPUT/$$TARGET; \ 64 BUILD_TARGET=$(OUTPUT)/$$TARGET; \
65 $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean; \ 65 $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean; \
66 done; 66 done;
67 rm -f tags 67 rm -f tags