Skip to content

Commit 43cc5a7

Browse files
committed
Merge branch 'Add USDT support for s390'
Ilya Leoshkevich says: ==================== This series adds USDT support for s390, making the "usdt" test pass there. Patch 1 is a collection of minor cleanups, patch 2 adds BPF-side support, patch 3 adds userspace-side support. ==================== Signed-off-by: Andrii Nakryiko <[email protected]>
2 parents ded6dff + 32e44e4 commit 43cc5a7

File tree

2 files changed

+68
-8
lines changed

2 files changed

+68
-8
lines changed

tools/lib/bpf/usdt.bpf.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ int bpf_usdt_arg(struct pt_regs *ctx, __u64 arg_num, long *res)
166166
case BPF_USDT_ARG_REG_DEREF:
167167
/* Arg is in memory addressed by register, plus some offset
168168
* (e.g., "-4@-1204(%rbp)" in USDT arg spec). Register is
169-
* identified lik with BPF_USDT_ARG_REG case, and the offset
169+
* identified like with BPF_USDT_ARG_REG case, and the offset
170170
* is in arg_spec->val_off. We first fetch register contents
171171
* from pt_regs, then do another user-space probe read to
172172
* fetch argument value itself.
@@ -177,6 +177,9 @@ int bpf_usdt_arg(struct pt_regs *ctx, __u64 arg_num, long *res)
177177
err = bpf_probe_read_user(&val, sizeof(val), (void *)val + arg_spec->val_off);
178178
if (err)
179179
return err;
180+
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
181+
val >>= arg_spec->arg_bitshift;
182+
#endif
180183
break;
181184
default:
182185
return -EINVAL;
@@ -198,7 +201,7 @@ int bpf_usdt_arg(struct pt_regs *ctx, __u64 arg_num, long *res)
198201
/* Retrieve user-specified cookie value provided during attach as
199202
* bpf_usdt_opts.usdt_cookie. This serves the same purpose as BPF cookie
200203
* returned by bpf_get_attach_cookie(). Libbpf's support for USDT is itself
201-
* utilizaing BPF cookies internally, so user can't use BPF cookie directly
204+
* utilizing BPF cookies internally, so user can't use BPF cookie directly
202205
* for USDT programs and has to use bpf_usdt_cookie() API instead.
203206
*/
204207
static inline __noinline

tools/lib/bpf/usdt.c

Lines changed: 63 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@
108108
* code through spec map. This allows BPF applications to quickly fetch the
109109
* actual value at runtime using a simple BPF-side code.
110110
*
111-
* With basics out of the way, let's go over less immeditately obvious aspects
111+
* With basics out of the way, let's go over less immediately obvious aspects
112112
* of supporting USDTs.
113113
*
114114
* First, there is no special USDT BPF program type. It is actually just
@@ -189,14 +189,14 @@
189189
#define USDT_NOTE_TYPE 3
190190
#define USDT_NOTE_NAME "stapsdt"
191191

192-
/* should match exactly enum __bpf_usdt_arg_type from bpf_usdt.bpf.h */
192+
/* should match exactly enum __bpf_usdt_arg_type from usdt.bpf.h */
193193
enum usdt_arg_type {
194194
USDT_ARG_CONST,
195195
USDT_ARG_REG,
196196
USDT_ARG_REG_DEREF,
197197
};
198198

199-
/* should match exactly struct __bpf_usdt_arg_spec from bpf_usdt.bpf.h */
199+
/* should match exactly struct __bpf_usdt_arg_spec from usdt.bpf.h */
200200
struct usdt_arg_spec {
201201
__u64 val_off;
202202
enum usdt_arg_type arg_type;
@@ -328,9 +328,9 @@ static int sanity_check_usdt_elf(Elf *elf, const char *path)
328328
return -EBADF;
329329
}
330330

331-
#if __BYTE_ORDER == __LITTLE_ENDIAN
331+
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
332332
endianness = ELFDATA2LSB;
333-
#elif __BYTE_ORDER == __BIG_ENDIAN
333+
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
334334
endianness = ELFDATA2MSB;
335335
#else
336336
# error "Unrecognized __BYTE_ORDER__"
@@ -843,7 +843,7 @@ static int bpf_link_usdt_detach(struct bpf_link *link)
843843
sizeof(*new_free_ids));
844844
/* If we couldn't resize free_spec_ids, we'll just leak
845845
* a bunch of free IDs; this is very unlikely to happen and if
846-
* system is so exausted on memory, it's the least of user's
846+
* system is so exhausted on memory, it's the least of user's
847847
* concerns, probably.
848848
* So just do our best here to return those IDs to usdt_manager.
849849
*/
@@ -1269,6 +1269,63 @@ static int parse_usdt_arg(const char *arg_str, int arg_num, struct usdt_arg_spec
12691269
return len;
12701270
}
12711271

1272+
#elif defined(__s390x__)
1273+
1274+
/* Do not support __s390__ for now, since user_pt_regs is broken with -m31. */
1275+
1276+
static int parse_usdt_arg(const char *arg_str, int arg_num,
1277+
struct usdt_arg_spec *arg)
1278+
{
1279+
unsigned int reg;
1280+
int sz, len;
1281+
long off;
1282+
1283+
if (sscanf(arg_str, " %d @ %ld ( %%r%u ) %n", &sz, &off, &reg, &len) == 3) {
1284+
/* Memory dereference case, e.g., -2@-28(%r15) */
1285+
arg->arg_type = USDT_ARG_REG_DEREF;
1286+
arg->val_off = off;
1287+
if (reg > 15) {
1288+
pr_warn("usdt: unrecognized register '%%r%u'\n", reg);
1289+
return -EINVAL;
1290+
}
1291+
arg->reg_off = offsetof(user_pt_regs, gprs[reg]);
1292+
} else if (sscanf(arg_str, " %d @ %%r%u %n", &sz, &reg, &len) == 2) {
1293+
/* Register read case, e.g., -8@%r0 */
1294+
arg->arg_type = USDT_ARG_REG;
1295+
arg->val_off = 0;
1296+
if (reg > 15) {
1297+
pr_warn("usdt: unrecognized register '%%r%u'\n", reg);
1298+
return -EINVAL;
1299+
}
1300+
arg->reg_off = offsetof(user_pt_regs, gprs[reg]);
1301+
} else if (sscanf(arg_str, " %d @ %ld %n", &sz, &off, &len) == 2) {
1302+
/* Constant value case, e.g., 4@71 */
1303+
arg->arg_type = USDT_ARG_CONST;
1304+
arg->val_off = off;
1305+
arg->reg_off = -1;
1306+
} else {
1307+
pr_warn("usdt: unrecognized arg #%d spec '%s'\n", arg_num,
1308+
arg_str);
1309+
return -EINVAL;
1310+
}
1311+
1312+
arg->arg_signed = sz < 0;
1313+
if (sz < 0)
1314+
sz = -sz;
1315+
1316+
switch (sz) {
1317+
case 1: case 2: case 4: case 8:
1318+
arg->arg_bitshift = 64 - sz * 8;
1319+
break;
1320+
default:
1321+
pr_warn("usdt: unsupported arg #%d (spec '%s') size: %d\n",
1322+
arg_num, arg_str, sz);
1323+
return -EINVAL;
1324+
}
1325+
1326+
return len;
1327+
}
1328+
12721329
#else
12731330

12741331
static int parse_usdt_arg(const char *arg_str, int arg_num, struct usdt_arg_spec *arg)

0 commit comments

Comments
 (0)