Skip to content

Commit 286a582

Browse files
committed
debug
fix fix2
1 parent da2d0e6 commit 286a582

File tree

2 files changed

+56
-29
lines changed

2 files changed

+56
-29
lines changed

arch/x86/kernel/uprobes.c

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -635,21 +635,48 @@ static bool is_reachable_by_call(unsigned long vtramp, unsigned long vaddr)
635635
return delta >= INT_MIN && delta <= INT_MAX;
636636
}
637637

638+
#define MASK_4GB ((1UL << 32) - 1)
639+
638640
static unsigned long find_nearest_page(unsigned long vaddr)
639641
{
640642
struct vm_unmapped_area_info info = {
641643
.length = PAGE_SIZE,
642644
.align_mask = ~PAGE_MASK,
643-
.low_limit = PAGE_SIZE,
644-
.high_limit = TASK_SIZE,
645645
};
646-
unsigned long limit, call_end = vaddr + 5;
646+
unsigned long low_limit = PAGE_SIZE, high_limit = TASK_SIZE;
647+
unsigned long limit, tramp_low_4GB, tramp_high_4GB;
648+
unsigned long call_end = vaddr + 5, tramp1, tramp2;
647649

648650
if (!check_add_overflow(call_end, INT_MIN, &limit))
649-
info.low_limit = limit;
651+
low_limit = limit;
650652
if (!check_add_overflow(call_end, INT_MAX, &limit))
651-
info.high_limit = limit;
652-
return vm_unmapped_area(&info);
653+
high_limit = limit;
654+
655+
tramp_low_4GB = call_end & MASK_4GB;
656+
tramp_high_4GB = tramp_low_4GB + (1UL << 32);
657+
658+
if (low_limit > tramp_low_4GB) {
659+
info.low_limit = tramp_high_4GB;
660+
info.high_limit = high_limit;
661+
} else {
662+
info.low_limit = tramp_low_4GB;
663+
info.high_limit = high_limit;;
664+
}
665+
666+
tramp1 = vm_unmapped_area(&info);
667+
668+
if (low_limit > tramp_low_4GB) {
669+
info.low_limit = low_limit;
670+
info.high_limit = tramp_high_4GB;
671+
} else {
672+
info.low_limit = low_limit;
673+
info.high_limit = tramp_low_4GB;
674+
}
675+
676+
info.flags = VM_UNMAPPED_AREA_TOPDOWN;
677+
tramp2 = vm_unmapped_area(&info);
678+
679+
return min(tramp1 & ~MASK_4GB, tramp2 & ~MASK_4GB);
653680
}
654681

655682
static struct uprobe_trampoline *create_uprobe_trampoline(unsigned long vaddr)
@@ -905,6 +932,8 @@ static void relative_call(void *dest, long from, long to)
905932
insn = (struct __arch_relative_insn *)dest;
906933
insn->raddr = (s32)(to - (from + 5));
907934
insn->op = CALL_INSN_OPCODE;
935+
936+
printk("relative_call from %lx to %lx raddr %x\n", from, to, insn->raddr);
908937
}
909938

910939
static int swbp_optimize(struct arch_uprobe *auprobe, struct vm_area_struct *vma,
@@ -1066,6 +1095,8 @@ static int __arch_uprobe_optimize(struct arch_uprobe *auprobe, struct mm_struct
10661095
bool new = false;
10671096
int err = 0;
10681097

1098+
printk("__arch_uprobe_optimize START %lx\n", vaddr);
1099+
10691100
vma = find_vma(mm, vaddr);
10701101
if (!vma)
10711102
return -EINVAL;
@@ -1075,6 +1106,7 @@ static int __arch_uprobe_optimize(struct arch_uprobe *auprobe, struct mm_struct
10751106
err = swbp_optimize(auprobe, vma, vaddr, tramp->vaddr);
10761107
if (WARN_ON_ONCE(err) && new)
10771108
destroy_uprobe_trampoline(tramp);
1109+
printk("__arch_uprobe_optimize END %lx\n", vaddr);
10781110
return err;
10791111
}
10801112

tools/testing/selftests/bpf/prog_tests/uprobe_syscall.c

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -357,8 +357,9 @@ __nocf_check __weak void usdt_test(void)
357357
USDT(optimized_uprobe, usdt);
358358
}
359359

360-
static int find_uprobes_trampoline(void **start, void **end)
360+
static int find_uprobes_trampoline(void *tramp_addr)
361361
{
362+
void *start, *end;
362363
char line[128];
363364
int ret = -1;
364365
FILE *maps;
@@ -373,12 +374,12 @@ static int find_uprobes_trampoline(void **start, void **end)
373374
int m = -1;
374375

375376
/* We care only about private r-x mappings. */
376-
if (sscanf(line, "%p-%p r-xp %*x %*x:%*x %*u %n", start, end, &m) != 2)
377+
if (sscanf(line, "%p-%p r-xp %*x %*x:%*x %*u %n", &start, &end, &m) != 2)
377378
continue;
378379
if (m < 0)
379380
continue;
380-
if (!strncmp(&line[m], TRAMP, sizeof(TRAMP)-1)) {
381-
ret = 0;
381+
if (!strncmp(&line[m], TRAMP, sizeof(TRAMP)-1) && (start == tramp_addr)) {
382+
ret = end - start == 4096 ? 0 : -1;
382383
break;
383384
}
384385
}
@@ -404,25 +405,20 @@ typedef void (__attribute__((nocf_check)) *trigger_t)(void);
404405

405406
static bool shstk_is_enabled;
406407

407-
static void check_attach(struct uprobe_syscall_executed *skel, trigger_t trigger,
408-
void *addr, int executed)
408+
static void *check_attach(struct uprobe_syscall_executed *skel, trigger_t trigger,
409+
void *addr, int executed)
409410
{
410-
void *tramp_start, *tramp_end;
411411
struct __arch_relative_insn {
412412
__u8 op;
413413
__s32 raddr;
414414
} __packed *call;
415-
__s32 delta;
415+
void *tramp = NULL;
416416
__u8 *bp;
417417

418418
/* Uprobe gets optimized after first trigger, so let's press twice. */
419419
trigger();
420420
trigger();
421421

422-
if (!shstk_is_enabled &&
423-
!ASSERT_OK(find_uprobes_trampoline(&tramp_start, &tramp_end), "uprobes_trampoline"))
424-
return;
425-
426422
/* Make sure bpf program got executed.. */
427423
ASSERT_EQ(skel->bss->executed, executed, "executed");
428424

@@ -433,30 +429,29 @@ static void check_attach(struct uprobe_syscall_executed *skel, trigger_t trigger
433429
} else {
434430
/* .. and check the trampoline is as expected. */
435431
call = (struct __arch_relative_insn *) addr;
436-
delta = (unsigned long) tramp_start - ((unsigned long) addr + 5);
437-
432+
tramp = (void *) (call + 1) + call->raddr;
438433
ASSERT_EQ(call->op, 0xe8, "call");
439-
ASSERT_EQ(call->raddr, delta, "delta");
440-
ASSERT_EQ(tramp_end - tramp_start, 4096, "size");
434+
ASSERT_OK(find_uprobes_trampoline(tramp), "uprobes_trampoline");
441435
}
436+
437+
return tramp;
442438
}
443439

444-
static void check_detach(struct uprobe_syscall_executed *skel, trigger_t trigger, void *addr)
440+
static void check_detach(void *addr, void *tramp)
445441
{
446-
void *tramp_start, *tramp_end;
447-
448442
/* [uprobes_trampoline] stays after detach */
449-
ASSERT_OK(!shstk_is_enabled &&
450-
find_uprobes_trampoline(&tramp_start, &tramp_end), "uprobes_trampoline");
443+
ASSERT_OK(!shstk_is_enabled && find_uprobes_trampoline(tramp), "uprobes_trampoline");
451444
ASSERT_OK(memcmp(addr, nop5, 5), "nop5");
452445
}
453446

454447
static void check(struct uprobe_syscall_executed *skel, struct bpf_link *link,
455448
trigger_t trigger, void *addr, int executed)
456449
{
457-
check_attach(skel, trigger, addr, executed);
450+
void *tramp;
451+
452+
tramp = check_attach(skel, trigger, addr, executed);
458453
bpf_link__destroy(link);
459-
check_detach(skel, trigger, addr);
454+
check_detach(addr, tramp);
460455
}
461456

462457
static void test_uprobe_legacy(void)

0 commit comments

Comments
 (0)