1666b2c10SAndrii Nakryiko // SPDX-License-Identifier: GPL-2.0 2666b2c10SAndrii Nakryiko // Copyright (c) 2019 Facebook 3666b2c10SAndrii Nakryiko 4666b2c10SAndrii Nakryiko #include <linux/ptrace.h> 5666b2c10SAndrii Nakryiko #include <linux/bpf.h> 63e689141SToke Høiland-Jørgensen #include <bpf/bpf_helpers.h> 7666b2c10SAndrii Nakryiko 8*256eab48SAndrii Nakryiko const struct { 9666b2c10SAndrii Nakryiko unsigned a[4]; 10666b2c10SAndrii Nakryiko /* 11666b2c10SAndrii Nakryiko * if the struct's size is multiple of 16, compiler will put it into 12666b2c10SAndrii Nakryiko * .rodata.cst16 section, which is not recognized by libbpf; work 13666b2c10SAndrii Nakryiko * around this by ensuring we don't have 16-aligned struct 14666b2c10SAndrii Nakryiko */ 15666b2c10SAndrii Nakryiko char _y; 16666b2c10SAndrii Nakryiko } rdonly_values = { .a = {2, 3, 4, 5} }; 17666b2c10SAndrii Nakryiko 18*256eab48SAndrii Nakryiko struct { 19666b2c10SAndrii Nakryiko unsigned did_run; 20666b2c10SAndrii Nakryiko unsigned iters; 21666b2c10SAndrii Nakryiko unsigned sum; 22*256eab48SAndrii Nakryiko } res = {}; 23666b2c10SAndrii Nakryiko 24666b2c10SAndrii Nakryiko SEC("raw_tracepoint/sys_enter:skip_loop") skip_loop(struct pt_regs * ctx)25666b2c10SAndrii Nakryikoint skip_loop(struct pt_regs *ctx) 26666b2c10SAndrii Nakryiko { 27666b2c10SAndrii Nakryiko /* prevent compiler to optimize everything out */ 28666b2c10SAndrii Nakryiko unsigned * volatile p = (void *)&rdonly_values.a; 29666b2c10SAndrii Nakryiko unsigned iters = 0, sum = 0; 30666b2c10SAndrii Nakryiko 31666b2c10SAndrii Nakryiko /* we should never enter this loop */ 32666b2c10SAndrii Nakryiko while (*p & 1) { 33666b2c10SAndrii Nakryiko iters++; 34666b2c10SAndrii Nakryiko sum += *p; 35666b2c10SAndrii Nakryiko p++; 36666b2c10SAndrii Nakryiko } 37666b2c10SAndrii Nakryiko res.did_run = 1; 38666b2c10SAndrii Nakryiko res.iters = iters; 39666b2c10SAndrii Nakryiko res.sum = sum; 40666b2c10SAndrii Nakryiko return 0; 41666b2c10SAndrii Nakryiko } 42666b2c10SAndrii Nakryiko 43666b2c10SAndrii Nakryiko SEC("raw_tracepoint/sys_enter:part_loop") part_loop(struct pt_regs * ctx)44666b2c10SAndrii Nakryikoint part_loop(struct pt_regs *ctx) 45666b2c10SAndrii Nakryiko { 46666b2c10SAndrii Nakryiko /* prevent compiler to optimize everything out */ 47666b2c10SAndrii Nakryiko unsigned * volatile p = (void *)&rdonly_values.a; 48666b2c10SAndrii Nakryiko unsigned iters = 0, sum = 0; 49666b2c10SAndrii Nakryiko 50666b2c10SAndrii Nakryiko /* validate verifier can derive loop termination */ 51666b2c10SAndrii Nakryiko while (*p < 5) { 52666b2c10SAndrii Nakryiko iters++; 53666b2c10SAndrii Nakryiko sum += *p; 54666b2c10SAndrii Nakryiko p++; 55666b2c10SAndrii Nakryiko } 56666b2c10SAndrii Nakryiko res.did_run = 1; 57666b2c10SAndrii Nakryiko res.iters = iters; 58666b2c10SAndrii Nakryiko res.sum = sum; 59666b2c10SAndrii Nakryiko return 0; 60666b2c10SAndrii Nakryiko } 61666b2c10SAndrii Nakryiko 62666b2c10SAndrii Nakryiko SEC("raw_tracepoint/sys_enter:full_loop") full_loop(struct pt_regs * ctx)63666b2c10SAndrii Nakryikoint full_loop(struct pt_regs *ctx) 64666b2c10SAndrii Nakryiko { 65666b2c10SAndrii Nakryiko /* prevent compiler to optimize everything out */ 66666b2c10SAndrii Nakryiko unsigned * volatile p = (void *)&rdonly_values.a; 67666b2c10SAndrii Nakryiko int i = sizeof(rdonly_values.a) / sizeof(rdonly_values.a[0]); 68666b2c10SAndrii Nakryiko unsigned iters = 0, sum = 0; 69666b2c10SAndrii Nakryiko 70666b2c10SAndrii Nakryiko /* validate verifier can allow full loop as well */ 71666b2c10SAndrii Nakryiko while (i > 0 ) { 72666b2c10SAndrii Nakryiko iters++; 73666b2c10SAndrii Nakryiko sum += *p; 74666b2c10SAndrii Nakryiko p++; 75666b2c10SAndrii Nakryiko i--; 76666b2c10SAndrii Nakryiko } 77666b2c10SAndrii Nakryiko res.did_run = 1; 78666b2c10SAndrii Nakryiko res.iters = iters; 79666b2c10SAndrii Nakryiko res.sum = sum; 80666b2c10SAndrii Nakryiko return 0; 81666b2c10SAndrii Nakryiko } 82666b2c10SAndrii Nakryiko 83666b2c10SAndrii Nakryiko char _license[] SEC("license") = "GPL"; 84