diff options
| -rw-r--r-- | arch/blackfin/kernel/kgdb.c | 207 | ||||
| -rw-r--r-- | arch/blackfin/mm/Makefile | 2 | ||||
| -rw-r--r-- | arch/blackfin/mm/maccess.c | 97 | ||||
| -rw-r--r-- | include/linux/kgdb.h | 7 | ||||
| -rw-r--r-- | include/linux/uaccess.h | 4 | ||||
| -rw-r--r-- | mm/maccess.c | 11 |
6 files changed, 114 insertions, 214 deletions
diff --git a/arch/blackfin/kernel/kgdb.c b/arch/blackfin/kernel/kgdb.c index f1036b6b9293..34c7c3ed2c9c 100644 --- a/arch/blackfin/kernel/kgdb.c +++ b/arch/blackfin/kernel/kgdb.c | |||
| @@ -6,23 +6,9 @@ | |||
| 6 | * Licensed under the GPL-2 or later. | 6 | * Licensed under the GPL-2 or later. |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #include <linux/string.h> | ||
| 10 | #include <linux/kernel.h> | ||
| 11 | #include <linux/sched.h> | ||
| 12 | #include <linux/smp.h> | ||
| 13 | #include <linux/spinlock.h> | ||
| 14 | #include <linux/delay.h> | ||
| 15 | #include <linux/ptrace.h> /* for linux pt_regs struct */ | 9 | #include <linux/ptrace.h> /* for linux pt_regs struct */ |
| 16 | #include <linux/kgdb.h> | 10 | #include <linux/kgdb.h> |
| 17 | #include <linux/console.h> | ||
| 18 | #include <linux/init.h> | ||
| 19 | #include <linux/errno.h> | ||
| 20 | #include <linux/irq.h> | ||
| 21 | #include <linux/uaccess.h> | 11 | #include <linux/uaccess.h> |
| 22 | #include <asm/system.h> | ||
| 23 | #include <asm/traps.h> | ||
| 24 | #include <asm/blackfin.h> | ||
| 25 | #include <asm/dma.h> | ||
| 26 | 12 | ||
| 27 | void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) | 13 | void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) |
| 28 | { | 14 | { |
| @@ -147,7 +133,7 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs) | |||
| 147 | regs->lb1 = gdb_regs[BFIN_LB1]; | 133 | regs->lb1 = gdb_regs[BFIN_LB1]; |
| 148 | regs->usp = gdb_regs[BFIN_USP]; | 134 | regs->usp = gdb_regs[BFIN_USP]; |
| 149 | regs->syscfg = gdb_regs[BFIN_SYSCFG]; | 135 | regs->syscfg = gdb_regs[BFIN_SYSCFG]; |
| 150 | regs->retx = gdb_regs[BFIN_PC]; | 136 | regs->retx = gdb_regs[BFIN_RETX]; |
| 151 | regs->retn = gdb_regs[BFIN_RETN]; | 137 | regs->retn = gdb_regs[BFIN_RETN]; |
| 152 | regs->rete = gdb_regs[BFIN_RETE]; | 138 | regs->rete = gdb_regs[BFIN_RETE]; |
| 153 | regs->pc = gdb_regs[BFIN_PC]; | 139 | regs->pc = gdb_regs[BFIN_PC]; |
| @@ -424,182 +410,6 @@ struct kgdb_arch arch_kgdb_ops = { | |||
| 424 | .correct_hw_break = bfin_correct_hw_break, | 410 | .correct_hw_break = bfin_correct_hw_break, |
| 425 | }; | 411 | }; |
| 426 | 412 | ||
| 427 | static int hex(char ch) | ||
| 428 | { | ||
| 429 | if ((ch >= 'a') && (ch <= 'f')) | ||
| 430 | return ch - 'a' + 10; | ||
| 431 | if ((ch >= '0') && (ch <= '9')) | ||
| 432 | return ch - '0'; | ||
| 433 | if ((ch >= 'A') && (ch <= 'F')) | ||
| 434 | return ch - 'A' + 10; | ||
| 435 | return -1; | ||
| 436 | } | ||
| 437 | |||
| 438 | static int validate_memory_access_address(unsigned long addr, int size) | ||
| 439 | { | ||
| 440 | if (size < 0 || addr == 0) | ||
| 441 | return -EFAULT; | ||
| 442 | return bfin_mem_access_type(addr, size); | ||
| 443 | } | ||
| 444 | |||
| 445 | static int bfin_probe_kernel_read(char *dst, char *src, int size) | ||
| 446 | { | ||
| 447 | unsigned long lsrc = (unsigned long)src; | ||
| 448 | int mem_type; | ||
| 449 | |||
| 450 | mem_type = validate_memory_access_address(lsrc, size); | ||
| 451 | if (mem_type < 0) | ||
| 452 | return mem_type; | ||
| 453 | |||
| 454 | if (lsrc >= SYSMMR_BASE) { | ||
| 455 | if (size == 2 && lsrc % 2 == 0) { | ||
| 456 | u16 mmr = bfin_read16(src); | ||
| 457 | memcpy(dst, &mmr, sizeof(mmr)); | ||
| 458 | return 0; | ||
| 459 | } else if (size == 4 && lsrc % 4 == 0) { | ||
| 460 | u32 mmr = bfin_read32(src); | ||
| 461 | memcpy(dst, &mmr, sizeof(mmr)); | ||
| 462 | return 0; | ||
| 463 | } | ||
| 464 | } else { | ||
| 465 | switch (mem_type) { | ||
| 466 | case BFIN_MEM_ACCESS_CORE: | ||
| 467 | case BFIN_MEM_ACCESS_CORE_ONLY: | ||
| 468 | return probe_kernel_read(dst, src, size); | ||
| 469 | /* XXX: should support IDMA here with SMP */ | ||
| 470 | case BFIN_MEM_ACCESS_DMA: | ||
| 471 | if (dma_memcpy(dst, src, size)) | ||
| 472 | return 0; | ||
| 473 | break; | ||
| 474 | case BFIN_MEM_ACCESS_ITEST: | ||
| 475 | if (isram_memcpy(dst, src, size)) | ||
| 476 | return 0; | ||
| 477 | break; | ||
| 478 | } | ||
| 479 | } | ||
| 480 | |||
| 481 | return -EFAULT; | ||
| 482 | } | ||
| 483 | |||
| 484 | static int bfin_probe_kernel_write(char *dst, char *src, int size) | ||
| 485 | { | ||
| 486 | unsigned long ldst = (unsigned long)dst; | ||
| 487 | int mem_type; | ||
| 488 | |||
| 489 | mem_type = validate_memory_access_address(ldst, size); | ||
| 490 | if (mem_type < 0) | ||
| 491 | return mem_type; | ||
| 492 | |||
| 493 | if (ldst >= SYSMMR_BASE) { | ||
| 494 | if (size == 2 && ldst % 2 == 0) { | ||
| 495 | u16 mmr; | ||
| 496 | memcpy(&mmr, src, sizeof(mmr)); | ||
| 497 | bfin_write16(dst, mmr); | ||
| 498 | return 0; | ||
| 499 | } else if (size == 4 && ldst % 4 == 0) { | ||
| 500 | u32 mmr; | ||
| 501 | memcpy(&mmr, src, sizeof(mmr)); | ||
| 502 | bfin_write32(dst, mmr); | ||
| 503 | return 0; | ||
| 504 | } | ||
| 505 | } else { | ||
| 506 | switch (mem_type) { | ||
| 507 | case BFIN_MEM_ACCESS_CORE: | ||
| 508 | case BFIN_MEM_ACCESS_CORE_ONLY: | ||
| 509 | return probe_kernel_write(dst, src, size); | ||
| 510 | /* XXX: should support IDMA here with SMP */ | ||
| 511 | case BFIN_MEM_ACCESS_DMA: | ||
| 512 | if (dma_memcpy(dst, src, size)) | ||
| 513 | return 0; | ||
| 514 | break; | ||
| 515 | case BFIN_MEM_ACCESS_ITEST: | ||
| 516 | if (isram_memcpy(dst, src, size)) | ||
| 517 | return 0; | ||
| 518 | break; | ||
| 519 | } | ||
| 520 | } | ||
| 521 | |||
| 522 | return -EFAULT; | ||
| 523 | } | ||
| 524 | |||
| 525 | /* | ||
| 526 | * Convert the memory pointed to by mem into hex, placing result in buf. | ||
| 527 | * Return a pointer to the last char put in buf (null). May return an error. | ||
| 528 | */ | ||
| 529 | int kgdb_mem2hex(char *mem, char *buf, int count) | ||
| 530 | { | ||
| 531 | char *tmp; | ||
| 532 | int err; | ||
| 533 | |||
| 534 | /* | ||
| 535 | * We use the upper half of buf as an intermediate buffer for the | ||
| 536 | * raw memory copy. Hex conversion will work against this one. | ||
| 537 | */ | ||
| 538 | tmp = buf + count; | ||
| 539 | |||
| 540 | err = bfin_probe_kernel_read(tmp, mem, count); | ||
| 541 | if (!err) { | ||
| 542 | while (count > 0) { | ||
| 543 | buf = pack_hex_byte(buf, *tmp); | ||
| 544 | tmp++; | ||
| 545 | count--; | ||
| 546 | } | ||
| 547 | |||
| 548 | *buf = 0; | ||
| 549 | } | ||
| 550 | |||
| 551 | return err; | ||
| 552 | } | ||
| 553 | |||
| 554 | /* | ||
| 555 | * Copy the binary array pointed to by buf into mem. Fix $, #, and | ||
| 556 | * 0x7d escaped with 0x7d. Return a pointer to the character after | ||
| 557 | * the last byte written. | ||
| 558 | */ | ||
| 559 | int kgdb_ebin2mem(char *buf, char *mem, int count) | ||
| 560 | { | ||
| 561 | char *tmp_old, *tmp_new; | ||
| 562 | int size; | ||
| 563 | |||
| 564 | tmp_old = tmp_new = buf; | ||
| 565 | |||
| 566 | for (size = 0; size < count; ++size) { | ||
| 567 | if (*tmp_old == 0x7d) | ||
| 568 | *tmp_new = *(++tmp_old) ^ 0x20; | ||
| 569 | else | ||
| 570 | *tmp_new = *tmp_old; | ||
| 571 | tmp_new++; | ||
| 572 | tmp_old++; | ||
| 573 | } | ||
| 574 | |||
| 575 | return bfin_probe_kernel_write(mem, buf, count); | ||
| 576 | } | ||
| 577 | |||
| 578 | /* | ||
| 579 | * Convert the hex array pointed to by buf into binary to be placed in mem. | ||
| 580 | * Return a pointer to the character AFTER the last byte written. | ||
| 581 | * May return an error. | ||
| 582 | */ | ||
| 583 | int kgdb_hex2mem(char *buf, char *mem, int count) | ||
| 584 | { | ||
| 585 | char *tmp_raw, *tmp_hex; | ||
| 586 | |||
| 587 | /* | ||
| 588 | * We use the upper half of buf as an intermediate buffer for the | ||
| 589 | * raw memory that is converted from hex. | ||
| 590 | */ | ||
| 591 | tmp_raw = buf + count * 2; | ||
| 592 | |||
| 593 | tmp_hex = tmp_raw - 1; | ||
| 594 | while (tmp_hex >= buf) { | ||
| 595 | tmp_raw--; | ||
| 596 | *tmp_raw = hex(*tmp_hex--); | ||
| 597 | *tmp_raw |= hex(*tmp_hex--) << 4; | ||
| 598 | } | ||
| 599 | |||
| 600 | return bfin_probe_kernel_write(mem, tmp_raw, count); | ||
| 601 | } | ||
| 602 | |||
| 603 | #define IN_MEM(addr, size, l1_addr, l1_size) \ | 413 | #define IN_MEM(addr, size, l1_addr, l1_size) \ |
| 604 | ({ \ | 414 | ({ \ |
| 605 | unsigned long __addr = (unsigned long)(addr); \ | 415 | unsigned long __addr = (unsigned long)(addr); \ |
| @@ -629,21 +439,6 @@ int kgdb_validate_break_address(unsigned long addr) | |||
| 629 | return -EFAULT; | 439 | return -EFAULT; |
| 630 | } | 440 | } |
| 631 | 441 | ||
| 632 | int kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr) | ||
| 633 | { | ||
| 634 | int err = bfin_probe_kernel_read(saved_instr, (char *)addr, | ||
| 635 | BREAK_INSTR_SIZE); | ||
| 636 | if (err) | ||
| 637 | return err; | ||
| 638 | return bfin_probe_kernel_write((char *)addr, arch_kgdb_ops.gdb_bpt_instr, | ||
| 639 | BREAK_INSTR_SIZE); | ||
| 640 | } | ||
| 641 | |||
| 642 | int kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle) | ||
| 643 | { | ||
| 644 | return bfin_probe_kernel_write((char *)addr, bundle, BREAK_INSTR_SIZE); | ||
| 645 | } | ||
| 646 | |||
| 647 | int kgdb_arch_init(void) | 442 | int kgdb_arch_init(void) |
| 648 | { | 443 | { |
| 649 | kgdb_single_step = 0; | 444 | kgdb_single_step = 0; |
diff --git a/arch/blackfin/mm/Makefile b/arch/blackfin/mm/Makefile index d489f894f4b1..4c011b1f661f 100644 --- a/arch/blackfin/mm/Makefile +++ b/arch/blackfin/mm/Makefile | |||
| @@ -2,4 +2,4 @@ | |||
| 2 | # arch/blackfin/mm/Makefile | 2 | # arch/blackfin/mm/Makefile |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | obj-y := sram-alloc.o isram-driver.o init.o | 5 | obj-y := sram-alloc.o isram-driver.o init.o maccess.o |
diff --git a/arch/blackfin/mm/maccess.c b/arch/blackfin/mm/maccess.c new file mode 100644 index 000000000000..b71cebc1f8a3 --- /dev/null +++ b/arch/blackfin/mm/maccess.c | |||
| @@ -0,0 +1,97 @@ | |||
| 1 | /* | ||
| 2 | * safe read and write memory routines callable while atomic | ||
| 3 | * | ||
| 4 | * Copyright 2005-2008 Analog Devices Inc. | ||
| 5 | * | ||
| 6 | * Licensed under the GPL-2 or later. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/uaccess.h> | ||
| 10 | #include <asm/dma.h> | ||
| 11 | |||
| 12 | static int validate_memory_access_address(unsigned long addr, int size) | ||
| 13 | { | ||
| 14 | if (size < 0 || addr == 0) | ||
| 15 | return -EFAULT; | ||
| 16 | return bfin_mem_access_type(addr, size); | ||
| 17 | } | ||
| 18 | |||
| 19 | long probe_kernel_read(void *dst, void *src, size_t size) | ||
| 20 | { | ||
| 21 | unsigned long lsrc = (unsigned long)src; | ||
| 22 | int mem_type; | ||
| 23 | |||
| 24 | mem_type = validate_memory_access_address(lsrc, size); | ||
| 25 | if (mem_type < 0) | ||
| 26 | return mem_type; | ||
| 27 | |||
| 28 | if (lsrc >= SYSMMR_BASE) { | ||
| 29 | if (size == 2 && lsrc % 2 == 0) { | ||
| 30 | u16 mmr = bfin_read16(src); | ||
| 31 | memcpy(dst, &mmr, sizeof(mmr)); | ||
| 32 | return 0; | ||
| 33 | } else if (size == 4 && lsrc % 4 == 0) { | ||
| 34 | u32 mmr = bfin_read32(src); | ||
| 35 | memcpy(dst, &mmr, sizeof(mmr)); | ||
| 36 | return 0; | ||
| 37 | } | ||
| 38 | } else { | ||
| 39 | switch (mem_type) { | ||
| 40 | case BFIN_MEM_ACCESS_CORE: | ||
| 41 | case BFIN_MEM_ACCESS_CORE_ONLY: | ||
| 42 | return __probe_kernel_read(dst, src, size); | ||
| 43 | /* XXX: should support IDMA here with SMP */ | ||
| 44 | case BFIN_MEM_ACCESS_DMA: | ||
| 45 | if (dma_memcpy(dst, src, size)) | ||
| 46 | return 0; | ||
| 47 | break; | ||
| 48 | case BFIN_MEM_ACCESS_ITEST: | ||
| 49 | if (isram_memcpy(dst, src, size)) | ||
| 50 | return 0; | ||
| 51 | break; | ||
| 52 | } | ||
| 53 | } | ||
| 54 | |||
| 55 | return -EFAULT; | ||
| 56 | } | ||
| 57 | |||
| 58 | long probe_kernel_write(void *dst, void *src, size_t size) | ||
| 59 | { | ||
| 60 | unsigned long ldst = (unsigned long)dst; | ||
| 61 | int mem_type; | ||
| 62 | |||
| 63 | mem_type = validate_memory_access_address(ldst, size); | ||
| 64 | if (mem_type < 0) | ||
| 65 | return mem_type; | ||
| 66 | |||
| 67 | if (ldst >= SYSMMR_BASE) { | ||
| 68 | if (size == 2 && ldst % 2 == 0) { | ||
| 69 | u16 mmr; | ||
| 70 | memcpy(&mmr, src, sizeof(mmr)); | ||
| 71 | bfin_write16(dst, mmr); | ||
| 72 | return 0; | ||
| 73 | } else if (size == 4 && ldst % 4 == 0) { | ||
| 74 | u32 mmr; | ||
| 75 | memcpy(&mmr, src, sizeof(mmr)); | ||
| 76 | bfin_write32(dst, mmr); | ||
| 77 | return 0; | ||
| 78 | } | ||
| 79 | } else { | ||
| 80 | switch (mem_type) { | ||
| 81 | case BFIN_MEM_ACCESS_CORE: | ||
| 82 | case BFIN_MEM_ACCESS_CORE_ONLY: | ||
| 83 | return __probe_kernel_write(dst, src, size); | ||
| 84 | /* XXX: should support IDMA here with SMP */ | ||
| 85 | case BFIN_MEM_ACCESS_DMA: | ||
| 86 | if (dma_memcpy(dst, src, size)) | ||
| 87 | return 0; | ||
| 88 | break; | ||
| 89 | case BFIN_MEM_ACCESS_ITEST: | ||
| 90 | if (isram_memcpy(dst, src, size)) | ||
| 91 | return 0; | ||
| 92 | break; | ||
| 93 | } | ||
| 94 | } | ||
| 95 | |||
| 96 | return -EFAULT; | ||
| 97 | } | ||
diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h index 6adcc297e354..19ec41a183f5 100644 --- a/include/linux/kgdb.h +++ b/include/linux/kgdb.h | |||
| @@ -29,8 +29,7 @@ struct pt_regs; | |||
| 29 | * | 29 | * |
| 30 | * On some architectures it is required to skip a breakpoint | 30 | * On some architectures it is required to skip a breakpoint |
| 31 | * exception when it occurs after a breakpoint has been removed. | 31 | * exception when it occurs after a breakpoint has been removed. |
| 32 | * This can be implemented in the architecture specific portion of | 32 | * This can be implemented in the architecture specific portion of kgdb. |
| 33 | * for kgdb. | ||
| 34 | */ | 33 | */ |
| 35 | extern int kgdb_skipexception(int exception, struct pt_regs *regs); | 34 | extern int kgdb_skipexception(int exception, struct pt_regs *regs); |
| 36 | 35 | ||
| @@ -65,7 +64,7 @@ struct uart_port; | |||
| 65 | /** | 64 | /** |
| 66 | * kgdb_breakpoint - compiled in breakpoint | 65 | * kgdb_breakpoint - compiled in breakpoint |
| 67 | * | 66 | * |
| 68 | * This will be impelmented a static inline per architecture. This | 67 | * This will be implemented as a static inline per architecture. This |
| 69 | * function is called by the kgdb core to execute an architecture | 68 | * function is called by the kgdb core to execute an architecture |
| 70 | * specific trap to cause kgdb to enter the exception processing. | 69 | * specific trap to cause kgdb to enter the exception processing. |
| 71 | * | 70 | * |
| @@ -190,7 +189,7 @@ kgdb_arch_handle_exception(int vector, int signo, int err_code, | |||
| 190 | * @flags: Current IRQ state | 189 | * @flags: Current IRQ state |
| 191 | * | 190 | * |
| 192 | * On SMP systems, we need to get the attention of the other CPUs | 191 | * On SMP systems, we need to get the attention of the other CPUs |
| 193 | * and get them be in a known state. This should do what is needed | 192 | * and get them into a known state. This should do what is needed |
| 194 | * to get the other CPUs to call kgdb_wait(). Note that on some arches, | 193 | * to get the other CPUs to call kgdb_wait(). Note that on some arches, |
| 195 | * the NMI approach is not used for rounding up all the CPUs. For example, | 194 | * the NMI approach is not used for rounding up all the CPUs. For example, |
| 196 | * in case of MIPS, smp_call_function() is used to roundup CPUs. In | 195 | * in case of MIPS, smp_call_function() is used to roundup CPUs. In |
diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h index 6b58367d145e..d512d98dfb7d 100644 --- a/include/linux/uaccess.h +++ b/include/linux/uaccess.h | |||
| @@ -94,6 +94,7 @@ static inline unsigned long __copy_from_user_nocache(void *to, | |||
| 94 | * happens, handle that and return -EFAULT. | 94 | * happens, handle that and return -EFAULT. |
| 95 | */ | 95 | */ |
| 96 | extern long probe_kernel_read(void *dst, void *src, size_t size); | 96 | extern long probe_kernel_read(void *dst, void *src, size_t size); |
| 97 | extern long __probe_kernel_read(void *dst, void *src, size_t size); | ||
| 97 | 98 | ||
| 98 | /* | 99 | /* |
| 99 | * probe_kernel_write(): safely attempt to write to a location | 100 | * probe_kernel_write(): safely attempt to write to a location |
| @@ -104,6 +105,7 @@ extern long probe_kernel_read(void *dst, void *src, size_t size); | |||
| 104 | * Safely write to address @dst from the buffer at @src. If a kernel fault | 105 | * Safely write to address @dst from the buffer at @src. If a kernel fault |
| 105 | * happens, handle that and return -EFAULT. | 106 | * happens, handle that and return -EFAULT. |
| 106 | */ | 107 | */ |
| 107 | extern long probe_kernel_write(void *dst, void *src, size_t size); | 108 | extern long notrace probe_kernel_write(void *dst, void *src, size_t size); |
| 109 | extern long notrace __probe_kernel_write(void *dst, void *src, size_t size); | ||
| 108 | 110 | ||
| 109 | #endif /* __LINUX_UACCESS_H__ */ | 111 | #endif /* __LINUX_UACCESS_H__ */ |
diff --git a/mm/maccess.c b/mm/maccess.c index 9073695ff25f..4e348dbaecd7 100644 --- a/mm/maccess.c +++ b/mm/maccess.c | |||
| @@ -14,7 +14,11 @@ | |||
| 14 | * Safely read from address @src to the buffer at @dst. If a kernel fault | 14 | * Safely read from address @src to the buffer at @dst. If a kernel fault |
| 15 | * happens, handle that and return -EFAULT. | 15 | * happens, handle that and return -EFAULT. |
| 16 | */ | 16 | */ |
| 17 | long probe_kernel_read(void *dst, void *src, size_t size) | 17 | |
| 18 | long __weak probe_kernel_read(void *dst, void *src, size_t size) | ||
| 19 | __attribute__((alias("__probe_kernel_read"))); | ||
| 20 | |||
| 21 | long __probe_kernel_read(void *dst, void *src, size_t size) | ||
| 18 | { | 22 | { |
| 19 | long ret; | 23 | long ret; |
| 20 | mm_segment_t old_fs = get_fs(); | 24 | mm_segment_t old_fs = get_fs(); |
| @@ -39,7 +43,10 @@ EXPORT_SYMBOL_GPL(probe_kernel_read); | |||
| 39 | * Safely write to address @dst from the buffer at @src. If a kernel fault | 43 | * Safely write to address @dst from the buffer at @src. If a kernel fault |
| 40 | * happens, handle that and return -EFAULT. | 44 | * happens, handle that and return -EFAULT. |
| 41 | */ | 45 | */ |
| 42 | long notrace __weak probe_kernel_write(void *dst, void *src, size_t size) | 46 | long __weak probe_kernel_write(void *dst, void *src, size_t size) |
| 47 | __attribute__((alias("__probe_kernel_write"))); | ||
| 48 | |||
| 49 | long __probe_kernel_write(void *dst, void *src, size_t size) | ||
| 43 | { | 50 | { |
| 44 | long ret; | 51 | long ret; |
| 45 | mm_segment_t old_fs = get_fs(); | 52 | mm_segment_t old_fs = get_fs(); |
