/* * Copyright (C) 2015 Josh Poimboeuf * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ /* * This file reads all the special sections which have alternate instructions * which can be patched in or redirected to at runtime. */ #include #include #include "special.h" #include "warn.h" #define EX_ENTRY_SIZE 12 #define EX_ORIG_OFFSET 0 #define EX_NEW_OFFSET 4 #define JUMP_ENTRY_SIZE 24 #define JUMP_ORIG_OFFSET 0 #define JUMP_NEW_OFFSET 8 #define ALT_ENTRY_SIZE 13 #define ALT_ORIG_OFFSET 0 #define ALT_NEW_OFFSET 4 #define ALT_FEATURE_OFFSET 8 #define ALT_ORIG_LEN_OFFSET 10 #define ALT_NEW_LEN_OFFSET 11 #define X86_FEATURE_POPCNT (4*32+23) struct special_entry { const char *sec; bool group, jump_or_nop; unsigned char size, orig, new; unsigned char orig_len, new_len; /* group only */ unsigned char feature; /* ALTERNATIVE macro CPU feature */ }; struct special_entry entries[] = { { .sec = ".altinstructions", .group = true, .size = ALT_ENTRY_SIZE, .orig = ALT_ORIG_OFFSET, .orig_len = ALT_ORIG_LEN_OFFSET, .new = ALT_NEW_OFFSET, .new_len = ALT_NEW_LEN_OFFSET, .feature = ALT_FEATURE_OFFSET, }, { .sec = "__jump_table", .jump_or_nop = true, .size = JUMP_ENTRY_SIZE, .orig = JUMP_ORIG_OFFSET, .new = JUMP_NEW_OFFSET, }, { .sec = "__ex_table", .size = EX_ENTRY_SIZE, .orig = EX_ORIG_OFFSET, .new = EX_NEW_OFFSET, }, {}, }; static int get_alt_entry(struct elf *elf, struct special_entry *entry, struct section *sec, int idx, struct special_alt *alt) { struct rela *orig_rela, *new_rela; unsigned long offset; offset = idx * entry->size; alt->group = entry->group; alt->jump_or_nop = entry->jump_or_nop; if (alt->group) { alt->orig_len = *(unsigned char *)(sec->data + offset + entry->orig_len); alt->new_len = *(unsigned char *)(sec->data + offset + entry->new_len); } if (entry->feature) { unsigned short feature; feature = *(unsigned short *)(sec->data + offset + entry->feature); /* * It has been requested that we don't validate the !POPCNT * feature path which is a "very very small percentage of * machines". */ if (feature == X86_FEATURE_POPCNT) alt->skip_orig = true; } orig_rela = find_rela_by_dest(sec, offset + entry->orig); if (!orig_rela) { WARN_FUNC("can't find orig rela", sec, offset + entry->orig); return -1; } if (orig_rela->sym->type != STT_SECTION) { WARN_FUNC("don't know how to handle non-section rela symbol %s", sec, offset + entry->orig, orig_rela->sym->name); return -1; } alt->orig_sec = orig_rela->sym->sec; alt->orig_off = orig_rela->addend; if (!entry->group || alt->new_len) { new_rela = find_rela_by_dest(sec, offset + entry->new); if (!new_rela) { WARN_FUNC("can't find new rela", sec, offset + entry->new); return -1; } alt->new_sec = new_rela->sym->sec; alt->new_off = (unsigned int)new_rela->addend; /* _ASM_EXTABLE_EX hack */ if (alt->new_off >= 0x7ffffff0) alt->new_off -= 0x7ffffff0; } return 0; } /* * Read all the special sections and create a list of special_alt structs which * describe all the alternate instructions which can be patched in or * redirected to at runtime. */ int special_get_alts(struct elf *elf, struct list_head *alts) { struct special_entry *entry; struct section *sec; unsigned int nr_entries; struct special_alt *alt; int idx, ret; INIT_LIST_HEAD(alts); for (entry = entries; entry->sec; entry++) { sec = find_section_by_name(elf, entry->sec); if (!sec) continue; if (sec->len % entry->size != 0) { WARN("%s size not a multiple of %d", sec->name, entry->size); return -1; } nr_entries = sec->len / entry->size; for (idx = 0; idx < nr_entries; idx++) { alt = malloc(sizeof(*alt)); if (!alt) { WARN("malloc failed"); return -1; } memset(alt, 0, sizeof(*alt)); ret = get_alt_entry(elf, entry, sec, idx, alt); if (ret) return ret; list_add_tail(&alt->list, alts); } } return 0; } o' class='commit-info'> authorLinus Torvalds <torvalds@linux-foundation.org>2017-02-01 11:52:27 -0800 committerLinus Torvalds <torvalds@linux-foundation.org>2017-02-01 11:52:27 -0800 commit6d04dfc8966019b8b0977b2cb942351f13d2b178 (patch) tree2d4f239c1daff620704b77a992c1e70ce1ce6b08 /drivers/usb/usbip/vhci_rx.c parent2883aaea363f7a897ff06d2e6c73ae7aae285bcb (diff)parent06425c308b92eaf60767bc71d359f4cbc7a561f8 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller: 1) Fix handling of interrupt status in stmmac driver. Just because we have masked the event from generating interrupts, doesn't mean the bit won't still be set in the interrupt status register. From Alexey Brodkin. 2) Fix DMA API debugging splats in gianfar driver, from Arseny Solokha. 3) Fix off-by-one error in __ip6_append_data(), from Vlad Yasevich. 4) cls_flow does not match on icmpv6 codes properly, from Simon Horman. 5) Initial MAC address can be set incorrectly in some scenerios, from Ivan Vecera. 6) Packet header pointer arithmetic fix in ip6_tnl_parse_tlv_end_lim(), from Dan Carpenter. 7) Fix divide by zero in __tcp_select_window(), from Eric Dumazet. 8) Fix crash in iwlwifi when unregistering thermal zone, from Jens Axboe. 9) Check for DMA mapping errors in starfire driver, from Alexey Khoroshilov. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (31 commits) tcp: fix 0 divide in __tcp_select_window() ipv6: pointer math error in ip6_tnl_parse_tlv_enc_lim() net: fix ndo_features_check/ndo_fix_features comment ordering net/sched: matchall: Fix configuration race be2net: fix initial MAC setting ipv6: fix flow labels when the traffic class is non-0 net: thunderx: avoid dereferencing xcv when NULL net/sched: cls_flower: Correct matching on ICMPv6 code ipv6: Paritially checksum full MTU frames net/mlx4_core: Avoid command timeouts during VF driver device shutdown gianfar: synchronize DMA API usage by free_skb_rx_queue w/ gfar_new_page net: ethtool: add support for 2500BaseT and 5000BaseT link modes can: bcm: fix hrtimer/tasklet termination in bcm op removal net: adaptec: starfire: add checks for dma mapping errors net: phy: micrel: KSZ8795 do not set SUPPORTED_[Asym_]Pause can: Fix kernel panic at security_sock_rcv_skb net: macb: Fix 64 bit addressing support for GEM stmmac: Discard masked flags in interrupt status register net/mlx5e: Check ets capability before ets query FW command net/mlx5e: Fix update of hash function/key via ethtool ...
Diffstat (limited to 'drivers/usb/usbip/vhci_rx.c')