diff options
24 files changed, 395 insertions, 285 deletions
diff --git a/arch/arm64/kernel/insn.c b/arch/arm64/kernel/insn.c index c08b9ad6f429..7371455160e5 100644 --- a/arch/arm64/kernel/insn.c +++ b/arch/arm64/kernel/insn.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * Copyright (C) 2013 Huawei Ltd. | 2 | * Copyright (C) 2013 Huawei Ltd. |
3 | * Author: Jiang Liu <liuj97@gmail.com> | 3 | * Author: Jiang Liu <liuj97@gmail.com> |
4 | * | 4 | * |
5 | * Copyright (C) 2014 Zi Shen Lim <zlim.lnx@gmail.com> | 5 | * Copyright (C) 2014-2016 Zi Shen Lim <zlim.lnx@gmail.com> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
@@ -363,6 +363,9 @@ u32 __kprobes aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type, | |||
363 | u32 immlo, immhi, mask; | 363 | u32 immlo, immhi, mask; |
364 | int shift; | 364 | int shift; |
365 | 365 | ||
366 | if (insn == AARCH64_BREAK_FAULT) | ||
367 | return AARCH64_BREAK_FAULT; | ||
368 | |||
366 | switch (type) { | 369 | switch (type) { |
367 | case AARCH64_INSN_IMM_ADR: | 370 | case AARCH64_INSN_IMM_ADR: |
368 | shift = 0; | 371 | shift = 0; |
@@ -377,7 +380,7 @@ u32 __kprobes aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type, | |||
377 | if (aarch64_get_imm_shift_mask(type, &mask, &shift) < 0) { | 380 | if (aarch64_get_imm_shift_mask(type, &mask, &shift) < 0) { |
378 | pr_err("aarch64_insn_encode_immediate: unknown immediate encoding %d\n", | 381 | pr_err("aarch64_insn_encode_immediate: unknown immediate encoding %d\n", |
379 | type); | 382 | type); |
380 | return 0; | 383 | return AARCH64_BREAK_FAULT; |
381 | } | 384 | } |
382 | } | 385 | } |
383 | 386 | ||
@@ -394,9 +397,12 @@ static u32 aarch64_insn_encode_register(enum aarch64_insn_register_type type, | |||
394 | { | 397 | { |
395 | int shift; | 398 | int shift; |
396 | 399 | ||
400 | if (insn == AARCH64_BREAK_FAULT) | ||
401 | return AARCH64_BREAK_FAULT; | ||
402 | |||
397 | if (reg < AARCH64_INSN_REG_0 || reg > AARCH64_INSN_REG_SP) { | 403 | if (reg < AARCH64_INSN_REG_0 || reg > AARCH64_INSN_REG_SP) { |
398 | pr_err("%s: unknown register encoding %d\n", __func__, reg); | 404 | pr_err("%s: unknown register encoding %d\n", __func__, reg); |
399 | return 0; | 405 | return AARCH64_BREAK_FAULT; |
400 | } | 406 | } |
401 | 407 | ||
402 | switch (type) { | 408 | switch (type) { |
@@ -417,7 +423,7 @@ static u32 aarch64_insn_encode_register(enum aarch64_insn_register_type type, | |||
417 | default: | 423 | default: |
418 | pr_err("%s: unknown register type encoding %d\n", __func__, | 424 | pr_err("%s: unknown register type encoding %d\n", __func__, |
419 | type); | 425 | type); |
420 | return 0; | 426 | return AARCH64_BREAK_FAULT; |
421 | } | 427 | } |
422 | 428 | ||
423 | insn &= ~(GENMASK(4, 0) << shift); | 429 | insn &= ~(GENMASK(4, 0) << shift); |
@@ -446,7 +452,7 @@ static u32 aarch64_insn_encode_ldst_size(enum aarch64_insn_size_type type, | |||
446 | break; | 452 | break; |
447 | default: | 453 | default: |
448 | pr_err("%s: unknown size encoding %d\n", __func__, type); | 454 | pr_err("%s: unknown size encoding %d\n", __func__, type); |
449 | return 0; | 455 | return AARCH64_BREAK_FAULT; |
450 | } | 456 | } |
451 | 457 | ||
452 | insn &= ~GENMASK(31, 30); | 458 | insn &= ~GENMASK(31, 30); |
@@ -460,14 +466,17 @@ static inline long branch_imm_common(unsigned long pc, unsigned long addr, | |||
460 | { | 466 | { |
461 | long offset; | 467 | long offset; |
462 | 468 | ||
463 | /* | 469 | if ((pc & 0x3) || (addr & 0x3)) { |
464 | * PC: A 64-bit Program Counter holding the address of the current | 470 | pr_err("%s: A64 instructions must be word aligned\n", __func__); |
465 | * instruction. A64 instructions must be word-aligned. | 471 | return range; |
466 | */ | 472 | } |
467 | BUG_ON((pc & 0x3) || (addr & 0x3)); | ||
468 | 473 | ||
469 | offset = ((long)addr - (long)pc); | 474 | offset = ((long)addr - (long)pc); |
470 | BUG_ON(offset < -range || offset >= range); | 475 | |
476 | if (offset < -range || offset >= range) { | ||
477 | pr_err("%s: offset out of range\n", __func__); | ||
478 | return range; | ||
479 | } | ||
471 | 480 | ||
472 | return offset; | 481 | return offset; |
473 | } | 482 | } |
@@ -484,6 +493,8 @@ u32 __kprobes aarch64_insn_gen_branch_imm(unsigned long pc, unsigned long addr, | |||
484 | * texts are within +/-128M. | 493 | * texts are within +/-128M. |
485 | */ | 494 | */ |
486 | offset = branch_imm_common(pc, addr, SZ_128M); | 495 | offset = branch_imm_common(pc, addr, SZ_128M); |
496 | if (offset >= SZ_128M) | ||
497 | return AARCH64_BREAK_FAULT; | ||
487 | 498 | ||
488 | switch (type) { | 499 | switch (type) { |
489 | case AARCH64_INSN_BRANCH_LINK: | 500 | case AARCH64_INSN_BRANCH_LINK: |
@@ -493,7 +504,7 @@ u32 __kprobes aarch64_insn_gen_branch_imm(unsigned long pc, unsigned long addr, | |||
493 | insn = aarch64_insn_get_b_value(); | 504 | insn = aarch64_insn_get_b_value(); |
494 | break; | 505 | break; |
495 | default: | 506 | default: |
496 | BUG_ON(1); | 507 | pr_err("%s: unknown branch encoding %d\n", __func__, type); |
497 | return AARCH64_BREAK_FAULT; | 508 | return AARCH64_BREAK_FAULT; |
498 | } | 509 | } |
499 | 510 | ||
@@ -510,6 +521,8 @@ u32 aarch64_insn_gen_comp_branch_imm(unsigned long pc, unsigned long addr, | |||
510 | long offset; | 521 | long offset; |
511 | 522 | ||
512 | offset = branch_imm_common(pc, addr, SZ_1M); | 523 | offset = branch_imm_common(pc, addr, SZ_1M); |
524 | if (offset >= SZ_1M) | ||
525 | return AARCH64_BREAK_FAULT; | ||
513 | 526 | ||
514 | switch (type) { | 527 | switch (type) { |
515 | case AARCH64_INSN_BRANCH_COMP_ZERO: | 528 | case AARCH64_INSN_BRANCH_COMP_ZERO: |
@@ -519,7 +532,7 @@ u32 aarch64_insn_gen_comp_branch_imm(unsigned long pc, unsigned long addr, | |||
519 | insn = aarch64_insn_get_cbnz_value(); | 532 | insn = aarch64_insn_get_cbnz_value(); |
520 | break; | 533 | break; |
521 | default: | 534 | default: |
522 | BUG_ON(1); | 535 | pr_err("%s: unknown branch encoding %d\n", __func__, type); |
523 | return AARCH64_BREAK_FAULT; | 536 | return AARCH64_BREAK_FAULT; |
524 | } | 537 | } |
525 | 538 | ||
@@ -530,7 +543,7 @@ u32 aarch64_insn_gen_comp_branch_imm(unsigned long pc, unsigned long addr, | |||
530 | insn |= AARCH64_INSN_SF_BIT; | 543 | insn |= AARCH64_INSN_SF_BIT; |
531 | break; | 544 | break; |
532 | default: | 545 | default: |
533 | BUG_ON(1); | 546 | pr_err("%s: unknown variant encoding %d\n", __func__, variant); |
534 | return AARCH64_BREAK_FAULT; | 547 | return AARCH64_BREAK_FAULT; |
535 | } | 548 | } |
536 | 549 | ||
@@ -550,7 +563,10 @@ u32 aarch64_insn_gen_cond_branch_imm(unsigned long pc, unsigned long addr, | |||
550 | 563 | ||
551 | insn = aarch64_insn_get_bcond_value(); | 564 | insn = aarch64_insn_get_bcond_value(); |
552 | 565 | ||
553 | BUG_ON(cond < AARCH64_INSN_COND_EQ || cond > AARCH64_INSN_COND_AL); | 566 | if (cond < AARCH64_INSN_COND_EQ || cond > AARCH64_INSN_COND_AL) { |
567 | pr_err("%s: unknown condition encoding %d\n", __func__, cond); | ||
568 | return AARCH64_BREAK_FAULT; | ||
569 | } | ||
554 | insn |= cond; | 570 | insn |= cond; |
555 | 571 | ||
556 | return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_19, insn, | 572 | return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_19, insn, |
@@ -583,7 +599,7 @@ u32 aarch64_insn_gen_branch_reg(enum aarch64_insn_register reg, | |||
583 | insn = aarch64_insn_get_ret_value(); | 599 | insn = aarch64_insn_get_ret_value(); |
584 | break; | 600 | break; |
585 | default: | 601 | default: |
586 | BUG_ON(1); | 602 | pr_err("%s: unknown branch encoding %d\n", __func__, type); |
587 | return AARCH64_BREAK_FAULT; | 603 | return AARCH64_BREAK_FAULT; |
588 | } | 604 | } |
589 | 605 | ||
@@ -606,7 +622,7 @@ u32 aarch64_insn_gen_load_store_reg(enum aarch64_insn_register reg, | |||
606 | insn = aarch64_insn_get_str_reg_value(); | 622 | insn = aarch64_insn_get_str_reg_value(); |
607 | break; | 623 | break; |
608 | default: | 624 | default: |
609 | BUG_ON(1); | 625 | pr_err("%s: unknown load/store encoding %d\n", __func__, type); |
610 | return AARCH64_BREAK_FAULT; | 626 | return AARCH64_BREAK_FAULT; |
611 | } | 627 | } |
612 | 628 | ||
@@ -645,26 +661,30 @@ u32 aarch64_insn_gen_load_store_pair(enum aarch64_insn_register reg1, | |||
645 | insn = aarch64_insn_get_stp_post_value(); | 661 | insn = aarch64_insn_get_stp_post_value(); |
646 | break; | 662 | break; |
647 | default: | 663 | default: |
648 | BUG_ON(1); | 664 | pr_err("%s: unknown load/store encoding %d\n", __func__, type); |
649 | return AARCH64_BREAK_FAULT; | 665 | return AARCH64_BREAK_FAULT; |
650 | } | 666 | } |
651 | 667 | ||
652 | switch (variant) { | 668 | switch (variant) { |
653 | case AARCH64_INSN_VARIANT_32BIT: | 669 | case AARCH64_INSN_VARIANT_32BIT: |
654 | /* offset must be multiples of 4 in the range [-256, 252] */ | 670 | if ((offset & 0x3) || (offset < -256) || (offset > 252)) { |
655 | BUG_ON(offset & 0x3); | 671 | pr_err("%s: offset must be multiples of 4 in the range of [-256, 252] %d\n", |
656 | BUG_ON(offset < -256 || offset > 252); | 672 | __func__, offset); |
673 | return AARCH64_BREAK_FAULT; | ||
674 | } | ||
657 | shift = 2; | 675 | shift = 2; |
658 | break; | 676 | break; |
659 | case AARCH64_INSN_VARIANT_64BIT: | 677 | case AARCH64_INSN_VARIANT_64BIT: |
660 | /* offset must be multiples of 8 in the range [-512, 504] */ | 678 | if ((offset & 0x7) || (offset < -512) || (offset > 504)) { |
661 | BUG_ON(offset & 0x7); | 679 | pr_err("%s: offset must be multiples of 8 in the range of [-512, 504] %d\n", |
662 | BUG_ON(offset < -512 || offset > 504); | 680 | __func__, offset); |
681 | return AARCH64_BREAK_FAULT; | ||
682 | } | ||
663 | shift = 3; | 683 | shift = 3; |
664 | insn |= AARCH64_INSN_SF_BIT; | 684 | insn |= AARCH64_INSN_SF_BIT; |
665 | break; | 685 | break; |
666 | default: | 686 | default: |
667 | BUG_ON(1); | 687 | pr_err("%s: unknown variant encoding %d\n", __func__, variant); |
668 | return AARCH64_BREAK_FAULT; | 688 | return AARCH64_BREAK_FAULT; |
669 | } | 689 | } |
670 | 690 | ||
@@ -702,7 +722,7 @@ u32 aarch64_insn_gen_add_sub_imm(enum aarch64_insn_register dst, | |||
702 | insn = aarch64_insn_get_subs_imm_value(); | 722 | insn = aarch64_insn_get_subs_imm_value(); |
703 | break; | 723 | break; |
704 | default: | 724 | default: |
705 | BUG_ON(1); | 725 | pr_err("%s: unknown add/sub encoding %d\n", __func__, type); |
706 | return AARCH64_BREAK_FAULT; | 726 | return AARCH64_BREAK_FAULT; |
707 | } | 727 | } |
708 | 728 | ||
@@ -713,11 +733,14 @@ u32 aarch64_insn_gen_add_sub_imm(enum aarch64_insn_register dst, | |||
713 | insn |= AARCH64_INSN_SF_BIT; | 733 | insn |= AARCH64_INSN_SF_BIT; |
714 | break; | 734 | break; |
715 | default: | 735 | default: |
716 | BUG_ON(1); | 736 | pr_err("%s: unknown variant encoding %d\n", __func__, variant); |
717 | return AARCH64_BREAK_FAULT; | 737 | return AARCH64_BREAK_FAULT; |
718 | } | 738 | } |
719 | 739 | ||
720 | BUG_ON(imm & ~(SZ_4K - 1)); | 740 | if (imm & ~(SZ_4K - 1)) { |
741 | pr_err("%s: invalid immediate encoding %d\n", __func__, imm); | ||
742 | return AARCH64_BREAK_FAULT; | ||
743 | } | ||
721 | 744 | ||
722 | insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst); | 745 | insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst); |
723 | 746 | ||
@@ -746,7 +769,7 @@ u32 aarch64_insn_gen_bitfield(enum aarch64_insn_register dst, | |||
746 | insn = aarch64_insn_get_sbfm_value(); | 769 | insn = aarch64_insn_get_sbfm_value(); |
747 | break; | 770 | break; |
748 | default: | 771 | default: |
749 | BUG_ON(1); | 772 | pr_err("%s: unknown bitfield encoding %d\n", __func__, type); |
750 | return AARCH64_BREAK_FAULT; | 773 | return AARCH64_BREAK_FAULT; |
751 | } | 774 | } |
752 | 775 | ||
@@ -759,12 +782,18 @@ u32 aarch64_insn_gen_bitfield(enum aarch64_insn_register dst, | |||
759 | mask = GENMASK(5, 0); | 782 | mask = GENMASK(5, 0); |
760 | break; | 783 | break; |
761 | default: | 784 | default: |
762 | BUG_ON(1); | 785 | pr_err("%s: unknown variant encoding %d\n", __func__, variant); |
763 | return AARCH64_BREAK_FAULT; | 786 | return AARCH64_BREAK_FAULT; |
764 | } | 787 | } |
765 | 788 | ||
766 | BUG_ON(immr & ~mask); | 789 | if (immr & ~mask) { |
767 | BUG_ON(imms & ~mask); | 790 | pr_err("%s: invalid immr encoding %d\n", __func__, immr); |
791 | return AARCH64_BREAK_FAULT; | ||
792 | } | ||
793 | if (imms & ~mask) { | ||
794 | pr_err("%s: invalid imms encoding %d\n", __func__, imms); | ||
795 | return AARCH64_BREAK_FAULT; | ||
796 | } | ||
768 | 797 | ||
769 | insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst); | 798 | insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst); |
770 | 799 | ||
@@ -793,23 +822,33 @@ u32 aarch64_insn_gen_movewide(enum aarch64_insn_register dst, | |||
793 | insn = aarch64_insn_get_movn_value(); | 822 | insn = aarch64_insn_get_movn_value(); |
794 | break; | 823 | break; |
795 | default: | 824 | default: |
796 | BUG_ON(1); | 825 | pr_err("%s: unknown movewide encoding %d\n", __func__, type); |
797 | return AARCH64_BREAK_FAULT; | 826 | return AARCH64_BREAK_FAULT; |
798 | } | 827 | } |
799 | 828 | ||
800 | BUG_ON(imm & ~(SZ_64K - 1)); | 829 | if (imm & ~(SZ_64K - 1)) { |
830 | pr_err("%s: invalid immediate encoding %d\n", __func__, imm); | ||
831 | return AARCH64_BREAK_FAULT; | ||
832 | } | ||
801 | 833 | ||
802 | switch (variant) { | 834 | switch (variant) { |
803 | case AARCH64_INSN_VARIANT_32BIT: | 835 | case AARCH64_INSN_VARIANT_32BIT: |
804 | BUG_ON(shift != 0 && shift != 16); | 836 | if (shift != 0 && shift != 16) { |
837 | pr_err("%s: invalid shift encoding %d\n", __func__, | ||
838 | shift); | ||
839 | return AARCH64_BREAK_FAULT; | ||
840 | } | ||
805 | break; | 841 | break; |
806 | case AARCH64_INSN_VARIANT_64BIT: | 842 | case AARCH64_INSN_VARIANT_64BIT: |
807 | insn |= AARCH64_INSN_SF_BIT; | 843 | insn |= AARCH64_INSN_SF_BIT; |
808 | BUG_ON(shift != 0 && shift != 16 && shift != 32 && | 844 | if (shift != 0 && shift != 16 && shift != 32 && shift != 48) { |
809 | shift != 48); | 845 | pr_err("%s: invalid shift encoding %d\n", __func__, |
846 | shift); | ||
847 | return AARCH64_BREAK_FAULT; | ||
848 | } | ||
810 | break; | 849 | break; |
811 | default: | 850 | default: |
812 | BUG_ON(1); | 851 | pr_err("%s: unknown variant encoding %d\n", __func__, variant); |
813 | return AARCH64_BREAK_FAULT; | 852 | return AARCH64_BREAK_FAULT; |
814 | } | 853 | } |
815 | 854 | ||
@@ -843,20 +882,28 @@ u32 aarch64_insn_gen_add_sub_shifted_reg(enum aarch64_insn_register dst, | |||
843 | insn = aarch64_insn_get_subs_value(); | 882 | insn = aarch64_insn_get_subs_value(); |
844 | break; | 883 | break; |
845 | default: | 884 | default: |
846 | BUG_ON(1); | 885 | pr_err("%s: unknown add/sub encoding %d\n", __func__, type); |
847 | return AARCH64_BREAK_FAULT; | 886 | return AARCH64_BREAK_FAULT; |
848 | } | 887 | } |
849 | 888 | ||
850 | switch (variant) { | 889 | switch (variant) { |
851 | case AARCH64_INSN_VARIANT_32BIT: | 890 | case AARCH64_INSN_VARIANT_32BIT: |
852 | BUG_ON(shift & ~(SZ_32 - 1)); | 891 | if (shift & ~(SZ_32 - 1)) { |
892 | pr_err("%s: invalid shift encoding %d\n", __func__, | ||
893 | shift); | ||
894 | return AARCH64_BREAK_FAULT; | ||
895 | } | ||
853 | break; | 896 | break; |
854 | case AARCH64_INSN_VARIANT_64BIT: | 897 | case AARCH64_INSN_VARIANT_64BIT: |
855 | insn |= AARCH64_INSN_SF_BIT; | 898 | insn |= AARCH64_INSN_SF_BIT; |
856 | BUG_ON(shift & ~(SZ_64 - 1)); | 899 | if (shift & ~(SZ_64 - 1)) { |
900 | pr_err("%s: invalid shift encoding %d\n", __func__, | ||
901 | shift); | ||
902 | return AARCH64_BREAK_FAULT; | ||
903 | } | ||
857 | break; | 904 | break; |
858 | default: | 905 | default: |
859 | BUG_ON(1); | 906 | pr_err("%s: unknown variant encoding %d\n", __func__, variant); |
860 | return AARCH64_BREAK_FAULT; | 907 | return AARCH64_BREAK_FAULT; |
861 | } | 908 | } |
862 | 909 | ||
@@ -885,11 +932,15 @@ u32 aarch64_insn_gen_data1(enum aarch64_insn_register dst, | |||
885 | insn = aarch64_insn_get_rev32_value(); | 932 | insn = aarch64_insn_get_rev32_value(); |
886 | break; | 933 | break; |
887 | case AARCH64_INSN_DATA1_REVERSE_64: | 934 | case AARCH64_INSN_DATA1_REVERSE_64: |
888 | BUG_ON(variant != AARCH64_INSN_VARIANT_64BIT); | 935 | if (variant != AARCH64_INSN_VARIANT_64BIT) { |
936 | pr_err("%s: invalid variant for reverse64 %d\n", | ||
937 | __func__, variant); | ||
938 | return AARCH64_BREAK_FAULT; | ||
939 | } | ||
889 | insn = aarch64_insn_get_rev64_value(); | 940 | insn = aarch64_insn_get_rev64_value(); |
890 | break; | 941 | break; |
891 | default: | 942 | default: |
892 | BUG_ON(1); | 943 | pr_err("%s: unknown data1 encoding %d\n", __func__, type); |
893 | return AARCH64_BREAK_FAULT; | 944 | return AARCH64_BREAK_FAULT; |
894 | } | 945 | } |
895 | 946 | ||
@@ -900,7 +951,7 @@ u32 aarch64_insn_gen_data1(enum aarch64_insn_register dst, | |||
900 | insn |= AARCH64_INSN_SF_BIT; | 951 | insn |= AARCH64_INSN_SF_BIT; |
901 | break; | 952 | break; |
902 | default: | 953 | default: |
903 | BUG_ON(1); | 954 | pr_err("%s: unknown variant encoding %d\n", __func__, variant); |
904 | return AARCH64_BREAK_FAULT; | 955 | return AARCH64_BREAK_FAULT; |
905 | } | 956 | } |
906 | 957 | ||
@@ -937,7 +988,7 @@ u32 aarch64_insn_gen_data2(enum aarch64_insn_register dst, | |||
937 | insn = aarch64_insn_get_rorv_value(); | 988 | insn = aarch64_insn_get_rorv_value(); |
938 | break; | 989 | break; |
939 | default: | 990 | default: |
940 | BUG_ON(1); | 991 | pr_err("%s: unknown data2 encoding %d\n", __func__, type); |
941 | return AARCH64_BREAK_FAULT; | 992 | return AARCH64_BREAK_FAULT; |
942 | } | 993 | } |
943 | 994 | ||
@@ -948,7 +999,7 @@ u32 aarch64_insn_gen_data2(enum aarch64_insn_register dst, | |||
948 | insn |= AARCH64_INSN_SF_BIT; | 999 | insn |= AARCH64_INSN_SF_BIT; |
949 | break; | 1000 | break; |
950 | default: | 1001 | default: |
951 | BUG_ON(1); | 1002 | pr_err("%s: unknown variant encoding %d\n", __func__, variant); |
952 | return AARCH64_BREAK_FAULT; | 1003 | return AARCH64_BREAK_FAULT; |
953 | } | 1004 | } |
954 | 1005 | ||
@@ -976,7 +1027,7 @@ u32 aarch64_insn_gen_data3(enum aarch64_insn_register dst, | |||
976 | insn = aarch64_insn_get_msub_value(); | 1027 | insn = aarch64_insn_get_msub_value(); |
977 | break; | 1028 | break; |
978 | default: | 1029 | default: |
979 | BUG_ON(1); | 1030 | pr_err("%s: unknown data3 encoding %d\n", __func__, type); |
980 | return AARCH64_BREAK_FAULT; | 1031 | return AARCH64_BREAK_FAULT; |
981 | } | 1032 | } |
982 | 1033 | ||
@@ -987,7 +1038,7 @@ u32 aarch64_insn_gen_data3(enum aarch64_insn_register dst, | |||
987 | insn |= AARCH64_INSN_SF_BIT; | 1038 | insn |= AARCH64_INSN_SF_BIT; |
988 | break; | 1039 | break; |
989 | default: | 1040 | default: |
990 | BUG_ON(1); | 1041 | pr_err("%s: unknown variant encoding %d\n", __func__, variant); |
991 | return AARCH64_BREAK_FAULT; | 1042 | return AARCH64_BREAK_FAULT; |
992 | } | 1043 | } |
993 | 1044 | ||
@@ -1037,20 +1088,28 @@ u32 aarch64_insn_gen_logical_shifted_reg(enum aarch64_insn_register dst, | |||
1037 | insn = aarch64_insn_get_bics_value(); | 1088 | insn = aarch64_insn_get_bics_value(); |
1038 | break; | 1089 | break; |
1039 | default: | 1090 | default: |
1040 | BUG_ON(1); | 1091 | pr_err("%s: unknown logical encoding %d\n", __func__, type); |
1041 | return AARCH64_BREAK_FAULT; | 1092 | return AARCH64_BREAK_FAULT; |
1042 | } | 1093 | } |
1043 | 1094 | ||
1044 | switch (variant) { | 1095 | switch (variant) { |
1045 | case AARCH64_INSN_VARIANT_32BIT: | 1096 | case AARCH64_INSN_VARIANT_32BIT: |
1046 | BUG_ON(shift & ~(SZ_32 - 1)); | 1097 | if (shift & ~(SZ_32 - 1)) { |
1098 | pr_err("%s: invalid shift encoding %d\n", __func__, | ||
1099 | shift); | ||
1100 | return AARCH64_BREAK_FAULT; | ||
1101 | } | ||
1047 | break; | 1102 | break; |
1048 | case AARCH64_INSN_VARIANT_64BIT: | 1103 | case AARCH64_INSN_VARIANT_64BIT: |
1049 | insn |= AARCH64_INSN_SF_BIT; | 1104 | insn |= AARCH64_INSN_SF_BIT; |
1050 | BUG_ON(shift & ~(SZ_64 - 1)); | 1105 | if (shift & ~(SZ_64 - 1)) { |
1106 | pr_err("%s: invalid shift encoding %d\n", __func__, | ||
1107 | shift); | ||
1108 | return AARCH64_BREAK_FAULT; | ||
1109 | } | ||
1051 | break; | 1110 | break; |
1052 | default: | 1111 | default: |
1053 | BUG_ON(1); | 1112 | pr_err("%s: unknown variant encoding %d\n", __func__, variant); |
1054 | return AARCH64_BREAK_FAULT; | 1113 | return AARCH64_BREAK_FAULT; |
1055 | } | 1114 | } |
1056 | 1115 | ||
diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c index 7658612d915c..a34420a5df9a 100644 --- a/arch/arm64/net/bpf_jit_comp.c +++ b/arch/arm64/net/bpf_jit_comp.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * BPF JIT compiler for ARM64 | 2 | * BPF JIT compiler for ARM64 |
3 | * | 3 | * |
4 | * Copyright (C) 2014-2015 Zi Shen Lim <zlim.lnx@gmail.com> | 4 | * Copyright (C) 2014-2016 Zi Shen Lim <zlim.lnx@gmail.com> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 as | 7 | * it under the terms of the GNU General Public License version 2 as |
@@ -737,6 +737,20 @@ static int build_body(struct jit_ctx *ctx) | |||
737 | return 0; | 737 | return 0; |
738 | } | 738 | } |
739 | 739 | ||
740 | static int validate_code(struct jit_ctx *ctx) | ||
741 | { | ||
742 | int i; | ||
743 | |||
744 | for (i = 0; i < ctx->idx; i++) { | ||
745 | u32 a64_insn = le32_to_cpu(ctx->image[i]); | ||
746 | |||
747 | if (a64_insn == AARCH64_BREAK_FAULT) | ||
748 | return -1; | ||
749 | } | ||
750 | |||
751 | return 0; | ||
752 | } | ||
753 | |||
740 | static inline void bpf_flush_icache(void *start, void *end) | 754 | static inline void bpf_flush_icache(void *start, void *end) |
741 | { | 755 | { |
742 | flush_icache_range((unsigned long)start, (unsigned long)end); | 756 | flush_icache_range((unsigned long)start, (unsigned long)end); |
@@ -799,6 +813,12 @@ void bpf_int_jit_compile(struct bpf_prog *prog) | |||
799 | 813 | ||
800 | build_epilogue(&ctx); | 814 | build_epilogue(&ctx); |
801 | 815 | ||
816 | /* 3. Extra pass to validate JITed code. */ | ||
817 | if (validate_code(&ctx)) { | ||
818 | bpf_jit_binary_free(header); | ||
819 | goto out; | ||
820 | } | ||
821 | |||
802 | /* And we're done. */ | 822 | /* And we're done. */ |
803 | if (bpf_jit_enable > 1) | 823 | if (bpf_jit_enable > 1) |
804 | bpf_jit_dump(prog->len, image_size, 2, ctx.image); | 824 | bpf_jit_dump(prog->len, image_size, 2, ctx.image); |
diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c index 3dfd287256d6..92ddae101ecc 100644 --- a/drivers/infiniband/hw/mlx5/cq.c +++ b/drivers/infiniband/hw/mlx5/cq.c | |||
@@ -756,7 +756,7 @@ struct ib_cq *mlx5_ib_create_cq(struct ib_device *ibdev, | |||
756 | int uninitialized_var(index); | 756 | int uninitialized_var(index); |
757 | int uninitialized_var(inlen); | 757 | int uninitialized_var(inlen); |
758 | int cqe_size; | 758 | int cqe_size; |
759 | int irqn; | 759 | unsigned int irqn; |
760 | int eqn; | 760 | int eqn; |
761 | int err; | 761 | int err; |
762 | 762 | ||
diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c index 21a0cfc3e7ec..771cc267f217 100644 --- a/drivers/net/ethernet/brocade/bna/bnad.c +++ b/drivers/net/ethernet/brocade/bna/bnad.c | |||
@@ -542,39 +542,50 @@ bnad_cq_drop_packet(struct bnad *bnad, struct bna_rcb *rcb, | |||
542 | } | 542 | } |
543 | 543 | ||
544 | static void | 544 | static void |
545 | bnad_cq_setup_skb_frags(struct bna_rcb *rcb, struct sk_buff *skb, | 545 | bnad_cq_setup_skb_frags(struct bna_ccb *ccb, struct sk_buff *skb, u32 nvecs) |
546 | u32 sop_ci, u32 nvecs, u32 last_fraglen) | ||
547 | { | 546 | { |
547 | struct bna_rcb *rcb; | ||
548 | struct bnad *bnad; | 548 | struct bnad *bnad; |
549 | u32 ci, vec, len, totlen = 0; | ||
550 | struct bnad_rx_unmap_q *unmap_q; | 549 | struct bnad_rx_unmap_q *unmap_q; |
551 | struct bnad_rx_unmap *unmap; | 550 | struct bna_cq_entry *cq, *cmpl; |
551 | u32 ci, pi, totlen = 0; | ||
552 | |||
553 | cq = ccb->sw_q; | ||
554 | pi = ccb->producer_index; | ||
555 | cmpl = &cq[pi]; | ||
552 | 556 | ||
557 | rcb = bna_is_small_rxq(cmpl->rxq_id) ? ccb->rcb[1] : ccb->rcb[0]; | ||
553 | unmap_q = rcb->unmap_q; | 558 | unmap_q = rcb->unmap_q; |
554 | bnad = rcb->bnad; | 559 | bnad = rcb->bnad; |
560 | ci = rcb->consumer_index; | ||
555 | 561 | ||
556 | /* prefetch header */ | 562 | /* prefetch header */ |
557 | prefetch(page_address(unmap_q->unmap[sop_ci].page) + | 563 | prefetch(page_address(unmap_q->unmap[ci].page) + |
558 | unmap_q->unmap[sop_ci].page_offset); | 564 | unmap_q->unmap[ci].page_offset); |
565 | |||
566 | while (nvecs--) { | ||
567 | struct bnad_rx_unmap *unmap; | ||
568 | u32 len; | ||
559 | 569 | ||
560 | for (vec = 1, ci = sop_ci; vec <= nvecs; vec++) { | ||
561 | unmap = &unmap_q->unmap[ci]; | 570 | unmap = &unmap_q->unmap[ci]; |
562 | BNA_QE_INDX_INC(ci, rcb->q_depth); | 571 | BNA_QE_INDX_INC(ci, rcb->q_depth); |
563 | 572 | ||
564 | dma_unmap_page(&bnad->pcidev->dev, | 573 | dma_unmap_page(&bnad->pcidev->dev, |
565 | dma_unmap_addr(&unmap->vector, dma_addr), | 574 | dma_unmap_addr(&unmap->vector, dma_addr), |
566 | unmap->vector.len, DMA_FROM_DEVICE); | 575 | unmap->vector.len, DMA_FROM_DEVICE); |
567 | 576 | ||
568 | len = (vec == nvecs) ? | 577 | len = ntohs(cmpl->length); |
569 | last_fraglen : unmap->vector.len; | ||
570 | skb->truesize += unmap->vector.len; | 578 | skb->truesize += unmap->vector.len; |
571 | totlen += len; | 579 | totlen += len; |
572 | 580 | ||
573 | skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, | 581 | skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, |
574 | unmap->page, unmap->page_offset, len); | 582 | unmap->page, unmap->page_offset, len); |
575 | 583 | ||
576 | unmap->page = NULL; | 584 | unmap->page = NULL; |
577 | unmap->vector.len = 0; | 585 | unmap->vector.len = 0; |
586 | |||
587 | BNA_QE_INDX_INC(pi, ccb->q_depth); | ||
588 | cmpl = &cq[pi]; | ||
578 | } | 589 | } |
579 | 590 | ||
580 | skb->len += totlen; | 591 | skb->len += totlen; |
@@ -704,7 +715,7 @@ bnad_cq_process(struct bnad *bnad, struct bna_ccb *ccb, int budget) | |||
704 | if (BNAD_RXBUF_IS_SK_BUFF(unmap_q->type)) | 715 | if (BNAD_RXBUF_IS_SK_BUFF(unmap_q->type)) |
705 | bnad_cq_setup_skb(bnad, skb, unmap, len); | 716 | bnad_cq_setup_skb(bnad, skb, unmap, len); |
706 | else | 717 | else |
707 | bnad_cq_setup_skb_frags(rcb, skb, sop_ci, nvecs, len); | 718 | bnad_cq_setup_skb_frags(ccb, skb, nvecs); |
708 | 719 | ||
709 | rcb->rxq->rx_packets++; | 720 | rcb->rxq->rx_packets++; |
710 | rcb->rxq->rx_bytes += totlen; | 721 | rcb->rxq->rx_bytes += totlen; |
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c index d2263c72bd8a..12188807468c 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c | |||
@@ -369,8 +369,17 @@ int hns_rcb_common_init_hw(struct rcb_common_cb *rcb_common) | |||
369 | dsaf_write_dev(rcb_common, RCB_COM_CFG_ENDIAN_REG, | 369 | dsaf_write_dev(rcb_common, RCB_COM_CFG_ENDIAN_REG, |
370 | HNS_RCB_COMMON_ENDIAN); | 370 | HNS_RCB_COMMON_ENDIAN); |
371 | 371 | ||
372 | dsaf_write_dev(rcb_common, RCB_COM_CFG_FNA_REG, 0x0); | 372 | if (AE_IS_VER1(rcb_common->dsaf_dev->dsaf_ver)) { |
373 | dsaf_write_dev(rcb_common, RCB_COM_CFG_FA_REG, 0x1); | 373 | dsaf_write_dev(rcb_common, RCB_COM_CFG_FNA_REG, 0x0); |
374 | dsaf_write_dev(rcb_common, RCB_COM_CFG_FA_REG, 0x1); | ||
375 | } else { | ||
376 | dsaf_set_dev_bit(rcb_common, RCBV2_COM_CFG_USER_REG, | ||
377 | RCB_COM_CFG_FNA_B, false); | ||
378 | dsaf_set_dev_bit(rcb_common, RCBV2_COM_CFG_USER_REG, | ||
379 | RCB_COM_CFG_FA_B, true); | ||
380 | dsaf_set_dev_bit(rcb_common, RCBV2_COM_CFG_TSO_MODE_REG, | ||
381 | RCB_COM_TSO_MODE_B, HNS_TSO_MODE_8BD_32K); | ||
382 | } | ||
374 | 383 | ||
375 | return 0; | 384 | return 0; |
376 | } | 385 | } |
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h index 29041b18741a..81fe9f849973 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h | |||
@@ -54,6 +54,9 @@ struct rcb_common_cb; | |||
54 | #define HNS_DUMP_REG_NUM 500 | 54 | #define HNS_DUMP_REG_NUM 500 |
55 | #define HNS_STATIC_REG_NUM 12 | 55 | #define HNS_STATIC_REG_NUM 12 |
56 | 56 | ||
57 | #define HNS_TSO_MODE_8BD_32K 1 | ||
58 | #define HNS_TSO_MDOE_4BD_16K 0 | ||
59 | |||
57 | enum rcb_int_flag { | 60 | enum rcb_int_flag { |
58 | RCB_INT_FLAG_TX = 0x1, | 61 | RCB_INT_FLAG_TX = 0x1, |
59 | RCB_INT_FLAG_RX = (0x1 << 1), | 62 | RCB_INT_FLAG_RX = (0x1 << 1), |
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h index 5d1b746e141d..f0c4f9b09d5b 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h | |||
@@ -363,6 +363,8 @@ | |||
363 | #define RCB_COM_CFG_FA_REG 0x3C | 363 | #define RCB_COM_CFG_FA_REG 0x3C |
364 | #define RCB_COM_CFG_PKT_TC_BP_REG 0x40 | 364 | #define RCB_COM_CFG_PKT_TC_BP_REG 0x40 |
365 | #define RCB_COM_CFG_PPE_TNL_CLKEN_REG 0x44 | 365 | #define RCB_COM_CFG_PPE_TNL_CLKEN_REG 0x44 |
366 | #define RCBV2_COM_CFG_USER_REG 0x30 | ||
367 | #define RCBV2_COM_CFG_TSO_MODE_REG 0x50 | ||
366 | 368 | ||
367 | #define RCB_COM_INTMSK_TX_PKT_REG 0x3A0 | 369 | #define RCB_COM_INTMSK_TX_PKT_REG 0x3A0 |
368 | #define RCB_COM_RINT_TX_PKT_REG 0x3A8 | 370 | #define RCB_COM_RINT_TX_PKT_REG 0x3A8 |
@@ -860,6 +862,9 @@ | |||
860 | 862 | ||
861 | #define PPE_COMMON_CNT_CLR_CE_B 0 | 863 | #define PPE_COMMON_CNT_CLR_CE_B 0 |
862 | #define PPE_COMMON_CNT_CLR_SNAP_EN_B 1 | 864 | #define PPE_COMMON_CNT_CLR_SNAP_EN_B 1 |
865 | #define RCB_COM_TSO_MODE_B 0 | ||
866 | #define RCB_COM_CFG_FNA_B 1 | ||
867 | #define RCB_COM_CFG_FA_B 0 | ||
863 | 868 | ||
864 | #define GMAC_DUPLEX_TYPE_B 0 | 869 | #define GMAC_DUPLEX_TYPE_B 0 |
865 | 870 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 5c74a734f158..c56d91a2812b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c | |||
@@ -752,7 +752,7 @@ static int mlx5e_create_cq(struct mlx5e_channel *c, | |||
752 | struct mlx5_core_dev *mdev = priv->mdev; | 752 | struct mlx5_core_dev *mdev = priv->mdev; |
753 | struct mlx5_core_cq *mcq = &cq->mcq; | 753 | struct mlx5_core_cq *mcq = &cq->mcq; |
754 | int eqn_not_used; | 754 | int eqn_not_used; |
755 | int irqn; | 755 | unsigned int irqn; |
756 | int err; | 756 | int err; |
757 | u32 i; | 757 | u32 i; |
758 | 758 | ||
@@ -806,7 +806,7 @@ static int mlx5e_enable_cq(struct mlx5e_cq *cq, struct mlx5e_cq_param *param) | |||
806 | void *in; | 806 | void *in; |
807 | void *cqc; | 807 | void *cqc; |
808 | int inlen; | 808 | int inlen; |
809 | int irqn_not_used; | 809 | unsigned int irqn_not_used; |
810 | int eqn; | 810 | int eqn; |
811 | int err; | 811 | int err; |
812 | 812 | ||
@@ -1517,7 +1517,7 @@ static int mlx5e_create_drop_cq(struct mlx5e_priv *priv, | |||
1517 | struct mlx5_core_dev *mdev = priv->mdev; | 1517 | struct mlx5_core_dev *mdev = priv->mdev; |
1518 | struct mlx5_core_cq *mcq = &cq->mcq; | 1518 | struct mlx5_core_cq *mcq = &cq->mcq; |
1519 | int eqn_not_used; | 1519 | int eqn_not_used; |
1520 | int irqn; | 1520 | unsigned int irqn; |
1521 | int err; | 1521 | int err; |
1522 | 1522 | ||
1523 | err = mlx5_cqwq_create(mdev, ¶m->wq, param->cqc, &cq->wq, | 1523 | err = mlx5_cqwq_create(mdev, ¶m->wq, param->cqc, &cq->wq, |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 67676cf0d507..b37749a3730e 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c | |||
@@ -585,7 +585,8 @@ static void mlx5_irq_clear_affinity_hints(struct mlx5_core_dev *mdev) | |||
585 | mlx5_irq_clear_affinity_hint(mdev, i); | 585 | mlx5_irq_clear_affinity_hint(mdev, i); |
586 | } | 586 | } |
587 | 587 | ||
588 | int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn, int *irqn) | 588 | int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn, |
589 | unsigned int *irqn) | ||
589 | { | 590 | { |
590 | struct mlx5_eq_table *table = &dev->priv.eq_table; | 591 | struct mlx5_eq_table *table = &dev->priv.eq_table; |
591 | struct mlx5_eq *eq, *n; | 592 | struct mlx5_eq *eq, *n; |
diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c index 8a8f6fb2880d..2174ec937b4d 100644 --- a/drivers/net/phy/at803x.c +++ b/drivers/net/phy/at803x.c | |||
@@ -20,10 +20,21 @@ | |||
20 | #include <linux/gpio/consumer.h> | 20 | #include <linux/gpio/consumer.h> |
21 | 21 | ||
22 | #define AT803X_INTR_ENABLE 0x12 | 22 | #define AT803X_INTR_ENABLE 0x12 |
23 | #define AT803X_INTR_ENABLE_AUTONEG_ERR BIT(15) | ||
24 | #define AT803X_INTR_ENABLE_SPEED_CHANGED BIT(14) | ||
25 | #define AT803X_INTR_ENABLE_DUPLEX_CHANGED BIT(13) | ||
26 | #define AT803X_INTR_ENABLE_PAGE_RECEIVED BIT(12) | ||
27 | #define AT803X_INTR_ENABLE_LINK_FAIL BIT(11) | ||
28 | #define AT803X_INTR_ENABLE_LINK_SUCCESS BIT(10) | ||
29 | #define AT803X_INTR_ENABLE_WIRESPEED_DOWNGRADE BIT(5) | ||
30 | #define AT803X_INTR_ENABLE_POLARITY_CHANGED BIT(1) | ||
31 | #define AT803X_INTR_ENABLE_WOL BIT(0) | ||
32 | |||
23 | #define AT803X_INTR_STATUS 0x13 | 33 | #define AT803X_INTR_STATUS 0x13 |
34 | |||
24 | #define AT803X_SMART_SPEED 0x14 | 35 | #define AT803X_SMART_SPEED 0x14 |
25 | #define AT803X_LED_CONTROL 0x18 | 36 | #define AT803X_LED_CONTROL 0x18 |
26 | #define AT803X_WOL_ENABLE 0x01 | 37 | |
27 | #define AT803X_DEVICE_ADDR 0x03 | 38 | #define AT803X_DEVICE_ADDR 0x03 |
28 | #define AT803X_LOC_MAC_ADDR_0_15_OFFSET 0x804C | 39 | #define AT803X_LOC_MAC_ADDR_0_15_OFFSET 0x804C |
29 | #define AT803X_LOC_MAC_ADDR_16_31_OFFSET 0x804B | 40 | #define AT803X_LOC_MAC_ADDR_16_31_OFFSET 0x804B |
@@ -31,13 +42,15 @@ | |||
31 | #define AT803X_MMD_ACCESS_CONTROL 0x0D | 42 | #define AT803X_MMD_ACCESS_CONTROL 0x0D |
32 | #define AT803X_MMD_ACCESS_CONTROL_DATA 0x0E | 43 | #define AT803X_MMD_ACCESS_CONTROL_DATA 0x0E |
33 | #define AT803X_FUNC_DATA 0x4003 | 44 | #define AT803X_FUNC_DATA 0x4003 |
34 | #define AT803X_INER 0x0012 | 45 | |
35 | #define AT803X_INER_INIT 0xec00 | ||
36 | #define AT803X_INSR 0x0013 | ||
37 | #define AT803X_DEBUG_ADDR 0x1D | 46 | #define AT803X_DEBUG_ADDR 0x1D |
38 | #define AT803X_DEBUG_DATA 0x1E | 47 | #define AT803X_DEBUG_DATA 0x1E |
39 | #define AT803X_DEBUG_SYSTEM_MODE_CTRL 0x05 | 48 | |
40 | #define AT803X_DEBUG_RGMII_TX_CLK_DLY BIT(8) | 49 | #define AT803X_DEBUG_REG_0 0x00 |
50 | #define AT803X_DEBUG_RX_CLK_DLY_EN BIT(15) | ||
51 | |||
52 | #define AT803X_DEBUG_REG_5 0x05 | ||
53 | #define AT803X_DEBUG_TX_CLK_DLY_EN BIT(8) | ||
41 | 54 | ||
42 | #define ATH8030_PHY_ID 0x004dd076 | 55 | #define ATH8030_PHY_ID 0x004dd076 |
43 | #define ATH8031_PHY_ID 0x004dd074 | 56 | #define ATH8031_PHY_ID 0x004dd074 |
@@ -61,6 +74,46 @@ struct at803x_context { | |||
61 | u16 led_control; | 74 | u16 led_control; |
62 | }; | 75 | }; |
63 | 76 | ||
77 | static int at803x_debug_reg_read(struct phy_device *phydev, u16 reg) | ||
78 | { | ||
79 | int ret; | ||
80 | |||
81 | ret = phy_write(phydev, AT803X_DEBUG_ADDR, reg); | ||
82 | if (ret < 0) | ||
83 | return ret; | ||
84 | |||
85 | return phy_read(phydev, AT803X_DEBUG_DATA); | ||
86 | } | ||
87 | |||
88 | static int at803x_debug_reg_mask(struct phy_device *phydev, u16 reg, | ||
89 | u16 clear, u16 set) | ||
90 | { | ||
91 | u16 val; | ||
92 | int ret; | ||
93 | |||
94 | ret = at803x_debug_reg_read(phydev, reg); | ||
95 | if (ret < 0) | ||
96 | return ret; | ||
97 | |||
98 | val = ret & 0xffff; | ||
99 | val &= ~clear; | ||
100 | val |= set; | ||
101 | |||
102 | return phy_write(phydev, AT803X_DEBUG_DATA, val); | ||
103 | } | ||
104 | |||
105 | static inline int at803x_enable_rx_delay(struct phy_device *phydev) | ||
106 | { | ||
107 | return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, 0, | ||
108 | AT803X_DEBUG_RX_CLK_DLY_EN); | ||
109 | } | ||
110 | |||
111 | static inline int at803x_enable_tx_delay(struct phy_device *phydev) | ||
112 | { | ||
113 | return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5, 0, | ||
114 | AT803X_DEBUG_TX_CLK_DLY_EN); | ||
115 | } | ||
116 | |||
64 | /* save relevant PHY registers to private copy */ | 117 | /* save relevant PHY registers to private copy */ |
65 | static void at803x_context_save(struct phy_device *phydev, | 118 | static void at803x_context_save(struct phy_device *phydev, |
66 | struct at803x_context *context) | 119 | struct at803x_context *context) |
@@ -119,14 +172,14 @@ static int at803x_set_wol(struct phy_device *phydev, | |||
119 | } | 172 | } |
120 | 173 | ||
121 | value = phy_read(phydev, AT803X_INTR_ENABLE); | 174 | value = phy_read(phydev, AT803X_INTR_ENABLE); |
122 | value |= AT803X_WOL_ENABLE; | 175 | value |= AT803X_INTR_ENABLE_WOL; |
123 | ret = phy_write(phydev, AT803X_INTR_ENABLE, value); | 176 | ret = phy_write(phydev, AT803X_INTR_ENABLE, value); |
124 | if (ret) | 177 | if (ret) |
125 | return ret; | 178 | return ret; |
126 | value = phy_read(phydev, AT803X_INTR_STATUS); | 179 | value = phy_read(phydev, AT803X_INTR_STATUS); |
127 | } else { | 180 | } else { |
128 | value = phy_read(phydev, AT803X_INTR_ENABLE); | 181 | value = phy_read(phydev, AT803X_INTR_ENABLE); |
129 | value &= (~AT803X_WOL_ENABLE); | 182 | value &= (~AT803X_INTR_ENABLE_WOL); |
130 | ret = phy_write(phydev, AT803X_INTR_ENABLE, value); | 183 | ret = phy_write(phydev, AT803X_INTR_ENABLE, value); |
131 | if (ret) | 184 | if (ret) |
132 | return ret; | 185 | return ret; |
@@ -145,7 +198,7 @@ static void at803x_get_wol(struct phy_device *phydev, | |||
145 | wol->wolopts = 0; | 198 | wol->wolopts = 0; |
146 | 199 | ||
147 | value = phy_read(phydev, AT803X_INTR_ENABLE); | 200 | value = phy_read(phydev, AT803X_INTR_ENABLE); |
148 | if (value & AT803X_WOL_ENABLE) | 201 | if (value & AT803X_INTR_ENABLE_WOL) |
149 | wol->wolopts |= WAKE_MAGIC; | 202 | wol->wolopts |= WAKE_MAGIC; |
150 | } | 203 | } |
151 | 204 | ||
@@ -157,7 +210,7 @@ static int at803x_suspend(struct phy_device *phydev) | |||
157 | mutex_lock(&phydev->lock); | 210 | mutex_lock(&phydev->lock); |
158 | 211 | ||
159 | value = phy_read(phydev, AT803X_INTR_ENABLE); | 212 | value = phy_read(phydev, AT803X_INTR_ENABLE); |
160 | wol_enabled = value & AT803X_WOL_ENABLE; | 213 | wol_enabled = value & AT803X_INTR_ENABLE_WOL; |
161 | 214 | ||
162 | value = phy_read(phydev, MII_BMCR); | 215 | value = phy_read(phydev, MII_BMCR); |
163 | 216 | ||
@@ -217,14 +270,17 @@ static int at803x_config_init(struct phy_device *phydev) | |||
217 | if (ret < 0) | 270 | if (ret < 0) |
218 | return ret; | 271 | return ret; |
219 | 272 | ||
220 | if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) { | 273 | if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID || |
221 | ret = phy_write(phydev, AT803X_DEBUG_ADDR, | 274 | phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) { |
222 | AT803X_DEBUG_SYSTEM_MODE_CTRL); | 275 | ret = at803x_enable_rx_delay(phydev); |
223 | if (ret) | 276 | if (ret < 0) |
224 | return ret; | 277 | return ret; |
225 | ret = phy_write(phydev, AT803X_DEBUG_DATA, | 278 | } |
226 | AT803X_DEBUG_RGMII_TX_CLK_DLY); | 279 | |
227 | if (ret) | 280 | if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID || |
281 | phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) { | ||
282 | ret = at803x_enable_tx_delay(phydev); | ||
283 | if (ret < 0) | ||
228 | return ret; | 284 | return ret; |
229 | } | 285 | } |
230 | 286 | ||
@@ -235,7 +291,7 @@ static int at803x_ack_interrupt(struct phy_device *phydev) | |||
235 | { | 291 | { |
236 | int err; | 292 | int err; |
237 | 293 | ||
238 | err = phy_read(phydev, AT803X_INSR); | 294 | err = phy_read(phydev, AT803X_INTR_STATUS); |
239 | 295 | ||
240 | return (err < 0) ? err : 0; | 296 | return (err < 0) ? err : 0; |
241 | } | 297 | } |
@@ -245,13 +301,19 @@ static int at803x_config_intr(struct phy_device *phydev) | |||
245 | int err; | 301 | int err; |
246 | int value; | 302 | int value; |
247 | 303 | ||
248 | value = phy_read(phydev, AT803X_INER); | 304 | value = phy_read(phydev, AT803X_INTR_ENABLE); |
305 | |||
306 | if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { | ||
307 | value |= AT803X_INTR_ENABLE_AUTONEG_ERR; | ||
308 | value |= AT803X_INTR_ENABLE_SPEED_CHANGED; | ||
309 | value |= AT803X_INTR_ENABLE_DUPLEX_CHANGED; | ||
310 | value |= AT803X_INTR_ENABLE_LINK_FAIL; | ||
311 | value |= AT803X_INTR_ENABLE_LINK_SUCCESS; | ||
249 | 312 | ||
250 | if (phydev->interrupts == PHY_INTERRUPT_ENABLED) | 313 | err = phy_write(phydev, AT803X_INTR_ENABLE, value); |
251 | err = phy_write(phydev, AT803X_INER, | 314 | } |
252 | value | AT803X_INER_INIT); | ||
253 | else | 315 | else |
254 | err = phy_write(phydev, AT803X_INER, 0); | 316 | err = phy_write(phydev, AT803X_INTR_ENABLE, 0); |
255 | 317 | ||
256 | return err; | 318 | return err; |
257 | } | 319 | } |
@@ -322,7 +384,7 @@ static struct phy_driver at803x_driver[] = { | |||
322 | .get_wol = at803x_get_wol, | 384 | .get_wol = at803x_get_wol, |
323 | .suspend = at803x_suspend, | 385 | .suspend = at803x_suspend, |
324 | .resume = at803x_resume, | 386 | .resume = at803x_resume, |
325 | .features = PHY_GBIT_FEATURES, | 387 | .features = PHY_BASIC_FEATURES, |
326 | .flags = PHY_HAS_INTERRUPT, | 388 | .flags = PHY_HAS_INTERRUPT, |
327 | .config_aneg = genphy_config_aneg, | 389 | .config_aneg = genphy_config_aneg, |
328 | .read_status = genphy_read_status, | 390 | .read_status = genphy_read_status, |
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 2528331de193..718ceeab4dbc 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c | |||
@@ -1872,10 +1872,10 @@ static int team_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, u16 vid) | |||
1872 | struct team *team = netdev_priv(dev); | 1872 | struct team *team = netdev_priv(dev); |
1873 | struct team_port *port; | 1873 | struct team_port *port; |
1874 | 1874 | ||
1875 | rcu_read_lock(); | 1875 | mutex_lock(&team->lock); |
1876 | list_for_each_entry_rcu(port, &team->port_list, list) | 1876 | list_for_each_entry(port, &team->port_list, list) |
1877 | vlan_vid_del(port->dev, proto, vid); | 1877 | vlan_vid_del(port->dev, proto, vid); |
1878 | rcu_read_unlock(); | 1878 | mutex_unlock(&team->lock); |
1879 | 1879 | ||
1880 | return 0; | 1880 | return 0; |
1881 | } | 1881 | } |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h index ef06f57a7a0e..d3c9f0d52ae3 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h | |||
@@ -47,8 +47,7 @@ static const char BRCM_ ## fw_nvram_name ## _FIRMWARE_NAME[] = \ | |||
47 | BRCMF_FW_DEFAULT_PATH fw; \ | 47 | BRCMF_FW_DEFAULT_PATH fw; \ |
48 | static const char BRCM_ ## fw_nvram_name ## _NVRAM_NAME[] = \ | 48 | static const char BRCM_ ## fw_nvram_name ## _NVRAM_NAME[] = \ |
49 | BRCMF_FW_DEFAULT_PATH nvram; \ | 49 | BRCMF_FW_DEFAULT_PATH nvram; \ |
50 | MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH fw); \ | 50 | MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH fw); |
51 | MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH nvram) | ||
52 | 51 | ||
53 | #define BRCMF_FW_DEF(fw_name, fw) \ | 52 | #define BRCMF_FW_DEF(fw_name, fw) \ |
54 | static const char BRCM_ ## fw_name ## _FIRMWARE_NAME[] = \ | 53 | static const char BRCM_ ## fw_name ## _FIRMWARE_NAME[] = \ |
diff --git a/include/linux/mlx5/cq.h b/include/linux/mlx5/cq.h index abc4767695e4..b2c9fada8eac 100644 --- a/include/linux/mlx5/cq.h +++ b/include/linux/mlx5/cq.h | |||
@@ -45,7 +45,7 @@ struct mlx5_core_cq { | |||
45 | atomic_t refcount; | 45 | atomic_t refcount; |
46 | struct completion free; | 46 | struct completion free; |
47 | unsigned vector; | 47 | unsigned vector; |
48 | int irqn; | 48 | unsigned int irqn; |
49 | void (*comp) (struct mlx5_core_cq *); | 49 | void (*comp) (struct mlx5_core_cq *); |
50 | void (*event) (struct mlx5_core_cq *, enum mlx5_event); | 50 | void (*event) (struct mlx5_core_cq *, enum mlx5_event); |
51 | struct mlx5_uar *uar; | 51 | struct mlx5_uar *uar; |
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index 2fd7019f69db..5162f3533042 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h | |||
@@ -303,7 +303,7 @@ struct mlx5_eq { | |||
303 | u32 cons_index; | 303 | u32 cons_index; |
304 | struct mlx5_buf buf; | 304 | struct mlx5_buf buf; |
305 | int size; | 305 | int size; |
306 | u8 irqn; | 306 | unsigned int irqn; |
307 | u8 eqn; | 307 | u8 eqn; |
308 | int nent; | 308 | int nent; |
309 | u64 mask; | 309 | u64 mask; |
@@ -783,7 +783,8 @@ int mlx5_create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq, u8 vecidx, | |||
783 | int mlx5_destroy_unmap_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq); | 783 | int mlx5_destroy_unmap_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq); |
784 | int mlx5_start_eqs(struct mlx5_core_dev *dev); | 784 | int mlx5_start_eqs(struct mlx5_core_dev *dev); |
785 | int mlx5_stop_eqs(struct mlx5_core_dev *dev); | 785 | int mlx5_stop_eqs(struct mlx5_core_dev *dev); |
786 | int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn, int *irqn); | 786 | int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn, |
787 | unsigned int *irqn); | ||
787 | int mlx5_core_attach_mcg(struct mlx5_core_dev *dev, union ib_gid *mgid, u32 qpn); | 788 | int mlx5_core_attach_mcg(struct mlx5_core_dev *dev, union ib_gid *mgid, u32 qpn); |
788 | int mlx5_core_detach_mcg(struct mlx5_core_dev *dev, union ib_gid *mgid, u32 qpn); | 789 | int mlx5_core_detach_mcg(struct mlx5_core_dev *dev, union ib_gid *mgid, u32 qpn); |
789 | 790 | ||
diff --git a/include/net/tcp_memcontrol.h b/include/net/tcp_memcontrol.h index 3a17b16ae8aa..01ff7c6efada 100644 --- a/include/net/tcp_memcontrol.h +++ b/include/net/tcp_memcontrol.h | |||
@@ -1,6 +1,9 @@ | |||
1 | #ifndef _TCP_MEMCG_H | 1 | #ifndef _TCP_MEMCG_H |
2 | #define _TCP_MEMCG_H | 2 | #define _TCP_MEMCG_H |
3 | 3 | ||
4 | struct cgroup_subsys; | ||
5 | struct mem_cgroup; | ||
6 | |||
4 | int tcp_init_cgroup(struct mem_cgroup *memcg, struct cgroup_subsys *ss); | 7 | int tcp_init_cgroup(struct mem_cgroup *memcg, struct cgroup_subsys *ss); |
5 | void tcp_destroy_cgroup(struct mem_cgroup *memcg); | 8 | void tcp_destroy_cgroup(struct mem_cgroup *memcg); |
6 | #endif /* _TCP_MEMCG_H */ | 9 | #endif /* _TCP_MEMCG_H */ |
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index d5d71ac96c8a..c24c481b666f 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c | |||
@@ -127,21 +127,17 @@ batadv_backbone_gw_free_ref(struct batadv_bla_backbone_gw *backbone_gw) | |||
127 | } | 127 | } |
128 | 128 | ||
129 | /* finally deinitialize the claim */ | 129 | /* finally deinitialize the claim */ |
130 | static void batadv_claim_free_rcu(struct rcu_head *rcu) | 130 | static void batadv_claim_release(struct batadv_bla_claim *claim) |
131 | { | 131 | { |
132 | struct batadv_bla_claim *claim; | ||
133 | |||
134 | claim = container_of(rcu, struct batadv_bla_claim, rcu); | ||
135 | |||
136 | batadv_backbone_gw_free_ref(claim->backbone_gw); | 132 | batadv_backbone_gw_free_ref(claim->backbone_gw); |
137 | kfree(claim); | 133 | kfree_rcu(claim, rcu); |
138 | } | 134 | } |
139 | 135 | ||
140 | /* free a claim, call claim_free_rcu if its the last reference */ | 136 | /* free a claim, call claim_free_rcu if its the last reference */ |
141 | static void batadv_claim_free_ref(struct batadv_bla_claim *claim) | 137 | static void batadv_claim_free_ref(struct batadv_bla_claim *claim) |
142 | { | 138 | { |
143 | if (atomic_dec_and_test(&claim->refcount)) | 139 | if (atomic_dec_and_test(&claim->refcount)) |
144 | call_rcu(&claim->rcu, batadv_claim_free_rcu); | 140 | batadv_claim_release(claim); |
145 | } | 141 | } |
146 | 142 | ||
147 | /** | 143 | /** |
diff --git a/net/batman-adv/hard-interface.h b/net/batman-adv/hard-interface.h index 5a31420513e1..7b12ea8ea29d 100644 --- a/net/batman-adv/hard-interface.h +++ b/net/batman-adv/hard-interface.h | |||
@@ -75,18 +75,6 @@ batadv_hardif_free_ref(struct batadv_hard_iface *hard_iface) | |||
75 | call_rcu(&hard_iface->rcu, batadv_hardif_free_rcu); | 75 | call_rcu(&hard_iface->rcu, batadv_hardif_free_rcu); |
76 | } | 76 | } |
77 | 77 | ||
78 | /** | ||
79 | * batadv_hardif_free_ref_now - decrement the hard interface refcounter and | ||
80 | * possibly free it (without rcu callback) | ||
81 | * @hard_iface: the hard interface to free | ||
82 | */ | ||
83 | static inline void | ||
84 | batadv_hardif_free_ref_now(struct batadv_hard_iface *hard_iface) | ||
85 | { | ||
86 | if (atomic_dec_and_test(&hard_iface->refcount)) | ||
87 | batadv_hardif_free_rcu(&hard_iface->rcu); | ||
88 | } | ||
89 | |||
90 | static inline struct batadv_hard_iface * | 78 | static inline struct batadv_hard_iface * |
91 | batadv_primary_if_get_selected(struct batadv_priv *bat_priv) | 79 | batadv_primary_if_get_selected(struct batadv_priv *bat_priv) |
92 | { | 80 | { |
diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c index c98b0ab85449..cc63b44f0d2e 100644 --- a/net/batman-adv/network-coding.c +++ b/net/batman-adv/network-coding.c | |||
@@ -203,28 +203,25 @@ void batadv_nc_init_orig(struct batadv_orig_node *orig_node) | |||
203 | } | 203 | } |
204 | 204 | ||
205 | /** | 205 | /** |
206 | * batadv_nc_node_free_rcu - rcu callback to free an nc node and remove | 206 | * batadv_nc_node_release - release nc_node from lists and queue for free after |
207 | * its refcount on the orig_node | 207 | * rcu grace period |
208 | * @rcu: rcu pointer of the nc node | 208 | * @nc_node: the nc node to free |
209 | */ | 209 | */ |
210 | static void batadv_nc_node_free_rcu(struct rcu_head *rcu) | 210 | static void batadv_nc_node_release(struct batadv_nc_node *nc_node) |
211 | { | 211 | { |
212 | struct batadv_nc_node *nc_node; | ||
213 | |||
214 | nc_node = container_of(rcu, struct batadv_nc_node, rcu); | ||
215 | batadv_orig_node_free_ref(nc_node->orig_node); | 212 | batadv_orig_node_free_ref(nc_node->orig_node); |
216 | kfree(nc_node); | 213 | kfree_rcu(nc_node, rcu); |
217 | } | 214 | } |
218 | 215 | ||
219 | /** | 216 | /** |
220 | * batadv_nc_node_free_ref - decrements the nc node refcounter and possibly | 217 | * batadv_nc_node_free_ref - decrement the nc node refcounter and possibly |
221 | * frees it | 218 | * release it |
222 | * @nc_node: the nc node to free | 219 | * @nc_node: the nc node to free |
223 | */ | 220 | */ |
224 | static void batadv_nc_node_free_ref(struct batadv_nc_node *nc_node) | 221 | static void batadv_nc_node_free_ref(struct batadv_nc_node *nc_node) |
225 | { | 222 | { |
226 | if (atomic_dec_and_test(&nc_node->refcount)) | 223 | if (atomic_dec_and_test(&nc_node->refcount)) |
227 | call_rcu(&nc_node->rcu, batadv_nc_node_free_rcu); | 224 | batadv_nc_node_release(nc_node); |
228 | } | 225 | } |
229 | 226 | ||
230 | /** | 227 | /** |
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index ae6d18cafc5a..fe578f75c391 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c | |||
@@ -163,148 +163,101 @@ err: | |||
163 | } | 163 | } |
164 | 164 | ||
165 | /** | 165 | /** |
166 | * batadv_neigh_ifinfo_free_rcu - free the neigh_ifinfo object | 166 | * batadv_neigh_ifinfo_release - release neigh_ifinfo from lists and queue for |
167 | * @rcu: rcu pointer of the neigh_ifinfo object | 167 | * free after rcu grace period |
168 | */ | ||
169 | static void batadv_neigh_ifinfo_free_rcu(struct rcu_head *rcu) | ||
170 | { | ||
171 | struct batadv_neigh_ifinfo *neigh_ifinfo; | ||
172 | |||
173 | neigh_ifinfo = container_of(rcu, struct batadv_neigh_ifinfo, rcu); | ||
174 | |||
175 | if (neigh_ifinfo->if_outgoing != BATADV_IF_DEFAULT) | ||
176 | batadv_hardif_free_ref_now(neigh_ifinfo->if_outgoing); | ||
177 | |||
178 | kfree(neigh_ifinfo); | ||
179 | } | ||
180 | |||
181 | /** | ||
182 | * batadv_neigh_ifinfo_free_now - decrement the refcounter and possibly free | ||
183 | * the neigh_ifinfo (without rcu callback) | ||
184 | * @neigh_ifinfo: the neigh_ifinfo object to release | 168 | * @neigh_ifinfo: the neigh_ifinfo object to release |
185 | */ | 169 | */ |
186 | static void | 170 | static void |
187 | batadv_neigh_ifinfo_free_ref_now(struct batadv_neigh_ifinfo *neigh_ifinfo) | 171 | batadv_neigh_ifinfo_release(struct batadv_neigh_ifinfo *neigh_ifinfo) |
188 | { | 172 | { |
189 | if (atomic_dec_and_test(&neigh_ifinfo->refcount)) | 173 | if (neigh_ifinfo->if_outgoing != BATADV_IF_DEFAULT) |
190 | batadv_neigh_ifinfo_free_rcu(&neigh_ifinfo->rcu); | 174 | batadv_hardif_free_ref(neigh_ifinfo->if_outgoing); |
175 | |||
176 | kfree_rcu(neigh_ifinfo, rcu); | ||
191 | } | 177 | } |
192 | 178 | ||
193 | /** | 179 | /** |
194 | * batadv_neigh_ifinfo_free_ref - decrement the refcounter and possibly free | 180 | * batadv_neigh_ifinfo_free_ref - decrement the refcounter and possibly release |
195 | * the neigh_ifinfo | 181 | * the neigh_ifinfo |
196 | * @neigh_ifinfo: the neigh_ifinfo object to release | 182 | * @neigh_ifinfo: the neigh_ifinfo object to release |
197 | */ | 183 | */ |
198 | void batadv_neigh_ifinfo_free_ref(struct batadv_neigh_ifinfo *neigh_ifinfo) | 184 | void batadv_neigh_ifinfo_free_ref(struct batadv_neigh_ifinfo *neigh_ifinfo) |
199 | { | 185 | { |
200 | if (atomic_dec_and_test(&neigh_ifinfo->refcount)) | 186 | if (atomic_dec_and_test(&neigh_ifinfo->refcount)) |
201 | call_rcu(&neigh_ifinfo->rcu, batadv_neigh_ifinfo_free_rcu); | 187 | batadv_neigh_ifinfo_release(neigh_ifinfo); |
202 | } | 188 | } |
203 | 189 | ||
204 | /** | 190 | /** |
205 | * batadv_hardif_neigh_free_rcu - free the hardif neigh_node | 191 | * batadv_hardif_neigh_release - release hardif neigh node from lists and |
206 | * @rcu: rcu pointer of the neigh_node | 192 | * queue for free after rcu grace period |
207 | */ | ||
208 | static void batadv_hardif_neigh_free_rcu(struct rcu_head *rcu) | ||
209 | { | ||
210 | struct batadv_hardif_neigh_node *hardif_neigh; | ||
211 | |||
212 | hardif_neigh = container_of(rcu, struct batadv_hardif_neigh_node, rcu); | ||
213 | |||
214 | batadv_hardif_free_ref_now(hardif_neigh->if_incoming); | ||
215 | kfree(hardif_neigh); | ||
216 | } | ||
217 | |||
218 | /** | ||
219 | * batadv_hardif_neigh_free_now - decrement the hardif neighbors refcounter | ||
220 | * and possibly free it (without rcu callback) | ||
221 | * @hardif_neigh: hardif neigh neighbor to free | 193 | * @hardif_neigh: hardif neigh neighbor to free |
222 | */ | 194 | */ |
223 | static void | 195 | static void |
224 | batadv_hardif_neigh_free_now(struct batadv_hardif_neigh_node *hardif_neigh) | 196 | batadv_hardif_neigh_release(struct batadv_hardif_neigh_node *hardif_neigh) |
225 | { | 197 | { |
226 | if (atomic_dec_and_test(&hardif_neigh->refcount)) { | 198 | spin_lock_bh(&hardif_neigh->if_incoming->neigh_list_lock); |
227 | spin_lock_bh(&hardif_neigh->if_incoming->neigh_list_lock); | 199 | hlist_del_init_rcu(&hardif_neigh->list); |
228 | hlist_del_init_rcu(&hardif_neigh->list); | 200 | spin_unlock_bh(&hardif_neigh->if_incoming->neigh_list_lock); |
229 | spin_unlock_bh(&hardif_neigh->if_incoming->neigh_list_lock); | ||
230 | 201 | ||
231 | batadv_hardif_neigh_free_rcu(&hardif_neigh->rcu); | 202 | batadv_hardif_free_ref(hardif_neigh->if_incoming); |
232 | } | 203 | kfree_rcu(hardif_neigh, rcu); |
233 | } | 204 | } |
234 | 205 | ||
235 | /** | 206 | /** |
236 | * batadv_hardif_neigh_free_ref - decrement the hardif neighbors refcounter | 207 | * batadv_hardif_neigh_free_ref - decrement the hardif neighbors refcounter |
237 | * and possibly free it | 208 | * and possibly release it |
238 | * @hardif_neigh: hardif neigh neighbor to free | 209 | * @hardif_neigh: hardif neigh neighbor to free |
239 | */ | 210 | */ |
240 | void batadv_hardif_neigh_free_ref(struct batadv_hardif_neigh_node *hardif_neigh) | 211 | void batadv_hardif_neigh_free_ref(struct batadv_hardif_neigh_node *hardif_neigh) |
241 | { | 212 | { |
242 | if (atomic_dec_and_test(&hardif_neigh->refcount)) { | 213 | if (atomic_dec_and_test(&hardif_neigh->refcount)) |
243 | spin_lock_bh(&hardif_neigh->if_incoming->neigh_list_lock); | 214 | batadv_hardif_neigh_release(hardif_neigh); |
244 | hlist_del_init_rcu(&hardif_neigh->list); | ||
245 | spin_unlock_bh(&hardif_neigh->if_incoming->neigh_list_lock); | ||
246 | |||
247 | call_rcu(&hardif_neigh->rcu, batadv_hardif_neigh_free_rcu); | ||
248 | } | ||
249 | } | 215 | } |
250 | 216 | ||
251 | /** | 217 | /** |
252 | * batadv_neigh_node_free_rcu - free the neigh_node | 218 | * batadv_neigh_node_release - release neigh_node from lists and queue for |
253 | * @rcu: rcu pointer of the neigh_node | 219 | * free after rcu grace period |
220 | * @neigh_node: neigh neighbor to free | ||
254 | */ | 221 | */ |
255 | static void batadv_neigh_node_free_rcu(struct rcu_head *rcu) | 222 | static void batadv_neigh_node_release(struct batadv_neigh_node *neigh_node) |
256 | { | 223 | { |
257 | struct hlist_node *node_tmp; | 224 | struct hlist_node *node_tmp; |
258 | struct batadv_neigh_node *neigh_node; | ||
259 | struct batadv_hardif_neigh_node *hardif_neigh; | 225 | struct batadv_hardif_neigh_node *hardif_neigh; |
260 | struct batadv_neigh_ifinfo *neigh_ifinfo; | 226 | struct batadv_neigh_ifinfo *neigh_ifinfo; |
261 | struct batadv_algo_ops *bao; | 227 | struct batadv_algo_ops *bao; |
262 | 228 | ||
263 | neigh_node = container_of(rcu, struct batadv_neigh_node, rcu); | ||
264 | bao = neigh_node->orig_node->bat_priv->bat_algo_ops; | 229 | bao = neigh_node->orig_node->bat_priv->bat_algo_ops; |
265 | 230 | ||
266 | hlist_for_each_entry_safe(neigh_ifinfo, node_tmp, | 231 | hlist_for_each_entry_safe(neigh_ifinfo, node_tmp, |
267 | &neigh_node->ifinfo_list, list) { | 232 | &neigh_node->ifinfo_list, list) { |
268 | batadv_neigh_ifinfo_free_ref_now(neigh_ifinfo); | 233 | batadv_neigh_ifinfo_free_ref(neigh_ifinfo); |
269 | } | 234 | } |
270 | 235 | ||
271 | hardif_neigh = batadv_hardif_neigh_get(neigh_node->if_incoming, | 236 | hardif_neigh = batadv_hardif_neigh_get(neigh_node->if_incoming, |
272 | neigh_node->addr); | 237 | neigh_node->addr); |
273 | if (hardif_neigh) { | 238 | if (hardif_neigh) { |
274 | /* batadv_hardif_neigh_get() increases refcount too */ | 239 | /* batadv_hardif_neigh_get() increases refcount too */ |
275 | batadv_hardif_neigh_free_now(hardif_neigh); | 240 | batadv_hardif_neigh_free_ref(hardif_neigh); |
276 | batadv_hardif_neigh_free_now(hardif_neigh); | 241 | batadv_hardif_neigh_free_ref(hardif_neigh); |
277 | } | 242 | } |
278 | 243 | ||
279 | if (bao->bat_neigh_free) | 244 | if (bao->bat_neigh_free) |
280 | bao->bat_neigh_free(neigh_node); | 245 | bao->bat_neigh_free(neigh_node); |
281 | 246 | ||
282 | batadv_hardif_free_ref_now(neigh_node->if_incoming); | 247 | batadv_hardif_free_ref(neigh_node->if_incoming); |
283 | 248 | ||
284 | kfree(neigh_node); | 249 | kfree_rcu(neigh_node, rcu); |
285 | } | ||
286 | |||
287 | /** | ||
288 | * batadv_neigh_node_free_ref_now - decrement the neighbors refcounter | ||
289 | * and possibly free it (without rcu callback) | ||
290 | * @neigh_node: neigh neighbor to free | ||
291 | */ | ||
292 | static void | ||
293 | batadv_neigh_node_free_ref_now(struct batadv_neigh_node *neigh_node) | ||
294 | { | ||
295 | if (atomic_dec_and_test(&neigh_node->refcount)) | ||
296 | batadv_neigh_node_free_rcu(&neigh_node->rcu); | ||
297 | } | 250 | } |
298 | 251 | ||
299 | /** | 252 | /** |
300 | * batadv_neigh_node_free_ref - decrement the neighbors refcounter | 253 | * batadv_neigh_node_free_ref - decrement the neighbors refcounter |
301 | * and possibly free it | 254 | * and possibly release it |
302 | * @neigh_node: neigh neighbor to free | 255 | * @neigh_node: neigh neighbor to free |
303 | */ | 256 | */ |
304 | void batadv_neigh_node_free_ref(struct batadv_neigh_node *neigh_node) | 257 | void batadv_neigh_node_free_ref(struct batadv_neigh_node *neigh_node) |
305 | { | 258 | { |
306 | if (atomic_dec_and_test(&neigh_node->refcount)) | 259 | if (atomic_dec_and_test(&neigh_node->refcount)) |
307 | call_rcu(&neigh_node->rcu, batadv_neigh_node_free_rcu); | 260 | batadv_neigh_node_release(neigh_node); |
308 | } | 261 | } |
309 | 262 | ||
310 | /** | 263 | /** |
@@ -733,108 +686,99 @@ int batadv_hardif_neigh_seq_print_text(struct seq_file *seq, void *offset) | |||
733 | } | 686 | } |
734 | 687 | ||
735 | /** | 688 | /** |
736 | * batadv_orig_ifinfo_free_rcu - free the orig_ifinfo object | 689 | * batadv_orig_ifinfo_release - release orig_ifinfo from lists and queue for |
737 | * @rcu: rcu pointer of the orig_ifinfo object | 690 | * free after rcu grace period |
691 | * @orig_ifinfo: the orig_ifinfo object to release | ||
738 | */ | 692 | */ |
739 | static void batadv_orig_ifinfo_free_rcu(struct rcu_head *rcu) | 693 | static void batadv_orig_ifinfo_release(struct batadv_orig_ifinfo *orig_ifinfo) |
740 | { | 694 | { |
741 | struct batadv_orig_ifinfo *orig_ifinfo; | ||
742 | struct batadv_neigh_node *router; | 695 | struct batadv_neigh_node *router; |
743 | 696 | ||
744 | orig_ifinfo = container_of(rcu, struct batadv_orig_ifinfo, rcu); | ||
745 | |||
746 | if (orig_ifinfo->if_outgoing != BATADV_IF_DEFAULT) | 697 | if (orig_ifinfo->if_outgoing != BATADV_IF_DEFAULT) |
747 | batadv_hardif_free_ref_now(orig_ifinfo->if_outgoing); | 698 | batadv_hardif_free_ref(orig_ifinfo->if_outgoing); |
748 | 699 | ||
749 | /* this is the last reference to this object */ | 700 | /* this is the last reference to this object */ |
750 | router = rcu_dereference_protected(orig_ifinfo->router, true); | 701 | router = rcu_dereference_protected(orig_ifinfo->router, true); |
751 | if (router) | 702 | if (router) |
752 | batadv_neigh_node_free_ref_now(router); | 703 | batadv_neigh_node_free_ref(router); |
753 | kfree(orig_ifinfo); | 704 | |
705 | kfree_rcu(orig_ifinfo, rcu); | ||
754 | } | 706 | } |
755 | 707 | ||
756 | /** | 708 | /** |
757 | * batadv_orig_ifinfo_free_ref - decrement the refcounter and possibly free | 709 | * batadv_orig_ifinfo_free_ref - decrement the refcounter and possibly release |
758 | * the orig_ifinfo (without rcu callback) | 710 | * the orig_ifinfo |
759 | * @orig_ifinfo: the orig_ifinfo object to release | 711 | * @orig_ifinfo: the orig_ifinfo object to release |
760 | */ | 712 | */ |
761 | static void | 713 | void batadv_orig_ifinfo_free_ref(struct batadv_orig_ifinfo *orig_ifinfo) |
762 | batadv_orig_ifinfo_free_ref_now(struct batadv_orig_ifinfo *orig_ifinfo) | ||
763 | { | 714 | { |
764 | if (atomic_dec_and_test(&orig_ifinfo->refcount)) | 715 | if (atomic_dec_and_test(&orig_ifinfo->refcount)) |
765 | batadv_orig_ifinfo_free_rcu(&orig_ifinfo->rcu); | 716 | batadv_orig_ifinfo_release(orig_ifinfo); |
766 | } | 717 | } |
767 | 718 | ||
768 | /** | 719 | /** |
769 | * batadv_orig_ifinfo_free_ref - decrement the refcounter and possibly free | 720 | * batadv_orig_node_free_rcu - free the orig_node |
770 | * the orig_ifinfo | 721 | * @rcu: rcu pointer of the orig_node |
771 | * @orig_ifinfo: the orig_ifinfo object to release | ||
772 | */ | 722 | */ |
773 | void batadv_orig_ifinfo_free_ref(struct batadv_orig_ifinfo *orig_ifinfo) | 723 | static void batadv_orig_node_free_rcu(struct rcu_head *rcu) |
774 | { | 724 | { |
775 | if (atomic_dec_and_test(&orig_ifinfo->refcount)) | 725 | struct batadv_orig_node *orig_node; |
776 | call_rcu(&orig_ifinfo->rcu, batadv_orig_ifinfo_free_rcu); | 726 | |
727 | orig_node = container_of(rcu, struct batadv_orig_node, rcu); | ||
728 | |||
729 | batadv_mcast_purge_orig(orig_node); | ||
730 | |||
731 | batadv_frag_purge_orig(orig_node, NULL); | ||
732 | |||
733 | if (orig_node->bat_priv->bat_algo_ops->bat_orig_free) | ||
734 | orig_node->bat_priv->bat_algo_ops->bat_orig_free(orig_node); | ||
735 | |||
736 | kfree(orig_node->tt_buff); | ||
737 | kfree(orig_node); | ||
777 | } | 738 | } |
778 | 739 | ||
779 | static void batadv_orig_node_free_rcu(struct rcu_head *rcu) | 740 | /** |
741 | * batadv_orig_node_release - release orig_node from lists and queue for | ||
742 | * free after rcu grace period | ||
743 | * @orig_node: the orig node to free | ||
744 | */ | ||
745 | static void batadv_orig_node_release(struct batadv_orig_node *orig_node) | ||
780 | { | 746 | { |
781 | struct hlist_node *node_tmp; | 747 | struct hlist_node *node_tmp; |
782 | struct batadv_neigh_node *neigh_node; | 748 | struct batadv_neigh_node *neigh_node; |
783 | struct batadv_orig_node *orig_node; | ||
784 | struct batadv_orig_ifinfo *orig_ifinfo; | 749 | struct batadv_orig_ifinfo *orig_ifinfo; |
785 | 750 | ||
786 | orig_node = container_of(rcu, struct batadv_orig_node, rcu); | ||
787 | |||
788 | spin_lock_bh(&orig_node->neigh_list_lock); | 751 | spin_lock_bh(&orig_node->neigh_list_lock); |
789 | 752 | ||
790 | /* for all neighbors towards this originator ... */ | 753 | /* for all neighbors towards this originator ... */ |
791 | hlist_for_each_entry_safe(neigh_node, node_tmp, | 754 | hlist_for_each_entry_safe(neigh_node, node_tmp, |
792 | &orig_node->neigh_list, list) { | 755 | &orig_node->neigh_list, list) { |
793 | hlist_del_rcu(&neigh_node->list); | 756 | hlist_del_rcu(&neigh_node->list); |
794 | batadv_neigh_node_free_ref_now(neigh_node); | 757 | batadv_neigh_node_free_ref(neigh_node); |
795 | } | 758 | } |
796 | 759 | ||
797 | hlist_for_each_entry_safe(orig_ifinfo, node_tmp, | 760 | hlist_for_each_entry_safe(orig_ifinfo, node_tmp, |
798 | &orig_node->ifinfo_list, list) { | 761 | &orig_node->ifinfo_list, list) { |
799 | hlist_del_rcu(&orig_ifinfo->list); | 762 | hlist_del_rcu(&orig_ifinfo->list); |
800 | batadv_orig_ifinfo_free_ref_now(orig_ifinfo); | 763 | batadv_orig_ifinfo_free_ref(orig_ifinfo); |
801 | } | 764 | } |
802 | spin_unlock_bh(&orig_node->neigh_list_lock); | 765 | spin_unlock_bh(&orig_node->neigh_list_lock); |
803 | 766 | ||
804 | batadv_mcast_purge_orig(orig_node); | ||
805 | |||
806 | /* Free nc_nodes */ | 767 | /* Free nc_nodes */ |
807 | batadv_nc_purge_orig(orig_node->bat_priv, orig_node, NULL); | 768 | batadv_nc_purge_orig(orig_node->bat_priv, orig_node, NULL); |
808 | 769 | ||
809 | batadv_frag_purge_orig(orig_node, NULL); | 770 | call_rcu(&orig_node->rcu, batadv_orig_node_free_rcu); |
810 | |||
811 | if (orig_node->bat_priv->bat_algo_ops->bat_orig_free) | ||
812 | orig_node->bat_priv->bat_algo_ops->bat_orig_free(orig_node); | ||
813 | |||
814 | kfree(orig_node->tt_buff); | ||
815 | kfree(orig_node); | ||
816 | } | 771 | } |
817 | 772 | ||
818 | /** | 773 | /** |
819 | * batadv_orig_node_free_ref - decrement the orig node refcounter and possibly | 774 | * batadv_orig_node_free_ref - decrement the orig node refcounter and possibly |
820 | * schedule an rcu callback for freeing it | 775 | * release it |
821 | * @orig_node: the orig node to free | 776 | * @orig_node: the orig node to free |
822 | */ | 777 | */ |
823 | void batadv_orig_node_free_ref(struct batadv_orig_node *orig_node) | 778 | void batadv_orig_node_free_ref(struct batadv_orig_node *orig_node) |
824 | { | 779 | { |
825 | if (atomic_dec_and_test(&orig_node->refcount)) | 780 | if (atomic_dec_and_test(&orig_node->refcount)) |
826 | call_rcu(&orig_node->rcu, batadv_orig_node_free_rcu); | 781 | batadv_orig_node_release(orig_node); |
827 | } | ||
828 | |||
829 | /** | ||
830 | * batadv_orig_node_free_ref_now - decrement the orig node refcounter and | ||
831 | * possibly free it (without rcu callback) | ||
832 | * @orig_node: the orig node to free | ||
833 | */ | ||
834 | void batadv_orig_node_free_ref_now(struct batadv_orig_node *orig_node) | ||
835 | { | ||
836 | if (atomic_dec_and_test(&orig_node->refcount)) | ||
837 | batadv_orig_node_free_rcu(&orig_node->rcu); | ||
838 | } | 782 | } |
839 | 783 | ||
840 | void batadv_originator_free(struct batadv_priv *bat_priv) | 784 | void batadv_originator_free(struct batadv_priv *bat_priv) |
diff --git a/net/batman-adv/originator.h b/net/batman-adv/originator.h index 29557753d552..cf0730414ed2 100644 --- a/net/batman-adv/originator.h +++ b/net/batman-adv/originator.h | |||
@@ -38,7 +38,6 @@ int batadv_originator_init(struct batadv_priv *bat_priv); | |||
38 | void batadv_originator_free(struct batadv_priv *bat_priv); | 38 | void batadv_originator_free(struct batadv_priv *bat_priv); |
39 | void batadv_purge_orig_ref(struct batadv_priv *bat_priv); | 39 | void batadv_purge_orig_ref(struct batadv_priv *bat_priv); |
40 | void batadv_orig_node_free_ref(struct batadv_orig_node *orig_node); | 40 | void batadv_orig_node_free_ref(struct batadv_orig_node *orig_node); |
41 | void batadv_orig_node_free_ref_now(struct batadv_orig_node *orig_node); | ||
42 | struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv, | 41 | struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv, |
43 | const u8 *addr); | 42 | const u8 *addr); |
44 | struct batadv_hardif_neigh_node * | 43 | struct batadv_hardif_neigh_node * |
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index a22080c53401..cdfc85fa2743 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c | |||
@@ -240,20 +240,6 @@ int batadv_tt_global_hash_count(struct batadv_priv *bat_priv, | |||
240 | return count; | 240 | return count; |
241 | } | 241 | } |
242 | 242 | ||
243 | static void batadv_tt_orig_list_entry_free_rcu(struct rcu_head *rcu) | ||
244 | { | ||
245 | struct batadv_tt_orig_list_entry *orig_entry; | ||
246 | |||
247 | orig_entry = container_of(rcu, struct batadv_tt_orig_list_entry, rcu); | ||
248 | |||
249 | /* We are in an rcu callback here, therefore we cannot use | ||
250 | * batadv_orig_node_free_ref() and its call_rcu(): | ||
251 | * An rcu_barrier() wouldn't wait for that to finish | ||
252 | */ | ||
253 | batadv_orig_node_free_ref_now(orig_entry->orig_node); | ||
254 | kfree(orig_entry); | ||
255 | } | ||
256 | |||
257 | /** | 243 | /** |
258 | * batadv_tt_local_size_mod - change the size by v of the local table identified | 244 | * batadv_tt_local_size_mod - change the size by v of the local table identified |
259 | * by vid | 245 | * by vid |
@@ -349,13 +335,25 @@ static void batadv_tt_global_size_dec(struct batadv_orig_node *orig_node, | |||
349 | batadv_tt_global_size_mod(orig_node, vid, -1); | 335 | batadv_tt_global_size_mod(orig_node, vid, -1); |
350 | } | 336 | } |
351 | 337 | ||
338 | /** | ||
339 | * batadv_tt_orig_list_entry_release - release tt orig entry from lists and | ||
340 | * queue for free after rcu grace period | ||
341 | * @orig_entry: tt orig entry to be free'd | ||
342 | */ | ||
343 | static void | ||
344 | batadv_tt_orig_list_entry_release(struct batadv_tt_orig_list_entry *orig_entry) | ||
345 | { | ||
346 | batadv_orig_node_free_ref(orig_entry->orig_node); | ||
347 | kfree_rcu(orig_entry, rcu); | ||
348 | } | ||
349 | |||
352 | static void | 350 | static void |
353 | batadv_tt_orig_list_entry_free_ref(struct batadv_tt_orig_list_entry *orig_entry) | 351 | batadv_tt_orig_list_entry_free_ref(struct batadv_tt_orig_list_entry *orig_entry) |
354 | { | 352 | { |
355 | if (!atomic_dec_and_test(&orig_entry->refcount)) | 353 | if (!atomic_dec_and_test(&orig_entry->refcount)) |
356 | return; | 354 | return; |
357 | 355 | ||
358 | call_rcu(&orig_entry->rcu, batadv_tt_orig_list_entry_free_rcu); | 356 | batadv_tt_orig_list_entry_release(orig_entry); |
359 | } | 357 | } |
360 | 358 | ||
361 | /** | 359 | /** |
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index c88d0f2d3e01..2d59df521915 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c | |||
@@ -1160,17 +1160,26 @@ int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb, | |||
1160 | const struct sw_flow_actions *acts, | 1160 | const struct sw_flow_actions *acts, |
1161 | struct sw_flow_key *key) | 1161 | struct sw_flow_key *key) |
1162 | { | 1162 | { |
1163 | int level = this_cpu_read(exec_actions_level); | 1163 | static const int ovs_recursion_limit = 5; |
1164 | int err; | 1164 | int err, level; |
1165 | |||
1166 | level = __this_cpu_inc_return(exec_actions_level); | ||
1167 | if (unlikely(level > ovs_recursion_limit)) { | ||
1168 | net_crit_ratelimited("ovs: recursion limit reached on datapath %s, probable configuration error\n", | ||
1169 | ovs_dp_name(dp)); | ||
1170 | kfree_skb(skb); | ||
1171 | err = -ENETDOWN; | ||
1172 | goto out; | ||
1173 | } | ||
1165 | 1174 | ||
1166 | this_cpu_inc(exec_actions_level); | ||
1167 | err = do_execute_actions(dp, skb, key, | 1175 | err = do_execute_actions(dp, skb, key, |
1168 | acts->actions, acts->actions_len); | 1176 | acts->actions, acts->actions_len); |
1169 | 1177 | ||
1170 | if (!level) | 1178 | if (level == 1) |
1171 | process_deferred_actions(dp); | 1179 | process_deferred_actions(dp); |
1172 | 1180 | ||
1173 | this_cpu_dec(exec_actions_level); | 1181 | out: |
1182 | __this_cpu_dec(exec_actions_level); | ||
1174 | return err; | 1183 | return err; |
1175 | } | 1184 | } |
1176 | 1185 | ||
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index 52838eaa1582..2522a6175291 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c | |||
@@ -333,7 +333,7 @@ struct sctp_association *sctp_endpoint_lookup_assoc( | |||
333 | if (!ep->base.bind_addr.port) | 333 | if (!ep->base.bind_addr.port) |
334 | goto out; | 334 | goto out; |
335 | t = sctp_epaddr_lookup_transport(ep, paddr); | 335 | t = sctp_epaddr_lookup_transport(ep, paddr); |
336 | if (!t || t->asoc->temp) | 336 | if (!t) |
337 | goto out; | 337 | goto out; |
338 | 338 | ||
339 | *transport = t; | 339 | *transport = t; |
diff --git a/net/sctp/input.c b/net/sctp/input.c index b9a536b52da2..bf61dfb8e09e 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -874,6 +874,9 @@ void sctp_hash_transport(struct sctp_transport *t) | |||
874 | { | 874 | { |
875 | struct sctp_hash_cmp_arg arg; | 875 | struct sctp_hash_cmp_arg arg; |
876 | 876 | ||
877 | if (t->asoc->temp) | ||
878 | return; | ||
879 | |||
877 | arg.ep = t->asoc->ep; | 880 | arg.ep = t->asoc->ep; |
878 | arg.paddr = &t->ipaddr; | 881 | arg.paddr = &t->ipaddr; |
879 | arg.net = sock_net(t->asoc->base.sk); | 882 | arg.net = sock_net(t->asoc->base.sk); |
@@ -886,6 +889,9 @@ reinsert: | |||
886 | 889 | ||
887 | void sctp_unhash_transport(struct sctp_transport *t) | 890 | void sctp_unhash_transport(struct sctp_transport *t) |
888 | { | 891 | { |
892 | if (t->asoc->temp) | ||
893 | return; | ||
894 | |||
889 | rhashtable_remove_fast(&sctp_transport_hashtable, &t->node, | 895 | rhashtable_remove_fast(&sctp_transport_hashtable, &t->node, |
890 | sctp_hash_params); | 896 | sctp_hash_params); |
891 | } | 897 | } |
@@ -931,7 +937,7 @@ static struct sctp_association *__sctp_lookup_association( | |||
931 | struct sctp_transport *t; | 937 | struct sctp_transport *t; |
932 | 938 | ||
933 | t = sctp_addrs_lookup_transport(net, local, peer); | 939 | t = sctp_addrs_lookup_transport(net, local, peer); |
934 | if (!t || t->dead || t->asoc->temp) | 940 | if (!t || t->dead) |
935 | return NULL; | 941 | return NULL; |
936 | 942 | ||
937 | sctp_association_hold(t->asoc); | 943 | sctp_association_hold(t->asoc); |