-/* Helper for bpf_load below. */
-#define BPF_DATA(_name) offsetof(struct seccomp_data, _name)
-/**
- * bpf_load: checks and returns a pointer to the requested offset
- * @off: offset into struct seccomp_data to load from
- *
- * Returns the requested 32-bits of data.
- * seccomp_check_filter() should assure that @off is 32-bit aligned
- * and not out of bounds. Failure to do so is a BUG.
- */
-u32 seccomp_bpf_load(int off)
-{
- struct pt_regs *regs = task_pt_regs(current);
- if (off == BPF_DATA(nr))
- return syscall_get_nr(current, regs);
- if (off == BPF_DATA(arch))
- return syscall_get_arch();
- if (off >= BPF_DATA(args[0]) && off < BPF_DATA(args[6])) {
- unsigned long value;
- int arg = (off - BPF_DATA(args[0])) / sizeof(u64);
- int index = !!(off % sizeof(u64));
- syscall_get_arguments(current, regs, arg, 1, &value);
- return get_u32(value, index);
- }
- if (off == BPF_DATA(instruction_pointer))
- return get_u32(KSTK_EIP(current), 0);
- if (off == BPF_DATA(instruction_pointer) + sizeof(u32))
- return get_u32(KSTK_EIP(current), 1);
- /* seccomp_check_filter should make this impossible. */
- BUG();
+ sd->nr = syscall_get_nr(task, regs);
+ sd->arch = syscall_get_arch();
+
+ /* Unroll syscall_get_args to help gcc on arm. */
+ syscall_get_arguments(task, regs, 0, 1, (unsigned long *) &sd->args[0]);
+ syscall_get_arguments(task, regs, 1, 1, (unsigned long *) &sd->args[1]);
+ syscall_get_arguments(task, regs, 2, 1, (unsigned long *) &sd->args[2]);
+ syscall_get_arguments(task, regs, 3, 1, (unsigned long *) &sd->args[3]);
+ syscall_get_arguments(task, regs, 4, 1, (unsigned long *) &sd->args[4]);
+ syscall_get_arguments(task, regs, 5, 1, (unsigned long *) &sd->args[5]);
+
+ sd->instruction_pointer = KSTK_EIP(task);