Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bna: Avoid clashing function prototypes

When built with Control Flow Integrity, function prototypes between
caller and function declaration must match. These mismatches are visible
at compile time with the new -Wcast-function-type-strict in Clang[1].

Fix a total of 227 warnings like these:

drivers/net/ethernet/brocade/bna/bna_enet.c:519:3: warning: cast from 'void (*)(struct bna_ethport *, enum bna_ethport_event)' to 'bfa_fsm_t' (aka 'void (*)(void *, int)') converts to incompatible function type [-Wcast-function-type-strict]
bfa_fsm_set_state(ethport, bna_ethport_sm_down);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The bna state machine code heavily overloads its state machine functions,
so these have been separated into their own sets of structs, enums,
typedefs, and helper functions. There are almost zero binary code changes,
all seem to be related to header file line numbers changing, or the
addition of the new stats helper.

Important to mention is that while I was manually implementing this changes
I was staring at this[2] patch from Kees Cook. Thanks, Kees. :)

Link: https://github.com/KSPP/linux/issues/240
[1] https://reviews.llvm.org/D134831
[2] https://lore.kernel.org/linux-hardening/20220929230334.2109344-1-keescook@chromium.org/
Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Gustavo A. R. Silva and committed by
David S. Miller
8719a1c3 8bd8dcc5

+82 -43
+38 -22
drivers/net/ethernet/brocade/bna/bfa_cs.h
··· 18 18 19 19 /* BFA state machine interfaces */ 20 20 21 - typedef void (*bfa_sm_t)(void *sm, int event); 22 - 23 21 /* For converting from state machine function to state encoding. */ 24 - struct bfa_sm_table { 25 - bfa_sm_t sm; /*!< state machine function */ 26 - int state; /*!< state machine encoding */ 27 - char *name; /*!< state name for display */ 28 - }; 29 - #define BFA_SM(_sm) ((bfa_sm_t)(_sm)) 22 + #define BFA_SM_TABLE(n, s, e, t) \ 23 + struct s; \ 24 + enum e; \ 25 + typedef void (*t)(struct s *, enum e); \ 26 + \ 27 + struct n ## _sm_table_s { \ 28 + t sm; /* state machine function */ \ 29 + int state; /* state machine encoding */ \ 30 + char *name; /* state name for display */ \ 31 + }; \ 32 + \ 33 + static inline int \ 34 + n ## _sm_to_state(struct n ## _sm_table_s *smt, t sm) \ 35 + { \ 36 + int i = 0; \ 37 + \ 38 + while (smt[i].sm && smt[i].sm != sm) \ 39 + i++; \ 40 + return smt[i].state; \ 41 + } 42 + 43 + BFA_SM_TABLE(iocpf, bfa_iocpf, iocpf_event, bfa_fsm_iocpf_t) 44 + BFA_SM_TABLE(ioc, bfa_ioc, ioc_event, bfa_fsm_ioc_t) 45 + BFA_SM_TABLE(cmdq, bfa_msgq_cmdq, cmdq_event, bfa_fsm_msgq_cmdq_t) 46 + BFA_SM_TABLE(rspq, bfa_msgq_rspq, rspq_event, bfa_fsm_msgq_rspq_t) 47 + 48 + BFA_SM_TABLE(ioceth, bna_ioceth, bna_ioceth_event, bna_fsm_ioceth_t) 49 + BFA_SM_TABLE(enet, bna_enet, bna_enet_event, bna_fsm_enet_t) 50 + BFA_SM_TABLE(ethport, bna_ethport, bna_ethport_event, bna_fsm_ethport_t) 51 + BFA_SM_TABLE(tx, bna_tx, bna_tx_event, bna_fsm_tx_t) 52 + BFA_SM_TABLE(rxf, bna_rxf, bna_rxf_event, bna_fsm_rxf_t) 53 + BFA_SM_TABLE(rx, bna_rx, bna_rx_event, bna_fsm_rx_t) 54 + 55 + #undef BFA_SM_TABLE 56 + 57 + #define BFA_SM(_sm) (_sm) 30 58 31 59 /* State machine with entry actions. */ 32 60 typedef void (*bfa_fsm_t)(void *fsm, int event); ··· 69 41 static void oc ## _sm_ ## st ## _entry(otype * fsm) 70 42 71 43 #define bfa_fsm_set_state(_fsm, _state) do { \ 72 - (_fsm)->fsm = (bfa_fsm_t)(_state); \ 44 + (_fsm)->fsm = (_state); \ 73 45 _state ## _entry(_fsm); \ 74 46 } while (0) 75 47 76 48 #define bfa_fsm_send_event(_fsm, _event) ((_fsm)->fsm((_fsm), (_event))) 77 - #define bfa_fsm_cmp_state(_fsm, _state) \ 78 - ((_fsm)->fsm == (bfa_fsm_t)(_state)) 79 - 80 - static inline int 81 - bfa_sm_to_state(const struct bfa_sm_table *smt, bfa_sm_t sm) 82 - { 83 - int i = 0; 84 - 85 - while (smt[i].sm && smt[i].sm != sm) 86 - i++; 87 - return smt[i].state; 88 - } 89 - 49 + #define bfa_fsm_cmp_state(_fsm, _state) ((_fsm)->fsm == (_state)) 90 50 /* Generic wait counter. */ 91 51 92 52 typedef void (*bfa_wc_resume_t) (void *cbarg);
+5 -5
drivers/net/ethernet/brocade/bna/bfa_ioc.c
··· 114 114 bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc, enum ioc_event); 115 115 bfa_fsm_state_decl(bfa_ioc, hwfail, struct bfa_ioc, enum ioc_event); 116 116 117 - static struct bfa_sm_table ioc_sm_table[] = { 117 + static struct ioc_sm_table_s ioc_sm_table[] = { 118 118 {BFA_SM(bfa_ioc_sm_uninit), BFA_IOC_UNINIT}, 119 119 {BFA_SM(bfa_ioc_sm_reset), BFA_IOC_RESET}, 120 120 {BFA_SM(bfa_ioc_sm_enabling), BFA_IOC_ENABLING}, ··· 183 183 enum iocpf_event); 184 184 bfa_fsm_state_decl(bfa_iocpf, disabled, struct bfa_iocpf, enum iocpf_event); 185 185 186 - static struct bfa_sm_table iocpf_sm_table[] = { 186 + static struct iocpf_sm_table_s iocpf_sm_table[] = { 187 187 {BFA_SM(bfa_iocpf_sm_reset), BFA_IOCPF_RESET}, 188 188 {BFA_SM(bfa_iocpf_sm_fwcheck), BFA_IOCPF_FWMISMATCH}, 189 189 {BFA_SM(bfa_iocpf_sm_mismatch), BFA_IOCPF_FWMISMATCH}, ··· 2860 2860 bfa_ioc_get_state(struct bfa_ioc *ioc) 2861 2861 { 2862 2862 enum bfa_iocpf_state iocpf_st; 2863 - enum bfa_ioc_state ioc_st = bfa_sm_to_state(ioc_sm_table, ioc->fsm); 2863 + enum bfa_ioc_state ioc_st = ioc_sm_to_state(ioc_sm_table, ioc->fsm); 2864 2864 2865 2865 if (ioc_st == BFA_IOC_ENABLING || 2866 2866 ioc_st == BFA_IOC_FAIL || ioc_st == BFA_IOC_INITFAIL) { 2867 2867 2868 - iocpf_st = bfa_sm_to_state(iocpf_sm_table, ioc->iocpf.fsm); 2868 + iocpf_st = iocpf_sm_to_state(iocpf_sm_table, ioc->iocpf.fsm); 2869 2869 2870 2870 switch (iocpf_st) { 2871 2871 case BFA_IOCPF_SEMWAIT: ··· 2983 2983 { 2984 2984 enum bfa_iocpf_state iocpf_st; 2985 2985 2986 - iocpf_st = bfa_sm_to_state(iocpf_sm_table, ioc->iocpf.fsm); 2986 + iocpf_st = iocpf_sm_to_state(iocpf_sm_table, ioc->iocpf.fsm); 2987 2987 2988 2988 if (iocpf_st == BFA_IOCPF_HWINIT) 2989 2989 bfa_ioc_poll_fwinit(ioc);
+6 -2
drivers/net/ethernet/brocade/bna/bfa_ioc.h
··· 147 147 (__notify)->cbarg = (__cbarg); \ 148 148 } while (0) 149 149 150 + enum iocpf_event; 151 + 150 152 struct bfa_iocpf { 151 - bfa_fsm_t fsm; 153 + void (*fsm)(struct bfa_iocpf *s, enum iocpf_event e); 152 154 struct bfa_ioc *ioc; 153 155 bool fw_mismatch_notified; 154 156 bool auto_recover; 155 157 u32 poll_time; 156 158 }; 157 159 160 + enum ioc_event; 161 + 158 162 struct bfa_ioc { 159 - bfa_fsm_t fsm; 163 + void (*fsm)(struct bfa_ioc *s, enum ioc_event e); 160 164 struct bfa *bfa; 161 165 struct bfa_pcidev pcidev; 162 166 struct timer_list ioc_timer;
+6 -2
drivers/net/ethernet/brocade/bna/bfa_msgq.h
··· 55 55 BFA_MSGQ_CMDQ_F_DB_UPDATE = 1, 56 56 }; 57 57 58 + enum cmdq_event; 59 + 58 60 struct bfa_msgq_cmdq { 59 - bfa_fsm_t fsm; 61 + void (*fsm)(struct bfa_msgq_cmdq *s, enum cmdq_event e); 60 62 enum bfa_msgq_cmdq_flags flags; 61 63 62 64 u16 producer_index; ··· 83 81 84 82 typedef void (*bfa_msgq_mcfunc_t)(void *cbarg, struct bfi_msgq_mhdr *mhdr); 85 83 84 + enum rspq_event; 85 + 86 86 struct bfa_msgq_rspq { 87 - bfa_fsm_t fsm; 87 + void (*fsm)(struct bfa_msgq_rspq *s, enum rspq_event e); 88 88 enum bfa_msgq_rspq_flags flags; 89 89 90 90 u16 producer_index;
+3 -3
drivers/net/ethernet/brocade/bna/bna_enet.c
··· 1257 1257 void 1258 1258 bna_enet_enable(struct bna_enet *enet) 1259 1259 { 1260 - if (enet->fsm != (bfa_sm_t)bna_enet_sm_stopped) 1260 + if (enet->fsm != bna_enet_sm_stopped) 1261 1261 return; 1262 1262 1263 1263 enet->flags |= BNA_ENET_F_ENABLED; ··· 1751 1751 void 1752 1752 bna_ioceth_enable(struct bna_ioceth *ioceth) 1753 1753 { 1754 - if (ioceth->fsm == (bfa_fsm_t)bna_ioceth_sm_ready) { 1754 + if (ioceth->fsm == bna_ioceth_sm_ready) { 1755 1755 bnad_cb_ioceth_ready(ioceth->bna->bnad); 1756 1756 return; 1757 1757 } 1758 1758 1759 - if (ioceth->fsm == (bfa_fsm_t)bna_ioceth_sm_stopped) 1759 + if (ioceth->fsm == bna_ioceth_sm_stopped) 1760 1760 bfa_fsm_send_event(ioceth, IOCETH_E_ENABLE); 1761 1761 } 1762 1762
+3 -3
drivers/net/ethernet/brocade/bna/bna_tx_rx.c
··· 1956 1956 bna_rx_stop(struct bna_rx *rx) 1957 1957 { 1958 1958 rx->rx_flags &= ~BNA_RX_F_ENET_STARTED; 1959 - if (rx->fsm == (bfa_fsm_t) bna_rx_sm_stopped) 1959 + if (rx->fsm == bna_rx_sm_stopped) 1960 1960 bna_rx_mod_cb_rx_stopped(&rx->bna->rx_mod, rx); 1961 1961 else { 1962 1962 rx->stop_cbfn = bna_rx_mod_cb_rx_stopped; ··· 2535 2535 void 2536 2536 bna_rx_enable(struct bna_rx *rx) 2537 2537 { 2538 - if (rx->fsm != (bfa_sm_t)bna_rx_sm_stopped) 2538 + if (rx->fsm != bna_rx_sm_stopped) 2539 2539 return; 2540 2540 2541 2541 rx->rx_flags |= BNA_RX_F_ENABLED; ··· 3523 3523 void 3524 3524 bna_tx_enable(struct bna_tx *tx) 3525 3525 { 3526 - if (tx->fsm != (bfa_sm_t)bna_tx_sm_stopped) 3526 + if (tx->fsm != bna_tx_sm_stopped) 3527 3527 return; 3528 3528 3529 3529 tx->flags |= BNA_TX_F_ENABLED;
+21 -6
drivers/net/ethernet/brocade/bna/bna_types.h
··· 312 312 313 313 /* IOCEth */ 314 314 315 + enum bna_ioceth_event; 316 + 315 317 struct bna_ioceth { 316 - bfa_fsm_t fsm; 318 + void (*fsm)(struct bna_ioceth *s, enum bna_ioceth_event e); 317 319 struct bfa_ioc ioc; 318 320 319 321 struct bna_attr attr; ··· 336 334 enum bna_status rx_pause; 337 335 }; 338 336 337 + enum bna_enet_event; 338 + 339 339 struct bna_enet { 340 - bfa_fsm_t fsm; 340 + void (*fsm)(struct bna_enet *s, enum bna_enet_event e); 341 341 enum bna_enet_flags flags; 342 342 343 343 enum bna_enet_type type; ··· 364 360 365 361 /* Ethport */ 366 362 363 + enum bna_ethport_event; 364 + 367 365 struct bna_ethport { 368 - bfa_fsm_t fsm; 366 + void (*fsm)(struct bna_ethport *s, enum bna_ethport_event e); 369 367 enum bna_ethport_flags flags; 370 368 371 369 enum bna_link_status link_status; ··· 460 454 }; 461 455 462 456 /* Tx object */ 457 + 458 + enum bna_tx_event; 459 + 463 460 struct bna_tx { 464 461 /* This should be the first one */ 465 462 struct list_head qe; 466 463 int rid; 467 464 int hw_id; 468 465 469 - bfa_fsm_t fsm; 466 + void (*fsm)(struct bna_tx *s, enum bna_tx_event e); 470 467 enum bna_tx_flags flags; 471 468 472 469 enum bna_tx_type type; ··· 707 698 }; 708 699 709 700 /* RxF structure (hardware Rx Function) */ 701 + 702 + enum bna_rxf_event; 703 + 710 704 struct bna_rxf { 711 - bfa_fsm_t fsm; 705 + void (*fsm)(struct bna_rxf *s, enum bna_rxf_event e); 712 706 713 707 struct bfa_msgq_cmd_entry msgq_cmd; 714 708 union { ··· 781 769 }; 782 770 783 771 /* Rx object */ 772 + 773 + enum bna_rx_event; 774 + 784 775 struct bna_rx { 785 776 /* This should be the first one */ 786 777 struct list_head qe; 787 778 int rid; 788 779 int hw_id; 789 780 790 - bfa_fsm_t fsm; 781 + void (*fsm)(struct bna_rx *s, enum bna_rx_event e); 791 782 792 783 enum bna_rx_type type; 793 784