Conflicts: net/ipv4/ip_gre.c Minor conflicts between tunnel bug fixes in net and ipv6 tunnel cleanups in net-next.
Unified · Split
| @@ -48,6 +48,9 @@ Felix Kuhling <fxkuehl@gmx.de> · 47 unmodified lines | ||
| 48 | 48 | Felix Moeller <felix@derklecks.de> |
| 49 | 49 | Filipe Lautert <filipe@icewall.org> |
| 50 | 50 | Franck Bui-Huu <vagabon.xyz@gmail.com> |
| 51 | +Frank Rowand <frowand.list@gmail.com> <frowand@mvista.com> | |
| 52 | +Frank Rowand <frowand.list@gmail.com> <frank.rowand@am.sony.com> | |
| 53 | +Frank Rowand <frowand.list@gmail.com> <frank.rowand@sonymobile.com> | |
| 51 | 54 | Frank Zago <fzago@systemfabricworks.com> |
| 52 | 55 | Greg Kroah-Hartman <greg@echidna.(none)> |
| 53 | 56 | Greg Kroah-Hartman <gregkh@suse.de> |
| @@ -79,6 +82,7 @@ Kay Sievers <kay.sievers@vrfy.org> · 25 unmodified lines | ||
| 79 | 82 | Kenneth W Chen <kenneth.w.chen@intel.com> |
| 80 | 83 | Konstantin Khlebnikov <koct9i@gmail.com> <k.khlebnikov@samsung.com> |
| 81 | 84 | Koushik <raghavendra.koushik@neterion.com> |
| 85 | +Krzysztof Kozlowski <krzk@kernel.org> <k.kozlowski.k@gmail.com> | |
| 82 | 86 | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> |
| 83 | 87 | Leonid I Ananiev <leonid.i.ananiev@intel.com> |
| 84 | 88 | Linas Vepstas <linas@austin.ibm.com> |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | |
| 3 | 3 | The ARC HS can be configured with a pipeline performance monitor for counting |
| 4 | 4 | CPU and cache events like cache misses and hits. Like conventional PCT there |
| 5 | −are 100+ hardware conditions dynamically mapped to upto 32 counters. | |
| 5 | +are 100+ hardware conditions dynamically mapped to up to 32 counters. | |
| 6 | 6 | It also supports overflow interrupts. |
| 7 | 7 | |
| 8 | 8 | Required properties: |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | |
| 3 | 3 | The ARC700 can be configured with a pipeline performance monitor for counting |
| 4 | 4 | CPU and cache events like cache misses and hits. Like conventional PCT there |
| 5 | −are 100+ hardware conditions dynamically mapped to upto 32 counters | |
| 5 | +are 100+ hardware conditions dynamically mapped to up to 32 counters | |
| 6 | 6 | |
| 7 | 7 | Note that: |
| 8 | 8 | * The ARC 700 PCT does not support interrupts; although HW events may be |
| @@ -6,8 +6,8 @@ RK3xxx SoCs. · 5 unmodified lines | ||
| 6 | 6 | Required properties : |
| 7 | 7 | |
| 8 | 8 | - reg : Offset and length of the register set for the device |
| 9 | − - compatible : should be "rockchip,rk3066-i2c", "rockchip,rk3188-i2c" or | |
| 10 | − "rockchip,rk3288-i2c". | |
| 9 | + - compatible : should be "rockchip,rk3066-i2c", "rockchip,rk3188-i2c", | |
| 10 | + "rockchip,rk3228-i2c" or "rockchip,rk3288-i2c". | |
| 11 | 11 | - interrupts : interrupt number |
| 12 | 12 | - clocks : parent clock |
| 13 | 13 | |
| @@ -45,13 +45,13 @@ Required properties: · 44 unmodified lines | ||
| 45 | 45 | Optional properties: |
| 46 | 46 | - dual_emac_res_vlan : Specifies VID to be used to segregate the ports |
| 47 | 47 | - mac-address : See ethernet.txt file in the same directory |
| 48 | −- phy_id : Specifies slave phy id | |
| 48 | +- phy_id : Specifies slave phy id (deprecated, use phy-handle) | |
| 49 | 49 | - phy-handle : See ethernet.txt file in the same directory |
| 50 | 50 | |
| 51 | 51 | Slave sub-nodes: |
| 52 | 52 | - fixed-link : See fixed-link.txt file in the same directory |
| 53 | − Either the property phy_id, or the sub-node | |
| 54 | − fixed-link can be specified | |
| 53 | + | |
| 54 | +Note: Exactly one of phy_id, phy-handle, or fixed-link must be specified. | |
| 55 | 55 | |
| 56 | 56 | Note: "ti,hwmods" field is used to fetch the base address and irq |
| 57 | 57 | resources from TI, omap hwmod data base during device registration. |
| @@ -6,7 +6,7 @@ This is the driver for the Altera Triple-Speed Ethernet (TSE) controllers · 5 unmodified lines | ||
| 6 | 6 | using the SGDMA and MSGDMA soft DMA IP components. The driver uses the |
| 7 | 7 | platform bus to obtain component resources. The designs used to test this |
| 8 | 8 | driver were built for a Cyclone(R) V SOC FPGA board, a Cyclone(R) V FPGA board, |
| 9 | −and tested with ARM and NIOS processor hosts seperately. The anticipated use | |
| 9 | +and tested with ARM and NIOS processor hosts separately. The anticipated use | |
| 10 | 10 | cases are simple communications between an embedded system and an external peer |
| 11 | 11 | for status and simple configuration of the embedded system. |
| 12 | 12 | |
| @@ -65,14 +65,14 @@ Driver parameters can be also passed in command line by using: · 52 unmodified lines | ||
| 65 | 65 | 4.1) Transmit process |
| 66 | 66 | When the driver's transmit routine is called by the kernel, it sets up a |
| 67 | 67 | transmit descriptor by calling the underlying DMA transmit routine (SGDMA or |
| 68 | −MSGDMA), and initites a transmit operation. Once the transmit is complete, an | |
| 68 | +MSGDMA), and initiates a transmit operation. Once the transmit is complete, an | |
| 69 | 69 | interrupt is driven by the transmit DMA logic. The driver handles the transmit |
| 70 | 70 | completion in the context of the interrupt handling chain by recycling |
| 71 | 71 | resource required to send and track the requested transmit operation. |
| 72 | 72 | |
| 73 | 73 | 4.2) Receive process |
| 74 | 74 | The driver will post receive buffers to the receive DMA logic during driver |
| 75 | −intialization. Receive buffers may or may not be queued depending upon the | |
| 75 | +initialization. Receive buffers may or may not be queued depending upon the | |
| 76 | 76 | underlying DMA logic (MSGDMA is able queue receive buffers, SGDMA is not able |
| 77 | 77 | to queue receive buffers to the SGDMA receive logic). When a packet is |
| 78 | 78 | received, the DMA logic generates an interrupt. The driver handles a receive |
| @@ -8,7 +8,7 @@ Initial Release: · 7 unmodified lines | ||
| 8 | 8 | This is conceptually very similar to the macvlan driver with one major |
| 9 | 9 | exception of using L3 for mux-ing /demux-ing among slaves. This property makes |
| 10 | 10 | the master device share the L2 with it's slave devices. I have developed this |
| 11 | −driver in conjuntion with network namespaces and not sure if there is use case | |
| 11 | +driver in conjunction with network namespaces and not sure if there is use case | |
| 12 | 12 | outside of it. |
| 13 | 13 | |
| 14 | 14 | |
| @@ -42,7 +42,7 @@ out. In this mode the slaves will RX/TX multicast and broadcast (if applicable) · 27 unmodified lines | ||
| 42 | 42 | as well. |
| 43 | 43 | |
| 44 | 44 | 4.2 L3 mode: |
| 45 | − In this mode TX processing upto L3 happens on the stack instance attached | |
| 45 | + In this mode TX processing up to L3 happens on the stack instance attached | |
| 46 | 46 | to the slave device and packets are switched to the stack instance of the |
| 47 | 47 | master device for the L2 processing and routing from that instance will be |
| 48 | 48 | used before packets are queued on the outbound device. In this mode the slaves |
| @@ -56,7 +56,7 @@ situations defines your use case then you can choose to use ipvlan - · 7 unmodified lines | ||
| 56 | 56 | (a) The Linux host that is connected to the external switch / router has |
| 57 | 57 | policy configured that allows only one mac per port. |
| 58 | 58 | (b) No of virtual devices created on a master exceed the mac capacity and |
| 59 | −puts the NIC in promiscous mode and degraded performance is a concern. | |
| 59 | +puts the NIC in promiscuous mode and degraded performance is a concern. | |
| 60 | 60 | (c) If the slave device is to be put into the hostile / untrusted network |
| 61 | 61 | namespace where L2 on the slave could be changed / misused. |
| 62 | 62 | |
| @@ -67,12 +67,12 @@ The two basic thread commands are: · 66 unmodified lines | ||
| 67 | 67 | * add_device DEVICE@NAME -- adds a single device |
| 68 | 68 | * rem_device_all -- remove all associated devices |
| 69 | 69 | |
| 70 | −When adding a device to a thread, a corrosponding procfile is created | |
| 70 | +When adding a device to a thread, a corresponding procfile is created | |
| 71 | 71 | which is used for configuring this device. Thus, device names need to |
| 72 | 72 | be unique. |
| 73 | 73 | |
| 74 | 74 | To support adding the same device to multiple threads, which is useful |
| 75 | −with multi queue NICs, a the device naming scheme is extended with "@": | |
| 75 | +with multi queue NICs, the device naming scheme is extended with "@": | |
| 76 | 76 | device@something |
| 77 | 77 | |
| 78 | 78 | The part after "@" can be anything, but it is custom to use the thread |
| @@ -221,7 +221,7 @@ Sample scripts · 142 unmodified lines | ||
| 221 | 221 | |
| 222 | 222 | A collection of tutorial scripts and helpers for pktgen is in the |
| 223 | 223 | samples/pktgen directory. The helper parameters.sh file support easy |
| 224 | −and consistant parameter parsing across the sample scripts. | |
| 224 | +and consistent parameter parsing across the sample scripts. | |
| 225 | 225 | |
| 226 | 226 | Usage example and help: |
| 227 | 227 | ./pktgen_sample01_simple.sh -i eth4 -m 00:1B:21:3C:9D:F8 -d 192.168.8.2 |
| @@ -41,7 +41,7 @@ using an rx_handler which gives the impression that packets flow through · 40 unmodified lines | ||
| 41 | 41 | the VRF device. Similarly on egress routing rules are used to send packets |
| 42 | 42 | to the VRF device driver before getting sent out the actual interface. This |
| 43 | 43 | allows tcpdump on a VRF device to capture all packets into and out of the |
| 44 | −VRF as a whole.[1] Similiarly, netfilter [2] and tc rules can be applied | |
| 44 | +VRF as a whole.[1] Similarly, netfilter [2] and tc rules can be applied | |
| 45 | 45 | using the VRF device to specify rules that apply to the VRF domain as a whole. |
| 46 | 46 | |
| 47 | 47 | [1] Packets in the forwarded state do not flow through the device, so those |
| @@ -4,7 +4,7 @@ Krisztian <hidden@balabit.hu> and others and additional patches · 3 unmodified lines | ||
| 4 | 4 | from Jamal <hadi@cyberus.ca>. |
| 5 | 5 | |
| 6 | 6 | The end goal for syncing is to be able to insert attributes + generate |
| 7 | −events so that the an SA can be safely moved from one machine to another | |
| 7 | +events so that the SA can be safely moved from one machine to another | |
| 8 | 8 | for HA purposes. |
| 9 | 9 | The idea is to synchronize the SA so that the takeover machine can do |
| 10 | 10 | the processing of the SA as accurate as possible if it has access to it. |
| @@ -13,7 +13,7 @@ We already have the ability to generate SA add/del/upd events. · 2 unmodified lines | ||
| 13 | 13 | These patches add ability to sync and have accurate lifetime byte (to |
| 14 | 14 | ensure proper decay of SAs) and replay counters to avoid replay attacks |
| 15 | 15 | with as minimal loss at failover time. |
| 16 | −This way a backup stays as closely uptodate as an active member. | |
| 16 | +This way a backup stays as closely up-to-date as an active member. | |
| 17 | 17 | |
| 18 | 18 | Because the above items change for every packet the SA receives, |
| 19 | 19 | it is possible for a lot of the events to be generated. |
| @@ -163,7 +163,7 @@ If you have an SA that is getting hit by traffic in bursts such that · 143 unmodified lines | ||
| 163 | 163 | there is a period where the timer threshold expires with no packets |
| 164 | 164 | seen, then an odd behavior is seen as follows: |
| 165 | 165 | The first packet arrival after a timer expiry will trigger a timeout |
| 166 | −aevent; i.e we dont wait for a timeout period or a packet threshold | |
| 166 | +event; i.e we don't wait for a timeout period or a packet threshold | |
| 167 | 167 | to be reached. This is done for simplicity and efficiency reasons. |
| 168 | 168 | |
| 169 | 169 | -JHS |
| @@ -581,15 +581,16 @@ Specify "[Nn]ode" for node order · 580 unmodified lines | ||
| 581 | 581 | "Zone Order" orders the zonelists by zone type, then by node within each |
| 582 | 582 | zone. Specify "[Zz]one" for zone order. |
| 583 | 583 | |
| 584 | −Specify "[Dd]efault" to request automatic configuration. Autoconfiguration | |
| 585 | −will select "node" order in following case. | |
| 586 | −(1) if the DMA zone does not exist or | |
| 587 | −(2) if the DMA zone comprises greater than 50% of the available memory or | |
| 588 | −(3) if any node's DMA zone comprises greater than 70% of its local memory and | |
| 589 | − the amount of local memory is big enough. | |
| 590 | − | |
| 591 | −Otherwise, "zone" order will be selected. Default order is recommended unless | |
| 592 | −this is causing problems for your system/application. | |
| 584 | +Specify "[Dd]efault" to request automatic configuration. | |
| 585 | + | |
| 586 | +On 32-bit, the Normal zone needs to be preserved for allocations accessible | |
| 587 | +by the kernel, so "zone" order will be selected. | |
| 588 | + | |
| 589 | +On 64-bit, devices that require DMA32/DMA are relatively rare, so "node" | |
| 590 | +order will be selected. | |
| 591 | + | |
| 592 | +Default order is recommended unless this is causing problems for your | |
| 593 | +system/application. | |
| 593 | 594 | |
| 594 | 595 | ============================================================== |
| 595 | 596 | |
| @@ -4745,7 +4745,7 @@ F: drivers/platform/x86/fujitsu-tablet.c · 4744 unmodified lines | ||
| 4745 | 4745 | |
| 4746 | 4746 | FUSE: FILESYSTEM IN USERSPACE |
| 4747 | 4747 | M: Miklos Szeredi <miklos@szeredi.hu> |
| 4748 | −L: fuse-devel@lists.sourceforge.net | |
| 4748 | +L: linux-fsdevel@vger.kernel.org | |
| 4749 | 4749 | W: http://fuse.sourceforge.net/ |
| 4750 | 4750 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse.git |
| 4751 | 4751 | S: Maintained |
| @@ -4904,7 +4904,7 @@ F: net/ipv4/gre_offload.c · 152 unmodified lines | ||
| 4904 | 4904 | F: include/net/gre.h |
| 4905 | 4905 | |
| 4906 | 4906 | GRETH 10/100/1G Ethernet MAC device driver |
| 4907 | −M: Kristoffer Glembo <kristoffer@gaisler.com> | |
| 4907 | +M: Andreas Larsson <andreas@gaisler.com> | |
| 4908 | 4908 | L: netdev@vger.kernel.org |
| 4909 | 4909 | S: Maintained |
| 4910 | 4910 | F: drivers/net/ethernet/aeroflex/ |
| @@ -6028,7 +6028,7 @@ F: include/scsi/*iscsi* · 1117 unmodified lines | ||
| 6028 | 6028 | |
| 6029 | 6029 | ISCSI EXTENSIONS FOR RDMA (ISER) INITIATOR |
| 6030 | 6030 | M: Or Gerlitz <ogerlitz@mellanox.com> |
| 6031 | −M: Sagi Grimberg <sagig@mellanox.com> | |
| 6031 | +M: Sagi Grimberg <sagi@grimberg.me> | |
| 6032 | 6032 | M: Roi Dayan <roid@mellanox.com> |
| 6033 | 6033 | L: linux-rdma@vger.kernel.org |
| 6034 | 6034 | S: Supported |
| @@ -6038,7 +6038,7 @@ Q: http://patchwork.kernel.org/project/linux-rdma/list/ · 3 unmodified lines | ||
| 6038 | 6038 | F: drivers/infiniband/ulp/iser/ |
| 6039 | 6039 | |
| 6040 | 6040 | ISCSI EXTENSIONS FOR RDMA (ISER) TARGET |
| 6041 | −M: Sagi Grimberg <sagig@mellanox.com> | |
| 6041 | +M: Sagi Grimberg <sagi@grimberg.me> | |
| 6042 | 6042 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git master |
| 6043 | 6043 | L: linux-rdma@vger.kernel.org |
| 6044 | 6044 | L: target-devel@vger.kernel.org |
| @@ -6401,7 +6401,7 @@ F: mm/kmemleak.c · 356 unmodified lines | ||
| 6401 | 6401 | F: mm/kmemleak-test.c |
| 6402 | 6402 | |
| 6403 | 6403 | KPROBES |
| 6404 | −M: Ananth N Mavinakayanahalli <ananth@in.ibm.com> | |
| 6404 | +M: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com> | |
| 6405 | 6405 | M: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> |
| 6406 | 6406 | M: "David S. Miller" <davem@davemloft.net> |
| 6407 | 6407 | M: Masami Hiramatsu <mhiramat@kernel.org> |
| @@ -10015,7 +10015,8 @@ F: drivers/infiniband/hw/ocrdma/ · 3607 unmodified lines | ||
| 10015 | 10015 | |
| 10016 | 10016 | SFC NETWORK DRIVER |
| 10017 | 10017 | M: Solarflare linux maintainers <linux-net-drivers@solarflare.com> |
| 10018 | −M: Shradha Shah <sshah@solarflare.com> | |
| 10018 | +M: Edward Cree <ecree@solarflare.com> | |
| 10019 | +M: Bert Kenward <bkenward@solarflare.com> | |
| 10019 | 10020 | L: netdev@vger.kernel.org |
| 10020 | 10021 | S: Supported |
| 10021 | 10022 | F: drivers/net/ethernet/sfc/ |
| @@ -1,8 +1,8 @@ | ||
| 1 | 1 | VERSION = 4 |
| 2 | 2 | PATCHLEVEL = 6 |
| 3 | 3 | SUBLEVEL = 0 |
| 4 | −EXTRAVERSION = -rc5 | |
| 5 | −NAME = Blurry Fish Butt | |
| 4 | +EXTRAVERSION = -rc6 | |
| 5 | +NAME = Charred Weasel | |
| 6 | 6 | |
| 7 | 7 | # *DOCUMENTATION* |
| 8 | 8 | # To see a list of typical targets execute "make help" |
| @@ -35,8 +35,10 @@ config ARC · 34 unmodified lines | ||
| 35 | 35 | select NO_BOOTMEM |
| 36 | 36 | select OF |
| 37 | 37 | select OF_EARLY_FLATTREE |
| 38 | + select OF_RESERVED_MEM | |
| 38 | 39 | select PERF_USE_VMALLOC |
| 39 | 40 | select HAVE_DEBUG_STACKOVERFLOW |
| 41 | + select HAVE_GENERIC_DMA_COHERENT | |
| 40 | 42 | |
| 41 | 43 | config MIGHT_HAVE_PCI |
| 42 | 44 | bool |
| @@ -18,6 +18,12 @@ · 17 unmodified lines | ||
| 18 | 18 | #define STATUS_AD_MASK (1<<STATUS_AD_BIT) |
| 19 | 19 | #define STATUS_IE_MASK (1<<STATUS_IE_BIT) |
| 20 | 20 | |
| 21 | +/* status32 Bits as encoded/expected by CLRI/SETI */ | |
| 22 | +#define CLRI_STATUS_IE_BIT 4 | |
| 23 | + | |
| 24 | +#define CLRI_STATUS_E_MASK 0xF | |
| 25 | +#define CLRI_STATUS_IE_MASK (1 << CLRI_STATUS_IE_BIT) | |
| 26 | + | |
| 21 | 27 | #define AUX_USER_SP 0x00D |
| 22 | 28 | #define AUX_IRQ_CTRL 0x00E |
| 23 | 29 | #define AUX_IRQ_ACT 0x043 /* Active Intr across all levels */ |
| @@ -100,6 +106,13 @@ static inline long arch_local_save_flags(void) · 76 unmodified lines | ||
| 100 | 106 | : |
| 101 | 107 | : "memory"); |
| 102 | 108 | |
| 109 | + /* To be compatible with irq_save()/irq_restore() | |
| 110 | + * encode the irq bits as expected by CLRI/SETI | |
| 111 | + * (this was needed to make CONFIG_TRACE_IRQFLAGS work) | |
| 112 | + */ | |
| 113 | + temp = (1 << 5) | | |
| 114 | + ((!!(temp & STATUS_IE_MASK)) << CLRI_STATUS_IE_BIT) | | |
| 115 | + (temp & CLRI_STATUS_E_MASK); | |
| 103 | 116 | return temp; |
| 104 | 117 | } |
| 105 | 118 | |
| @@ -108,7 +121,7 @@ static inline long arch_local_save_flags(void) · 2 unmodified lines | ||
| 108 | 121 | */ |
| 109 | 122 | static inline int arch_irqs_disabled_flags(unsigned long flags) |
| 110 | 123 | { |
| 111 | − return !(flags & (STATUS_IE_MASK)); | |
| 124 | + return !(flags & CLRI_STATUS_IE_MASK); | |
| 112 | 125 | } |
| 113 | 126 | |
| 114 | 127 | static inline int arch_irqs_disabled(void) |
| @@ -128,11 +141,32 @@ static inline void arc_softirq_clear(int irq) · 13 unmodified lines | ||
| 128 | 141 | |
| 129 | 142 | #else |
| 130 | 143 | |
| 144 | +#ifdef CONFIG_TRACE_IRQFLAGS | |
| 145 | + | |
| 146 | +.macro TRACE_ASM_IRQ_DISABLE | |
| 147 | + bl trace_hardirqs_off | |
| 148 | +.endm | |
| 149 | + | |
| 150 | +.macro TRACE_ASM_IRQ_ENABLE | |
| 151 | + bl trace_hardirqs_on | |
| 152 | +.endm | |
| 153 | + | |
| 154 | +#else | |
| 155 | + | |
| 156 | +.macro TRACE_ASM_IRQ_DISABLE | |
| 157 | +.endm | |
| 158 | + | |
| 159 | +.macro TRACE_ASM_IRQ_ENABLE | |
| 160 | +.endm | |
| 161 | + | |
| 162 | +#endif | |
| 131 | 163 | .macro IRQ_DISABLE scratch |
| 132 | 164 | clri |
| 165 | + TRACE_ASM_IRQ_DISABLE | |
| 133 | 166 | .endm |
| 134 | 167 | |
| 135 | 168 | .macro IRQ_ENABLE scratch |
| 169 | + TRACE_ASM_IRQ_ENABLE | |
| 136 | 170 | seti |
| 137 | 171 | .endm |
| 138 | 172 | |
| @@ -69,8 +69,11 @@ ENTRY(handle_interrupt) · 68 unmodified lines | ||
| 69 | 69 | |
| 70 | 70 | clri ; To make status32.IE agree with CPU internal state |
| 71 | 71 | |
| 72 | − lr r0, [ICAUSE] | |
| 72 | +#ifdef CONFIG_TRACE_IRQFLAGS | |
| 73 | + TRACE_ASM_IRQ_DISABLE | |
| 74 | +#endif | |
| 73 | 75 | |
| 76 | + lr r0, [ICAUSE] | |
| 74 | 77 | mov blink, ret_from_exception |
| 75 | 78 | |
| 76 | 79 | b.d arch_do_IRQ |
| @@ -169,6 +172,11 @@ END(EV_TLBProtV) · 92 unmodified lines | ||
| 169 | 172 | |
| 170 | 173 | .Lrestore_regs: |
| 171 | 174 | |
| 175 | + # Interrpts are actually disabled from this point on, but will get | |
| 176 | + # reenabled after we return from interrupt/exception. | |
| 177 | + # But irq tracer needs to be told now... | |
| 178 | + TRACE_ASM_IRQ_ENABLE | |
| 179 | + | |
| 172 | 180 | ld r0, [sp, PT_status32] ; U/K mode at time of entry |
| 173 | 181 | lr r10, [AUX_IRQ_ACT] |
| 174 | 182 | |
| @@ -341,6 +341,9 @@ END(call_do_page_fault) · 340 unmodified lines | ||
| 341 | 341 | |
| 342 | 342 | .Lrestore_regs: |
| 343 | 343 | |
| 344 | + # Interrpts are actually disabled from this point on, but will get | |
| 345 | + # reenabled after we return from interrupt/exception. | |
| 346 | + # But irq tracer needs to be told now... | |
| 344 | 347 | TRACE_ASM_IRQ_ENABLE |
| 345 | 348 | |
| 346 | 349 | lr r10, [status32] |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | #ifdef CONFIG_BLK_DEV_INITRD |
| 14 | 14 | #include <linux/initrd.h> |
| 15 | 15 | #endif |
| 16 | +#include <linux/of_fdt.h> | |
| 16 | 17 | #include <linux/swap.h> |
| 17 | 18 | #include <linux/module.h> |
| 18 | 19 | #include <linux/highmem.h> |
| @@ -136,6 +137,9 @@ void __init setup_arch_memory(void) · 117 unmodified lines | ||
| 136 | 137 | memblock_reserve(__pa(initrd_start), initrd_end - initrd_start); |
| 137 | 138 | #endif |
| 138 | 139 | |
| 140 | + early_init_fdt_reserve_self(); | |
| 141 | + early_init_fdt_scan_reserved_mem(); | |
| 142 | + | |
| 139 | 143 | memblock_dump_all(); |
| 140 | 144 | |
| 141 | 145 | /*----------------- node/zones setup --------------------------*/ |
| @@ -68,7 +68,7 @@ void *memset(void *s, int c, size_t count) · 67 unmodified lines | ||
| 68 | 68 | "=r" (charcnt), /* %1 Output */ |
| 69 | 69 | "=r" (dwordcnt), /* %2 Output */ |
| 70 | 70 | "=r" (fill8reg), /* %3 Output */ |
| 71 | − "=r" (wrkrega) /* %4 Output */ | |
| 71 | + "=&r" (wrkrega) /* %4 Output only */ | |
| 72 | 72 | : "r" (c), /* %5 Input */ |
| 73 | 73 | "0" (s), /* %0 Input/Output */ |
| 74 | 74 | "1" (count) /* %1 Input/Output */ |
| @@ -384,3 +384,5 @@ SYSCALL(ni_syscall) · 383 unmodified lines | ||
| 384 | 384 | SYSCALL(ni_syscall) |
| 385 | 385 | SYSCALL(mlock2) |
| 386 | 386 | SYSCALL(copy_file_range) |
| 387 | +COMPAT_SYS_SPU(preadv2) | |
| 388 | +COMPAT_SYS_SPU(pwritev2) | |
| @@ -12,7 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <uapi/asm/unistd.h> |
| 13 | 13 | |
| 14 | 14 | |
| 15 | −#define NR_syscalls 380 | |
| 15 | +#define NR_syscalls 382 | |
| 16 | 16 | |
| 17 | 17 | #define __NR__exit __NR_exit |
| 18 | 18 | |
| @@ -390,5 +390,7 @@ · 389 unmodified lines | ||
| 390 | 390 | #define __NR_membarrier 365 |
| 391 | 391 | #define __NR_mlock2 378 |
| 392 | 392 | #define __NR_copy_file_range 379 |
| 393 | +#define __NR_preadv2 380 | |
| 394 | +#define __NR_pwritev2 381 | |
| 393 | 395 | |
| 394 | 396 | #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */ |
| @@ -11,7 +11,7 @@ typedef struct { · 10 unmodified lines | ||
| 11 | 11 | spinlock_t list_lock; |
| 12 | 12 | struct list_head pgtable_list; |
| 13 | 13 | struct list_head gmap_list; |
| 14 | − unsigned long asce_bits; | |
| 14 | + unsigned long asce; | |
| 15 | 15 | unsigned long asce_limit; |
| 16 | 16 | unsigned long vdso_base; |
| 17 | 17 | /* The mmu context allocates 4K page tables. */ |
| @@ -26,12 +26,28 @@ static inline int init_new_context(struct task_struct *tsk, · 25 unmodified lines | ||
| 26 | 26 | mm->context.has_pgste = 0; |
| 27 | 27 | mm->context.use_skey = 0; |
| 28 | 28 | #endif |
| 29 | − if (mm->context.asce_limit == 0) { | |
| 29 | + switch (mm->context.asce_limit) { | |
| 30 | + case 1UL << 42: | |
| 31 | + /* | |
| 32 | + * forked 3-level task, fall through to set new asce with new | |
| 33 | + * mm->pgd | |
| 34 | + */ | |
| 35 | + case 0: | |
| 30 | 36 | /* context created by exec, set asce limit to 4TB */ |
| 31 | − mm->context.asce_bits = _ASCE_TABLE_LENGTH | | |
| 32 | − _ASCE_USER_BITS | _ASCE_TYPE_REGION3; | |
| 33 | 37 | mm->context.asce_limit = STACK_TOP_MAX; |
| 34 | − } else if (mm->context.asce_limit == (1UL << 31)) { | |
| 38 | + mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | | |
| 39 | + _ASCE_USER_BITS | _ASCE_TYPE_REGION3; | |
| 40 | + break; | |
| 41 | + case 1UL << 53: | |
| 42 | + /* forked 4-level task, set new asce with new mm->pgd */ | |
| 43 | + mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | | |
| 44 | + _ASCE_USER_BITS | _ASCE_TYPE_REGION2; | |
| 45 | + break; | |
| 46 | + case 1UL << 31: | |
| 47 | + /* forked 2-level compat task, set new asce with new mm->pgd */ | |
| 48 | + mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | | |
| 49 | + _ASCE_USER_BITS | _ASCE_TYPE_SEGMENT; | |
| 50 | + /* pgd_alloc() did not increase mm->nr_pmds */ | |
| 35 | 51 | mm_inc_nr_pmds(mm); |
| 36 | 52 | } |
| 37 | 53 | crst_table_init((unsigned long *) mm->pgd, pgd_entry_type(mm)); |
| @@ -42,7 +58,7 @@ static inline int init_new_context(struct task_struct *tsk, · 4 unmodified lines | ||
| 42 | 58 | |
| 43 | 59 | static inline void set_user_asce(struct mm_struct *mm) |
| 44 | 60 | { |
| 45 | − S390_lowcore.user_asce = mm->context.asce_bits | __pa(mm->pgd); | |
| 61 | + S390_lowcore.user_asce = mm->context.asce; | |
| 46 | 62 | if (current->thread.mm_segment.ar4) |
| 47 | 63 | __ctl_load(S390_lowcore.user_asce, 7, 7); |
| 48 | 64 | set_cpu_flag(CIF_ASCE); |
| @@ -71,7 +87,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, · 22 unmodified lines | ||
| 71 | 87 | { |
| 72 | 88 | int cpu = smp_processor_id(); |
| 73 | 89 | |
| 74 | − S390_lowcore.user_asce = next->context.asce_bits | __pa(next->pgd); | |
| 90 | + S390_lowcore.user_asce = next->context.asce; | |
| 75 | 91 | if (prev == next) |
| 76 | 92 | return; |
| 77 | 93 | if (MACHINE_HAS_TLB_LC) |
| @@ -52,8 +52,8 @@ static inline unsigned long pgd_entry_type(struct mm_struct *mm) · 51 unmodified lines | ||
| 52 | 52 | return _REGION2_ENTRY_EMPTY; |
| 53 | 53 | } |
| 54 | 54 | |
| 55 | −int crst_table_upgrade(struct mm_struct *, unsigned long limit); | |
| 56 | −void crst_table_downgrade(struct mm_struct *, unsigned long limit); | |
| 55 | +int crst_table_upgrade(struct mm_struct *); | |
| 56 | +void crst_table_downgrade(struct mm_struct *); | |
| 57 | 57 | |
| 58 | 58 | static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address) |
| 59 | 59 | { |
| @@ -175,7 +175,7 @@ extern __vector128 init_task_fpu_regs[__NUM_VXRS]; · 174 unmodified lines | ||
| 175 | 175 | regs->psw.mask = PSW_USER_BITS | PSW_MASK_BA; \ |
| 176 | 176 | regs->psw.addr = new_psw; \ |
| 177 | 177 | regs->gprs[15] = new_stackp; \ |
| 178 | − crst_table_downgrade(current->mm, 1UL << 31); \ | |
| 178 | + crst_table_downgrade(current->mm); \ | |
| 179 | 179 | execve_tail(); \ |
| 180 | 180 | } while (0) |
| 181 | 181 | |
| @@ -110,8 +110,7 @@ static inline void __tlb_flush_asce(struct mm_struct *mm, unsigned long asce) · 109 unmodified lines | ||
| 110 | 110 | static inline void __tlb_flush_kernel(void) |
| 111 | 111 | { |
| 112 | 112 | if (MACHINE_HAS_IDTE) |
| 113 | − __tlb_flush_idte((unsigned long) init_mm.pgd | | |
| 114 | − init_mm.context.asce_bits); | |
| 113 | + __tlb_flush_idte(init_mm.context.asce); | |
| 115 | 114 | else |
| 116 | 115 | __tlb_flush_global(); |
| 117 | 116 | } |
| @@ -133,8 +132,7 @@ static inline void __tlb_flush_asce(struct mm_struct *mm, unsigned long asce) · 15 unmodified lines | ||
| 133 | 132 | static inline void __tlb_flush_kernel(void) |
| 134 | 133 | { |
| 135 | 134 | if (MACHINE_HAS_TLB_LC) |
| 136 | − __tlb_flush_idte_local((unsigned long) init_mm.pgd | | |
| 137 | − init_mm.context.asce_bits); | |
| 135 | + __tlb_flush_idte_local(init_mm.context.asce); | |
| 138 | 136 | else |
| 139 | 137 | __tlb_flush_local(); |
| 140 | 138 | } |
| @@ -148,8 +146,7 @@ static inline void __tlb_flush_mm(struct mm_struct * mm) · 7 unmodified lines | ||
| 148 | 146 | * only ran on the local cpu. |
| 149 | 147 | */ |
| 150 | 148 | if (MACHINE_HAS_IDTE && list_empty(&mm->context.gmap_list)) |
| 151 | − __tlb_flush_asce(mm, (unsigned long) mm->pgd | | |
| 152 | − mm->context.asce_bits); | |
| 149 | + __tlb_flush_asce(mm, mm->context.asce); | |
| 153 | 150 | else |
| 154 | 151 | __tlb_flush_full(mm); |
| 155 | 152 | } |
| @@ -89,7 +89,8 @@ void __init paging_init(void) · 88 unmodified lines | ||
| 89 | 89 | asce_bits = _ASCE_TYPE_REGION3 | _ASCE_TABLE_LENGTH; |
| 90 | 90 | pgd_type = _REGION3_ENTRY_EMPTY; |
| 91 | 91 | } |
| 92 | − S390_lowcore.kernel_asce = (__pa(init_mm.pgd) & PAGE_MASK) | asce_bits; | |
| 92 | + init_mm.context.asce = (__pa(init_mm.pgd) & PAGE_MASK) | asce_bits; | |
| 93 | + S390_lowcore.kernel_asce = init_mm.context.asce; | |
| 93 | 94 | clear_table((unsigned long *) init_mm.pgd, pgd_type, |
| 94 | 95 | sizeof(unsigned long)*2048); |
| 95 | 96 | vmem_map_init(); |
| @@ -174,7 +174,7 @@ int s390_mmap_check(unsigned long addr, unsigned long len, unsigned long flags) · 173 unmodified lines | ||
| 174 | 174 | if (!(flags & MAP_FIXED)) |
| 175 | 175 | addr = 0; |
| 176 | 176 | if ((addr + len) >= TASK_SIZE) |
| 177 | − return crst_table_upgrade(current->mm, TASK_MAX_SIZE); | |
| 177 | + return crst_table_upgrade(current->mm); | |
| 178 | 178 | return 0; |
| 179 | 179 | } |
| 180 | 180 | |
| @@ -191,7 +191,7 @@ s390_get_unmapped_area(struct file *filp, unsigned long addr, · 10 unmodified lines | ||
| 191 | 191 | return area; |
| 192 | 192 | if (area == -ENOMEM && !is_compat_task() && TASK_SIZE < TASK_MAX_SIZE) { |
| 193 | 193 | /* Upgrade the page table to 4 levels and retry. */ |
| 194 | − rc = crst_table_upgrade(mm, TASK_MAX_SIZE); | |
| 194 | + rc = crst_table_upgrade(mm); | |
| 195 | 195 | if (rc) |
| 196 | 196 | return (unsigned long) rc; |
| 197 | 197 | area = arch_get_unmapped_area(filp, addr, len, pgoff, flags); |
| @@ -213,7 +213,7 @@ s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr, · 15 unmodified lines | ||
| 213 | 213 | return area; |
| 214 | 214 | if (area == -ENOMEM && !is_compat_task() && TASK_SIZE < TASK_MAX_SIZE) { |
| 215 | 215 | /* Upgrade the page table to 4 levels and retry. */ |
| 216 | − rc = crst_table_upgrade(mm, TASK_MAX_SIZE); | |
| 216 | + rc = crst_table_upgrade(mm); | |
| 217 | 217 | if (rc) |
| 218 | 218 | return (unsigned long) rc; |
| 219 | 219 | area = arch_get_unmapped_area_topdown(filp, addr, len, |
| @@ -76,81 +76,52 @@ static void __crst_table_upgrade(void *arg) · 75 unmodified lines | ||
| 76 | 76 | __tlb_flush_local(); |
| 77 | 77 | } |
| 78 | 78 | |
| 79 | −int crst_table_upgrade(struct mm_struct *mm, unsigned long limit) | |
| 79 | +int crst_table_upgrade(struct mm_struct *mm) | |
| 80 | 80 | { |
| 81 | 81 | unsigned long *table, *pgd; |
| 82 | − unsigned long entry; | |
| 83 | − int flush; | |
| 84 | 82 | |
| 85 | − BUG_ON(limit > TASK_MAX_SIZE); | |
| 86 | − flush = 0; | |
| 87 | −repeat: | |
| 83 | + /* upgrade should only happen from 3 to 4 levels */ | |
| 84 | + BUG_ON(mm->context.asce_limit != (1UL << 42)); | |
| 85 | + | |
| 88 | 86 | table = crst_table_alloc(mm); |
| 89 | 87 | if (!table) |
| 90 | 88 | return -ENOMEM; |
| 89 | + | |
| 91 | 90 | spin_lock_bh(&mm->page_table_lock); |
| 92 | − if (mm->context.asce_limit < limit) { | |
| 93 | − pgd = (unsigned long *) mm->pgd; | |
| 94 | − if (mm->context.asce_limit <= (1UL << 31)) { | |
| 95 | − entry = _REGION3_ENTRY_EMPTY; | |
| 96 | − mm->context.asce_limit = 1UL << 42; | |
| 97 | − mm->context.asce_bits = _ASCE_TABLE_LENGTH | | |
| 98 | − _ASCE_USER_BITS | | |
| 99 | − _ASCE_TYPE_REGION3; | |
| 100 | − } else { | |
| 101 | − entry = _REGION2_ENTRY_EMPTY; | |
| 102 | − mm->context.asce_limit = 1UL << 53; | |
| 103 | − mm->context.asce_bits = _ASCE_TABLE_LENGTH | | |
| 104 | − _ASCE_USER_BITS | | |
| 105 | − _ASCE_TYPE_REGION2; | |
| 106 | − } | |
| 107 | − crst_table_init(table, entry); | |
| 108 | − pgd_populate(mm, (pgd_t *) table, (pud_t *) pgd); | |
| 109 | − mm->pgd = (pgd_t *) table; | |
| 110 | − mm->task_size = mm->context.asce_limit; | |
| 111 | − table = NULL; | |
| 112 | − flush = 1; | |
| 113 | − } | |
| 91 | + pgd = (unsigned long *) mm->pgd; | |
| 92 | + crst_table_init(table, _REGION2_ENTRY_EMPTY); | |
| 93 | + pgd_populate(mm, (pgd_t *) table, (pud_t *) pgd); | |
| 94 | + mm->pgd = (pgd_t *) table; | |
| 95 | + mm->context.asce_limit = 1UL << 53; | |
| 96 | + mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | | |
| 97 | + _ASCE_USER_BITS | _ASCE_TYPE_REGION2; | |
| 98 | + mm->task_size = mm->context.asce_limit; | |
| 114 | 99 | spin_unlock_bh(&mm->page_table_lock); |
| 115 | − if (table) | |
| 116 | − crst_table_free(mm, table); | |
| 117 | − if (mm->context.asce_limit < limit) | |
| 118 | − goto repeat; | |
| 119 | − if (flush) | |
| 120 | − on_each_cpu(__crst_table_upgrade, mm, 0); | |
| 100 | + | |
| 101 | + on_each_cpu(__crst_table_upgrade, mm, 0); | |
| 121 | 102 | return 0; |
| 122 | 103 | } |
| 123 | 104 | |
| 124 | −void crst_table_downgrade(struct mm_struct *mm, unsigned long limit) | |
| 105 | +void crst_table_downgrade(struct mm_struct *mm) | |
| 125 | 106 | { |
| 126 | 107 | pgd_t *pgd; |
| 127 | 108 | |
| 109 | + /* downgrade should only happen from 3 to 2 levels (compat only) */ | |
| 110 | + BUG_ON(mm->context.asce_limit != (1UL << 42)); | |
| 111 | + | |
| 128 | 112 | if (current->active_mm == mm) { |
| 129 | 113 | clear_user_asce(); |
| 130 | 114 | __tlb_flush_mm(mm); |
| 131 | 115 | } |
| 132 | − while (mm->context.asce_limit > limit) { | |
| 133 | − pgd = mm->pgd; | |
| 134 | − switch (pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) { | |
| 135 | − case _REGION_ENTRY_TYPE_R2: | |
| 136 | − mm->context.asce_limit = 1UL << 42; | |
| 137 | − mm->context.asce_bits = _ASCE_TABLE_LENGTH | | |
| 138 | − _ASCE_USER_BITS | | |
| 139 | − _ASCE_TYPE_REGION3; | |
| 140 | − break; | |
| 141 | − case _REGION_ENTRY_TYPE_R3: | |
| 142 | − mm->context.asce_limit = 1UL << 31; | |
| 143 | − mm->context.asce_bits = _ASCE_TABLE_LENGTH | | |
| 144 | − _ASCE_USER_BITS | | |
| 145 | − _ASCE_TYPE_SEGMENT; | |
| 146 | − break; | |
| 147 | − default: | |
| 148 | − BUG(); | |
| 149 | − } | |
| 150 | − mm->pgd = (pgd_t *) (pgd_val(*pgd) & _REGION_ENTRY_ORIGIN); | |
| 151 | − mm->task_size = mm->context.asce_limit; | |
| 152 | − crst_table_free(mm, (unsigned long *) pgd); | |
| 153 | − } | |
| 116 | + | |
| 117 | + pgd = mm->pgd; | |
| 118 | + mm->pgd = (pgd_t *) (pgd_val(*pgd) & _REGION_ENTRY_ORIGIN); | |
| 119 | + mm->context.asce_limit = 1UL << 31; | |
| 120 | + mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | | |
| 121 | + _ASCE_USER_BITS | _ASCE_TYPE_SEGMENT; | |
| 122 | + mm->task_size = mm->context.asce_limit; | |
| 123 | + crst_table_free(mm, (unsigned long *) pgd); | |
| 124 | + | |
| 154 | 125 | if (current->active_mm == mm) |
| 155 | 126 | set_user_asce(mm); |
| 156 | 127 | } |
| @@ -457,7 +457,7 @@ int zpci_dma_init_device(struct zpci_dev *zdev) · 456 unmodified lines | ||
| 457 | 457 | zdev->dma_table = dma_alloc_cpu_table(); |
| 458 | 458 | if (!zdev->dma_table) { |
| 459 | 459 | rc = -ENOMEM; |
| 460 | − goto out_clean; | |
| 460 | + goto out; | |
| 461 | 461 | } |
| 462 | 462 | |
| 463 | 463 | /* |
| @@ -477,18 +477,22 @@ int zpci_dma_init_device(struct zpci_dev *zdev) · 13 unmodified lines | ||
| 477 | 477 | zdev->iommu_bitmap = vzalloc(zdev->iommu_pages / 8); |
| 478 | 478 | if (!zdev->iommu_bitmap) { |
| 479 | 479 | rc = -ENOMEM; |
| 480 | − goto out_reg; | |
| 480 | + goto free_dma_table; | |
| 481 | 481 | } |
| 482 | 482 | |
| 483 | 483 | rc = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma, |
| 484 | 484 | (u64) zdev->dma_table); |
| 485 | 485 | if (rc) |
| 486 | − goto out_reg; | |
| 487 | − return 0; | |
| 486 | + goto free_bitmap; | |
| 488 | 487 | |
| 489 | −out_reg: | |
| 488 | + return 0; | |
| 489 | +free_bitmap: | |
| 490 | + vfree(zdev->iommu_bitmap); | |
| 491 | + zdev->iommu_bitmap = NULL; | |
| 492 | +free_dma_table: | |
| 490 | 493 | dma_free_cpu_table(zdev->dma_table); |
| 491 | −out_clean: | |
| 494 | + zdev->dma_table = NULL; | |
| 495 | +out: | |
| 492 | 496 | return rc; |
| 493 | 497 | } |
| 494 | 498 | |
| @@ -24,7 +24,6 @@ CONFIG_INET_AH=y · 23 unmodified lines | ||
| 24 | 24 | CONFIG_INET_ESP=y |
| 25 | 25 | CONFIG_INET_IPCOMP=y |
| 26 | 26 | # CONFIG_INET_LRO is not set |
| 27 | −CONFIG_IPV6_PRIVACY=y | |
| 28 | 27 | CONFIG_INET6_AH=m |
| 29 | 28 | CONFIG_INET6_ESP=m |
| 30 | 29 | CONFIG_INET6_IPCOMP=m |
| @@ -48,7 +48,6 @@ CONFIG_SYN_COOKIES=y · 47 unmodified lines | ||
| 48 | 48 | CONFIG_INET_AH=y |
| 49 | 49 | CONFIG_INET_ESP=y |
| 50 | 50 | CONFIG_INET_IPCOMP=y |
| 51 | −CONFIG_IPV6_PRIVACY=y | |
| 52 | 51 | CONFIG_IPV6_ROUTER_PREF=y |
| 53 | 52 | CONFIG_IPV6_ROUTE_INFO=y |
| 54 | 53 | CONFIG_IPV6_OPTIMISTIC_DAD=y |
| @@ -48,6 +48,7 @@ · 47 unmodified lines | ||
| 48 | 48 | #define SUN4V_CHIP_SPARC_M6 0x06 |
| 49 | 49 | #define SUN4V_CHIP_SPARC_M7 0x07 |
| 50 | 50 | #define SUN4V_CHIP_SPARC64X 0x8a |
| 51 | +#define SUN4V_CHIP_SPARC_SN 0x8b | |
| 51 | 52 | #define SUN4V_CHIP_UNKNOWN 0xff |
| 52 | 53 | |
| 53 | 54 | #ifndef __ASSEMBLY__ |
| @@ -423,8 +423,10 @@ · 422 unmodified lines | ||
| 423 | 423 | #define __NR_setsockopt 355 |
| 424 | 424 | #define __NR_mlock2 356 |
| 425 | 425 | #define __NR_copy_file_range 357 |
| 426 | +#define __NR_preadv2 358 | |
| 427 | +#define __NR_pwritev2 359 | |
| 426 | 428 | |
| 427 | −#define NR_syscalls 358 | |
| 429 | +#define NR_syscalls 360 | |
| 428 | 430 | |
| 429 | 431 | /* Bitmask values returned from kern_features system call. */ |
| 430 | 432 | #define KERN_FEATURE_MIXED_MODE_STACK 0x00000001 |
| @@ -214,8 +214,7 @@ do_dcpe_tl1_nonfatal: /* Ok we may use interrupt globals safely. */ · 213 unmodified lines | ||
| 214 | 214 | subcc %g1, %g2, %g1 ! Next cacheline |
| 215 | 215 | bge,pt %icc, 1b |
| 216 | 216 | nop |
| 217 | − ba,pt %xcc, dcpe_icpe_tl1_common | |
| 218 | − nop | |
| 217 | + ba,a,pt %xcc, dcpe_icpe_tl1_common | |
| 219 | 218 | |
| 220 | 219 | do_dcpe_tl1_fatal: |
| 221 | 220 | sethi %hi(1f), %g7 |
| @@ -224,8 +223,7 @@ do_dcpe_tl1_fatal: · 2 unmodified lines | ||
| 224 | 223 | mov 0x2, %o0 |
| 225 | 224 | call cheetah_plus_parity_error |
| 226 | 225 | add %sp, PTREGS_OFF, %o1 |
| 227 | − ba,pt %xcc, rtrap | |
| 228 | − nop | |
| 226 | + ba,a,pt %xcc, rtrap | |
| 229 | 227 | .size do_dcpe_tl1,.-do_dcpe_tl1 |
| 230 | 228 | |
| 231 | 229 | .globl do_icpe_tl1 |
| @@ -259,8 +257,7 @@ do_icpe_tl1_nonfatal: /* Ok we may use interrupt globals safely. */ · 27 unmodified lines | ||
| 259 | 257 | subcc %g1, %g2, %g1 |
| 260 | 258 | bge,pt %icc, 1b |
| 261 | 259 | nop |
| 262 | − ba,pt %xcc, dcpe_icpe_tl1_common | |
| 263 | − nop | |
| 260 | + ba,a,pt %xcc, dcpe_icpe_tl1_common | |
| 264 | 261 | |
| 265 | 262 | do_icpe_tl1_fatal: |
| 266 | 263 | sethi %hi(1f), %g7 |
| @@ -269,8 +266,7 @@ do_icpe_tl1_fatal: · 2 unmodified lines | ||
| 269 | 266 | mov 0x3, %o0 |
| 270 | 267 | call cheetah_plus_parity_error |
| 271 | 268 | add %sp, PTREGS_OFF, %o1 |
| 272 | − ba,pt %xcc, rtrap | |
| 273 | − nop | |
| 269 | + ba,a,pt %xcc, rtrap | |
| 274 | 270 | .size do_icpe_tl1,.-do_icpe_tl1 |
| 275 | 271 | |
| 276 | 272 | .type dcpe_icpe_tl1_common,#function |
| @@ -456,7 +452,7 @@ __cheetah_log_error: · 179 unmodified lines | ||
| 456 | 452 | cmp %g2, 0x63 |
| 457 | 453 | be c_cee |
| 458 | 454 | nop |
| 459 | − ba,pt %xcc, c_deferred | |
| 455 | + ba,a,pt %xcc, c_deferred | |
| 460 | 456 | .size __cheetah_log_error,.-__cheetah_log_error |
| 461 | 457 | |
| 462 | 458 | /* Cheetah FECC trap handling, we get here from tl{0,1}_fecc |
| @@ -506,6 +506,12 @@ static void __init sun4v_cpu_probe(void) · 505 unmodified lines | ||
| 506 | 506 | sparc_pmu_type = "sparc-m7"; |
| 507 | 507 | break; |
| 508 | 508 | |
| 509 | + case SUN4V_CHIP_SPARC_SN: | |
| 510 | + sparc_cpu_type = "SPARC-SN"; | |
| 511 | + sparc_fpu_type = "SPARC-SN integrated FPU"; | |
| 512 | + sparc_pmu_type = "sparc-sn"; | |
| 513 | + break; | |
| 514 | + | |
| 509 | 515 | case SUN4V_CHIP_SPARC64X: |
| 510 | 516 | sparc_cpu_type = "SPARC64-X"; |
| 511 | 517 | sparc_fpu_type = "SPARC64-X integrated FPU"; |
| @@ -328,6 +328,7 @@ static int iterate_cpu(struct cpuinfo_tree *t, unsigned int root_index) · 327 unmodified lines | ||
| 328 | 328 | case SUN4V_CHIP_NIAGARA5: |
| 329 | 329 | case SUN4V_CHIP_SPARC_M6: |
| 330 | 330 | case SUN4V_CHIP_SPARC_M7: |
| 331 | + case SUN4V_CHIP_SPARC_SN: | |
| 331 | 332 | case SUN4V_CHIP_SPARC64X: |
| 332 | 333 | rover_inc_table = niagara_iterate_method; |
| 333 | 334 | break; |
| @@ -100,8 +100,8 @@ do_fpdis: · 99 unmodified lines | ||
| 100 | 100 | fmuld %f0, %f2, %f26 |
| 101 | 101 | faddd %f0, %f2, %f28 |
| 102 | 102 | fmuld %f0, %f2, %f30 |
| 103 | − b,pt %xcc, fpdis_exit | |
| 104 | − nop | |
| 103 | + ba,a,pt %xcc, fpdis_exit | |
| 104 | + | |
| 105 | 105 | 2: andcc %g5, FPRS_DU, %g0 |
| 106 | 106 | bne,pt %icc, 3f |
| 107 | 107 | fzero %f32 |
| @@ -144,8 +144,8 @@ do_fpdis: · 36 unmodified lines | ||
| 144 | 144 | fmuld %f32, %f34, %f58 |
| 145 | 145 | faddd %f32, %f34, %f60 |
| 146 | 146 | fmuld %f32, %f34, %f62 |
| 147 | − ba,pt %xcc, fpdis_exit | |
| 148 | − nop | |
| 147 | + ba,a,pt %xcc, fpdis_exit | |
| 148 | + | |
| 149 | 149 | 3: mov SECONDARY_CONTEXT, %g3 |
| 150 | 150 | add %g6, TI_FPREGS, %g1 |
| 151 | 151 | |
| @@ -197,8 +197,7 @@ fpdis_exit2: · 45 unmodified lines | ||
| 197 | 197 | fp_other_bounce: |
| 198 | 198 | call do_fpother |
| 199 | 199 | add %sp, PTREGS_OFF, %o0 |
| 200 | − ba,pt %xcc, rtrap | |
| 201 | − nop | |
| 200 | + ba,a,pt %xcc, rtrap | |
| 202 | 201 | .size fp_other_bounce,.-fp_other_bounce |
| 203 | 202 | |
| 204 | 203 | .align 32 |
| @@ -414,6 +414,8 @@ sun4v_chip_type: · 413 unmodified lines | ||
| 414 | 414 | cmp %g2, 'T' |
| 415 | 415 | be,pt %xcc, 70f |
| 416 | 416 | cmp %g2, 'M' |
| 417 | + be,pt %xcc, 70f | |
| 418 | + cmp %g2, 'S' | |
| 417 | 419 | bne,pn %xcc, 49f |
| 418 | 420 | nop |
| 419 | 421 | |
| @@ -433,6 +435,9 @@ sun4v_chip_type: · 13 unmodified lines | ||
| 433 | 435 | cmp %g2, '7' |
| 434 | 436 | be,pt %xcc, 5f |
| 435 | 437 | mov SUN4V_CHIP_SPARC_M7, %g4 |
| 438 | + cmp %g2, 'N' | |
| 439 | + be,pt %xcc, 5f | |
| 440 | + mov SUN4V_CHIP_SPARC_SN, %g4 | |
| 436 | 441 | ba,pt %xcc, 49f |
| 437 | 442 | nop |
| 438 | 443 | |
| @@ -461,9 +466,8 @@ sun4v_chip_type: · 22 unmodified lines | ||
| 461 | 466 | subcc %g3, 1, %g3 |
| 462 | 467 | bne,pt %xcc, 41b |
| 463 | 468 | add %g1, 1, %g1 |
| 464 | − mov SUN4V_CHIP_SPARC64X, %g4 | |
| 465 | 469 | ba,pt %xcc, 5f |
| 466 | − nop | |
| 470 | + mov SUN4V_CHIP_SPARC64X, %g4 | |
| 467 | 471 | |
| 468 | 472 | 49: |
| 469 | 473 | mov SUN4V_CHIP_UNKNOWN, %g4 |
| @@ -548,8 +552,7 @@ sun4u_init: · 78 unmodified lines | ||
| 548 | 552 | stxa %g0, [%g7] ASI_DMMU |
| 549 | 553 | membar #Sync |
| 550 | 554 | |
| 551 | − ba,pt %xcc, sun4u_continue | |
| 552 | − nop | |
| 555 | + ba,a,pt %xcc, sun4u_continue | |
| 553 | 556 | |
| 554 | 557 | sun4v_init: |
| 555 | 558 | /* Set ctx 0 */ |
| @@ -560,14 +563,12 @@ sun4v_init: · 4 unmodified lines | ||
| 560 | 563 | mov SECONDARY_CONTEXT, %g7 |
| 561 | 564 | stxa %g0, [%g7] ASI_MMU |
| 562 | 565 | membar #Sync |
| 563 | − ba,pt %xcc, niagara_tlb_fixup | |
| 564 | − nop | |
| 566 | + ba,a,pt %xcc, niagara_tlb_fixup | |
| 565 | 567 | |
| 566 | 568 | sun4u_continue: |
| 567 | 569 | BRANCH_IF_ANY_CHEETAH(g1, g7, cheetah_tlb_fixup) |
| 568 | 570 | |
| 569 | − ba,pt %xcc, spitfire_tlb_fixup | |
| 570 | − nop | |
| 571 | + ba,a,pt %xcc, spitfire_tlb_fixup | |
| 571 | 572 | |
| 572 | 573 | niagara_tlb_fixup: |
| 573 | 574 | mov 3, %g2 /* Set TLB type to hypervisor. */ |
| @@ -595,6 +596,9 @@ niagara_tlb_fixup: · 21 unmodified lines | ||
| 595 | 596 | be,pt %xcc, niagara4_patch |
| 596 | 597 | nop |
| 597 | 598 | cmp %g1, SUN4V_CHIP_SPARC_M7 |
| 599 | + be,pt %xcc, niagara4_patch | |
| 600 | + nop | |
| 601 | + cmp %g1, SUN4V_CHIP_SPARC_SN | |
| 598 | 602 | be,pt %xcc, niagara4_patch |
| 599 | 603 | nop |
| 600 | 604 | |
| @@ -639,8 +643,7 @@ niagara_patch: · 38 unmodified lines | ||
| 639 | 643 | call hypervisor_patch_cachetlbops |
| 640 | 644 | nop |
| 641 | 645 | |
| 642 | − ba,pt %xcc, tlb_fixup_done | |
| 643 | − nop | |
| 646 | + ba,a,pt %xcc, tlb_fixup_done | |
| 644 | 647 | |
| 645 | 648 | cheetah_tlb_fixup: |
| 646 | 649 | mov 2, %g2 /* Set TLB type to cheetah+. */ |
| @@ -659,8 +662,7 @@ cheetah_tlb_fixup: · 12 unmodified lines | ||
| 659 | 662 | call cheetah_patch_cachetlbops |
| 660 | 663 | nop |
| 661 | 664 | |
| 662 | − ba,pt %xcc, tlb_fixup_done | |
| 663 | − nop | |
| 665 | + ba,a,pt %xcc, tlb_fixup_done | |
| 664 | 666 | |
| 665 | 667 | spitfire_tlb_fixup: |
| 666 | 668 | /* Set TLB type to spitfire. */ |
| @@ -774,8 +776,7 @@ setup_trap_table: · 107 unmodified lines | ||
| 774 | 776 | call %o1 |
| 775 | 777 | add %sp, (2047 + 128), %o0 |
| 776 | 778 | |
| 777 | − ba,pt %xcc, 2f | |
| 778 | − nop | |
| 779 | + ba,a,pt %xcc, 2f | |
| 779 | 780 | |
| 780 | 781 | 1: sethi %hi(sparc64_ttable_tl0), %o0 |
| 781 | 782 | set prom_set_trap_table_name, %g2 |
| @@ -814,8 +815,7 @@ setup_trap_table: · 32 unmodified lines | ||
| 814 | 815 | |
| 815 | 816 | BRANCH_IF_ANY_CHEETAH(o2, o3, 1f) |
| 816 | 817 | |
| 817 | − ba,pt %xcc, 2f | |
| 818 | − nop | |
| 818 | + ba,a,pt %xcc, 2f | |
| 819 | 819 | |
| 820 | 820 | /* Disable STICK_INT interrupts. */ |
| 821 | 821 | 1: |
| @@ -18,8 +18,7 @@ __do_privact: · 17 unmodified lines | ||
| 18 | 18 | 109: or %g7, %lo(109b), %g7 |
| 19 | 19 | call do_privact |
| 20 | 20 | add %sp, PTREGS_OFF, %o0 |
| 21 | − ba,pt %xcc, rtrap | |
| 22 | − nop | |
| 21 | + ba,a,pt %xcc, rtrap | |
| 23 | 22 | .size __do_privact,.-__do_privact |
| 24 | 23 | |
| 25 | 24 | .type do_mna,#function |
| @@ -46,8 +45,7 @@ do_mna: · 20 unmodified lines | ||
| 46 | 45 | mov %l5, %o2 |
| 47 | 46 | call mem_address_unaligned |
| 48 | 47 | add %sp, PTREGS_OFF, %o0 |
| 49 | − ba,pt %xcc, rtrap | |
| 50 | − nop | |
| 48 | + ba,a,pt %xcc, rtrap | |
| 51 | 49 | .size do_mna,.-do_mna |
| 52 | 50 | |
| 53 | 51 | .type do_lddfmna,#function |
| @@ -65,8 +63,7 @@ do_lddfmna: · 11 unmodified lines | ||
| 65 | 63 | mov %l5, %o2 |
| 66 | 64 | call handle_lddfmna |
| 67 | 65 | add %sp, PTREGS_OFF, %o0 |
| 68 | − ba,pt %xcc, rtrap | |
| 69 | − nop | |
| 66 | + ba,a,pt %xcc, rtrap | |
| 70 | 67 | .size do_lddfmna,.-do_lddfmna |
| 71 | 68 | |
| 72 | 69 | .type do_stdfmna,#function |
| @@ -84,8 +81,7 @@ do_stdfmna: · 11 unmodified lines | ||
| 84 | 81 | mov %l5, %o2 |
| 85 | 82 | call handle_stdfmna |
| 86 | 83 | add %sp, PTREGS_OFF, %o0 |
| 87 | − ba,pt %xcc, rtrap | |
| 88 | − nop | |
| 84 | + ba,a,pt %xcc, rtrap | |
| 89 | 85 | .size do_stdfmna,.-do_stdfmna |
| 90 | 86 | |
| 91 | 87 | .type breakpoint_trap,#function |
| @@ -245,6 +245,18 @@ static void pci_parse_of_addrs(struct platform_device *op, · 244 unmodified lines | ||
| 245 | 245 | } |
| 246 | 246 | } |
| 247 | 247 | |
| 248 | +static void pci_init_dev_archdata(struct dev_archdata *sd, void *iommu, | |
| 249 | + void *stc, void *host_controller, | |
| 250 | + struct platform_device *op, | |
| 251 | + int numa_node) | |
| 252 | +{ | |
| 253 | + sd->iommu = iommu; | |
| 254 | + sd->stc = stc; | |
| 255 | + sd->host_controller = host_controller; | |
| 256 | + sd->op = op; | |
| 257 | + sd->numa_node = numa_node; | |
| 258 | +} | |
| 259 | + | |
| 248 | 260 | static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, |
| 249 | 261 | struct device_node *node, |
| 250 | 262 | struct pci_bus *bus, int devfn) |
| @@ -259,13 +271,10 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, · 8 unmodified lines | ||
| 259 | 271 | if (!dev) |
| 260 | 272 | return NULL; |
| 261 | 273 | |
| 274 | + op = of_find_device_by_node(node); | |
| 262 | 275 | sd = &dev->dev.archdata; |
| 263 | − sd->iommu = pbm->iommu; | |
| 264 | − sd->stc = &pbm->stc; | |
| 265 | − sd->host_controller = pbm; | |
| 266 | − sd->op = op = of_find_device_by_node(node); | |
| 267 | − sd->numa_node = pbm->numa_node; | |
| 268 | − | |
| 276 | + pci_init_dev_archdata(sd, pbm->iommu, &pbm->stc, pbm, op, | |
| 277 | + pbm->numa_node); | |
| 269 | 278 | sd = &op->dev.archdata; |
| 270 | 279 | sd->iommu = pbm->iommu; |
| 271 | 280 | sd->stc = &pbm->stc; |
| @@ -994,6 +1003,27 @@ void pcibios_set_master(struct pci_dev *dev) · 722 unmodified lines | ||
| 994 | 1003 | /* No special bus mastering setup handling */ |
| 995 | 1004 | } |
| 996 | 1005 | |
| 1006 | +#ifdef CONFIG_PCI_IOV | |
| 1007 | +int pcibios_add_device(struct pci_dev *dev) | |
| 1008 | +{ | |
| 1009 | + struct pci_dev *pdev; | |
| 1010 | + | |
| 1011 | + /* Add sriov arch specific initialization here. | |
| 1012 | + * Copy dev_archdata from PF to VF | |
| 1013 | + */ | |
| 1014 | + if (dev->is_virtfn) { | |
| 1015 | + struct dev_archdata *psd; | |
| 1016 | + | |
| 1017 | + pdev = dev->physfn; | |
| 1018 | + psd = &pdev->dev.archdata; | |
| 1019 | + pci_init_dev_archdata(&dev->dev.archdata, psd->iommu, | |
| 1020 | + psd->stc, psd->host_controller, NULL, | |
| 1021 | + psd->numa_node); | |
| 1022 | + } | |
| 1023 | + return 0; | |
| 1024 | +} | |
| 1025 | +#endif /* CONFIG_PCI_IOV */ | |
| 1026 | + | |
| 997 | 1027 | static int __init pcibios_init(void) |
| 998 | 1028 | { |
| 999 | 1029 | pci_dfl_cache_line_size = 64 >> 2; |
| @@ -285,7 +285,8 @@ static void __init sun4v_patch(void) · 284 unmodified lines | ||
| 285 | 285 | |
| 286 | 286 | sun4v_patch_2insn_range(&__sun4v_2insn_patch, |
| 287 | 287 | &__sun4v_2insn_patch_end); |
| 288 | − if (sun4v_chip_type == SUN4V_CHIP_SPARC_M7) | |
| 288 | + if (sun4v_chip_type == SUN4V_CHIP_SPARC_M7 || | |
| 289 | + sun4v_chip_type == SUN4V_CHIP_SPARC_SN) | |
| 289 | 290 | sun_m7_patch_2insn_range(&__sun_m7_2insn_patch, |
| 290 | 291 | &__sun_m7_2insn_patch_end); |
| 291 | 292 | |
| @@ -524,6 +525,7 @@ static void __init init_sparc64_elf_hwcap(void) · 232 unmodified lines | ||
| 524 | 525 | sun4v_chip_type == SUN4V_CHIP_NIAGARA5 || |
| 525 | 526 | sun4v_chip_type == SUN4V_CHIP_SPARC_M6 || |
| 526 | 527 | sun4v_chip_type == SUN4V_CHIP_SPARC_M7 || |
| 528 | + sun4v_chip_type == SUN4V_CHIP_SPARC_SN || | |
| 527 | 529 | sun4v_chip_type == SUN4V_CHIP_SPARC64X) |
| 528 | 530 | cap |= HWCAP_SPARC_BLKINIT; |
| 529 | 531 | if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || |
| @@ -532,6 +534,7 @@ static void __init init_sparc64_elf_hwcap(void) · 2 unmodified lines | ||
| 532 | 534 | sun4v_chip_type == SUN4V_CHIP_NIAGARA5 || |
| 533 | 535 | sun4v_chip_type == SUN4V_CHIP_SPARC_M6 || |
| 534 | 536 | sun4v_chip_type == SUN4V_CHIP_SPARC_M7 || |
| 537 | + sun4v_chip_type == SUN4V_CHIP_SPARC_SN || | |
| 535 | 538 | sun4v_chip_type == SUN4V_CHIP_SPARC64X) |
| 536 | 539 | cap |= HWCAP_SPARC_N2; |
| 537 | 540 | } |
| @@ -561,6 +564,7 @@ static void __init init_sparc64_elf_hwcap(void) · 23 unmodified lines | ||
| 561 | 564 | sun4v_chip_type == SUN4V_CHIP_NIAGARA5 || |
| 562 | 565 | sun4v_chip_type == SUN4V_CHIP_SPARC_M6 || |
| 563 | 566 | sun4v_chip_type == SUN4V_CHIP_SPARC_M7 || |
| 567 | + sun4v_chip_type == SUN4V_CHIP_SPARC_SN || | |
| 564 | 568 | sun4v_chip_type == SUN4V_CHIP_SPARC64X) |
| 565 | 569 | cap |= (AV_SPARC_VIS | AV_SPARC_VIS2 | |
| 566 | 570 | AV_SPARC_ASI_BLK_INIT | |
| @@ -570,6 +574,7 @@ static void __init init_sparc64_elf_hwcap(void) · 3 unmodified lines | ||
| 570 | 574 | sun4v_chip_type == SUN4V_CHIP_NIAGARA5 || |
| 571 | 575 | sun4v_chip_type == SUN4V_CHIP_SPARC_M6 || |
| 572 | 576 | sun4v_chip_type == SUN4V_CHIP_SPARC_M7 || |
| 577 | + sun4v_chip_type == SUN4V_CHIP_SPARC_SN || | |
| 573 | 578 | sun4v_chip_type == SUN4V_CHIP_SPARC64X) |
| 574 | 579 | cap |= (AV_SPARC_VIS3 | AV_SPARC_HPC | |
| 575 | 580 | AV_SPARC_FMAF); |
| @@ -85,8 +85,7 @@ __spitfire_cee_trap_continue: · 84 unmodified lines | ||
| 85 | 85 | ba,pt %xcc, etraptl1 |
| 86 | 86 | rd %pc, %g7 |
| 87 | 87 | |
| 88 | − ba,pt %xcc, 2f | |
| 89 | − nop | |
| 88 | + ba,a,pt %xcc, 2f | |
| 90 | 89 | |
| 91 | 90 | 1: ba,pt %xcc, etrap_irq |
| 92 | 91 | rd %pc, %g7 |
| @@ -100,8 +99,7 @@ __spitfire_cee_trap_continue: · 7 unmodified lines | ||
| 100 | 99 | mov %l5, %o2 |
| 101 | 100 | call spitfire_access_error |
| 102 | 101 | add %sp, PTREGS_OFF, %o0 |
| 103 | − ba,pt %xcc, rtrap | |
| 104 | − nop | |
| 102 | + ba,a,pt %xcc, rtrap | |
| 105 | 103 | .size __spitfire_access_error,.-__spitfire_access_error |
| 106 | 104 | |
| 107 | 105 | /* This is the trap handler entry point for ECC correctable |
| @@ -179,8 +177,7 @@ __spitfire_data_access_exception_tl1: · 71 unmodified lines | ||
| 179 | 177 | mov %l5, %o2 |
| 180 | 178 | call spitfire_data_access_exception_tl1 |
| 181 | 179 | add %sp, PTREGS_OFF, %o0 |
| 182 | − ba,pt %xcc, rtrap | |
| 183 | − nop | |
| 180 | + ba,a,pt %xcc, rtrap | |
| 184 | 181 | .size __spitfire_data_access_exception_tl1,.-__spitfire_data_access_exception_tl1 |
| 185 | 182 | |
| 186 | 183 | .type __spitfire_data_access_exception,#function |
| @@ -200,8 +197,7 @@ __spitfire_data_access_exception: · 13 unmodified lines | ||
| 200 | 197 | mov %l5, %o2 |
| 201 | 198 | call spitfire_data_access_exception |
| 202 | 199 | add %sp, PTREGS_OFF, %o0 |
| 203 | − ba,pt %xcc, rtrap | |
| 204 | − nop | |
| 200 | + ba,a,pt %xcc, rtrap | |
| 205 | 201 | .size __spitfire_data_access_exception,.-__spitfire_data_access_exception |
| 206 | 202 | |
| 207 | 203 | .type __spitfire_insn_access_exception_tl1,#function |
| @@ -220,8 +216,7 @@ __spitfire_insn_access_exception_tl1: · 12 unmodified lines | ||
| 220 | 216 | mov %l5, %o2 |
| 221 | 217 | call spitfire_insn_access_exception_tl1 |
| 222 | 218 | add %sp, PTREGS_OFF, %o0 |
| 223 | − ba,pt %xcc, rtrap | |
| 224 | − nop | |
| 219 | + ba,a,pt %xcc, rtrap | |
| 225 | 220 | .size __spitfire_insn_access_exception_tl1,.-__spitfire_insn_access_exception_tl1 |
| 226 | 221 | |
| 227 | 222 | .type __spitfire_insn_access_exception,#function |
| @@ -240,6 +235,5 @@ __spitfire_insn_access_exception: · 12 unmodified lines | ||
| 240 | 235 | mov %l5, %o2 |
| 241 | 236 | call spitfire_insn_access_exception |
| 242 | 237 | add %sp, PTREGS_OFF, %o0 |
| 243 | − ba,pt %xcc, rtrap | |
| 244 | − nop | |
| 238 | + ba,a,pt %xcc, rtrap | |
| 245 | 239 | .size __spitfire_insn_access_exception,.-__spitfire_insn_access_exception |
| @@ -88,4 +88,4 @@ sys_call_table: · 87 unmodified lines | ||
| 88 | 88 | /*340*/ .long sys_ni_syscall, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr |
| 89 | 89 | /*345*/ .long sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf |
| 90 | 90 | /*350*/ .long sys_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen |
| 91 | −/*355*/ .long sys_setsockopt, sys_mlock2, sys_copy_file_range | |
| 91 | +/*355*/ .long sys_setsockopt, sys_mlock2, sys_copy_file_range, sys_preadv2, sys_pwritev2 | |
| @@ -89,7 +89,7 @@ sys_call_table32: · 88 unmodified lines | ||
| 89 | 89 | /*340*/ .word sys_kern_features, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr |
| 90 | 90 | .word sys32_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf |
| 91 | 91 | /*350*/ .word sys32_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen |
| 92 | − .word compat_sys_setsockopt, sys_mlock2, sys_copy_file_range | |
| 92 | + .word compat_sys_setsockopt, sys_mlock2, sys_copy_file_range, compat_sys_preadv2, compat_sys_pwritev2 | |
| 93 | 93 | |
| 94 | 94 | #endif /* CONFIG_COMPAT */ |
| 95 | 95 | |
| @@ -170,4 +170,4 @@ sys_call_table: · 74 unmodified lines | ||
| 170 | 170 | /*340*/ .word sys_kern_features, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr |
| 171 | 171 | .word sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf |
| 172 | 172 | /*350*/ .word sys64_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen |
| 173 | − .word sys_setsockopt, sys_mlock2, sys_copy_file_range | |
| 173 | + .word sys_setsockopt, sys_mlock2, sys_copy_file_range, sys_preadv2, sys_pwritev2 | |
| @@ -11,8 +11,7 @@ utrap_trap: /* %g3=handler,%g4=level */ · 10 unmodified lines | ||
| 11 | 11 | mov %l4, %o1 |
| 12 | 12 | call bad_trap |
| 13 | 13 | add %sp, PTREGS_OFF, %o0 |
| 14 | − ba,pt %xcc, rtrap | |
| 15 | − nop | |
| 14 | + ba,a,pt %xcc, rtrap | |
| 16 | 15 | |
| 17 | 16 | invoke_utrap: |
| 18 | 17 | sllx %g3, 3, %g3 |
| @@ -45,6 +45,14 @@ static const struct vio_device_id *vio_match_device( · 44 unmodified lines | ||
| 45 | 45 | return NULL; |
| 46 | 46 | } |
| 47 | 47 | |
| 48 | +static int vio_hotplug(struct device *dev, struct kobj_uevent_env *env) | |
| 49 | +{ | |
| 50 | + const struct vio_dev *vio_dev = to_vio_dev(dev); | |
| 51 | + | |
| 52 | + add_uevent_var(env, "MODALIAS=vio:T%sS%s", vio_dev->type, vio_dev->compat); | |
| 53 | + return 0; | |
| 54 | +} | |
| 55 | + | |
| 48 | 56 | static int vio_bus_match(struct device *dev, struct device_driver *drv) |
| 49 | 57 | { |
| 50 | 58 | struct vio_dev *vio_dev = to_vio_dev(dev); |
| @@ -105,15 +113,25 @@ static ssize_t type_show(struct device *dev, · 54 unmodified lines | ||
| 105 | 113 | return sprintf(buf, "%s\n", vdev->type); |
| 106 | 114 | } |
| 107 | 115 | |
| 116 | +static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, | |
| 117 | + char *buf) | |
| 118 | +{ | |
| 119 | + const struct vio_dev *vdev = to_vio_dev(dev); | |
| 120 | + | |
| 121 | + return sprintf(buf, "vio:T%sS%s\n", vdev->type, vdev->compat); | |
| 122 | +} | |
| 123 | + | |
| 108 | 124 | static struct device_attribute vio_dev_attrs[] = { |
| 109 | 125 | __ATTR_RO(devspec), |
| 110 | 126 | __ATTR_RO(type), |
| 127 | + __ATTR_RO(modalias), | |
| 111 | 128 | __ATTR_NULL |
| 112 | 129 | }; |
| 113 | 130 | |
| 114 | 131 | static struct bus_type vio_bus_type = { |
| 115 | 132 | .name = "vio", |
| 116 | 133 | .dev_attrs = vio_dev_attrs, |
| 134 | + .uevent = vio_hotplug, | |
| 117 | 135 | .match = vio_bus_match, |
| 118 | 136 | .probe = vio_device_probe, |
| 119 | 137 | .remove = vio_device_remove, |
| @@ -33,6 +33,10 @@ ENTRY(_start) · 32 unmodified lines | ||
| 33 | 33 | jiffies = jiffies_64; |
| 34 | 34 | #endif |
| 35 | 35 | |
| 36 | +#ifdef CONFIG_SPARC64 | |
| 37 | +ASSERT((swapper_tsb == 0x0000000000408000), "Error: sparc64 early assembler too large") | |
| 38 | +#endif | |
| 39 | + | |
| 36 | 40 | SECTIONS |
| 37 | 41 | { |
| 38 | 42 | #ifdef CONFIG_SPARC64 |
| @@ -32,8 +32,7 @@ fill_fixup: · 31 unmodified lines | ||
| 32 | 32 | rd %pc, %g7 |
| 33 | 33 | call do_sparc64_fault |
| 34 | 34 | add %sp, PTREGS_OFF, %o0 |
| 35 | − ba,pt %xcc, rtrap | |
| 36 | − nop | |
| 35 | + ba,a,pt %xcc, rtrap | |
| 37 | 36 | |
| 38 | 37 | /* Be very careful about usage of the trap globals here. |
| 39 | 38 | * You cannot touch %g5 as that has the fault information. |
| @@ -1769,6 +1769,7 @@ static void __init setup_page_offset(void) · 1768 unmodified lines | ||
| 1769 | 1769 | max_phys_bits = 47; |
| 1770 | 1770 | break; |
| 1771 | 1771 | case SUN4V_CHIP_SPARC_M7: |
| 1772 | + case SUN4V_CHIP_SPARC_SN: | |
| 1772 | 1773 | default: |
| 1773 | 1774 | /* M7 and later support 52-bit virtual addresses. */ |
| 1774 | 1775 | sparc64_va_hole_top = 0xfff8000000000000UL; |
| @@ -1986,6 +1987,7 @@ static void __init sun4v_linear_pte_xor_finalize(void) · 211 unmodified lines | ||
| 1986 | 1987 | */ |
| 1987 | 1988 | switch (sun4v_chip_type) { |
| 1988 | 1989 | case SUN4V_CHIP_SPARC_M7: |
| 1990 | + case SUN4V_CHIP_SPARC_SN: | |
| 1989 | 1991 | pagecv_flag = 0x00; |
| 1990 | 1992 | break; |
| 1991 | 1993 | default: |
| @@ -2138,6 +2140,7 @@ void __init paging_init(void) · 146 unmodified lines | ||
| 2138 | 2140 | */ |
| 2139 | 2141 | switch (sun4v_chip_type) { |
| 2140 | 2142 | case SUN4V_CHIP_SPARC_M7: |
| 2143 | + case SUN4V_CHIP_SPARC_SN: | |
| 2141 | 2144 | page_cache4v_flag = _PAGE_CP_4V; |
| 2142 | 2145 | break; |
| 2143 | 2146 | default: |
| @@ -115,7 +115,7 @@ static __initconst const u64 amd_hw_cache_event_ids · 114 unmodified lines | ||
| 115 | 115 | /* |
| 116 | 116 | * AMD Performance Monitor K7 and later. |
| 117 | 117 | */ |
| 118 | −static const u64 amd_perfmon_event_map[] = | |
| 118 | +static const u64 amd_perfmon_event_map[PERF_COUNT_HW_MAX] = | |
| 119 | 119 | { |
| 120 | 120 | [PERF_COUNT_HW_CPU_CYCLES] = 0x0076, |
| 121 | 121 | [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, |
| @@ -3639,6 +3639,7 @@ __init int intel_pmu_init(void) · 3638 unmodified lines | ||
| 3639 | 3639 | |
| 3640 | 3640 | case 78: /* 14nm Skylake Mobile */ |
| 3641 | 3641 | case 94: /* 14nm Skylake Desktop */ |
| 3642 | + case 85: /* 14nm Skylake Server */ | |
| 3642 | 3643 | x86_pmu.late_ack = true; |
| 3643 | 3644 | memcpy(hw_cache_event_ids, skl_hw_cache_event_ids, sizeof(hw_cache_event_ids)); |
| 3644 | 3645 | memcpy(hw_cache_extra_regs, skl_hw_cache_extra_regs, sizeof(hw_cache_extra_regs)); |
| @@ -63,7 +63,7 @@ static enum { · 62 unmodified lines | ||
| 63 | 63 | |
| 64 | 64 | #define LBR_PLM (LBR_KERNEL | LBR_USER) |
| 65 | 65 | |
| 66 | −#define LBR_SEL_MASK 0x1ff /* valid bits in LBR_SELECT */ | |
| 66 | +#define LBR_SEL_MASK 0x3ff /* valid bits in LBR_SELECT */ | |
| 67 | 67 | #define LBR_NOT_SUPP -1 /* LBR filter not supported */ |
| 68 | 68 | #define LBR_IGN 0 /* ignored */ |
| 69 | 69 | |
| @@ -610,8 +610,10 @@ static int intel_pmu_setup_hw_lbr_filter(struct perf_event *event) · 540 unmodified lines | ||
| 610 | 610 | * The first 9 bits (LBR_SEL_MASK) in LBR_SELECT operate |
| 611 | 611 | * in suppress mode. So LBR_SELECT should be set to |
| 612 | 612 | * (~mask & LBR_SEL_MASK) | (mask & ~LBR_SEL_MASK) |
| 613 | + * But the 10th bit LBR_CALL_STACK does not operate | |
| 614 | + * in suppress mode. | |
| 613 | 615 | */ |
| 614 | − reg->config = mask ^ x86_pmu.lbr_sel_mask; | |
| 616 | + reg->config = mask ^ (x86_pmu.lbr_sel_mask & ~LBR_CALL_STACK); | |
| 615 | 617 | |
| 616 | 618 | if ((br_type & PERF_SAMPLE_BRANCH_NO_CYCLES) && |
| 617 | 619 | (br_type & PERF_SAMPLE_BRANCH_NO_FLAGS) && |
| @@ -136,9 +136,21 @@ static int __init pt_pmu_hw_init(void) · 135 unmodified lines | ||
| 136 | 136 | struct dev_ext_attribute *de_attrs; |
| 137 | 137 | struct attribute **attrs; |
| 138 | 138 | size_t size; |
| 139 | + u64 reg; | |
| 139 | 140 | int ret; |
| 140 | 141 | long i; |
| 141 | 142 | |
| 143 | + if (boot_cpu_has(X86_FEATURE_VMX)) { | |
| 144 | + /* | |
| 145 | + * Intel SDM, 36.5 "Tracing post-VMXON" says that | |
| 146 | + * "IA32_VMX_MISC[bit 14]" being 1 means PT can trace | |
| 147 | + * post-VMXON. | |
| 148 | + */ | |
| 149 | + rdmsrl(MSR_IA32_VMX_MISC, reg); | |
| 150 | + if (reg & BIT(14)) | |
| 151 | + pt_pmu.vmx = true; | |
| 152 | + } | |
| 153 | + | |
| 142 | 154 | attrs = NULL; |
| 143 | 155 | |
| 144 | 156 | for (i = 0; i < PT_CPUID_LEAVES; i++) { |
| @@ -269,20 +281,23 @@ static void pt_config(struct perf_event *event) · 124 unmodified lines | ||
| 269 | 281 | |
| 270 | 282 | reg |= (event->attr.config & PT_CONFIG_MASK); |
| 271 | 283 | |
| 284 | + event->hw.config = reg; | |
| 272 | 285 | wrmsrl(MSR_IA32_RTIT_CTL, reg); |
| 273 | 286 | } |
| 274 | 287 | |
| 275 | −static void pt_config_start(bool start) | |
| 288 | +static void pt_config_stop(struct perf_event *event) | |
| 276 | 289 | { |
| 277 | − u64 ctl; | |
| 290 | + u64 ctl = READ_ONCE(event->hw.config); | |
| 291 | + | |
| 292 | + /* may be already stopped by a PMI */ | |
| 293 | + if (!(ctl & RTIT_CTL_TRACEEN)) | |
| 294 | + return; | |
| 278 | 295 | |
| 279 | − rdmsrl(MSR_IA32_RTIT_CTL, ctl); | |
| 280 | − if (start) | |
| 281 | − ctl |= RTIT_CTL_TRACEEN; | |
| 282 | − else | |
| 283 | − ctl &= ~RTIT_CTL_TRACEEN; | |
| 296 | + ctl &= ~RTIT_CTL_TRACEEN; | |
| 284 | 297 | wrmsrl(MSR_IA32_RTIT_CTL, ctl); |
| 285 | 298 | |
| 299 | + WRITE_ONCE(event->hw.config, ctl); | |
| 300 | + | |
| 286 | 301 | /* |
| 287 | 302 | * A wrmsr that disables trace generation serializes other PT |
| 288 | 303 | * registers and causes all data packets to be written to memory, |
| @@ -291,8 +306,7 @@ static void pt_config_start(bool start) · 2 unmodified lines | ||
| 291 | 306 | * The below WMB, separating data store and aux_head store matches |
| 292 | 307 | * the consumer's RMB that separates aux_head load and data load. |
| 293 | 308 | */ |
| 294 | − if (!start) | |
| 295 | − wmb(); | |
| 309 | + wmb(); | |
| 296 | 310 | } |
| 297 | 311 | |
| 298 | 312 | static void pt_config_buffer(void *buf, unsigned int topa_idx, |
| @@ -942,11 +956,17 @@ void intel_pt_interrupt(void) · 643 unmodified lines | ||
| 942 | 956 | if (!ACCESS_ONCE(pt->handle_nmi)) |
| 943 | 957 | return; |
| 944 | 958 | |
| 945 | − pt_config_start(false); | |
| 959 | + /* | |
| 960 | + * If VMX is on and PT does not support it, don't touch anything. | |
| 961 | + */ | |
| 962 | + if (READ_ONCE(pt->vmx_on)) | |
| 963 | + return; | |
| 946 | 964 | |
| 947 | 965 | if (!event) |
| 948 | 966 | return; |
| 949 | 967 | |
| 968 | + pt_config_stop(event); | |
| 969 | + | |
| 950 | 970 | buf = perf_get_aux(&pt->handle); |
| 951 | 971 | if (!buf) |
| 952 | 972 | return; |
| @@ -983,6 +1003,35 @@ void intel_pt_interrupt(void) · 30 unmodified lines | ||
| 983 | 1003 | } |
| 984 | 1004 | } |
| 985 | 1005 | |
| 1006 | +void intel_pt_handle_vmx(int on) | |
| 1007 | +{ | |
| 1008 | + struct pt *pt = this_cpu_ptr(&pt_ctx); | |
| 1009 | + struct perf_event *event; | |
| 1010 | + unsigned long flags; | |
| 1011 | + | |
| 1012 | + /* PT plays nice with VMX, do nothing */ | |
| 1013 | + if (pt_pmu.vmx) | |
| 1014 | + return; | |
| 1015 | + | |
| 1016 | + /* | |
| 1017 | + * VMXON will clear RTIT_CTL.TraceEn; we need to make | |
| 1018 | + * sure to not try to set it while VMX is on. Disable | |
| 1019 | + * interrupts to avoid racing with pmu callbacks; | |
| 1020 | + * concurrent PMI should be handled fine. | |
| 1021 | + */ | |
| 1022 | + local_irq_save(flags); | |
| 1023 | + WRITE_ONCE(pt->vmx_on, on); | |
| 1024 | + | |
| 1025 | + if (on) { | |
| 1026 | + /* prevent pt_config_stop() from writing RTIT_CTL */ | |
| 1027 | + event = pt->handle.event; | |
| 1028 | + if (event) | |
| 1029 | + event->hw.config = 0; | |
| 1030 | + } | |
| 1031 | + local_irq_restore(flags); | |
| 1032 | +} | |
| 1033 | +EXPORT_SYMBOL_GPL(intel_pt_handle_vmx); | |
| 1034 | + | |
| 986 | 1035 | /* |
| 987 | 1036 | * PMU callbacks |
| 988 | 1037 | */ |
| @@ -992,6 +1041,9 @@ static void pt_event_start(struct perf_event *event, int mode) · 3 unmodified lines | ||
| 992 | 1041 | struct pt *pt = this_cpu_ptr(&pt_ctx); |
| 993 | 1042 | struct pt_buffer *buf = perf_get_aux(&pt->handle); |
| 994 | 1043 | |
| 1044 | + if (READ_ONCE(pt->vmx_on)) | |
| 1045 | + return; | |
| 1046 | + | |
| 995 | 1047 | if (!buf || pt_buffer_is_full(buf, pt)) { |
| 996 | 1048 | event->hw.state = PERF_HES_STOPPED; |
| 997 | 1049 | return; |
| @@ -1014,7 +1066,8 @@ static void pt_event_stop(struct perf_event *event, int mode) · 16 unmodified lines | ||
| 1014 | 1066 | * see comment in intel_pt_interrupt(). |
| 1015 | 1067 | */ |
| 1016 | 1068 | ACCESS_ONCE(pt->handle_nmi) = 0; |
| 1017 | − pt_config_start(false); | |
| 1069 | + | |
| 1070 | + pt_config_stop(event); | |
| 1018 | 1071 | |
| 1019 | 1072 | if (event->hw.state == PERF_HES_STOPPED) |
| 1020 | 1073 | return; |
| @@ -65,6 +65,7 @@ enum pt_capabilities { · 64 unmodified lines | ||
| 65 | 65 | struct pt_pmu { |
| 66 | 66 | struct pmu pmu; |
| 67 | 67 | u32 caps[PT_CPUID_REGS_NUM * PT_CPUID_LEAVES]; |
| 68 | + bool vmx; | |
| 68 | 69 | }; |
| 69 | 70 | |
| 70 | 71 | /** |
| @@ -107,10 +108,12 @@ struct pt_buffer { · 36 unmodified lines | ||
| 107 | 108 | * struct pt - per-cpu pt context |
| 108 | 109 | * @handle: perf output handle |
| 109 | 110 | * @handle_nmi: do handle PT PMI on this cpu, there's an active event |
| 111 | + * @vmx_on: 1 if VMX is ON on this cpu | |
| 110 | 112 | */ |
| 111 | 113 | struct pt { |
| 112 | 114 | struct perf_output_handle handle; |
| 113 | 115 | int handle_nmi; |
| 116 | + int vmx_on; | |
| 114 | 117 | }; |
| 115 | 118 | |
| 116 | 119 | #endif /* __INTEL_PT_H__ */ |
| @@ -718,6 +718,7 @@ static int __init rapl_pmu_init(void) · 717 unmodified lines | ||
| 718 | 718 | break; |
| 719 | 719 | case 60: /* Haswell */ |
| 720 | 720 | case 69: /* Haswell-Celeron */ |
| 721 | + case 70: /* Haswell GT3e */ | |
| 721 | 722 | case 61: /* Broadwell */ |
| 722 | 723 | case 71: /* Broadwell-H */ |
| 723 | 724 | rapl_cntr_mask = RAPL_IDX_HSW; |
| @@ -285,6 +285,10 @@ static inline void perf_events_lapic_init(void) { } · 284 unmodified lines | ||
| 285 | 285 | static inline void perf_check_microcode(void) { } |
| 286 | 286 | #endif |
| 287 | 287 | |
| 288 | +#ifdef CONFIG_CPU_SUP_INTEL | |
| 289 | + extern void intel_pt_handle_vmx(int on); | |
| 290 | +#endif | |
| 291 | + | |
| 288 | 292 | #if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_AMD) |
| 289 | 293 | extern void amd_pmu_enable_virt(void); |
| 290 | 294 | extern void amd_pmu_disable_virt(void); |
| @@ -256,7 +256,8 @@ static void clear_irq_vector(int irq, struct apic_chip_data *data) · 255 unmodified lines | ||
| 256 | 256 | struct irq_desc *desc; |
| 257 | 257 | int cpu, vector; |
| 258 | 258 | |
| 259 | − BUG_ON(!data->cfg.vector); | |
| 259 | + if (!data->cfg.vector) | |
| 260 | + return; | |
| 260 | 261 | |
| 261 | 262 | vector = data->cfg.vector; |
| 262 | 263 | for_each_cpu_and(cpu, data->domain, cpu_online_mask) |
| @@ -389,12 +389,6 @@ default_entry: · 388 unmodified lines | ||
| 389 | 389 | /* Make changes effective */ |
| 390 | 390 | wrmsr |
| 391 | 391 | |
| 392 | − /* | |
| 393 | − * And make sure that all the mappings we set up have NX set from | |
| 394 | − * the beginning. | |
| 395 | − */ | |
| 396 | − orl $(1 << (_PAGE_BIT_NX - 32)), pa(__supported_pte_mask + 4) | |
| 397 | − | |
| 398 | 392 | enable_paging: |
| 399 | 393 | |
| 400 | 394 | /* |
| @@ -3103,6 +3103,8 @@ static __init int vmx_disabled_by_bios(void) · 3102 unmodified lines | ||
| 3103 | 3103 | |
| 3104 | 3104 | static void kvm_cpu_vmxon(u64 addr) |
| 3105 | 3105 | { |
| 3106 | + intel_pt_handle_vmx(1); | |
| 3107 | + | |
| 3106 | 3108 | asm volatile (ASM_VMX_VMXON_RAX |
| 3107 | 3109 | : : "a"(&addr), "m"(addr) |
| 3108 | 3110 | : "memory", "cc"); |
| @@ -3172,6 +3174,8 @@ static void vmclear_local_loaded_vmcss(void) · 63 unmodified lines | ||
| 3172 | 3174 | static void kvm_cpu_vmxoff(void) |
| 3173 | 3175 | { |
| 3174 | 3176 | asm volatile (__ex(ASM_VMX_VMXOFF) : : : "cc"); |
| 3177 | + | |
| 3178 | + intel_pt_handle_vmx(0); | |
| 3175 | 3179 | } |
| 3176 | 3180 | |
| 3177 | 3181 | static void hardware_disable(void) |
| @@ -32,8 +32,9 @@ early_param("noexec", noexec_setup); · 31 unmodified lines | ||
| 32 | 32 | |
| 33 | 33 | void x86_configure_nx(void) |
| 34 | 34 | { |
| 35 | − /* If disable_nx is set, clear NX on all new mappings going forward. */ | |
| 36 | − if (disable_nx) | |
| 35 | + if (boot_cpu_has(X86_FEATURE_NX) && !disable_nx) | |
| 36 | + __supported_pte_mask |= _PAGE_NX; | |
| 37 | + else | |
| 37 | 38 | __supported_pte_mask &= ~_PAGE_NX; |
| 38 | 39 | } |
| 39 | 40 | |
| @@ -27,6 +27,12 @@ static bool xen_pvspin = true; · 26 unmodified lines | ||
| 27 | 27 | |
| 28 | 28 | static void xen_qlock_kick(int cpu) |
| 29 | 29 | { |
| 30 | + int irq = per_cpu(lock_kicker_irq, cpu); | |
| 31 | + | |
| 32 | + /* Don't kick if the target's kicker interrupt is not initialized. */ | |
| 33 | + if (irq == -1) | |
| 34 | + return; | |
| 35 | + | |
| 30 | 36 | xen_send_IPI_one(cpu, XEN_SPIN_UNLOCK_VECTOR); |
| 31 | 37 | } |
| 32 | 38 | |
| @@ -538,7 +538,6 @@ static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id, · 537 unmodified lines | ||
| 538 | 538 | u8 *order, u64 *snap_size); |
| 539 | 539 | static int _rbd_dev_v2_snap_features(struct rbd_device *rbd_dev, u64 snap_id, |
| 540 | 540 | u64 *snap_features); |
| 541 | −static u64 rbd_snap_id_by_name(struct rbd_device *rbd_dev, const char *name); | |
| 542 | 541 | |
| 543 | 542 | static int rbd_open(struct block_device *bdev, fmode_t mode) |
| 544 | 543 | { |
| @@ -3127,9 +3126,6 @@ static void rbd_watch_cb(u64 ver, u64 notify_id, u8 opcode, void *data) · 2582 unmodified lines | ||
| 3127 | 3126 | struct rbd_device *rbd_dev = (struct rbd_device *)data; |
| 3128 | 3127 | int ret; |
| 3129 | 3128 | |
| 3130 | − if (!rbd_dev) | |
| 3131 | − return; | |
| 3132 | − | |
| 3133 | 3129 | dout("%s: \"%s\" notify_id %llu opcode %u\n", __func__, |
| 3134 | 3130 | rbd_dev->header_name, (unsigned long long)notify_id, |
| 3135 | 3131 | (unsigned int)opcode); |
| @@ -3263,6 +3259,9 @@ static void rbd_dev_header_unwatch_sync(struct rbd_device *rbd_dev) · 127 unmodified lines | ||
| 3263 | 3259 | |
| 3264 | 3260 | ceph_osdc_cancel_event(rbd_dev->watch_event); |
| 3265 | 3261 | rbd_dev->watch_event = NULL; |
| 3262 | + | |
| 3263 | + dout("%s flushing notifies\n", __func__); | |
| 3264 | + ceph_osdc_flush_notifies(&rbd_dev->rbd_client->client->osdc); | |
| 3266 | 3265 | } |
| 3267 | 3266 | |
| 3268 | 3267 | /* |
| @@ -3642,21 +3641,14 @@ static void rbd_exists_validate(struct rbd_device *rbd_dev) · 373 unmodified lines | ||
| 3642 | 3641 | static void rbd_dev_update_size(struct rbd_device *rbd_dev) |
| 3643 | 3642 | { |
| 3644 | 3643 | sector_t size; |
| 3645 | − bool removing; | |
| 3646 | 3644 | |
| 3647 | 3645 | /* |
| 3648 | − * Don't hold the lock while doing disk operations, | |
| 3649 | − * or lock ordering will conflict with the bdev mutex via: | |
| 3650 | − * rbd_add() -> blkdev_get() -> rbd_open() | |
| 3646 | + * If EXISTS is not set, rbd_dev->disk may be NULL, so don't | |
| 3647 | + * try to update its size. If REMOVING is set, updating size | |
| 3648 | + * is just useless work since the device can't be opened. | |
| 3651 | 3649 | */ |
| 3652 | − spin_lock_irq(&rbd_dev->lock); | |
| 3653 | − removing = test_bit(RBD_DEV_FLAG_REMOVING, &rbd_dev->flags); | |
| 3654 | − spin_unlock_irq(&rbd_dev->lock); | |
| 3655 | − /* | |
| 3656 | − * If the device is being removed, rbd_dev->disk has | |
| 3657 | − * been destroyed, so don't try to update its size | |
| 3658 | − */ | |
| 3659 | − if (!removing) { | |
| 3650 | + if (test_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags) && | |
| 3651 | + !test_bit(RBD_DEV_FLAG_REMOVING, &rbd_dev->flags)) { | |
| 3660 | 3652 | size = (sector_t)rbd_dev->mapping.size / SECTOR_SIZE; |
| 3661 | 3653 | dout("setting size to %llu sectors", (unsigned long long)size); |
| 3662 | 3654 | set_capacity(rbd_dev->disk, size); |
| @@ -4191,7 +4183,7 @@ static int _rbd_dev_v2_snap_features(struct rbd_device *rbd_dev, u64 snap_id, · 528 unmodified lines | ||
| 4191 | 4183 | __le64 features; |
| 4192 | 4184 | __le64 incompat; |
| 4193 | 4185 | } __attribute__ ((packed)) features_buf = { 0 }; |
| 4194 | − u64 incompat; | |
| 4186 | + u64 unsup; | |
| 4195 | 4187 | int ret; |
| 4196 | 4188 | |
| 4197 | 4189 | ret = rbd_obj_method_sync(rbd_dev, rbd_dev->header_name, |
| @@ -4204,9 +4196,12 @@ static int _rbd_dev_v2_snap_features(struct rbd_device *rbd_dev, u64 snap_id, · 6 unmodified lines | ||
| 4204 | 4196 | if (ret < sizeof (features_buf)) |
| 4205 | 4197 | return -ERANGE; |
| 4206 | 4198 | |
| 4207 | − incompat = le64_to_cpu(features_buf.incompat); | |
| 4208 | − if (incompat & ~RBD_FEATURES_SUPPORTED) | |
| 4199 | + unsup = le64_to_cpu(features_buf.incompat) & ~RBD_FEATURES_SUPPORTED; | |
| 4200 | + if (unsup) { | |
| 4201 | + rbd_warn(rbd_dev, "image uses unsupported features: 0x%llx", | |
| 4202 | + unsup); | |
| 4209 | 4203 | return -ENXIO; |
| 4204 | + } | |
| 4210 | 4205 | |
| 4211 | 4206 | *snap_features = le64_to_cpu(features_buf.features); |
| 4212 | 4207 | |
| @@ -5187,6 +5182,10 @@ out_err: · 974 unmodified lines | ||
| 5187 | 5182 | return ret; |
| 5188 | 5183 | } |
| 5189 | 5184 | |
| 5185 | +/* | |
| 5186 | + * rbd_dev->header_rwsem must be locked for write and will be unlocked | |
| 5187 | + * upon return. | |
| 5188 | + */ | |
| 5190 | 5189 | static int rbd_dev_device_setup(struct rbd_device *rbd_dev) |
| 5191 | 5190 | { |
| 5192 | 5191 | int ret; |
| @@ -5195,7 +5194,7 @@ static int rbd_dev_device_setup(struct rbd_device *rbd_dev) · 2 unmodified lines | ||
| 5195 | 5194 | |
| 5196 | 5195 | ret = rbd_dev_id_get(rbd_dev); |
| 5197 | 5196 | if (ret) |
| 5198 | − return ret; | |
| 5197 | + goto err_out_unlock; | |
| 5199 | 5198 | |
| 5200 | 5199 | BUILD_BUG_ON(DEV_NAME_LEN |
| 5201 | 5200 | < sizeof (RBD_DRV_NAME) + MAX_INT_FORMAT_WIDTH); |
| @@ -5236,8 +5235,9 @@ static int rbd_dev_device_setup(struct rbd_device *rbd_dev) · 34 unmodified lines | ||
| 5236 | 5235 | /* Everything's ready. Announce the disk to the world. */ |
| 5237 | 5236 | |
| 5238 | 5237 | set_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags); |
| 5239 | − add_disk(rbd_dev->disk); | |
| 5238 | + up_write(&rbd_dev->header_rwsem); | |
| 5240 | 5239 | |
| 5240 | + add_disk(rbd_dev->disk); | |
| 5241 | 5241 | pr_info("%s: added with size 0x%llx\n", rbd_dev->disk->disk_name, |
| 5242 | 5242 | (unsigned long long) rbd_dev->mapping.size); |
| 5243 | 5243 | |
| @@ -5252,6 +5252,8 @@ err_out_blkdev: · 8 unmodified lines | ||
| 5252 | 5252 | unregister_blkdev(rbd_dev->major, rbd_dev->name); |
| 5253 | 5253 | err_out_id: |
| 5254 | 5254 | rbd_dev_id_put(rbd_dev); |
| 5255 | +err_out_unlock: | |
| 5256 | + up_write(&rbd_dev->header_rwsem); | |
| 5255 | 5257 | return ret; |
| 5256 | 5258 | } |
| 5257 | 5259 | |
| @@ -5442,6 +5444,7 @@ static ssize_t do_rbd_add(struct bus_type *bus, · 184 unmodified lines | ||
| 5442 | 5444 | spec = NULL; /* rbd_dev now owns this */ |
| 5443 | 5445 | rbd_opts = NULL; /* rbd_dev now owns this */ |
| 5444 | 5446 | |
| 5447 | + down_write(&rbd_dev->header_rwsem); | |
| 5445 | 5448 | rc = rbd_dev_image_probe(rbd_dev, 0); |
| 5446 | 5449 | if (rc < 0) |
| 5447 | 5450 | goto err_out_rbd_dev; |
| @@ -5471,6 +5474,7 @@ out: · 23 unmodified lines | ||
| 5471 | 5474 | return rc; |
| 5472 | 5475 | |
| 5473 | 5476 | err_out_rbd_dev: |
| 5477 | + up_write(&rbd_dev->header_rwsem); | |
| 5474 | 5478 | rbd_dev_destroy(rbd_dev); |
| 5475 | 5479 | err_out_client: |
| 5476 | 5480 | rbd_put_client(rbdc); |
| @@ -5577,12 +5581,6 @@ static ssize_t do_rbd_remove(struct bus_type *bus, · 100 unmodified lines | ||
| 5577 | 5581 | return ret; |
| 5578 | 5582 | |
| 5579 | 5583 | rbd_dev_header_unwatch_sync(rbd_dev); |
| 5580 | − /* | |
| 5581 | − * flush remaining watch callbacks - these must be complete | |
| 5582 | − * before the osd_client is shutdown | |
| 5583 | − */ | |
| 5584 | − dout("%s: flushing notifies", __func__); | |
| 5585 | − ceph_osdc_flush_notifies(&rbd_dev->rbd_client->client->osdc); | |
| 5586 | 5584 | |
| 5587 | 5585 | /* |
| 5588 | 5586 | * Don't free anything from rbd_dev->disk until after all |
| @@ -394,7 +394,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) · 393 unmodified lines | ||
| 394 | 394 | clk[IMX6QDL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1", 2, 7); |
| 395 | 395 | } else { |
| 396 | 396 | clk[IMX6QDL_CLK_ECSPI_ROOT] = imx_clk_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6); |
| 397 | − clk[IMX6QDL_CLK_CAN_ROOT] = imx_clk_divider("can_root", "pll3_60", base + 0x20, 2, 6); | |
| 397 | + clk[IMX6QDL_CLK_CAN_ROOT] = imx_clk_divider("can_root", "pll3_60m", base + 0x20, 2, 6); | |
| 398 | 398 | clk[IMX6QDL_CLK_IPG_PER] = imx_clk_fixup_divider("ipg_per", "ipg", base + 0x1c, 0, 6, imx_cscmr1_fixup); |
| 399 | 399 | clk[IMX6QDL_CLK_UART_SERIAL_PODF] = imx_clk_divider("uart_serial_podf", "pll3_80m", base + 0x24, 0, 6); |
| 400 | 400 | clk[IMX6QDL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); |
| @@ -193,12 +193,8 @@ unsigned int dbs_update(struct cpufreq_policy *policy) · 192 unmodified lines | ||
| 193 | 193 | wall_time = cur_wall_time - j_cdbs->prev_cpu_wall; |
| 194 | 194 | j_cdbs->prev_cpu_wall = cur_wall_time; |
| 195 | 195 | |
| 196 | − if (cur_idle_time <= j_cdbs->prev_cpu_idle) { | |
| 197 | − idle_time = 0; | |
| 198 | − } else { | |
| 199 | − idle_time = cur_idle_time - j_cdbs->prev_cpu_idle; | |
| 200 | − j_cdbs->prev_cpu_idle = cur_idle_time; | |
| 201 | − } | |
| 196 | + idle_time = cur_idle_time - j_cdbs->prev_cpu_idle; | |
| 197 | + j_cdbs->prev_cpu_idle = cur_idle_time; | |
| 202 | 198 | |
| 203 | 199 | if (ignore_nice) { |
| 204 | 200 | u64 cur_nice = kcpustat_cpu(j).cpustat[CPUTIME_NICE]; |
| @@ -813,6 +813,11 @@ static int core_get_max_pstate(void) · 812 unmodified lines | ||
| 813 | 813 | if (err) |
| 814 | 814 | goto skip_tar; |
| 815 | 815 | |
| 816 | + /* For level 1 and 2, bits[23:16] contain the ratio */ | |
| 817 | + if (tdp_ctrl) | |
| 818 | + tdp_ratio >>= 16; | |
| 819 | + | |
| 820 | + tdp_ratio &= 0xff; /* ratios are only 8 bits long */ | |
| 816 | 821 | if (tdp_ratio - 1 == tar) { |
| 817 | 822 | max_pstate = tar; |
| 818 | 823 | pr_debug("max_pstate=TAC %x\n", max_pstate); |
| @@ -1866,7 +1866,7 @@ static int i7core_mce_check_error(struct notifier_block *nb, unsigned long val, · 1865 unmodified lines | ||
| 1866 | 1866 | |
| 1867 | 1867 | i7_dev = get_i7core_dev(mce->socketid); |
| 1868 | 1868 | if (!i7_dev) |
| 1869 | − return NOTIFY_BAD; | |
| 1869 | + return NOTIFY_DONE; | |
| 1870 | 1870 | |
| 1871 | 1871 | mci = i7_dev->mci; |
| 1872 | 1872 | pvt = mci->pvt_info; |
| @@ -3168,7 +3168,7 @@ static int sbridge_mce_check_error(struct notifier_block *nb, unsigned long val, · 3167 unmodified lines | ||
| 3168 | 3168 | |
| 3169 | 3169 | mci = get_mci_for_node_id(mce->socketid); |
| 3170 | 3170 | if (!mci) |
| 3171 | − return NOTIFY_BAD; | |
| 3171 | + return NOTIFY_DONE; | |
| 3172 | 3172 | pvt = mci->pvt_info; |
| 3173 | 3173 | |
| 3174 | 3174 | /* |
| @@ -202,29 +202,44 @@ static const struct variable_validate variable_validate[] = { · 201 unmodified lines | ||
| 202 | 202 | { NULL_GUID, "", NULL }, |
| 203 | 203 | }; |
| 204 | 204 | |
| 205 | +/* | |
| 206 | + * Check if @var_name matches the pattern given in @match_name. | |
| 207 | + * | |
| 208 | + * @var_name: an array of @len non-NUL characters. | |
| 209 | + * @match_name: a NUL-terminated pattern string, optionally ending in "*". A | |
| 210 | + * final "*" character matches any trailing characters @var_name, | |
| 211 | + * including the case when there are none left in @var_name. | |
| 212 | + * @match: on output, the number of non-wildcard characters in @match_name | |
| 213 | + * that @var_name matches, regardless of the return value. | |
| 214 | + * @return: whether @var_name fully matches @match_name. | |
| 215 | + */ | |
| 205 | 216 | static bool |
| 206 | 217 | variable_matches(const char *var_name, size_t len, const char *match_name, |
| 207 | 218 | int *match) |
| 208 | 219 | { |
| 209 | 220 | for (*match = 0; ; (*match)++) { |
| 210 | 221 | char c = match_name[*match]; |
| 211 | − char u = var_name[*match]; | |
| 212 | 222 | |
| 213 | − /* Wildcard in the matching name means we've matched */ | |
| 214 | − if (c == '*') | |
| 223 | + switch (c) { | |
| 224 | + case '*': | |
| 225 | + /* Wildcard in @match_name means we've matched. */ | |
| 215 | 226 | return true; |
| 216 | 227 | |
| 217 | − /* Case sensitive match */ | |
| 218 | − if (!c && *match == len) | |
| 219 | − return true; | |
| 228 | + case '\0': | |
| 229 | + /* @match_name has ended. Has @var_name too? */ | |
| 230 | + return (*match == len); | |
| 220 | 231 | |
| 221 | − if (c != u) | |
| 232 | + default: | |
| 233 | + /* | |
| 234 | + * We've reached a non-wildcard char in @match_name. | |
| 235 | + * Continue only if there's an identical character in | |
| 236 | + * @var_name. | |
| 237 | + */ | |
| 238 | + if (*match < len && c == var_name[*match]) | |
| 239 | + continue; | |
| 222 | 240 | return false; |
| 223 | − | |
| 224 | − if (!c) | |
| 225 | − return true; | |
| 241 | + } | |
| 226 | 242 | } |
| 227 | − return true; | |
| 228 | 243 | } |
| 229 | 244 | |
| 230 | 245 | bool |
| @@ -196,44 +196,6 @@ static int gpio_rcar_irq_set_wake(struct irq_data *d, unsigned int on) · 195 unmodified lines | ||
| 196 | 196 | return 0; |
| 197 | 197 | } |
| 198 | 198 | |
| 199 | −static void gpio_rcar_irq_bus_lock(struct irq_data *d) | |
| 200 | −{ | |
| 201 | − struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | |
| 202 | − struct gpio_rcar_priv *p = gpiochip_get_data(gc); | |
| 203 | − | |
| 204 | − pm_runtime_get_sync(&p->pdev->dev); | |
| 205 | −} | |
| 206 | − | |
| 207 | −static void gpio_rcar_irq_bus_sync_unlock(struct irq_data *d) | |
| 208 | −{ | |
| 209 | − struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | |
| 210 | − struct gpio_rcar_priv *p = gpiochip_get_data(gc); | |
| 211 | − | |
| 212 | − pm_runtime_put(&p->pdev->dev); | |
| 213 | −} | |
| 214 | − | |
| 215 | − | |
| 216 | −static int gpio_rcar_irq_request_resources(struct irq_data *d) | |
| 217 | −{ | |
| 218 | − struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | |
| 219 | − struct gpio_rcar_priv *p = gpiochip_get_data(gc); | |
| 220 | − int error; | |
| 221 | − | |
| 222 | − error = pm_runtime_get_sync(&p->pdev->dev); | |
| 223 | − if (error < 0) | |
| 224 | − return error; | |
| 225 | − | |
| 226 | − return 0; | |
| 227 | −} | |
| 228 | − | |
| 229 | −static void gpio_rcar_irq_release_resources(struct irq_data *d) | |
| 230 | −{ | |
| 231 | − struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | |
| 232 | − struct gpio_rcar_priv *p = gpiochip_get_data(gc); | |
| 233 | − | |
| 234 | − pm_runtime_put(&p->pdev->dev); | |
| 235 | −} | |
| 236 | − | |
| 237 | 199 | static irqreturn_t gpio_rcar_irq_handler(int irq, void *dev_id) |
| 238 | 200 | { |
| 239 | 201 | struct gpio_rcar_priv *p = dev_id; |
| @@ -280,32 +242,18 @@ static void gpio_rcar_config_general_input_output_mode(struct gpio_chip *chip, · 40 unmodified lines | ||
| 280 | 242 | |
| 281 | 243 | static int gpio_rcar_request(struct gpio_chip *chip, unsigned offset) |
| 282 | 244 | { |
| 283 | − struct gpio_rcar_priv *p = gpiochip_get_data(chip); | |
| 284 | − int error; | |
| 285 | − | |
| 286 | − error = pm_runtime_get_sync(&p->pdev->dev); | |
| 287 | − if (error < 0) | |
| 288 | − return error; | |
| 289 | − | |
| 290 | − error = pinctrl_request_gpio(chip->base + offset); | |
| 291 | − if (error) | |
| 292 | − pm_runtime_put(&p->pdev->dev); | |
| 293 | − | |
| 294 | − return error; | |
| 245 | + return pinctrl_request_gpio(chip->base + offset); | |
| 295 | 246 | } |
| 296 | 247 | |
| 297 | 248 | static void gpio_rcar_free(struct gpio_chip *chip, unsigned offset) |
| 298 | 249 | { |
| 299 | − struct gpio_rcar_priv *p = gpiochip_get_data(chip); | |
| 300 | − | |
| 301 | 250 | pinctrl_free_gpio(chip->base + offset); |
| 302 | 251 | |
| 303 | − /* Set the GPIO as an input to ensure that the next GPIO request won't | |
| 252 | + /* | |
| 253 | + * Set the GPIO as an input to ensure that the next GPIO request won't | |
| 304 | 254 | * drive the GPIO pin as an output. |
| 305 | 255 | */ |
| 306 | 256 | gpio_rcar_config_general_input_output_mode(chip, offset, false); |
| 307 | − | |
| 308 | − pm_runtime_put(&p->pdev->dev); | |
| 309 | 257 | } |
| 310 | 258 | |
| 311 | 259 | static int gpio_rcar_direction_input(struct gpio_chip *chip, unsigned offset) |
| @@ -452,6 +400,7 @@ static int gpio_rcar_probe(struct platform_device *pdev) · 140 unmodified lines | ||
| 452 | 400 | } |
| 453 | 401 | |
| 454 | 402 | pm_runtime_enable(dev); |
| 403 | + pm_runtime_get_sync(dev); | |
| 455 | 404 | |
| 456 | 405 | io = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 457 | 406 | irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
| @@ -488,10 +437,6 @@ static int gpio_rcar_probe(struct platform_device *pdev) · 30 unmodified lines | ||
| 488 | 437 | irq_chip->irq_unmask = gpio_rcar_irq_enable; |
| 489 | 438 | irq_chip->irq_set_type = gpio_rcar_irq_set_type; |
| 490 | 439 | irq_chip->irq_set_wake = gpio_rcar_irq_set_wake; |
| 491 | − irq_chip->irq_bus_lock = gpio_rcar_irq_bus_lock; | |
| 492 | − irq_chip->irq_bus_sync_unlock = gpio_rcar_irq_bus_sync_unlock; | |
| 493 | − irq_chip->irq_request_resources = gpio_rcar_irq_request_resources; | |
| 494 | − irq_chip->irq_release_resources = gpio_rcar_irq_release_resources; | |
| 495 | 440 | irq_chip->flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_MASK_ON_SUSPEND; |
| 496 | 441 | |
| 497 | 442 | ret = gpiochip_add_data(gpio_chip, p); |
| @@ -522,6 +467,7 @@ static int gpio_rcar_probe(struct platform_device *pdev) · 24 unmodified lines | ||
| 522 | 467 | err1: |
| 523 | 468 | gpiochip_remove(gpio_chip); |
| 524 | 469 | err0: |
| 470 | + pm_runtime_put(dev); | |
| 525 | 471 | pm_runtime_disable(dev); |
| 526 | 472 | return ret; |
| 527 | 473 | } |
| @@ -532,6 +478,7 @@ static int gpio_rcar_remove(struct platform_device *pdev) · 4 unmodified lines | ||
| 532 | 478 | |
| 533 | 479 | gpiochip_remove(&p->gpio_chip); |
| 534 | 480 | |
| 481 | + pm_runtime_put(&pdev->dev); | |
| 535 | 482 | pm_runtime_disable(&pdev->dev); |
| 536 | 483 | return 0; |
| 537 | 484 | } |
| @@ -977,7 +977,7 @@ bool acpi_can_fallback_to_crs(struct acpi_device *adev, const char *con_id) · 976 unmodified lines | ||
| 977 | 977 | lookup = kmalloc(sizeof(*lookup), GFP_KERNEL); |
| 978 | 978 | if (lookup) { |
| 979 | 979 | lookup->adev = adev; |
| 980 | − lookup->con_id = con_id; | |
| 980 | + lookup->con_id = kstrdup(con_id, GFP_KERNEL); | |
| 981 | 981 | list_add_tail(&lookup->node, &acpi_crs_lookup_list); |
| 982 | 982 | } |
| 983 | 983 | } |
| @@ -63,10 +63,6 @@ bool amdgpu_has_atpx(void) { · 62 unmodified lines | ||
| 63 | 63 | return amdgpu_atpx_priv.atpx_detected; |
| 64 | 64 | } |
| 65 | 65 | |
| 66 | −bool amdgpu_has_atpx_dgpu_power_cntl(void) { | |
| 67 | − return amdgpu_atpx_priv.atpx.functions.power_cntl; | |
| 68 | −} | |
| 69 | − | |
| 70 | 66 | /** |
| 71 | 67 | * amdgpu_atpx_call - call an ATPX method |
| 72 | 68 | * |
| @@ -146,6 +142,13 @@ static void amdgpu_atpx_parse_functions(struct amdgpu_atpx_functions *f, u32 mas · 73 unmodified lines | ||
| 146 | 142 | */ |
| 147 | 143 | static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx) |
| 148 | 144 | { |
| 145 | + /* make sure required functions are enabled */ | |
| 146 | + /* dGPU power control is required */ | |
| 147 | + if (atpx->functions.power_cntl == false) { | |
| 148 | + printk("ATPX dGPU power cntl not present, forcing\n"); | |
| 149 | + atpx->functions.power_cntl = true; | |
| 150 | + } | |
| 151 | + | |
| 149 | 152 | if (atpx->functions.px_params) { |
| 150 | 153 | union acpi_object *info; |
| 151 | 154 | struct atpx_px_params output; |
| @@ -62,12 +62,6 @@ static const char *amdgpu_asic_name[] = { · 61 unmodified lines | ||
| 62 | 62 | "LAST", |
| 63 | 63 | }; |
| 64 | 64 | |
| 65 | −#if defined(CONFIG_VGA_SWITCHEROO) | |
| 66 | −bool amdgpu_has_atpx_dgpu_power_cntl(void); | |
| 67 | −#else | |
| 68 | −static inline bool amdgpu_has_atpx_dgpu_power_cntl(void) { return false; } | |
| 69 | −#endif | |
| 70 | − | |
| 71 | 65 | bool amdgpu_device_is_px(struct drm_device *dev) |
| 72 | 66 | { |
| 73 | 67 | struct amdgpu_device *adev = dev->dev_private; |
| @@ -1485,7 +1479,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, · 1411 unmodified lines | ||
| 1485 | 1479 | |
| 1486 | 1480 | if (amdgpu_runtime_pm == 1) |
| 1487 | 1481 | runtime = true; |
| 1488 | − if (amdgpu_device_is_px(ddev) && amdgpu_has_atpx_dgpu_power_cntl()) | |
| 1482 | + if (amdgpu_device_is_px(ddev)) | |
| 1489 | 1483 | runtime = true; |
| 1490 | 1484 | vga_switcheroo_register_client(adev->pdev, &amdgpu_switcheroo_ops, runtime); |
| 1491 | 1485 | if (runtime) |
| @@ -910,7 +910,10 @@ static int gmc_v7_0_late_init(void *handle) · 909 unmodified lines | ||
| 910 | 910 | { |
| 911 | 911 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 912 | 912 | |
| 913 | − return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0); | |
| 913 | + if (amdgpu_vm_fault_stop != AMDGPU_VM_FAULT_STOP_ALWAYS) | |
| 914 | + return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0); | |
| 915 | + else | |
| 916 | + return 0; | |
| 914 | 917 | } |
| 915 | 918 | |
| 916 | 919 | static int gmc_v7_0_sw_init(void *handle) |
| @@ -870,7 +870,10 @@ static int gmc_v8_0_late_init(void *handle) · 869 unmodified lines | ||
| 870 | 870 | { |
| 871 | 871 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 872 | 872 | |
| 873 | − return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0); | |
| 873 | + if (amdgpu_vm_fault_stop != AMDGPU_VM_FAULT_STOP_ALWAYS) | |
| 874 | + return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0); | |
| 875 | + else | |
| 876 | + return 0; | |
| 874 | 877 | } |
| 875 | 878 | |
| 876 | 879 | #define mmMC_SEQ_MISC0_FIJI 0xA71 |
| @@ -1796,6 +1796,11 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr) · 1795 unmodified lines | ||
| 1796 | 1796 | req_payload.start_slot = cur_slots; |
| 1797 | 1797 | if (mgr->proposed_vcpis[i]) { |
| 1798 | 1798 | port = container_of(mgr->proposed_vcpis[i], struct drm_dp_mst_port, vcpi); |
| 1799 | + port = drm_dp_get_validated_port_ref(mgr, port); | |
| 1800 | + if (!port) { | |
| 1801 | + mutex_unlock(&mgr->payload_lock); | |
| 1802 | + return -EINVAL; | |
| 1803 | + } | |
| 1799 | 1804 | req_payload.num_slots = mgr->proposed_vcpis[i]->num_slots; |
| 1800 | 1805 | req_payload.vcpi = mgr->proposed_vcpis[i]->vcpi; |
| 1801 | 1806 | } else { |
| @@ -1823,6 +1828,9 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr) · 21 unmodified lines | ||
| 1823 | 1828 | mgr->payloads[i].payload_state = req_payload.payload_state; |
| 1824 | 1829 | } |
| 1825 | 1830 | cur_slots += req_payload.num_slots; |
| 1831 | + | |
| 1832 | + if (port) | |
| 1833 | + drm_dp_put_port(port); | |
| 1826 | 1834 | } |
| 1827 | 1835 | |
| 1828 | 1836 | for (i = 0; i < mgr->max_payloads; i++) { |
| @@ -2128,6 +2136,8 @@ int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr) · 299 unmodified lines | ||
| 2128 | 2136 | |
| 2129 | 2137 | if (mgr->mst_primary) { |
| 2130 | 2138 | int sret; |
| 2139 | + u8 guid[16]; | |
| 2140 | + | |
| 2131 | 2141 | sret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd, DP_RECEIVER_CAP_SIZE); |
| 2132 | 2142 | if (sret != DP_RECEIVER_CAP_SIZE) { |
| 2133 | 2143 | DRM_DEBUG_KMS("dpcd read failed - undocked during suspend?\n"); |
| @@ -2142,6 +2152,16 @@ int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr) · 8 unmodified lines | ||
| 2142 | 2152 | ret = -1; |
| 2143 | 2153 | goto out_unlock; |
| 2144 | 2154 | } |
| 2155 | + | |
| 2156 | + /* Some hubs forget their guids after they resume */ | |
| 2157 | + sret = drm_dp_dpcd_read(mgr->aux, DP_GUID, guid, 16); | |
| 2158 | + if (sret != 16) { | |
| 2159 | + DRM_DEBUG_KMS("dpcd read failed - undocked during suspend?\n"); | |
| 2160 | + ret = -1; | |
| 2161 | + goto out_unlock; | |
| 2162 | + } | |
| 2163 | + drm_dp_check_mstb_guid(mgr->mst_primary, guid); | |
| 2164 | + | |
| 2145 | 2165 | ret = 0; |
| 2146 | 2166 | } else |
| 2147 | 2167 | ret = -1; |
| @@ -572,6 +572,24 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu) · 571 unmodified lines | ||
| 572 | 572 | goto fail; |
| 573 | 573 | } |
| 574 | 574 | |
| 575 | + /* | |
| 576 | + * Set the GPU linear window to be at the end of the DMA window, where | |
| 577 | + * the CMA area is likely to reside. This ensures that we are able to | |
| 578 | + * map the command buffers while having the linear window overlap as | |
| 579 | + * much RAM as possible, so we can optimize mappings for other buffers. | |
| 580 | + * | |
| 581 | + * For 3D cores only do this if MC2.0 is present, as with MC1.0 it leads | |
| 582 | + * to different views of the memory on the individual engines. | |
| 583 | + */ | |
| 584 | + if (!(gpu->identity.features & chipFeatures_PIPE_3D) || | |
| 585 | + (gpu->identity.minor_features0 & chipMinorFeatures0_MC20)) { | |
| 586 | + u32 dma_mask = (u32)dma_get_required_mask(gpu->dev); | |
| 587 | + if (dma_mask < PHYS_OFFSET + SZ_2G) | |
| 588 | + gpu->memory_base = PHYS_OFFSET; | |
| 589 | + else | |
| 590 | + gpu->memory_base = dma_mask - SZ_2G + 1; | |
| 591 | + } | |
| 592 | + | |
| 575 | 593 | ret = etnaviv_hw_reset(gpu); |
| 576 | 594 | if (ret) |
| 577 | 595 | goto fail; |
| @@ -1566,7 +1584,6 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev) · 988 unmodified lines | ||
| 1566 | 1584 | { |
| 1567 | 1585 | struct device *dev = &pdev->dev; |
| 1568 | 1586 | struct etnaviv_gpu *gpu; |
| 1569 | − u32 dma_mask; | |
| 1570 | 1587 | int err = 0; |
| 1571 | 1588 | |
| 1572 | 1589 | gpu = devm_kzalloc(dev, sizeof(*gpu), GFP_KERNEL); |
| @@ -1576,18 +1593,6 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev) · 3 unmodified lines | ||
| 1576 | 1593 | gpu->dev = &pdev->dev; |
| 1577 | 1594 | mutex_init(&gpu->lock); |
| 1578 | 1595 | |
| 1579 | − /* | |
| 1580 | − * Set the GPU linear window to be at the end of the DMA window, where | |
| 1581 | − * the CMA area is likely to reside. This ensures that we are able to | |
| 1582 | − * map the command buffers while having the linear window overlap as | |
| 1583 | − * much RAM as possible, so we can optimize mappings for other buffers. | |
| 1584 | − */ | |
| 1585 | − dma_mask = (u32)dma_get_required_mask(dev); | |
| 1586 | − if (dma_mask < PHYS_OFFSET + SZ_2G) | |
| 1587 | − gpu->memory_base = PHYS_OFFSET; | |
| 1588 | − else | |
| 1589 | − gpu->memory_base = dma_mask - SZ_2G + 1; | |
| 1590 | − | |
| 1591 | 1596 | /* Map registers: */ |
| 1592 | 1597 | gpu->mmio = etnaviv_ioremap(pdev, NULL, dev_name(gpu->dev)); |
| 1593 | 1598 | if (IS_ERR(gpu->mmio)) |
| @@ -2608,10 +2608,152 @@ static void evergreen_agp_enable(struct radeon_device *rdev) · 2607 unmodified lines | ||
| 2608 | 2608 | WREG32(VM_CONTEXT1_CNTL, 0); |
| 2609 | 2609 | } |
| 2610 | 2610 | |
| 2611 | +static const unsigned ni_dig_offsets[] = | |
| 2612 | +{ | |
| 2613 | + NI_DIG0_REGISTER_OFFSET, | |
| 2614 | + NI_DIG1_REGISTER_OFFSET, | |
| 2615 | + NI_DIG2_REGISTER_OFFSET, | |
| 2616 | + NI_DIG3_REGISTER_OFFSET, | |
| 2617 | + NI_DIG4_REGISTER_OFFSET, | |
| 2618 | + NI_DIG5_REGISTER_OFFSET | |
| 2619 | +}; | |
| 2620 | + | |
| 2621 | +static const unsigned ni_tx_offsets[] = | |
| 2622 | +{ | |
| 2623 | + NI_DCIO_UNIPHY0_UNIPHY_TX_CONTROL1, | |
| 2624 | + NI_DCIO_UNIPHY1_UNIPHY_TX_CONTROL1, | |
| 2625 | + NI_DCIO_UNIPHY2_UNIPHY_TX_CONTROL1, | |
| 2626 | + NI_DCIO_UNIPHY3_UNIPHY_TX_CONTROL1, | |
| 2627 | + NI_DCIO_UNIPHY4_UNIPHY_TX_CONTROL1, | |
| 2628 | + NI_DCIO_UNIPHY5_UNIPHY_TX_CONTROL1 | |
| 2629 | +}; | |
| 2630 | + | |
| 2631 | +static const unsigned evergreen_dp_offsets[] = | |
| 2632 | +{ | |
| 2633 | + EVERGREEN_DP0_REGISTER_OFFSET, | |
| 2634 | + EVERGREEN_DP1_REGISTER_OFFSET, | |
| 2635 | + EVERGREEN_DP2_REGISTER_OFFSET, | |
| 2636 | + EVERGREEN_DP3_REGISTER_OFFSET, | |
| 2637 | + EVERGREEN_DP4_REGISTER_OFFSET, | |
| 2638 | + EVERGREEN_DP5_REGISTER_OFFSET | |
| 2639 | +}; | |
| 2640 | + | |
| 2641 | + | |
| 2642 | +/* | |
| 2643 | + * Assumption is that EVERGREEN_CRTC_MASTER_EN enable for requested crtc | |
| 2644 | + * We go from crtc to connector and it is not relible since it | |
| 2645 | + * should be an opposite direction .If crtc is enable then | |
| 2646 | + * find the dig_fe which selects this crtc and insure that it enable. | |
| 2647 | + * if such dig_fe is found then find dig_be which selects found dig_be and | |
| 2648 | + * insure that it enable and in DP_SST mode. | |
| 2649 | + * if UNIPHY_PLL_CONTROL1.enable then we should disconnect timing | |
| 2650 | + * from dp symbols clocks . | |
| 2651 | + */ | |
| 2652 | +static bool evergreen_is_dp_sst_stream_enabled(struct radeon_device *rdev, | |
| 2653 | + unsigned crtc_id, unsigned *ret_dig_fe) | |
| 2654 | +{ | |
| 2655 | + unsigned i; | |
| 2656 | + unsigned dig_fe; | |
| 2657 | + unsigned dig_be; | |
| 2658 | + unsigned dig_en_be; | |
| 2659 | + unsigned uniphy_pll; | |
| 2660 | + unsigned digs_fe_selected; | |
| 2661 | + unsigned dig_be_mode; | |
| 2662 | + unsigned dig_fe_mask; | |
| 2663 | + bool is_enabled = false; | |
| 2664 | + bool found_crtc = false; | |
| 2665 | + | |
| 2666 | + /* loop through all running dig_fe to find selected crtc */ | |
| 2667 | + for (i = 0; i < ARRAY_SIZE(ni_dig_offsets); i++) { | |
| 2668 | + dig_fe = RREG32(NI_DIG_FE_CNTL + ni_dig_offsets[i]); | |
| 2669 | + if (dig_fe & NI_DIG_FE_CNTL_SYMCLK_FE_ON && | |
| 2670 | + crtc_id == NI_DIG_FE_CNTL_SOURCE_SELECT(dig_fe)) { | |
| 2671 | + /* found running pipe */ | |
| 2672 | + found_crtc = true; | |
| 2673 | + dig_fe_mask = 1 << i; | |
| 2674 | + dig_fe = i; | |
| 2675 | + break; | |
| 2676 | + } | |
| 2677 | + } | |
| 2678 | + | |
| 2679 | + if (found_crtc) { | |
| 2680 | + /* loop through all running dig_be to find selected dig_fe */ | |
| 2681 | + for (i = 0; i < ARRAY_SIZE(ni_dig_offsets); i++) { | |
| 2682 | + dig_be = RREG32(NI_DIG_BE_CNTL + ni_dig_offsets[i]); | |
| 2683 | + /* if dig_fe_selected by dig_be? */ | |
| 2684 | + digs_fe_selected = NI_DIG_BE_CNTL_FE_SOURCE_SELECT(dig_be); | |
| 2685 | + dig_be_mode = NI_DIG_FE_CNTL_MODE(dig_be); | |
| 2686 | + if (dig_fe_mask & digs_fe_selected && | |
| 2687 | + /* if dig_be in sst mode? */ | |
| 2688 | + dig_be_mode == NI_DIG_BE_DPSST) { | |
| 2689 | + dig_en_be = RREG32(NI_DIG_BE_EN_CNTL + | |
| 2690 | + ni_dig_offsets[i]); | |
| 2691 | + uniphy_pll = RREG32(NI_DCIO_UNIPHY0_PLL_CONTROL1 + | |
| 2692 | + ni_tx_offsets[i]); | |
| 2693 | + /* dig_be enable and tx is running */ | |
| 2694 | + if (dig_en_be & NI_DIG_BE_EN_CNTL_ENABLE && | |
| 2695 | + dig_en_be & NI_DIG_BE_EN_CNTL_SYMBCLK_ON && | |
| 2696 | + uniphy_pll & NI_DCIO_UNIPHY0_PLL_CONTROL1_ENABLE) { | |
| 2697 | + is_enabled = true; | |
| 2698 | + *ret_dig_fe = dig_fe; | |
| 2699 | + break; | |
| 2700 | + } | |
| 2701 | + } | |
| 2702 | + } | |
| 2703 | + } | |
| 2704 | + | |
| 2705 | + return is_enabled; | |
| 2706 | +} | |
| 2707 | + | |
| 2708 | +/* | |
| 2709 | + * Blank dig when in dp sst mode | |
| 2710 | + * Dig ignores crtc timing | |
| 2711 | + */ | |
| 2712 | +static void evergreen_blank_dp_output(struct radeon_device *rdev, | |
| 2713 | + unsigned dig_fe) | |
| 2714 | +{ | |
| 2715 | + unsigned stream_ctrl; | |
| 2716 | + unsigned fifo_ctrl; | |
| 2717 | + unsigned counter = 0; | |
| 2718 | + | |
| 2719 | + if (dig_fe >= ARRAY_SIZE(evergreen_dp_offsets)) { | |
| 2720 | + DRM_ERROR("invalid dig_fe %d\n", dig_fe); | |
| 2721 | + return; | |
| 2722 | + } | |
| 2723 | + | |
| 2724 | + stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL + | |
| 2725 | + evergreen_dp_offsets[dig_fe]); | |
| 2726 | + if (!(stream_ctrl & EVERGREEN_DP_VID_STREAM_CNTL_ENABLE)) { | |
| 2727 | + DRM_ERROR("dig %d , should be enable\n", dig_fe); | |
| 2728 | + return; | |
| 2729 | + } | |
| 2730 | + | |
| 2731 | + stream_ctrl &=~EVERGREEN_DP_VID_STREAM_CNTL_ENABLE; | |
| 2732 | + WREG32(EVERGREEN_DP_VID_STREAM_CNTL + | |
| 2733 | + evergreen_dp_offsets[dig_fe], stream_ctrl); | |
| 2734 | + | |
| 2735 | + stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL + | |
| 2736 | + evergreen_dp_offsets[dig_fe]); | |
| 2737 | + while (counter < 32 && stream_ctrl & EVERGREEN_DP_VID_STREAM_STATUS) { | |
| 2738 | + msleep(1); | |
| 2739 | + counter++; | |
| 2740 | + stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL + | |
| 2741 | + evergreen_dp_offsets[dig_fe]); | |
| 2742 | + } | |
| 2743 | + if (counter >= 32 ) | |
| 2744 | + DRM_ERROR("counter exceeds %d\n", counter); | |
| 2745 | + | |
| 2746 | + fifo_ctrl = RREG32(EVERGREEN_DP_STEER_FIFO + evergreen_dp_offsets[dig_fe]); | |
| 2747 | + fifo_ctrl |= EVERGREEN_DP_STEER_FIFO_RESET; | |
| 2748 | + WREG32(EVERGREEN_DP_STEER_FIFO + evergreen_dp_offsets[dig_fe], fifo_ctrl); | |
| 2749 | + | |
| 2750 | +} | |
| 2751 | + | |
| 2611 | 2752 | void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) |
| 2612 | 2753 | { |
| 2613 | 2754 | u32 crtc_enabled, tmp, frame_count, blackout; |
| 2614 | 2755 | int i, j; |
| 2756 | + unsigned dig_fe; | |
| 2615 | 2757 | |
| 2616 | 2758 | if (!ASIC_IS_NODCE(rdev)) { |
| 2617 | 2759 | save->vga_render_control = RREG32(VGA_RENDER_CONTROL); |
| @@ -2651,7 +2793,17 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav · 33 unmodified lines | ||
| 2651 | 2793 | break; |
| 2652 | 2794 | udelay(1); |
| 2653 | 2795 | } |
| 2654 | − | |
| 2796 | + /*we should disable dig if it drives dp sst*/ | |
| 2797 | + /*but we are in radeon_device_init and the topology is unknown*/ | |
| 2798 | + /*and it is available after radeon_modeset_init*/ | |
| 2799 | + /*the following method radeon_atom_encoder_dpms_dig*/ | |
| 2800 | + /*does the job if we initialize it properly*/ | |
| 2801 | + /*for now we do it this manually*/ | |
| 2802 | + /**/ | |
| 2803 | + if (ASIC_IS_DCE5(rdev) && | |
| 2804 | + evergreen_is_dp_sst_stream_enabled(rdev, i ,&dig_fe)) | |
| 2805 | + evergreen_blank_dp_output(rdev, dig_fe); | |
| 2806 | + /*we could remove 6 lines below*/ | |
| 2655 | 2807 | /* XXX this is a hack to avoid strange behavior with EFI on certain systems */ |
| 2656 | 2808 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1); |
| 2657 | 2809 | tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]); |
| @@ -250,8 +250,43 @@ · 249 unmodified lines | ||
| 250 | 250 | |
| 251 | 251 | /* HDMI blocks at 0x7030, 0x7c30, 0x10830, 0x11430, 0x12030, 0x12c30 */ |
| 252 | 252 | #define EVERGREEN_HDMI_BASE 0x7030 |
| 253 | +/*DIG block*/ | |
| 254 | +#define NI_DIG0_REGISTER_OFFSET (0x7000 - 0x7000) | |
| 255 | +#define NI_DIG1_REGISTER_OFFSET (0x7C00 - 0x7000) | |
| 256 | +#define NI_DIG2_REGISTER_OFFSET (0x10800 - 0x7000) | |
| 257 | +#define NI_DIG3_REGISTER_OFFSET (0x11400 - 0x7000) | |
| 258 | +#define NI_DIG4_REGISTER_OFFSET (0x12000 - 0x7000) | |
| 259 | +#define NI_DIG5_REGISTER_OFFSET (0x12C00 - 0x7000) | |
| 260 | + | |
| 261 | + | |
| 262 | +#define NI_DIG_FE_CNTL 0x7000 | |
| 263 | +# define NI_DIG_FE_CNTL_SOURCE_SELECT(x) ((x) & 0x3) | |
| 264 | +# define NI_DIG_FE_CNTL_SYMCLK_FE_ON (1<<24) | |
| 265 | + | |
| 266 | + | |
| 267 | +#define NI_DIG_BE_CNTL 0x7140 | |
| 268 | +# define NI_DIG_BE_CNTL_FE_SOURCE_SELECT(x) (((x) >> 8 ) & 0x3F) | |
| 269 | +# define NI_DIG_FE_CNTL_MODE(x) (((x) >> 16) & 0x7 ) | |
| 270 | + | |
| 271 | +#define NI_DIG_BE_EN_CNTL 0x7144 | |
| 272 | +# define NI_DIG_BE_EN_CNTL_ENABLE (1 << 0) | |
| 273 | +# define NI_DIG_BE_EN_CNTL_SYMBCLK_ON (1 << 8) | |
| 274 | +# define NI_DIG_BE_DPSST 0 | |
| 253 | 275 | |
| 254 | 276 | /* Display Port block */ |
| 277 | +#define EVERGREEN_DP0_REGISTER_OFFSET (0x730C - 0x730C) | |
| 278 | +#define EVERGREEN_DP1_REGISTER_OFFSET (0x7F0C - 0x730C) | |
| 279 | +#define EVERGREEN_DP2_REGISTER_OFFSET (0x10B0C - 0x730C) | |
| 280 | +#define EVERGREEN_DP3_REGISTER_OFFSET (0x1170C - 0x730C) | |
| 281 | +#define EVERGREEN_DP4_REGISTER_OFFSET (0x1230C - 0x730C) | |
| 282 | +#define EVERGREEN_DP5_REGISTER_OFFSET (0x12F0C - 0x730C) | |
| 283 | + | |
| 284 | + | |
| 285 | +#define EVERGREEN_DP_VID_STREAM_CNTL 0x730C | |
| 286 | +# define EVERGREEN_DP_VID_STREAM_CNTL_ENABLE (1 << 0) | |
| 287 | +# define EVERGREEN_DP_VID_STREAM_STATUS (1 <<16) | |
| 288 | +#define EVERGREEN_DP_STEER_FIFO 0x7310 | |
| 289 | +# define EVERGREEN_DP_STEER_FIFO_RESET (1 << 0) | |
| 255 | 290 | #define EVERGREEN_DP_SEC_CNTL 0x7280 |
| 256 | 291 | # define EVERGREEN_DP_SEC_STREAM_ENABLE (1 << 0) |
| 257 | 292 | # define EVERGREEN_DP_SEC_ASP_ENABLE (1 << 4) |
| @@ -266,4 +301,15 @@ · 8 unmodified lines | ||
| 266 | 301 | # define EVERGREEN_DP_SEC_N_BASE_MULTIPLE(x) (((x) & 0xf) << 24) |
| 267 | 302 | # define EVERGREEN_DP_SEC_SS_EN (1 << 28) |
| 268 | 303 | |
| 304 | +/*DCIO_UNIPHY block*/ | |
| 305 | +#define NI_DCIO_UNIPHY0_UNIPHY_TX_CONTROL1 (0x6600 -0x6600) | |
| 306 | +#define NI_DCIO_UNIPHY1_UNIPHY_TX_CONTROL1 (0x6640 -0x6600) | |
| 307 | +#define NI_DCIO_UNIPHY2_UNIPHY_TX_CONTROL1 (0x6680 - 0x6600) | |
| 308 | +#define NI_DCIO_UNIPHY3_UNIPHY_TX_CONTROL1 (0x66C0 - 0x6600) | |
| 309 | +#define NI_DCIO_UNIPHY4_UNIPHY_TX_CONTROL1 (0x6700 - 0x6600) | |
| 310 | +#define NI_DCIO_UNIPHY5_UNIPHY_TX_CONTROL1 (0x6740 - 0x6600) | |
| 311 | + | |
| 312 | +#define NI_DCIO_UNIPHY0_PLL_CONTROL1 0x6618 | |
| 313 | +# define NI_DCIO_UNIPHY0_PLL_CONTROL1_ENABLE (1 << 0) | |
| 314 | + | |
| 269 | 315 | #endif |
| @@ -230,22 +230,13 @@ EXPORT_SYMBOL(ttm_bo_del_sub_from_lru); · 229 unmodified lines | ||
| 230 | 230 | |
| 231 | 231 | void ttm_bo_move_to_lru_tail(struct ttm_buffer_object *bo) |
| 232 | 232 | { |
| 233 | − struct ttm_bo_device *bdev = bo->bdev; | |
| 234 | − struct ttm_mem_type_manager *man; | |
| 233 | + int put_count = 0; | |
| 235 | 234 | |
| 236 | 235 | lockdep_assert_held(&bo->resv->lock.base); |
| 237 | 236 | |
| 238 | − if (bo->mem.placement & TTM_PL_FLAG_NO_EVICT) { | |
| 239 | − list_del_init(&bo->swap); | |
| 240 | − list_del_init(&bo->lru); | |
| 241 | − | |
| 242 | − } else { | |
| 243 | − if (bo->ttm && !(bo->ttm->page_flags & TTM_PAGE_FLAG_SG)) | |
| 244 | − list_move_tail(&bo->swap, &bo->glob->swap_lru); | |
| 245 | − | |
| 246 | − man = &bdev->man[bo->mem.mem_type]; | |
| 247 | − list_move_tail(&bo->lru, &man->lru); | |
| 248 | − } | |
| 237 | + put_count = ttm_bo_del_from_lru(bo); | |
| 238 | + ttm_bo_list_ref_sub(bo, put_count, true); | |
| 239 | + ttm_bo_add_to_lru(bo); | |
| 249 | 240 | } |
| 250 | 241 | EXPORT_SYMBOL(ttm_bo_move_to_lru_tail); |
| 251 | 242 | |
| @@ -267,11 +267,23 @@ static int virtio_gpu_crtc_atomic_check(struct drm_crtc *crtc, · 266 unmodified lines | ||
| 267 | 267 | return 0; |
| 268 | 268 | } |
| 269 | 269 | |
| 270 | +static void virtio_gpu_crtc_atomic_flush(struct drm_crtc *crtc, | |
| 271 | + struct drm_crtc_state *old_state) | |
| 272 | +{ | |
| 273 | + unsigned long flags; | |
| 274 | + | |
| 275 | + spin_lock_irqsave(&crtc->dev->event_lock, flags); | |
| 276 | + if (crtc->state->event) | |
| 277 | + drm_crtc_send_vblank_event(crtc, crtc->state->event); | |
| 278 | + spin_unlock_irqrestore(&crtc->dev->event_lock, flags); | |
| 279 | +} | |
| 280 | + | |
| 270 | 281 | static const struct drm_crtc_helper_funcs virtio_gpu_crtc_helper_funcs = { |
| 271 | 282 | .enable = virtio_gpu_crtc_enable, |
| 272 | 283 | .disable = virtio_gpu_crtc_disable, |
| 273 | 284 | .mode_set_nofb = virtio_gpu_crtc_mode_set_nofb, |
| 274 | 285 | .atomic_check = virtio_gpu_crtc_atomic_check, |
| 286 | + .atomic_flush = virtio_gpu_crtc_atomic_flush, | |
| 275 | 287 | }; |
| 276 | 288 | |
| 277 | 289 | static void virtio_gpu_enc_mode_set(struct drm_encoder *encoder, |
| @@ -3293,19 +3293,19 @@ static const struct vmw_cmd_entry vmw_cmd_entries[SVGA_3D_CMD_MAX] = { · 3292 unmodified lines | ||
| 3293 | 3293 | &vmw_cmd_dx_cid_check, true, false, true), |
| 3294 | 3294 | VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_QUERY, &vmw_cmd_dx_define_query, |
| 3295 | 3295 | true, false, true), |
| 3296 | − VMW_CMD_DEF(SVGA_3D_CMD_DX_DESTROY_QUERY, &vmw_cmd_ok, | |
| 3296 | + VMW_CMD_DEF(SVGA_3D_CMD_DX_DESTROY_QUERY, &vmw_cmd_dx_cid_check, | |
| 3297 | 3297 | true, false, true), |
| 3298 | 3298 | VMW_CMD_DEF(SVGA_3D_CMD_DX_BIND_QUERY, &vmw_cmd_dx_bind_query, |
| 3299 | 3299 | true, false, true), |
| 3300 | 3300 | VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_QUERY_OFFSET, |
| 3301 | − &vmw_cmd_ok, true, false, true), | |
| 3302 | − VMW_CMD_DEF(SVGA_3D_CMD_DX_BEGIN_QUERY, &vmw_cmd_ok, | |
| 3301 | + &vmw_cmd_dx_cid_check, true, false, true), | |
| 3302 | + VMW_CMD_DEF(SVGA_3D_CMD_DX_BEGIN_QUERY, &vmw_cmd_dx_cid_check, | |
| 3303 | 3303 | true, false, true), |
| 3304 | − VMW_CMD_DEF(SVGA_3D_CMD_DX_END_QUERY, &vmw_cmd_ok, | |
| 3304 | + VMW_CMD_DEF(SVGA_3D_CMD_DX_END_QUERY, &vmw_cmd_dx_cid_check, | |
| 3305 | 3305 | true, false, true), |
| 3306 | 3306 | VMW_CMD_DEF(SVGA_3D_CMD_DX_READBACK_QUERY, &vmw_cmd_invalid, |
| 3307 | 3307 | true, false, true), |
| 3308 | − VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_PREDICATION, &vmw_cmd_invalid, | |
| 3308 | + VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_PREDICATION, &vmw_cmd_dx_cid_check, | |
| 3309 | 3309 | true, false, true), |
| 3310 | 3310 | VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_VIEWPORTS, &vmw_cmd_dx_cid_check, |
| 3311 | 3311 | true, false, true), |
| @@ -573,9 +573,9 @@ static int vmw_fb_set_par(struct fb_info *info) · 572 unmodified lines | ||
| 573 | 573 | mode = old_mode; |
| 574 | 574 | old_mode = NULL; |
| 575 | 575 | } else if (!vmw_kms_validate_mode_vram(vmw_priv, |
| 576 | − mode->hdisplay * | |
| 577 | − (var->bits_per_pixel + 7) / 8, | |
| 578 | − mode->vdisplay)) { | |
| 576 | + mode->hdisplay * | |
| 577 | + DIV_ROUND_UP(var->bits_per_pixel, 8), | |
| 578 | + mode->vdisplay)) { | |
| 579 | 579 | drm_mode_destroy(vmw_priv->dev, mode); |
| 580 | 580 | return -EINVAL; |
| 581 | 581 | } |
| @@ -259,6 +259,7 @@ · 258 unmodified lines | ||
| 259 | 259 | #define USB_DEVICE_ID_CORSAIR_K90 0x1b02 |
| 260 | 260 | |
| 261 | 261 | #define USB_VENDOR_ID_CREATIVELABS 0x041e |
| 262 | +#define USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51 0x322c | |
| 262 | 263 | #define USB_DEVICE_ID_PRODIKEYS_PCMIDI 0x2801 |
| 263 | 264 | |
| 264 | 265 | #define USB_VENDOR_ID_CVTOUCH 0x1ff7 |
| @@ -71,6 +71,7 @@ static const struct hid_blacklist { · 70 unmodified lines | ||
| 71 | 71 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK, HID_QUIRK_NOGET }, |
| 72 | 72 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET }, |
| 73 | 73 | { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL }, |
| 74 | + { USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51, HID_QUIRK_NOGET }, | |
| 74 | 75 | { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, |
| 75 | 76 | { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU, HID_QUIRK_MULTI_INPUT }, |
| 76 | 77 | { USB_VENDOR_ID_ELAN, HID_ANY_ID, HID_QUIRK_ALWAYS_POLL }, |
| @@ -684,6 +684,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) · 683 unmodified lines | ||
| 684 | 684 | |
| 685 | 685 | wacom->tool[idx] = wacom_intuos_get_tool_type(wacom->id[idx]); |
| 686 | 686 | |
| 687 | + wacom->shared->stylus_in_proximity = true; | |
| 687 | 688 | return 1; |
| 688 | 689 | } |
| 689 | 690 | |
| @@ -3395,6 +3396,10 @@ static const struct wacom_features wacom_features_0x33E = · 2705 unmodified lines | ||
| 3395 | 3396 | { "Wacom Intuos PT M 2", 21600, 13500, 2047, 63, |
| 3396 | 3397 | INTUOSHT2, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 16, |
| 3397 | 3398 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; |
| 3399 | +static const struct wacom_features wacom_features_0x343 = | |
| 3400 | + { "Wacom DTK1651", 34616, 19559, 1023, 0, | |
| 3401 | + DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4, | |
| 3402 | + WACOM_DTU_OFFSET, WACOM_DTU_OFFSET }; | |
| 3398 | 3403 | |
| 3399 | 3404 | static const struct wacom_features wacom_features_HID_ANY_ID = |
| 3400 | 3405 | { "Wacom HID", .type = HID_GENERIC }; |
| @@ -3560,6 +3565,7 @@ const struct hid_device_id wacom_ids[] = { · 159 unmodified lines | ||
| 3560 | 3565 | { USB_DEVICE_WACOM(0x33C) }, |
| 3561 | 3566 | { USB_DEVICE_WACOM(0x33D) }, |
| 3562 | 3567 | { USB_DEVICE_WACOM(0x33E) }, |
| 3568 | + { USB_DEVICE_WACOM(0x343) }, | |
| 3563 | 3569 | { USB_DEVICE_WACOM(0x4001) }, |
| 3564 | 3570 | { USB_DEVICE_WACOM(0x4004) }, |
| 3565 | 3571 | { USB_DEVICE_WACOM(0x5000) }, |
| @@ -975,10 +975,10 @@ config I2C_XLR · 974 unmodified lines | ||
| 975 | 975 | |
| 976 | 976 | config I2C_XLP9XX |
| 977 | 977 | tristate "XLP9XX I2C support" |
| 978 | − depends on CPU_XLP || COMPILE_TEST | |
| 978 | + depends on CPU_XLP || ARCH_VULCAN || COMPILE_TEST | |
| 979 | 979 | help |
| 980 | 980 | This driver enables support for the on-chip I2C interface of |
| 981 | − the Broadcom XLP9xx/XLP5xx MIPS processors. | |
| 981 | + the Broadcom XLP9xx/XLP5xx MIPS and Vulcan ARM64 processors. | |
| 982 | 982 | |
| 983 | 983 | This driver can also be built as a module. If so, the module will |
| 984 | 984 | be called i2c-xlp9xx. |
| @@ -116,8 +116,8 @@ struct cpm_i2c { · 115 unmodified lines | ||
| 116 | 116 | cbd_t __iomem *rbase; |
| 117 | 117 | u_char *txbuf[CPM_MAXBD]; |
| 118 | 118 | u_char *rxbuf[CPM_MAXBD]; |
| 119 | − u32 txdma[CPM_MAXBD]; | |
| 120 | − u32 rxdma[CPM_MAXBD]; | |
| 119 | + dma_addr_t txdma[CPM_MAXBD]; | |
| 120 | + dma_addr_t rxdma[CPM_MAXBD]; | |
| 121 | 121 | }; |
| 122 | 122 | |
| 123 | 123 | static irqreturn_t cpm_i2c_interrupt(int irq, void *dev_id) |
| @@ -671,7 +671,9 @@ static int exynos5_i2c_xfer(struct i2c_adapter *adap, · 670 unmodified lines | ||
| 671 | 671 | return -EIO; |
| 672 | 672 | } |
| 673 | 673 | |
| 674 | − clk_prepare_enable(i2c->clk); | |
| 674 | + ret = clk_enable(i2c->clk); | |
| 675 | + if (ret) | |
| 676 | + return ret; | |
| 675 | 677 | |
| 676 | 678 | for (i = 0; i < num; i++, msgs++) { |
| 677 | 679 | stop = (i == num - 1); |
| @@ -695,7 +697,7 @@ static int exynos5_i2c_xfer(struct i2c_adapter *adap, · 17 unmodified lines | ||
| 695 | 697 | } |
| 696 | 698 | |
| 697 | 699 | out: |
| 698 | − clk_disable_unprepare(i2c->clk); | |
| 700 | + clk_disable(i2c->clk); | |
| 699 | 701 | return ret; |
| 700 | 702 | } |
| 701 | 703 | |
| @@ -747,7 +749,9 @@ static int exynos5_i2c_probe(struct platform_device *pdev) · 45 unmodified lines | ||
| 747 | 749 | return -ENOENT; |
| 748 | 750 | } |
| 749 | 751 | |
| 750 | − clk_prepare_enable(i2c->clk); | |
| 752 | + ret = clk_prepare_enable(i2c->clk); | |
| 753 | + if (ret) | |
| 754 | + return ret; | |
| 751 | 755 | |
| 752 | 756 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 753 | 757 | i2c->regs = devm_ioremap_resource(&pdev->dev, mem); |
| @@ -799,6 +803,10 @@ static int exynos5_i2c_probe(struct platform_device *pdev) · 45 unmodified lines | ||
| 799 | 803 | |
| 800 | 804 | platform_set_drvdata(pdev, i2c); |
| 801 | 805 | |
| 806 | + clk_disable(i2c->clk); | |
| 807 | + | |
| 808 | + return 0; | |
| 809 | + | |
| 802 | 810 | err_clk: |
| 803 | 811 | clk_disable_unprepare(i2c->clk); |
| 804 | 812 | return ret; |
| @@ -810,6 +818,8 @@ static int exynos5_i2c_remove(struct platform_device *pdev) · 5 unmodified lines | ||
| 810 | 818 | |
| 811 | 819 | i2c_del_adapter(&i2c->adap); |
| 812 | 820 | |
| 821 | + clk_unprepare(i2c->clk); | |
| 822 | + | |
| 813 | 823 | return 0; |
| 814 | 824 | } |
| 815 | 825 | |
| @@ -821,6 +831,8 @@ static int exynos5_i2c_suspend_noirq(struct device *dev) · 5 unmodified lines | ||
| 821 | 831 | |
| 822 | 832 | i2c->suspended = 1; |
| 823 | 833 | |
| 834 | + clk_unprepare(i2c->clk); | |
| 835 | + | |
| 824 | 836 | return 0; |
| 825 | 837 | } |
| 826 | 838 | |
| @@ -830,7 +842,9 @@ static int exynos5_i2c_resume_noirq(struct device *dev) · 3 unmodified lines | ||
| 830 | 842 | struct exynos5_i2c *i2c = platform_get_drvdata(pdev); |
| 831 | 843 | int ret = 0; |
| 832 | 844 | |
| 833 | − clk_prepare_enable(i2c->clk); | |
| 845 | + ret = clk_prepare_enable(i2c->clk); | |
| 846 | + if (ret) | |
| 847 | + return ret; | |
| 834 | 848 | |
| 835 | 849 | ret = exynos5_hsi2c_clock_setup(i2c); |
| 836 | 850 | if (ret) { |
| @@ -839,7 +853,7 @@ static int exynos5_i2c_resume_noirq(struct device *dev) · 2 unmodified lines | ||
| 839 | 853 | } |
| 840 | 854 | |
| 841 | 855 | exynos5_i2c_init(i2c); |
| 842 | − clk_disable_unprepare(i2c->clk); | |
| 856 | + clk_disable(i2c->clk); | |
| 843 | 857 | i2c->suspended = 0; |
| 844 | 858 | |
| 845 | 859 | return 0; |
| @@ -75,6 +75,7 @@ · 74 unmodified lines | ||
| 75 | 75 | /* PCI DIDs for the Intel SMBus Message Transport (SMT) Devices */ |
| 76 | 76 | #define PCI_DEVICE_ID_INTEL_S1200_SMT0 0x0c59 |
| 77 | 77 | #define PCI_DEVICE_ID_INTEL_S1200_SMT1 0x0c5a |
| 78 | +#define PCI_DEVICE_ID_INTEL_DNV_SMT 0x19ac | |
| 78 | 79 | #define PCI_DEVICE_ID_INTEL_AVOTON_SMT 0x1f15 |
| 79 | 80 | |
| 80 | 81 | #define ISMT_DESC_ENTRIES 2 /* number of descriptor entries */ |
| @@ -180,6 +181,7 @@ struct ismt_priv { · 99 unmodified lines | ||
| 180 | 181 | static const struct pci_device_id ismt_ids[] = { |
| 181 | 182 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_S1200_SMT0) }, |
| 182 | 183 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_S1200_SMT1) }, |
| 184 | + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DNV_SMT) }, | |
| 183 | 185 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_AVOTON_SMT) }, |
| 184 | 186 | { 0, } |
| 185 | 187 | }; |
| @@ -855,6 +855,7 @@ static struct rk3x_i2c_soc_data soc_data[3] = { · 854 unmodified lines | ||
| 855 | 855 | static const struct of_device_id rk3x_i2c_match[] = { |
| 856 | 856 | { .compatible = "rockchip,rk3066-i2c", .data = (void *)&soc_data[0] }, |
| 857 | 857 | { .compatible = "rockchip,rk3188-i2c", .data = (void *)&soc_data[1] }, |
| 858 | + { .compatible = "rockchip,rk3228-i2c", .data = (void *)&soc_data[2] }, | |
| 858 | 859 | { .compatible = "rockchip,rk3288-i2c", .data = (void *)&soc_data[2] }, |
| 859 | 860 | {}, |
| 860 | 861 | }; |
| @@ -691,7 +691,8 @@ void ib_cache_gid_set_default_gid(struct ib_device *ib_dev, u8 port, · 690 unmodified lines | ||
| 691 | 691 | NULL); |
| 692 | 692 | |
| 693 | 693 | /* Coudn't find default GID location */ |
| 694 | − WARN_ON(ix < 0); | |
| 694 | + if (WARN_ON(ix < 0)) | |
| 695 | + goto release; | |
| 695 | 696 | |
| 696 | 697 | zattr_type.gid_type = gid_type; |
| 697 | 698 | |
| @@ -48,6 +48,7 @@ · 47 unmodified lines | ||
| 48 | 48 | |
| 49 | 49 | #include <asm/uaccess.h> |
| 50 | 50 | |
| 51 | +#include <rdma/ib.h> | |
| 51 | 52 | #include <rdma/ib_cm.h> |
| 52 | 53 | #include <rdma/ib_user_cm.h> |
| 53 | 54 | #include <rdma/ib_marshall.h> |
| @@ -1103,6 +1104,9 @@ static ssize_t ib_ucm_write(struct file *filp, const char __user *buf, · 1049 unmodified lines | ||
| 1103 | 1104 | struct ib_ucm_cmd_hdr hdr; |
| 1104 | 1105 | ssize_t result; |
| 1105 | 1106 | |
| 1107 | + if (WARN_ON_ONCE(!ib_safe_file_access(filp))) | |
| 1108 | + return -EACCES; | |
| 1109 | + | |
| 1106 | 1110 | if (len < sizeof(hdr)) |
| 1107 | 1111 | return -EINVAL; |
| 1108 | 1112 | |
| @@ -1574,6 +1574,9 @@ static ssize_t ucma_write(struct file *filp, const char __user *buf, · 1573 unmodified lines | ||
| 1574 | 1574 | struct rdma_ucm_cmd_hdr hdr; |
| 1575 | 1575 | ssize_t ret; |
| 1576 | 1576 | |
| 1577 | + if (WARN_ON_ONCE(!ib_safe_file_access(filp))) | |
| 1578 | + return -EACCES; | |
| 1579 | + | |
| 1577 | 1580 | if (len < sizeof(hdr)) |
| 1578 | 1581 | return -EINVAL; |
| 1579 | 1582 | |
| @@ -48,6 +48,8 @@ · 47 unmodified lines | ||
| 48 | 48 | |
| 49 | 49 | #include <asm/uaccess.h> |
| 50 | 50 | |
| 51 | +#include <rdma/ib.h> | |
| 52 | + | |
| 51 | 53 | #include "uverbs.h" |
| 52 | 54 | |
| 53 | 55 | MODULE_AUTHOR("Roland Dreier"); |
| @@ -709,6 +711,9 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf, · 655 unmodified lines | ||
| 709 | 711 | int srcu_key; |
| 710 | 712 | ssize_t ret; |
| 711 | 713 | |
| 714 | + if (WARN_ON_ONCE(!ib_safe_file_access(filp))) | |
| 715 | + return -EACCES; | |
| 716 | + | |
| 712 | 717 | if (count < sizeof hdr) |
| 713 | 718 | return -EINVAL; |
| 714 | 719 | |
| @@ -1860,6 +1860,7 @@ EXPORT_SYMBOL(ib_drain_rq); · 1859 unmodified lines | ||
| 1860 | 1860 | void ib_drain_qp(struct ib_qp *qp) |
| 1861 | 1861 | { |
| 1862 | 1862 | ib_drain_sq(qp); |
| 1863 | − ib_drain_rq(qp); | |
| 1863 | + if (!qp->srq) | |
| 1864 | + ib_drain_rq(qp); | |
| 1864 | 1865 | } |
| 1865 | 1866 | EXPORT_SYMBOL(ib_drain_qp); |
| @@ -1390,6 +1390,8 @@ int iwch_register_device(struct iwch_dev *dev) · 1389 unmodified lines | ||
| 1390 | 1390 | dev->ibdev.iwcm->add_ref = iwch_qp_add_ref; |
| 1391 | 1391 | dev->ibdev.iwcm->rem_ref = iwch_qp_rem_ref; |
| 1392 | 1392 | dev->ibdev.iwcm->get_qp = iwch_get_qp; |
| 1393 | + memcpy(dev->ibdev.iwcm->ifname, dev->rdev.t3cdev_p->lldev->name, | |
| 1394 | + sizeof(dev->ibdev.iwcm->ifname)); | |
| 1393 | 1395 | |
| 1394 | 1396 | ret = ib_register_device(&dev->ibdev, NULL); |
| 1395 | 1397 | if (ret) |
| @@ -162,7 +162,7 @@ static int create_cq(struct c4iw_rdev *rdev, struct t4_cq *cq, · 161 unmodified lines | ||
| 162 | 162 | cq->bar2_va = c4iw_bar2_addrs(rdev, cq->cqid, T4_BAR2_QTYPE_INGRESS, |
| 163 | 163 | &cq->bar2_qid, |
| 164 | 164 | user ? &cq->bar2_pa : NULL); |
| 165 | − if (user && !cq->bar2_va) { | |
| 165 | + if (user && !cq->bar2_pa) { | |
| 166 | 166 | pr_warn(MOD "%s: cqid %u not in BAR2 range.\n", |
| 167 | 167 | pci_name(rdev->lldi.pdev), cq->cqid); |
| 168 | 168 | ret = -EINVAL; |
| @@ -580,6 +580,8 @@ int c4iw_register_device(struct c4iw_dev *dev) · 579 unmodified lines | ||
| 580 | 580 | dev->ibdev.iwcm->add_ref = c4iw_qp_add_ref; |
| 581 | 581 | dev->ibdev.iwcm->rem_ref = c4iw_qp_rem_ref; |
| 582 | 582 | dev->ibdev.iwcm->get_qp = c4iw_get_qp; |
| 583 | + memcpy(dev->ibdev.iwcm->ifname, dev->rdev.lldi.ports[0]->name, | |
| 584 | + sizeof(dev->ibdev.iwcm->ifname)); | |
| 583 | 585 | |
| 584 | 586 | ret = ib_register_device(&dev->ibdev, NULL); |
| 585 | 587 | if (ret) |
| @@ -185,6 +185,10 @@ void __iomem *c4iw_bar2_addrs(struct c4iw_rdev *rdev, unsigned int qid, · 184 unmodified lines | ||
| 185 | 185 | |
| 186 | 186 | if (pbar2_pa) |
| 187 | 187 | *pbar2_pa = (rdev->bar2_pa + bar2_qoffset) & PAGE_MASK; |
| 188 | + | |
| 189 | + if (is_t4(rdev->lldi.adapter_type)) | |
| 190 | + return NULL; | |
| 191 | + | |
| 188 | 192 | return rdev->bar2_kva + bar2_qoffset; |
| 189 | 193 | } |
| 190 | 194 | |
| @@ -270,7 +274,7 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq, · 79 unmodified lines | ||
| 270 | 274 | /* |
| 271 | 275 | * User mode must have bar2 access. |
| 272 | 276 | */ |
| 273 | − if (user && (!wq->sq.bar2_va || !wq->rq.bar2_va)) { | |
| 277 | + if (user && (!wq->sq.bar2_pa || !wq->rq.bar2_pa)) { | |
| 274 | 278 | pr_warn(MOD "%s: sqid %u or rqid %u not in BAR2 range.\n", |
| 275 | 279 | pci_name(rdev->lldi.pdev), wq->sq.qid, wq->rq.qid); |
| 276 | 280 | goto free_dma; |
| @@ -1895,13 +1899,27 @@ int c4iw_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, · 1618 unmodified lines | ||
| 1895 | 1899 | void c4iw_drain_sq(struct ib_qp *ibqp) |
| 1896 | 1900 | { |
| 1897 | 1901 | struct c4iw_qp *qp = to_c4iw_qp(ibqp); |
| 1902 | + unsigned long flag; | |
| 1903 | + bool need_to_wait; | |
| 1898 | 1904 | |
| 1899 | − wait_for_completion(&qp->sq_drained); | |
| 1905 | + spin_lock_irqsave(&qp->lock, flag); | |
| 1906 | + need_to_wait = !t4_sq_empty(&qp->wq); | |
| 1907 | + spin_unlock_irqrestore(&qp->lock, flag); | |
| 1908 | + | |
| 1909 | + if (need_to_wait) | |
| 1910 | + wait_for_completion(&qp->sq_drained); | |
| 1900 | 1911 | } |
| 1901 | 1912 | |
| 1902 | 1913 | void c4iw_drain_rq(struct ib_qp *ibqp) |
| 1903 | 1914 | { |
| 1904 | 1915 | struct c4iw_qp *qp = to_c4iw_qp(ibqp); |
| 1916 | + unsigned long flag; | |
| 1917 | + bool need_to_wait; | |
| 1918 | + | |
| 1919 | + spin_lock_irqsave(&qp->lock, flag); | |
| 1920 | + need_to_wait = !t4_rq_empty(&qp->wq); | |
| 1921 | + spin_unlock_irqrestore(&qp->lock, flag); | |
| 1905 | 1922 | |
| 1906 | − wait_for_completion(&qp->rq_drained); | |
| 1923 | + if (need_to_wait) | |
| 1924 | + wait_for_completion(&qp->rq_drained); | |
| 1907 | 1925 | } |
| @@ -530,7 +530,7 @@ static int mlx5_ib_query_device(struct ib_device *ibdev, · 529 unmodified lines | ||
| 530 | 530 | sizeof(struct mlx5_wqe_ctrl_seg)) / |
| 531 | 531 | sizeof(struct mlx5_wqe_data_seg); |
| 532 | 532 | props->max_sge = min(max_rq_sg, max_sq_sg); |
| 533 | − props->max_sge_rd = props->max_sge; | |
| 533 | + props->max_sge_rd = MLX5_MAX_SGE_RD; | |
| 534 | 534 | props->max_cq = 1 << MLX5_CAP_GEN(mdev, log_max_cq); |
| 535 | 535 | props->max_cqe = (1 << MLX5_CAP_GEN(mdev, log_max_cq_sz)) - 1; |
| 536 | 536 | props->max_mr = 1 << MLX5_CAP_GEN(mdev, log_max_mkey); |
| @@ -498,9 +498,6 @@ static int nes_netdev_start_xmit(struct sk_buff *skb, struct net_device *netdev) · 497 unmodified lines | ||
| 498 | 498 | * skb_shinfo(skb)->nr_frags, skb_is_gso(skb)); |
| 499 | 499 | */ |
| 500 | 500 | |
| 501 | − if (!netif_carrier_ok(netdev)) | |
| 502 | − return NETDEV_TX_OK; | |
| 503 | − | |
| 504 | 501 | if (netif_queue_stopped(netdev)) |
| 505 | 502 | return NETDEV_TX_BUSY; |
| 506 | 503 | |
| @@ -45,6 +45,8 @@ · 44 unmodified lines | ||
| 45 | 45 | #include <linux/export.h> |
| 46 | 46 | #include <linux/uio.h> |
| 47 | 47 | |
| 48 | +#include <rdma/ib.h> | |
| 49 | + | |
| 48 | 50 | #include "qib.h" |
| 49 | 51 | #include "qib_common.h" |
| 50 | 52 | #include "qib_user_sdma.h" |
| @@ -2067,6 +2069,9 @@ static ssize_t qib_write(struct file *fp, const char __user *data, · 2016 unmodified lines | ||
| 2067 | 2069 | ssize_t ret = 0; |
| 2068 | 2070 | void *dest; |
| 2069 | 2071 | |
| 2072 | + if (WARN_ON_ONCE(!ib_safe_file_access(fp))) | |
| 2073 | + return -EACCES; | |
| 2074 | + | |
| 2070 | 2075 | if (count < sizeof(cmd.type)) { |
| 2071 | 2076 | ret = -EINVAL; |
| 2072 | 2077 | goto bail; |
| @@ -1637,9 +1637,9 @@ bail: · 1636 unmodified lines | ||
| 1637 | 1637 | spin_unlock_irqrestore(&qp->s_hlock, flags); |
| 1638 | 1638 | if (nreq) { |
| 1639 | 1639 | if (call_send) |
| 1640 | − rdi->driver_f.schedule_send_no_lock(qp); | |
| 1641 | − else | |
| 1642 | 1640 | rdi->driver_f.do_send(qp); |
| 1641 | + else | |
| 1642 | + rdi->driver_f.schedule_send_no_lock(qp); | |
| 1643 | 1643 | } |
| 1644 | 1644 | return err; |
| 1645 | 1645 | } |
| @@ -284,6 +284,8 @@ static blk_qc_t md_make_request(struct request_queue *q, struct bio *bio) · 283 unmodified lines | ||
| 284 | 284 | * go away inside make_request |
| 285 | 285 | */ |
| 286 | 286 | sectors = bio_sectors(bio); |
| 287 | + /* bio could be mergeable after passing to underlayer */ | |
| 288 | + bio->bi_rw &= ~REQ_NOMERGE; | |
| 287 | 289 | mddev->pers->make_request(mddev, bio); |
| 288 | 290 | |
| 289 | 291 | cpu = part_stat_lock(); |
| @@ -70,7 +70,6 @@ static void dump_zones(struct mddev *mddev) · 69 unmodified lines | ||
| 70 | 70 | (unsigned long long)zone_size>>1); |
| 71 | 71 | zone_start = conf->strip_zone[j].zone_end; |
| 72 | 72 | } |
| 73 | − printk(KERN_INFO "\n"); | |
| 74 | 73 | } |
| 75 | 74 | |
| 76 | 75 | static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf) |
| @@ -85,6 +84,7 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf) · 8 unmodified lines | ||
| 85 | 84 | struct r0conf *conf = kzalloc(sizeof(*conf), GFP_KERNEL); |
| 86 | 85 | unsigned short blksize = 512; |
| 87 | 86 | |
| 87 | + *private_conf = ERR_PTR(-ENOMEM); | |
| 88 | 88 | if (!conf) |
| 89 | 89 | return -ENOMEM; |
| 90 | 90 | rdev_for_each(rdev1, mddev) { |
| @@ -3502,8 +3502,6 @@ returnbi: · 3501 unmodified lines | ||
| 3502 | 3502 | dev = &sh->dev[i]; |
| 3503 | 3503 | } else if (test_bit(R5_Discard, &dev->flags)) |
| 3504 | 3504 | discard_pending = 1; |
| 3505 | − WARN_ON(test_bit(R5_SkipCopy, &dev->flags)); | |
| 3506 | − WARN_ON(dev->page != dev->orig_page); | |
| 3507 | 3505 | } |
| 3508 | 3506 | |
| 3509 | 3507 | r5l_stripe_write_finished(sh); |
| @@ -1452,13 +1452,6 @@ static int usbvision_probe(struct usb_interface *intf, · 1451 unmodified lines | ||
| 1452 | 1452 | printk(KERN_INFO "%s: %s found\n", __func__, |
| 1453 | 1453 | usbvision_device_data[model].model_string); |
| 1454 | 1454 | |
| 1455 | − /* | |
| 1456 | − * this is a security check. | |
| 1457 | − * an exploit using an incorrect bInterfaceNumber is known | |
| 1458 | − */ | |
| 1459 | − if (ifnum >= USB_MAXINTERFACES || !dev->actconfig->interface[ifnum]) | |
| 1460 | − return -ENODEV; | |
| 1461 | − | |
| 1462 | 1455 | if (usbvision_device_data[model].interface >= 0) |
| 1463 | 1456 | interface = &dev->actconfig->interface[usbvision_device_data[model].interface]->altsetting[0]; |
| 1464 | 1457 | else if (ifnum < dev->actconfig->desc.bNumInterfaces) |
| @@ -1645,7 +1645,7 @@ static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking) · 1644 unmodified lines | ||
| 1645 | 1645 | * Will sleep if required for nonblocking == false. |
| 1646 | 1646 | */ |
| 1647 | 1647 | static int __vb2_get_done_vb(struct vb2_queue *q, struct vb2_buffer **vb, |
| 1648 | − int nonblocking) | |
| 1648 | + void *pb, int nonblocking) | |
| 1649 | 1649 | { |
| 1650 | 1650 | unsigned long flags; |
| 1651 | 1651 | int ret; |
| @@ -1666,10 +1666,10 @@ static int __vb2_get_done_vb(struct vb2_queue *q, struct vb2_buffer **vb, · 14 unmodified lines | ||
| 1666 | 1666 | /* |
| 1667 | 1667 | * Only remove the buffer from done_list if v4l2_buffer can handle all |
| 1668 | 1668 | * the planes. |
| 1669 | − * Verifying planes is NOT necessary since it already has been checked | |
| 1670 | − * before the buffer is queued/prepared. So it can never fail. | |
| 1671 | 1669 | */ |
| 1672 | − list_del(&(*vb)->done_entry); | |
| 1670 | + ret = call_bufop(q, verify_planes_array, *vb, pb); | |
| 1671 | + if (!ret) | |
| 1672 | + list_del(&(*vb)->done_entry); | |
| 1673 | 1673 | spin_unlock_irqrestore(&q->done_lock, flags); |
| 1674 | 1674 | |
| 1675 | 1675 | return ret; |
| @@ -1748,7 +1748,7 @@ int vb2_core_dqbuf(struct vb2_queue *q, unsigned int *pindex, void *pb, · 72 unmodified lines | ||
| 1748 | 1748 | struct vb2_buffer *vb = NULL; |
| 1749 | 1749 | int ret; |
| 1750 | 1750 | |
| 1751 | − ret = __vb2_get_done_vb(q, &vb, nonblocking); | |
| 1751 | + ret = __vb2_get_done_vb(q, &vb, pb, nonblocking); | |
| 1752 | 1752 | if (ret < 0) |
| 1753 | 1753 | return ret; |
| 1754 | 1754 | |
| @@ -2297,6 +2297,16 @@ unsigned int vb2_core_poll(struct vb2_queue *q, struct file *file, · 542 unmodified lines | ||
| 2297 | 2297 | if (!vb2_is_streaming(q) || q->error) |
| 2298 | 2298 | return POLLERR; |
| 2299 | 2299 | |
| 2300 | + /* | |
| 2301 | + * If this quirk is set and QBUF hasn't been called yet then | |
| 2302 | + * return POLLERR as well. This only affects capture queues, output | |
| 2303 | + * queues will always initialize waiting_for_buffers to false. | |
| 2304 | + * This quirk is set by V4L2 for backwards compatibility reasons. | |
| 2305 | + */ | |
| 2306 | + if (q->quirk_poll_must_check_waiting_for_buffers && | |
| 2307 | + q->waiting_for_buffers && (req_events & (POLLIN | POLLRDNORM))) | |
| 2308 | + return POLLERR; | |
| 2309 | + | |
| 2300 | 2310 | /* |
| 2301 | 2311 | * For output streams you can call write() as long as there are fewer |
| 2302 | 2312 | * buffers queued than there are buffers available. |
| @@ -49,7 +49,7 @@ struct frame_vector *vb2_create_framevec(unsigned long start, · 48 unmodified lines | ||
| 49 | 49 | vec = frame_vector_create(nr); |
| 50 | 50 | if (!vec) |
| 51 | 51 | return ERR_PTR(-ENOMEM); |
| 52 | − ret = get_vaddr_frames(start, nr, write, 1, vec); | |
| 52 | + ret = get_vaddr_frames(start & PAGE_MASK, nr, write, true, vec); | |
| 53 | 53 | if (ret < 0) |
| 54 | 54 | goto out_destroy; |
| 55 | 55 | /* We accept only complete set of PFNs */ |
| @@ -74,6 +74,11 @@ static int __verify_planes_array(struct vb2_buffer *vb, const struct v4l2_buffer · 73 unmodified lines | ||
| 74 | 74 | return 0; |
| 75 | 75 | } |
| 76 | 76 | |
| 77 | +static int __verify_planes_array_core(struct vb2_buffer *vb, const void *pb) | |
| 78 | +{ | |
| 79 | + return __verify_planes_array(vb, pb); | |
| 80 | +} | |
| 81 | + | |
| 77 | 82 | /** |
| 78 | 83 | * __verify_length() - Verify that the bytesused value for each plane fits in |
| 79 | 84 | * the plane length and that the data offset doesn't exceed the bytesused value. |
| @@ -437,6 +442,7 @@ static int __fill_vb2_buffer(struct vb2_buffer *vb, · 357 unmodified lines | ||
| 437 | 442 | } |
| 438 | 443 | |
| 439 | 444 | static const struct vb2_buf_ops v4l2_buf_ops = { |
| 445 | + .verify_planes_array = __verify_planes_array_core, | |
| 440 | 446 | .fill_user_buffer = __fill_v4l2_buffer, |
| 441 | 447 | .fill_vb2_buffer = __fill_vb2_buffer, |
| 442 | 448 | .copy_timestamp = __copy_timestamp, |
| @@ -765,6 +771,12 @@ int vb2_queue_init(struct vb2_queue *q) · 322 unmodified lines | ||
| 765 | 771 | q->is_output = V4L2_TYPE_IS_OUTPUT(q->type); |
| 766 | 772 | q->copy_timestamp = (q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) |
| 767 | 773 | == V4L2_BUF_FLAG_TIMESTAMP_COPY; |
| 774 | + /* | |
| 775 | + * For compatibility with vb1: if QBUF hasn't been called yet, then | |
| 776 | + * return POLLERR as well. This only affects capture queues, output | |
| 777 | + * queues will always initialize waiting_for_buffers to false. | |
| 778 | + */ | |
| 779 | + q->quirk_poll_must_check_waiting_for_buffers = true; | |
| 768 | 780 | |
| 769 | 781 | return vb2_core_queue_init(q); |
| 770 | 782 | } |
| @@ -818,14 +830,6 @@ unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait) · 47 unmodified lines | ||
| 818 | 830 | poll_wait(file, &fh->wait, wait); |
| 819 | 831 | } |
| 820 | 832 | |
| 821 | − /* | |
| 822 | − * For compatibility with vb1: if QBUF hasn't been called yet, then | |
| 823 | − * return POLLERR as well. This only affects capture queues, output | |
| 824 | − * queues will always initialize waiting_for_buffers to false. | |
| 825 | − */ | |
| 826 | − if (q->waiting_for_buffers && (req_events & (POLLIN | POLLRDNORM))) | |
| 827 | − return POLLERR; | |
| 828 | − | |
| 829 | 833 | return res | vb2_core_poll(q, file, wait); |
| 830 | 834 | } |
| 831 | 835 | EXPORT_SYMBOL_GPL(vb2_poll); |
| @@ -223,6 +223,13 @@ int __detach_context(struct cxl_context *ctx) · 222 unmodified lines | ||
| 223 | 223 | cxl_ops->link_ok(ctx->afu->adapter, ctx->afu)); |
| 224 | 224 | flush_work(&ctx->fault_work); /* Only needed for dedicated process */ |
| 225 | 225 | |
| 226 | + /* | |
| 227 | + * Wait until no further interrupts are presented by the PSL | |
| 228 | + * for this context. | |
| 229 | + */ | |
| 230 | + if (cxl_ops->irq_wait) | |
| 231 | + cxl_ops->irq_wait(ctx); | |
| 232 | + | |
| 226 | 233 | /* release the reference to the group leader and mm handling pid */ |
| 227 | 234 | put_pid(ctx->pid); |
| 228 | 235 | put_pid(ctx->glpid); |
| @@ -274,6 +274,7 @@ static const cxl_p2n_reg_t CXL_PSL_WED_An = {0x0A0}; · 273 unmodified lines | ||
| 274 | 274 | #define CXL_PSL_DSISR_An_PE (1ull << (63-4)) /* PSL Error (implementation specific) */ |
| 275 | 275 | #define CXL_PSL_DSISR_An_AE (1ull << (63-5)) /* AFU Error */ |
| 276 | 276 | #define CXL_PSL_DSISR_An_OC (1ull << (63-6)) /* OS Context Warning */ |
| 277 | +#define CXL_PSL_DSISR_PENDING (CXL_PSL_DSISR_TRANS | CXL_PSL_DSISR_An_PE | CXL_PSL_DSISR_An_AE | CXL_PSL_DSISR_An_OC) | |
| 277 | 278 | /* NOTE: Bits 32:63 are undefined if DSISR[DS] = 1 */ |
| 278 | 279 | #define CXL_PSL_DSISR_An_M DSISR_NOHPTE /* PTE not found */ |
| 279 | 280 | #define CXL_PSL_DSISR_An_P DSISR_PROTFAULT /* Storage protection violation */ |
| @@ -855,6 +856,7 @@ struct cxl_backend_ops { · 575 unmodified lines | ||
| 855 | 856 | u64 dsisr, u64 errstat); |
| 856 | 857 | irqreturn_t (*psl_interrupt)(int irq, void *data); |
| 857 | 858 | int (*ack_irq)(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask); |
| 859 | + void (*irq_wait)(struct cxl_context *ctx); | |
| 858 | 860 | int (*attach_process)(struct cxl_context *ctx, bool kernel, |
| 859 | 861 | u64 wed, u64 amr); |
| 860 | 862 | int (*detach_process)(struct cxl_context *ctx); |
| @@ -203,7 +203,6 @@ unsigned int cxl_map_irq(struct cxl *adapter, irq_hw_number_t hwirq, · 202 unmodified lines | ||
| 203 | 203 | void cxl_unmap_irq(unsigned int virq, void *cookie) |
| 204 | 204 | { |
| 205 | 205 | free_irq(virq, cookie); |
| 206 | − irq_dispose_mapping(virq); | |
| 207 | 206 | } |
| 208 | 207 | |
| 209 | 208 | int cxl_register_one_irq(struct cxl *adapter, |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | #include <linux/mutex.h> |
| 15 | 15 | #include <linux/mm.h> |
| 16 | 16 | #include <linux/uaccess.h> |
| 17 | +#include <linux/delay.h> | |
| 17 | 18 | #include <asm/synch.h> |
| 18 | 19 | #include <misc/cxl-base.h> |
| 19 | 20 | |
| @@ -797,6 +798,35 @@ static irqreturn_t native_irq_multiplexed(int irq, void *data) · 777 unmodified lines | ||
| 797 | 798 | return fail_psl_irq(afu, &irq_info); |
| 798 | 799 | } |
| 799 | 800 | |
| 801 | +void native_irq_wait(struct cxl_context *ctx) | |
| 802 | +{ | |
| 803 | + u64 dsisr; | |
| 804 | + int timeout = 1000; | |
| 805 | + int ph; | |
| 806 | + | |
| 807 | + /* | |
| 808 | + * Wait until no further interrupts are presented by the PSL | |
| 809 | + * for this context. | |
| 810 | + */ | |
| 811 | + while (timeout--) { | |
| 812 | + ph = cxl_p2n_read(ctx->afu, CXL_PSL_PEHandle_An) & 0xffff; | |
| 813 | + if (ph != ctx->pe) | |
| 814 | + return; | |
| 815 | + dsisr = cxl_p2n_read(ctx->afu, CXL_PSL_DSISR_An); | |
| 816 | + if ((dsisr & CXL_PSL_DSISR_PENDING) == 0) | |
| 817 | + return; | |
| 818 | + /* | |
| 819 | + * We are waiting for the workqueue to process our | |
| 820 | + * irq, so need to let that run here. | |
| 821 | + */ | |
| 822 | + msleep(1); | |
| 823 | + } | |
| 824 | + | |
| 825 | + dev_warn(&ctx->afu->dev, "WARNING: waiting on DSI for PE %i" | |
| 826 | + " DSISR %016llx!\n", ph, dsisr); | |
| 827 | + return; | |
| 828 | +} | |
| 829 | + | |
| 800 | 830 | static irqreturn_t native_slice_irq_err(int irq, void *data) |
| 801 | 831 | { |
| 802 | 832 | struct cxl_afu *afu = data; |
| @@ -1076,6 +1106,7 @@ const struct cxl_backend_ops cxl_native_ops = { · 273 unmodified lines | ||
| 1076 | 1106 | .handle_psl_slice_error = native_handle_psl_slice_error, |
| 1077 | 1107 | .psl_interrupt = NULL, |
| 1078 | 1108 | .ack_irq = native_ack_irq, |
| 1109 | + .irq_wait = native_irq_wait, | |
| 1079 | 1110 | .attach_process = native_attach_process, |
| 1080 | 1111 | .detach_process = native_detach_process, |
| 1081 | 1112 | .support_attributes = native_support_attributes, |
| @@ -97,6 +97,7 @@ config MMC_RICOH_MMC · 96 unmodified lines | ||
| 97 | 97 | config MMC_SDHCI_ACPI |
| 98 | 98 | tristate "SDHCI support for ACPI enumerated SDHCI controllers" |
| 99 | 99 | depends on MMC_SDHCI && ACPI |
| 100 | + select IOSF_MBI if X86 | |
| 100 | 101 | help |
| 101 | 102 | This selects support for ACPI enumerated SDHCI controllers, |
| 102 | 103 | identified by ACPI Compatibility ID PNP0D40 or specific |
| @@ -41,6 +41,11 @@ · 40 unmodified lines | ||
| 41 | 41 | #include <linux/mmc/pm.h> |
| 42 | 42 | #include <linux/mmc/slot-gpio.h> |
| 43 | 43 | |
| 44 | +#ifdef CONFIG_X86 | |
| 45 | +#include <asm/cpu_device_id.h> | |
| 46 | +#include <asm/iosf_mbi.h> | |
| 47 | +#endif | |
| 48 | + | |
| 44 | 49 | #include "sdhci.h" |
| 45 | 50 | |
| 46 | 51 | enum { |
| @@ -116,6 +121,75 @@ static const struct sdhci_acpi_chip sdhci_acpi_chip_int = { · 69 unmodified lines | ||
| 116 | 121 | .ops = &sdhci_acpi_ops_int, |
| 117 | 122 | }; |
| 118 | 123 | |
| 124 | +#ifdef CONFIG_X86 | |
| 125 | + | |
| 126 | +static bool sdhci_acpi_byt(void) | |
| 127 | +{ | |
| 128 | + static const struct x86_cpu_id byt[] = { | |
| 129 | + { X86_VENDOR_INTEL, 6, 0x37 }, | |
| 130 | + {} | |
| 131 | + }; | |
| 132 | + | |
| 133 | + return x86_match_cpu(byt); | |
| 134 | +} | |
| 135 | + | |
| 136 | +#define BYT_IOSF_SCCEP 0x63 | |
| 137 | +#define BYT_IOSF_OCP_NETCTRL0 0x1078 | |
| 138 | +#define BYT_IOSF_OCP_TIMEOUT_BASE GENMASK(10, 8) | |
| 139 | + | |
| 140 | +static void sdhci_acpi_byt_setting(struct device *dev) | |
| 141 | +{ | |
| 142 | + u32 val = 0; | |
| 143 | + | |
| 144 | + if (!sdhci_acpi_byt()) | |
| 145 | + return; | |
| 146 | + | |
| 147 | + if (iosf_mbi_read(BYT_IOSF_SCCEP, MBI_CR_READ, BYT_IOSF_OCP_NETCTRL0, | |
| 148 | + &val)) { | |
| 149 | + dev_err(dev, "%s read error\n", __func__); | |
| 150 | + return; | |
| 151 | + } | |
| 152 | + | |
| 153 | + if (!(val & BYT_IOSF_OCP_TIMEOUT_BASE)) | |
| 154 | + return; | |
| 155 | + | |
| 156 | + val &= ~BYT_IOSF_OCP_TIMEOUT_BASE; | |
| 157 | + | |
| 158 | + if (iosf_mbi_write(BYT_IOSF_SCCEP, MBI_CR_WRITE, BYT_IOSF_OCP_NETCTRL0, | |
| 159 | + val)) { | |
| 160 | + dev_err(dev, "%s write error\n", __func__); | |
| 161 | + return; | |
| 162 | + } | |
| 163 | + | |
| 164 | + dev_dbg(dev, "%s completed\n", __func__); | |
| 165 | +} | |
| 166 | + | |
| 167 | +static bool sdhci_acpi_byt_defer(struct device *dev) | |
| 168 | +{ | |
| 169 | + if (!sdhci_acpi_byt()) | |
| 170 | + return false; | |
| 171 | + | |
| 172 | + if (!iosf_mbi_available()) | |
| 173 | + return true; | |
| 174 | + | |
| 175 | + sdhci_acpi_byt_setting(dev); | |
| 176 | + | |
| 177 | + return false; | |
| 178 | +} | |
| 179 | + | |
| 180 | +#else | |
| 181 | + | |
| 182 | +static inline void sdhci_acpi_byt_setting(struct device *dev) | |
| 183 | +{ | |
| 184 | +} | |
| 185 | + | |
| 186 | +static inline bool sdhci_acpi_byt_defer(struct device *dev) | |
| 187 | +{ | |
| 188 | + return false; | |
| 189 | +} | |
| 190 | + | |
| 191 | +#endif | |
| 192 | + | |
| 119 | 193 | static int bxt_get_cd(struct mmc_host *mmc) |
| 120 | 194 | { |
| 121 | 195 | int gpio_cd = mmc_gpio_get_cd(mmc); |
| @@ -322,6 +396,9 @@ static int sdhci_acpi_probe(struct platform_device *pdev) · 200 unmodified lines | ||
| 322 | 396 | if (acpi_bus_get_status(device) || !device->status.present) |
| 323 | 397 | return -ENODEV; |
| 324 | 398 | |
| 399 | + if (sdhci_acpi_byt_defer(dev)) | |
| 400 | + return -EPROBE_DEFER; | |
| 401 | + | |
| 325 | 402 | hid = acpi_device_hid(device); |
| 326 | 403 | uid = device->pnp.unique_id; |
| 327 | 404 | |
| @@ -447,6 +524,8 @@ static int sdhci_acpi_resume(struct device *dev) · 119 unmodified lines | ||
| 447 | 524 | { |
| 448 | 525 | struct sdhci_acpi_host *c = dev_get_drvdata(dev); |
| 449 | 526 | |
| 527 | + sdhci_acpi_byt_setting(&c->pdev->dev); | |
| 528 | + | |
| 450 | 529 | return sdhci_resume_host(c->host); |
| 451 | 530 | } |
| 452 | 531 | |
| @@ -470,6 +549,8 @@ static int sdhci_acpi_runtime_resume(struct device *dev) · 17 unmodified lines | ||
| 470 | 549 | { |
| 471 | 550 | struct sdhci_acpi_host *c = dev_get_drvdata(dev); |
| 472 | 551 | |
| 552 | + sdhci_acpi_byt_setting(&c->pdev->dev); | |
| 553 | + | |
| 473 | 554 | return sdhci_runtime_resume_host(c->host); |
| 474 | 555 | } |
| 475 | 556 | |
| @@ -1129,6 +1129,11 @@ static int sunxi_mmc_probe(struct platform_device *pdev) · 1128 unmodified lines | ||
| 1129 | 1129 | MMC_CAP_1_8V_DDR | |
| 1130 | 1130 | MMC_CAP_ERASE | MMC_CAP_SDIO_IRQ; |
| 1131 | 1131 | |
| 1132 | + /* TODO MMC DDR is not working on A80 */ | |
| 1133 | + if (of_device_is_compatible(pdev->dev.of_node, | |
| 1134 | + "allwinner,sun9i-a80-mmc")) | |
| 1135 | + mmc->caps &= ~MMC_CAP_1_8V_DDR; | |
| 1136 | + | |
| 1132 | 1137 | ret = mmc_of_parse(mmc); |
| 1133 | 1138 | if (ret) |
| 1134 | 1139 | goto error_free_dma; |
| @@ -2202,7 +2202,7 @@ int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, · 2201 unmodified lines | ||
| 2202 | 2202 | struct net_device *bridge) |
| 2203 | 2203 | { |
| 2204 | 2204 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); |
| 2205 | − int i, err; | |
| 2205 | + int i, err = 0; | |
| 2206 | 2206 | |
| 2207 | 2207 | mutex_lock(&ps->smi_mutex); |
| 2208 | 2208 | |
| @@ -588,12 +588,30 @@ static inline int bnxt_alloc_rx_page(struct bnxt *bp, · 587 unmodified lines | ||
| 588 | 588 | struct page *page; |
| 589 | 589 | dma_addr_t mapping; |
| 590 | 590 | u16 sw_prod = rxr->rx_sw_agg_prod; |
| 591 | + unsigned int offset = 0; | |
| 591 | 592 | |
| 592 | − page = alloc_page(gfp); | |
| 593 | − if (!page) | |
| 594 | − return -ENOMEM; | |
| 593 | + if (PAGE_SIZE > BNXT_RX_PAGE_SIZE) { | |
| 594 | + page = rxr->rx_page; | |
| 595 | + if (!page) { | |
| 596 | + page = alloc_page(gfp); | |
| 597 | + if (!page) | |
| 598 | + return -ENOMEM; | |
| 599 | + rxr->rx_page = page; | |
| 600 | + rxr->rx_page_offset = 0; | |
| 601 | + } | |
| 602 | + offset = rxr->rx_page_offset; | |
| 603 | + rxr->rx_page_offset += BNXT_RX_PAGE_SIZE; | |
| 604 | + if (rxr->rx_page_offset == PAGE_SIZE) | |
| 605 | + rxr->rx_page = NULL; | |
| 606 | + else | |
| 607 | + get_page(page); | |
| 608 | + } else { | |
| 609 | + page = alloc_page(gfp); | |
| 610 | + if (!page) | |
| 611 | + return -ENOMEM; | |
| 612 | + } | |
| 595 | 613 | |
| 596 | − mapping = dma_map_page(&pdev->dev, page, 0, PAGE_SIZE, | |
| 614 | + mapping = dma_map_page(&pdev->dev, page, offset, BNXT_RX_PAGE_SIZE, | |
| 597 | 615 | PCI_DMA_FROMDEVICE); |
| 598 | 616 | if (dma_mapping_error(&pdev->dev, mapping)) { |
| 599 | 617 | __free_page(page); |
| @@ -608,6 +626,7 @@ static inline int bnxt_alloc_rx_page(struct bnxt *bp, · 8 unmodified lines | ||
| 608 | 626 | rxr->rx_sw_agg_prod = NEXT_RX_AGG(sw_prod); |
| 609 | 627 | |
| 610 | 628 | rx_agg_buf->page = page; |
| 629 | + rx_agg_buf->offset = offset; | |
| 611 | 630 | rx_agg_buf->mapping = mapping; |
| 612 | 631 | rxbd->rx_bd_haddr = cpu_to_le64(mapping); |
| 613 | 632 | rxbd->rx_bd_opaque = sw_prod; |
| @@ -649,6 +668,7 @@ static void bnxt_reuse_rx_agg_bufs(struct bnxt_napi *bnapi, u16 cp_cons, · 35 unmodified lines | ||
| 649 | 668 | page = cons_rx_buf->page; |
| 650 | 669 | cons_rx_buf->page = NULL; |
| 651 | 670 | prod_rx_buf->page = page; |
| 671 | + prod_rx_buf->offset = cons_rx_buf->offset; | |
| 652 | 672 | |
| 653 | 673 | prod_rx_buf->mapping = cons_rx_buf->mapping; |
| 654 | 674 | |
| @@ -716,7 +736,8 @@ static struct sk_buff *bnxt_rx_pages(struct bnxt *bp, struct bnxt_napi *bnapi, · 61 unmodified lines | ||
| 716 | 736 | RX_AGG_CMP_LEN) >> RX_AGG_CMP_LEN_SHIFT; |
| 717 | 737 | |
| 718 | 738 | cons_rx_buf = &rxr->rx_agg_ring[cons]; |
| 719 | − skb_fill_page_desc(skb, i, cons_rx_buf->page, 0, frag_len); | |
| 739 | + skb_fill_page_desc(skb, i, cons_rx_buf->page, | |
| 740 | + cons_rx_buf->offset, frag_len); | |
| 720 | 741 | __clear_bit(cons, rxr->rx_agg_bmap); |
| 721 | 742 | |
| 722 | 743 | /* It is possible for bnxt_alloc_rx_page() to allocate |
| @@ -747,7 +768,7 @@ static struct sk_buff *bnxt_rx_pages(struct bnxt *bp, struct bnxt_napi *bnapi, · 24 unmodified lines | ||
| 747 | 768 | return NULL; |
| 748 | 769 | } |
| 749 | 770 | |
| 750 | − dma_unmap_page(&pdev->dev, mapping, PAGE_SIZE, | |
| 771 | + dma_unmap_page(&pdev->dev, mapping, BNXT_RX_PAGE_SIZE, | |
| 751 | 772 | PCI_DMA_FROMDEVICE); |
| 752 | 773 | |
| 753 | 774 | skb->data_len += frag_len; |
| @@ -1635,13 +1656,17 @@ static void bnxt_free_rx_skbs(struct bnxt *bp) · 881 unmodified lines | ||
| 1635 | 1656 | |
| 1636 | 1657 | dma_unmap_page(&pdev->dev, |
| 1637 | 1658 | dma_unmap_addr(rx_agg_buf, mapping), |
| 1638 | − PAGE_SIZE, PCI_DMA_FROMDEVICE); | |
| 1659 | + BNXT_RX_PAGE_SIZE, PCI_DMA_FROMDEVICE); | |
| 1639 | 1660 | |
| 1640 | 1661 | rx_agg_buf->page = NULL; |
| 1641 | 1662 | __clear_bit(j, rxr->rx_agg_bmap); |
| 1642 | 1663 | |
| 1643 | 1664 | __free_page(page); |
| 1644 | 1665 | } |
| 1666 | + if (rxr->rx_page) { | |
| 1667 | + __free_page(rxr->rx_page); | |
| 1668 | + rxr->rx_page = NULL; | |
| 1669 | + } | |
| 1645 | 1670 | } |
| 1646 | 1671 | } |
| 1647 | 1672 | |
| @@ -2024,7 +2049,7 @@ static int bnxt_init_one_rx_ring(struct bnxt *bp, int ring_nr) · 376 unmodified lines | ||
| 2024 | 2049 | if (!(bp->flags & BNXT_FLAG_AGG_RINGS)) |
| 2025 | 2050 | return 0; |
| 2026 | 2051 | |
| 2027 | − type = ((u32)PAGE_SIZE << RX_BD_LEN_SHIFT) | | |
| 2052 | + type = ((u32)BNXT_RX_PAGE_SIZE << RX_BD_LEN_SHIFT) | | |
| 2028 | 2053 | RX_BD_TYPE_RX_AGG_BD | RX_BD_FLAGS_SOP; |
| 2029 | 2054 | |
| 2030 | 2055 | bnxt_init_rxbd_pages(ring, type); |
| @@ -2215,7 +2240,7 @@ void bnxt_set_ring_params(struct bnxt *bp) · 184 unmodified lines | ||
| 2215 | 2240 | bp->rx_agg_nr_pages = 0; |
| 2216 | 2241 | |
| 2217 | 2242 | if (bp->flags & BNXT_FLAG_TPA) |
| 2218 | − agg_factor = 4; | |
| 2243 | + agg_factor = min_t(u32, 4, 65536 / BNXT_RX_PAGE_SIZE); | |
| 2219 | 2244 | |
| 2220 | 2245 | bp->flags &= ~BNXT_FLAG_JUMBO; |
| 2221 | 2246 | if (rx_space > PAGE_SIZE) { |
| @@ -3076,12 +3101,12 @@ static int bnxt_hwrm_vnic_set_tpa(struct bnxt *bp, u16 vnic_id, u32 tpa_flags) · 854 unmodified lines | ||
| 3076 | 3101 | /* Number of segs are log2 units, and first packet is not |
| 3077 | 3102 | * included as part of this units. |
| 3078 | 3103 | */ |
| 3079 | − if (mss <= PAGE_SIZE) { | |
| 3080 | − n = PAGE_SIZE / mss; | |
| 3104 | + if (mss <= BNXT_RX_PAGE_SIZE) { | |
| 3105 | + n = BNXT_RX_PAGE_SIZE / mss; | |
| 3081 | 3106 | nsegs = (MAX_SKB_FRAGS - 1) * n; |
| 3082 | 3107 | } else { |
| 3083 | − n = mss / PAGE_SIZE; | |
| 3084 | − if (mss & (PAGE_SIZE - 1)) | |
| 3108 | + n = mss / BNXT_RX_PAGE_SIZE; | |
| 3109 | + if (mss & (BNXT_RX_PAGE_SIZE - 1)) | |
| 3085 | 3110 | n++; |
| 3086 | 3111 | nsegs = (MAX_SKB_FRAGS - n) / n; |
| 3087 | 3112 | } |
| @@ -4367,7 +4392,7 @@ static int bnxt_setup_int_mode(struct bnxt *bp) · 1279 unmodified lines | ||
| 4367 | 4392 | if (bp->flags & BNXT_FLAG_MSIX_CAP) |
| 4368 | 4393 | rc = bnxt_setup_msix(bp); |
| 4369 | 4394 | |
| 4370 | − if (!(bp->flags & BNXT_FLAG_USING_MSIX)) { | |
| 4395 | + if (!(bp->flags & BNXT_FLAG_USING_MSIX) && BNXT_PF(bp)) { | |
| 4371 | 4396 | /* fallback to INTA */ |
| 4372 | 4397 | rc = bnxt_setup_inta(bp); |
| 4373 | 4398 | } |
| @@ -407,6 +407,15 @@ struct rx_tpa_end_cmp_ext { · 406 unmodified lines | ||
| 407 | 407 | |
| 408 | 408 | #define BNXT_PAGE_SIZE (1 << BNXT_PAGE_SHIFT) |
| 409 | 409 | |
| 410 | +/* The RXBD length is 16-bit so we can only support page sizes < 64K */ | |
| 411 | +#if (PAGE_SHIFT > 15) | |
| 412 | +#define BNXT_RX_PAGE_SHIFT 15 | |
| 413 | +#else | |
| 414 | +#define BNXT_RX_PAGE_SHIFT PAGE_SHIFT | |
| 415 | +#endif | |
| 416 | + | |
| 417 | +#define BNXT_RX_PAGE_SIZE (1 << BNXT_RX_PAGE_SHIFT) | |
| 418 | + | |
| 410 | 419 | #define BNXT_MIN_PKT_SIZE 45 |
| 411 | 420 | |
| 412 | 421 | #define BNXT_NUM_TESTS(bp) 0 |
| @@ -506,6 +515,7 @@ struct bnxt_sw_rx_bd { · 93 unmodified lines | ||
| 506 | 515 | |
| 507 | 516 | struct bnxt_sw_rx_agg_bd { |
| 508 | 517 | struct page *page; |
| 518 | + unsigned int offset; | |
| 509 | 519 | dma_addr_t mapping; |
| 510 | 520 | }; |
| 511 | 521 | |
| @@ -586,6 +596,9 @@ struct bnxt_rx_ring_info { · 74 unmodified lines | ||
| 586 | 596 | unsigned long *rx_agg_bmap; |
| 587 | 597 | u16 rx_agg_bmap_size; |
| 588 | 598 | |
| 599 | + struct page *rx_page; | |
| 600 | + unsigned int rx_page_offset; | |
| 601 | + | |
| 589 | 602 | dma_addr_t rx_desc_mapping[MAX_RX_PAGES]; |
| 590 | 603 | dma_addr_t rx_agg_desc_mapping[MAX_RX_AGG_PAGES]; |
| 591 | 604 | |
| @@ -440,7 +440,7 @@ static int macb_mii_init(struct macb *bp) · 439 unmodified lines | ||
| 440 | 440 | snprintf(bp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x", |
| 441 | 441 | bp->pdev->name, bp->pdev->id); |
| 442 | 442 | bp->mii_bus->priv = bp; |
| 443 | − bp->mii_bus->parent = &bp->dev->dev; | |
| 443 | + bp->mii_bus->parent = &bp->pdev->dev; | |
| 444 | 444 | pdata = dev_get_platdata(&bp->pdev->dev); |
| 445 | 445 | |
| 446 | 446 | dev_set_drvdata(&bp->dev->dev, bp->mii_bus); |
| @@ -458,7 +458,8 @@ static int macb_mii_init(struct macb *bp) · 11 unmodified lines | ||
| 458 | 458 | struct phy_device *phydev; |
| 459 | 459 | |
| 460 | 460 | phydev = mdiobus_scan(bp->mii_bus, i); |
| 461 | − if (IS_ERR(phydev)) { | |
| 461 | + if (IS_ERR(phydev) && | |
| 462 | + PTR_ERR(phydev) != -ENODEV) { | |
| 462 | 463 | err = PTR_ERR(phydev); |
| 463 | 464 | break; |
| 464 | 465 | } |
| @@ -3005,29 +3006,36 @@ static int macb_probe(struct platform_device *pdev) · 2540 unmodified lines | ||
| 3005 | 3006 | if (err) |
| 3006 | 3007 | goto err_out_free_netdev; |
| 3007 | 3008 | |
| 3009 | + err = macb_mii_init(bp); | |
| 3010 | + if (err) | |
| 3011 | + goto err_out_free_netdev; | |
| 3012 | + | |
| 3013 | + phydev = bp->phy_dev; | |
| 3014 | + | |
| 3015 | + netif_carrier_off(dev); | |
| 3016 | + | |
| 3008 | 3017 | err = register_netdev(dev); |
| 3009 | 3018 | if (err) { |
| 3010 | 3019 | dev_err(&pdev->dev, "Cannot register net device, aborting.\n"); |
| 3011 | − goto err_out_unregister_netdev; | |
| 3020 | + goto err_out_unregister_mdio; | |
| 3012 | 3021 | } |
| 3013 | 3022 | |
| 3014 | − err = macb_mii_init(bp); | |
| 3015 | − if (err) | |
| 3016 | − goto err_out_unregister_netdev; | |
| 3017 | − | |
| 3018 | − netif_carrier_off(dev); | |
| 3023 | + phy_attached_info(phydev); | |
| 3019 | 3024 | |
| 3020 | 3025 | netdev_info(dev, "Cadence %s rev 0x%08x at 0x%08lx irq %d (%pM)\n", |
| 3021 | 3026 | macb_is_gem(bp) ? "GEM" : "MACB", macb_readl(bp, MID), |
| 3022 | 3027 | dev->base_addr, dev->irq, dev->dev_addr); |
| 3023 | 3028 | |
| 3024 | − phydev = bp->phy_dev; | |
| 3025 | − phy_attached_info(phydev); | |
| 3026 | − | |
| 3027 | 3029 | return 0; |
| 3028 | 3030 | |
| 3029 | −err_out_unregister_netdev: | |
| 3030 | − unregister_netdev(dev); | |
| 3031 | +err_out_unregister_mdio: | |
| 3032 | + phy_disconnect(bp->phy_dev); | |
| 3033 | + mdiobus_unregister(bp->mii_bus); | |
| 3034 | + mdiobus_free(bp->mii_bus); | |
| 3035 | + | |
| 3036 | + /* Shutdown the PHY if there is a GPIO reset */ | |
| 3037 | + if (bp->reset_gpio) | |
| 3038 | + gpiod_set_value(bp->reset_gpio, 0); | |
| 3031 | 3039 | |
| 3032 | 3040 | err_out_free_netdev: |
| 3033 | 3041 | free_netdev(dev); |
| @@ -576,7 +576,7 @@ static void setup_rss(struct adapter *adap) · 575 unmodified lines | ||
| 576 | 576 | unsigned int nq0 = adap2pinfo(adap, 0)->nqsets; |
| 577 | 577 | unsigned int nq1 = adap->port[1] ? adap2pinfo(adap, 1)->nqsets : 1; |
| 578 | 578 | u8 cpus[SGE_QSETS + 1]; |
| 579 | − u16 rspq_map[RSS_TABLE_SIZE]; | |
| 579 | + u16 rspq_map[RSS_TABLE_SIZE + 1]; | |
| 580 | 580 | |
| 581 | 581 | for (i = 0; i < SGE_QSETS; ++i) |
| 582 | 582 | cpus[i] = i; |
| @@ -586,6 +586,7 @@ static void setup_rss(struct adapter *adap) · 3 unmodified lines | ||
| 586 | 586 | rspq_map[i] = i % nq0; |
| 587 | 587 | rspq_map[i + RSS_TABLE_SIZE / 2] = (i % nq1) + nq0; |
| 588 | 588 | } |
| 589 | + rspq_map[RSS_TABLE_SIZE] = 0xffff; /* terminator */ | |
| 589 | 590 | |
| 590 | 591 | t3_config_rss(adap, F_RQFEEDBACKENABLE | F_TNLLKPEN | F_TNLMAPEN | |
| 591 | 592 | F_TNLPRTEN | F_TNL2TUPEN | F_TNL4TUPEN | |
| @@ -3354,8 +3354,7 @@ static int mvneta_percpu_notifier(struct notifier_block *nfb, · 3353 unmodified lines | ||
| 3354 | 3354 | /* Enable per-CPU interrupts on the CPU that is |
| 3355 | 3355 | * brought up. |
| 3356 | 3356 | */ |
| 3357 | − smp_call_function_single(cpu, mvneta_percpu_enable, | |
| 3358 | − pp, true); | |
| 3357 | + mvneta_percpu_enable(pp); | |
| 3359 | 3358 | |
| 3360 | 3359 | /* Enable per-CPU interrupt on the one CPU we care |
| 3361 | 3360 | * about. |
| @@ -3387,8 +3386,7 @@ static int mvneta_percpu_notifier(struct notifier_block *nfb, · 25 unmodified lines | ||
| 3387 | 3386 | /* Disable per-CPU interrupts on the CPU that is |
| 3388 | 3387 | * brought down. |
| 3389 | 3388 | */ |
| 3390 | − smp_call_function_single(cpu, mvneta_percpu_disable, | |
| 3391 | − pp, true); | |
| 3389 | + mvneta_percpu_disable(pp); | |
| 3392 | 3390 | |
| 3393 | 3391 | break; |
| 3394 | 3392 | case CPU_DEAD: |
| @@ -979,6 +979,8 @@ static int pxa168_init_phy(struct net_device *dev) · 978 unmodified lines | ||
| 979 | 979 | return 0; |
| 980 | 980 | |
| 981 | 981 | pep->phy = mdiobus_scan(pep->smi_bus, pep->phy_addr); |
| 982 | + if (IS_ERR(pep->phy)) | |
| 983 | + return PTR_ERR(pep->phy); | |
| 982 | 984 | if (!pep->phy) |
| 983 | 985 | return -ENODEV; |
| 984 | 986 | |
| @@ -14,6 +14,7 @@ config MLX5_CORE_EN · 13 unmodified lines | ||
| 14 | 14 | bool "Mellanox Technologies ConnectX-4 Ethernet support" |
| 15 | 15 | depends on NETDEVICES && ETHERNET && PCI && MLX5_CORE |
| 16 | 16 | select PTP_1588_CLOCK |
| 17 | + select VXLAN if MLX5_CORE=y | |
| 17 | 18 | default n |
| 18 | 19 | ---help--- |
| 19 | 20 | Ethernet support in Mellanox Technologies ConnectX-4 NIC. |
| @@ -525,6 +525,7 @@ struct mlx5e_priv { · 524 unmodified lines | ||
| 525 | 525 | struct mlx5e_vxlan_db vxlan; |
| 526 | 526 | |
| 527 | 527 | struct mlx5e_params params; |
| 528 | + struct workqueue_struct *wq; | |
| 528 | 529 | struct work_struct update_carrier_work; |
| 529 | 530 | struct work_struct set_rx_mode_work; |
| 530 | 531 | struct delayed_work update_stats_work; |
| @@ -231,9 +231,8 @@ static void mlx5e_update_stats_work(struct work_struct *work) · 230 unmodified lines | ||
| 231 | 231 | mutex_lock(&priv->state_lock); |
| 232 | 232 | if (test_bit(MLX5E_STATE_OPENED, &priv->state)) { |
| 233 | 233 | mlx5e_update_stats(priv); |
| 234 | − schedule_delayed_work(dwork, | |
| 235 | − msecs_to_jiffies( | |
| 236 | − MLX5E_UPDATE_STATS_INTERVAL)); | |
| 234 | + queue_delayed_work(priv->wq, dwork, | |
| 235 | + msecs_to_jiffies(MLX5E_UPDATE_STATS_INTERVAL)); | |
| 237 | 236 | } |
| 238 | 237 | mutex_unlock(&priv->state_lock); |
| 239 | 238 | } |
| @@ -249,7 +248,7 @@ static void mlx5e_async_event(struct mlx5_core_dev *mdev, void *vpriv, · 9 unmodified lines | ||
| 249 | 248 | switch (event) { |
| 250 | 249 | case MLX5_DEV_EVENT_PORT_UP: |
| 251 | 250 | case MLX5_DEV_EVENT_PORT_DOWN: |
| 252 | − schedule_work(&priv->update_carrier_work); | |
| 251 | + queue_work(priv->wq, &priv->update_carrier_work); | |
| 253 | 252 | break; |
| 254 | 253 | |
| 255 | 254 | default: |
| @@ -1695,7 +1694,7 @@ int mlx5e_open_locked(struct net_device *netdev) · 1439 unmodified lines | ||
| 1695 | 1694 | priv->netdev->rx_cpu_rmap = priv->mdev->rmap; |
| 1696 | 1695 | #endif |
| 1697 | 1696 | |
| 1698 | − schedule_delayed_work(&priv->update_stats_work, 0); | |
| 1697 | + queue_delayed_work(priv->wq, &priv->update_stats_work, 0); | |
| 1699 | 1698 | |
| 1700 | 1699 | return 0; |
| 1701 | 1700 | |
| @@ -2202,7 +2201,7 @@ static void mlx5e_set_rx_mode(struct net_device *dev) · 500 unmodified lines | ||
| 2202 | 2201 | { |
| 2203 | 2202 | struct mlx5e_priv *priv = netdev_priv(dev); |
| 2204 | 2203 | |
| 2205 | − schedule_work(&priv->set_rx_mode_work); | |
| 2204 | + queue_work(priv->wq, &priv->set_rx_mode_work); | |
| 2206 | 2205 | } |
| 2207 | 2206 | |
| 2208 | 2207 | static int mlx5e_set_mac(struct net_device *netdev, void *addr) |
| @@ -2217,7 +2216,7 @@ static int mlx5e_set_mac(struct net_device *netdev, void *addr) · 8 unmodified lines | ||
| 2217 | 2216 | ether_addr_copy(netdev->dev_addr, saddr->sa_data); |
| 2218 | 2217 | netif_addr_unlock_bh(netdev); |
| 2219 | 2218 | |
| 2220 | − schedule_work(&priv->set_rx_mode_work); | |
| 2219 | + queue_work(priv->wq, &priv->set_rx_mode_work); | |
| 2221 | 2220 | |
| 2222 | 2221 | return 0; |
| 2223 | 2222 | } |
| @@ -2503,7 +2502,7 @@ static void mlx5e_add_vxlan_port(struct net_device *netdev, · 279 unmodified lines | ||
| 2503 | 2502 | if (!mlx5e_vxlan_allowed(priv->mdev)) |
| 2504 | 2503 | return; |
| 2505 | 2504 | |
| 2506 | − mlx5e_vxlan_add_port(priv, be16_to_cpu(port)); | |
| 2505 | + mlx5e_vxlan_queue_work(priv, sa_family, be16_to_cpu(port), 1); | |
| 2507 | 2506 | } |
| 2508 | 2507 | |
| 2509 | 2508 | static void mlx5e_del_vxlan_port(struct net_device *netdev, |
| @@ -2514,7 +2513,7 @@ static void mlx5e_del_vxlan_port(struct net_device *netdev, · 4 unmodified lines | ||
| 2514 | 2513 | if (!mlx5e_vxlan_allowed(priv->mdev)) |
| 2515 | 2514 | return; |
| 2516 | 2515 | |
| 2517 | − mlx5e_vxlan_del_port(priv, be16_to_cpu(port)); | |
| 2516 | + mlx5e_vxlan_queue_work(priv, sa_family, be16_to_cpu(port), 0); | |
| 2518 | 2517 | } |
| 2519 | 2518 | |
| 2520 | 2519 | static netdev_features_t mlx5e_vxlan_features_check(struct mlx5e_priv *priv, |
| @@ -2947,10 +2946,14 @@ static void *mlx5e_create_netdev(struct mlx5_core_dev *mdev) · 426 unmodified lines | ||
| 2947 | 2946 | |
| 2948 | 2947 | priv = netdev_priv(netdev); |
| 2949 | 2948 | |
| 2949 | + priv->wq = create_singlethread_workqueue("mlx5e"); | |
| 2950 | + if (!priv->wq) | |
| 2951 | + goto err_free_netdev; | |
| 2952 | + | |
| 2950 | 2953 | err = mlx5_alloc_map_uar(mdev, &priv->cq_uar, false); |
| 2951 | 2954 | if (err) { |
| 2952 | 2955 | mlx5_core_err(mdev, "alloc_map uar failed, %d\n", err); |
| 2953 | − goto err_free_netdev; | |
| 2956 | + goto err_destroy_wq; | |
| 2954 | 2957 | } |
| 2955 | 2958 | |
| 2956 | 2959 | err = mlx5_core_alloc_pd(mdev, &priv->pdn); |
| @@ -3034,7 +3037,7 @@ static void *mlx5e_create_netdev(struct mlx5_core_dev *mdev) · 77 unmodified lines | ||
| 3034 | 3037 | } |
| 3035 | 3038 | |
| 3036 | 3039 | mlx5e_enable_async_events(priv); |
| 3037 | − schedule_work(&priv->set_rx_mode_work); | |
| 3040 | + queue_work(priv->wq, &priv->set_rx_mode_work); | |
| 3038 | 3041 | |
| 3039 | 3042 | return priv; |
| 3040 | 3043 | |
| @@ -3072,6 +3075,9 @@ err_dealloc_pd: · 31 unmodified lines | ||
| 3072 | 3075 | err_unmap_free_uar: |
| 3073 | 3076 | mlx5_unmap_free_uar(mdev, &priv->cq_uar); |
| 3074 | 3077 | |
| 3078 | +err_destroy_wq: | |
| 3079 | + destroy_workqueue(priv->wq); | |
| 3080 | + | |
| 3075 | 3081 | err_free_netdev: |
| 3076 | 3082 | free_netdev(netdev); |
| 3077 | 3083 | |
| @@ -3085,9 +3091,9 @@ static void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, void *vpriv) · 7 unmodified lines | ||
| 3085 | 3091 | |
| 3086 | 3092 | set_bit(MLX5E_STATE_DESTROYING, &priv->state); |
| 3087 | 3093 | |
| 3088 | − schedule_work(&priv->set_rx_mode_work); | |
| 3094 | + queue_work(priv->wq, &priv->set_rx_mode_work); | |
| 3089 | 3095 | mlx5e_disable_async_events(priv); |
| 3090 | − flush_scheduled_work(); | |
| 3096 | + flush_workqueue(priv->wq); | |
| 3091 | 3097 | if (test_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &mdev->intf_state)) { |
| 3092 | 3098 | netif_device_detach(netdev); |
| 3093 | 3099 | mutex_lock(&priv->state_lock); |
| @@ -3111,6 +3117,8 @@ static void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, void *vpriv) · 17 unmodified lines | ||
| 3111 | 3117 | mlx5_core_dealloc_transport_domain(priv->mdev, priv->tdn); |
| 3112 | 3118 | mlx5_core_dealloc_pd(priv->mdev, priv->pdn); |
| 3113 | 3119 | mlx5_unmap_free_uar(priv->mdev, &priv->cq_uar); |
| 3120 | + cancel_delayed_work_sync(&priv->update_stats_work); | |
| 3121 | + destroy_workqueue(priv->wq); | |
| 3114 | 3122 | |
| 3115 | 3123 | if (!test_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &mdev->intf_state)) |
| 3116 | 3124 | free_netdev(netdev); |
| @@ -269,8 +269,10 @@ EXPORT_SYMBOL(mlx5_alloc_map_uar); · 268 unmodified lines | ||
| 269 | 269 | |
| 270 | 270 | void mlx5_unmap_free_uar(struct mlx5_core_dev *mdev, struct mlx5_uar *uar) |
| 271 | 271 | { |
| 272 | − iounmap(uar->map); | |
| 273 | − iounmap(uar->bf_map); | |
| 272 | + if (uar->map) | |
| 273 | + iounmap(uar->map); | |
| 274 | + else | |
| 275 | + iounmap(uar->bf_map); | |
| 274 | 276 | mlx5_cmd_free_uar(mdev, uar->index); |
| 275 | 277 | } |
| 276 | 278 | EXPORT_SYMBOL(mlx5_unmap_free_uar); |
| @@ -95,21 +95,22 @@ struct mlx5e_vxlan *mlx5e_vxlan_lookup_port(struct mlx5e_priv *priv, u16 port) · 94 unmodified lines | ||
| 95 | 95 | return vxlan; |
| 96 | 96 | } |
| 97 | 97 | |
| 98 | −int mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port) | |
| 98 | +static void mlx5e_vxlan_add_port(struct work_struct *work) | |
| 99 | 99 | { |
| 100 | + struct mlx5e_vxlan_work *vxlan_work = | |
| 101 | + container_of(work, struct mlx5e_vxlan_work, work); | |
| 102 | + struct mlx5e_priv *priv = vxlan_work->priv; | |
| 100 | 103 | struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan; |
| 104 | + u16 port = vxlan_work->port; | |
| 101 | 105 | struct mlx5e_vxlan *vxlan; |
| 102 | 106 | int err; |
| 103 | 107 | |
| 104 | − err = mlx5e_vxlan_core_add_port_cmd(priv->mdev, port); | |
| 105 | − if (err) | |
| 106 | − return err; | |
| 108 | + if (mlx5e_vxlan_core_add_port_cmd(priv->mdev, port)) | |
| 109 | + goto free_work; | |
| 107 | 110 | |
| 108 | 111 | vxlan = kzalloc(sizeof(*vxlan), GFP_KERNEL); |
| 109 | − if (!vxlan) { | |
| 110 | − err = -ENOMEM; | |
| 112 | + if (!vxlan) | |
| 111 | 113 | goto err_delete_port; |
| 112 | − } | |
| 113 | 114 | |
| 114 | 115 | vxlan->udp_port = port; |
| 115 | 116 | |
| @@ -119,13 +120,14 @@ int mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port) · 3 unmodified lines | ||
| 119 | 120 | if (err) |
| 120 | 121 | goto err_free; |
| 121 | 122 | |
| 122 | − return 0; | |
| 123 | + goto free_work; | |
| 123 | 124 | |
| 124 | 125 | err_free: |
| 125 | 126 | kfree(vxlan); |
| 126 | 127 | err_delete_port: |
| 127 | 128 | mlx5e_vxlan_core_del_port_cmd(priv->mdev, port); |
| 128 | − return err; | |
| 129 | +free_work: | |
| 130 | + kfree(vxlan_work); | |
| 129 | 131 | } |
| 130 | 132 | |
| 131 | 133 | static void __mlx5e_vxlan_core_del_port(struct mlx5e_priv *priv, u16 port) |
| @@ -145,12 +147,36 @@ static void __mlx5e_vxlan_core_del_port(struct mlx5e_priv *priv, u16 port) · 13 unmodified lines | ||
| 145 | 147 | kfree(vxlan); |
| 146 | 148 | } |
| 147 | 149 | |
| 148 | −void mlx5e_vxlan_del_port(struct mlx5e_priv *priv, u16 port) | |
| 150 | +static void mlx5e_vxlan_del_port(struct work_struct *work) | |
| 149 | 151 | { |
| 150 | − if (!mlx5e_vxlan_lookup_port(priv, port)) | |
| 151 | − return; | |
| 152 | + struct mlx5e_vxlan_work *vxlan_work = | |
| 153 | + container_of(work, struct mlx5e_vxlan_work, work); | |
| 154 | + struct mlx5e_priv *priv = vxlan_work->priv; | |
| 155 | + u16 port = vxlan_work->port; | |
| 152 | 156 | |
| 153 | 157 | __mlx5e_vxlan_core_del_port(priv, port); |
| 158 | + | |
| 159 | + kfree(vxlan_work); | |
| 160 | +} | |
| 161 | + | |
| 162 | +void mlx5e_vxlan_queue_work(struct mlx5e_priv *priv, sa_family_t sa_family, | |
| 163 | + u16 port, int add) | |
| 164 | +{ | |
| 165 | + struct mlx5e_vxlan_work *vxlan_work; | |
| 166 | + | |
| 167 | + vxlan_work = kmalloc(sizeof(*vxlan_work), GFP_ATOMIC); | |
| 168 | + if (!vxlan_work) | |
| 169 | + return; | |
| 170 | + | |
| 171 | + if (add) | |
| 172 | + INIT_WORK(&vxlan_work->work, mlx5e_vxlan_add_port); | |
| 173 | + else | |
| 174 | + INIT_WORK(&vxlan_work->work, mlx5e_vxlan_del_port); | |
| 175 | + | |
| 176 | + vxlan_work->priv = priv; | |
| 177 | + vxlan_work->port = port; | |
| 178 | + vxlan_work->sa_family = sa_family; | |
| 179 | + queue_work(priv->wq, &vxlan_work->work); | |
| 154 | 180 | } |
| 155 | 181 | |
| 156 | 182 | void mlx5e_vxlan_cleanup(struct mlx5e_priv *priv) |
| @@ -39,6 +39,13 @@ struct mlx5e_vxlan { · 38 unmodified lines | ||
| 39 | 39 | u16 udp_port; |
| 40 | 40 | }; |
| 41 | 41 | |
| 42 | +struct mlx5e_vxlan_work { | |
| 43 | + struct work_struct work; | |
| 44 | + struct mlx5e_priv *priv; | |
| 45 | + sa_family_t sa_family; | |
| 46 | + u16 port; | |
| 47 | +}; | |
| 48 | + | |
| 42 | 49 | static inline bool mlx5e_vxlan_allowed(struct mlx5_core_dev *mdev) |
| 43 | 50 | { |
| 44 | 51 | return (MLX5_CAP_ETH(mdev, tunnel_stateless_vxlan) && |
| @@ -46,8 +53,8 @@ static inline bool mlx5e_vxlan_allowed(struct mlx5_core_dev *mdev) · 1 unmodified line | ||
| 46 | 53 | } |
| 47 | 54 | |
| 48 | 55 | void mlx5e_vxlan_init(struct mlx5e_priv *priv); |
| 49 | −int mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port); | |
| 50 | −void mlx5e_vxlan_del_port(struct mlx5e_priv *priv, u16 port); | |
| 56 | +void mlx5e_vxlan_queue_work(struct mlx5e_priv *priv, sa_family_t sa_family, | |
| 57 | + u16 port, int add); | |
| 51 | 58 | struct mlx5e_vxlan *mlx5e_vxlan_lookup_port(struct mlx5e_priv *priv, u16 port); |
| 52 | 59 | void mlx5e_vxlan_cleanup(struct mlx5e_priv *priv); |
| 53 | 60 | |
| @@ -2668,9 +2668,9 @@ static int myri10ge_close(struct net_device *dev) · 2667 unmodified lines | ||
| 2668 | 2668 | |
| 2669 | 2669 | del_timer_sync(&mgp->watchdog_timer); |
| 2670 | 2670 | mgp->running = MYRI10GE_ETH_STOPPING; |
| 2671 | − local_bh_disable(); /* myri10ge_ss_lock_napi needs bh disabled */ | |
| 2672 | 2671 | for (i = 0; i < mgp->num_slices; i++) { |
| 2673 | 2672 | napi_disable(&mgp->ss[i].napi); |
| 2673 | + local_bh_disable(); /* myri10ge_ss_lock_napi needs this */ | |
| 2674 | 2674 | /* Lock the slice to prevent the busy_poll handler from |
| 2675 | 2675 | * accessing it. Later when we bring the NIC up, myri10ge_open |
| 2676 | 2676 | * resets the slice including this lock. |
| @@ -2679,8 +2679,8 @@ static int myri10ge_close(struct net_device *dev) · 2 unmodified lines | ||
| 2679 | 2679 | pr_info("Slice %d locked\n", i); |
| 2680 | 2680 | mdelay(1); |
| 2681 | 2681 | } |
| 2682 | + local_bh_enable(); | |
| 2682 | 2683 | } |
| 2683 | − local_bh_enable(); | |
| 2684 | 2684 | netif_carrier_off(dev); |
| 2685 | 2685 | |
| 2686 | 2686 | netif_tx_stop_all_queues(dev); |
| @@ -1920,6 +1920,10 @@ static int efx_ef10_alloc_rss_context(struct efx_nic *efx, u32 *context, · 1919 unmodified lines | ||
| 1920 | 1920 | return 0; |
| 1921 | 1921 | } |
| 1922 | 1922 | |
| 1923 | + if (nic_data->datapath_caps & | |
| 1924 | + 1 << MC_CMD_GET_CAPABILITIES_OUT_RX_RSS_LIMITED_LBN) | |
| 1925 | + return -EOPNOTSUPP; | |
| 1926 | + | |
| 1923 | 1927 | MCDI_SET_DWORD(inbuf, RSS_CONTEXT_ALLOC_IN_UPSTREAM_PORT_ID, |
| 1924 | 1928 | nic_data->vport_id); |
| 1925 | 1929 | MCDI_SET_DWORD(inbuf, RSS_CONTEXT_ALLOC_IN_TYPE, alloc_type); |
| @@ -2923,9 +2927,16 @@ static void efx_ef10_filter_push_prep(struct efx_nic *efx, · 997 unmodified lines | ||
| 2923 | 2927 | bool replacing) |
| 2924 | 2928 | { |
| 2925 | 2929 | struct efx_ef10_nic_data *nic_data = efx->nic_data; |
| 2930 | + u32 flags = spec->flags; | |
| 2926 | 2931 | |
| 2927 | 2932 | memset(inbuf, 0, MC_CMD_FILTER_OP_IN_LEN); |
| 2928 | 2933 | |
| 2934 | + /* Remove RSS flag if we don't have an RSS context. */ | |
| 2935 | + if (flags & EFX_FILTER_FLAG_RX_RSS && | |
| 2936 | + spec->rss_context == EFX_FILTER_RSS_CONTEXT_DEFAULT && | |
| 2937 | + nic_data->rx_rss_context == EFX_EF10_RSS_CONTEXT_INVALID) | |
| 2938 | + flags &= ~EFX_FILTER_FLAG_RX_RSS; | |
| 2939 | + | |
| 2929 | 2940 | if (replacing) { |
| 2930 | 2941 | MCDI_SET_DWORD(inbuf, FILTER_OP_IN_OP, |
| 2931 | 2942 | MC_CMD_FILTER_OP_IN_OP_REPLACE); |
| @@ -2985,10 +2996,10 @@ static void efx_ef10_filter_push_prep(struct efx_nic *efx, · 53 unmodified lines | ||
| 2985 | 2996 | spec->dmaq_id == EFX_FILTER_RX_DMAQ_ID_DROP ? |
| 2986 | 2997 | 0 : spec->dmaq_id); |
| 2987 | 2998 | MCDI_SET_DWORD(inbuf, FILTER_OP_IN_RX_MODE, |
| 2988 | − (spec->flags & EFX_FILTER_FLAG_RX_RSS) ? | |
| 2999 | + (flags & EFX_FILTER_FLAG_RX_RSS) ? | |
| 2989 | 3000 | MC_CMD_FILTER_OP_IN_RX_MODE_RSS : |
| 2990 | 3001 | MC_CMD_FILTER_OP_IN_RX_MODE_SIMPLE); |
| 2991 | − if (spec->flags & EFX_FILTER_FLAG_RX_RSS) | |
| 3002 | + if (flags & EFX_FILTER_FLAG_RX_RSS) | |
| 2992 | 3003 | MCDI_SET_DWORD(inbuf, FILTER_OP_IN_RX_CONTEXT, |
| 2993 | 3004 | spec->rss_context != |
| 2994 | 3005 | EFX_FILTER_RSS_CONTEXT_DEFAULT ? |
| @@ -367,7 +367,6 @@ struct cpsw_priv { · 366 unmodified lines | ||
| 367 | 367 | spinlock_t lock; |
| 368 | 368 | struct platform_device *pdev; |
| 369 | 369 | struct net_device *ndev; |
| 370 | − struct device_node *phy_node; | |
| 371 | 370 | struct napi_struct napi_rx; |
| 372 | 371 | struct napi_struct napi_tx; |
| 373 | 372 | struct device *dev; |
| @@ -1142,25 +1141,34 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv) · 768 unmodified lines | ||
| 1142 | 1141 | cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast, |
| 1143 | 1142 | 1 << slave_port, 0, 0, ALE_MCAST_FWD_2); |
| 1144 | 1143 | |
| 1145 | − if (priv->phy_node) | |
| 1146 | − slave->phy = of_phy_connect(priv->ndev, priv->phy_node, | |
| 1144 | + if (slave->data->phy_node) { | |
| 1145 | + slave->phy = of_phy_connect(priv->ndev, slave->data->phy_node, | |
| 1147 | 1146 | &cpsw_adjust_link, 0, slave->data->phy_if); |
| 1148 | − else | |
| 1147 | + if (!slave->phy) { | |
| 1148 | + dev_err(priv->dev, "phy \"%s\" not found on slave %d\n", | |
| 1149 | + slave->data->phy_node->full_name, | |
| 1150 | + slave->slave_num); | |
| 1151 | + return; | |
| 1152 | + } | |
| 1153 | + } else { | |
| 1149 | 1154 | slave->phy = phy_connect(priv->ndev, slave->data->phy_id, |
| 1150 | 1155 | &cpsw_adjust_link, slave->data->phy_if); |
| 1151 | − if (IS_ERR(slave->phy)) { | |
| 1152 | − dev_err(priv->dev, "phy %s not found on slave %d\n", | |
| 1153 | − slave->data->phy_id, slave->slave_num); | |
| 1154 | − slave->phy = NULL; | |
| 1155 | − } else { | |
| 1156 | − phy_attached_info(slave->phy); | |
| 1156 | + if (IS_ERR(slave->phy)) { | |
| 1157 | + dev_err(priv->dev, | |
| 1158 | + "phy \"%s\" not found on slave %d, err %ld\n", | |
| 1159 | + slave->data->phy_id, slave->slave_num, | |
| 1160 | + PTR_ERR(slave->phy)); | |
| 1161 | + slave->phy = NULL; | |
| 1162 | + return; | |
| 1163 | + } | |
| 1164 | + } | |
| 1157 | 1165 | |
| 1158 | − phy_start(slave->phy); | |
| 1166 | + phy_attached_info(slave->phy); | |
| 1159 | 1167 | |
| 1160 | − /* Configure GMII_SEL register */ | |
| 1161 | − cpsw_phy_sel(&priv->pdev->dev, slave->phy->interface, | |
| 1162 | − slave->slave_num); | |
| 1163 | − } | |
| 1168 | + phy_start(slave->phy); | |
| 1169 | + | |
| 1170 | + /* Configure GMII_SEL register */ | |
| 1171 | + cpsw_phy_sel(&priv->pdev->dev, slave->phy->interface, slave->slave_num); | |
| 1164 | 1172 | } |
| 1165 | 1173 | |
| 1166 | 1174 | static inline void cpsw_add_default_vlan(struct cpsw_priv *priv) |
| @@ -1932,12 +1940,11 @@ static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv, · 765 unmodified lines | ||
| 1932 | 1940 | slave->port_vlan = data->dual_emac_res_vlan; |
| 1933 | 1941 | } |
| 1934 | 1942 | |
| 1935 | −static int cpsw_probe_dt(struct cpsw_priv *priv, | |
| 1943 | +static int cpsw_probe_dt(struct cpsw_platform_data *data, | |
| 1936 | 1944 | struct platform_device *pdev) |
| 1937 | 1945 | { |
| 1938 | 1946 | struct device_node *node = pdev->dev.of_node; |
| 1939 | 1947 | struct device_node *slave_node; |
| 1940 | − struct cpsw_platform_data *data = &priv->data; | |
| 1941 | 1948 | int i = 0, ret; |
| 1942 | 1949 | u32 prop; |
| 1943 | 1950 | |
| @@ -2025,25 +2032,21 @@ static int cpsw_probe_dt(struct cpsw_priv *priv, · 81 unmodified lines | ||
| 2025 | 2032 | if (strcmp(slave_node->name, "slave")) |
| 2026 | 2033 | continue; |
| 2027 | 2034 | |
| 2028 | − priv->phy_node = of_parse_phandle(slave_node, "phy-handle", 0); | |
| 2035 | + slave_data->phy_node = of_parse_phandle(slave_node, | |
| 2036 | + "phy-handle", 0); | |
| 2029 | 2037 | parp = of_get_property(slave_node, "phy_id", &lenp); |
| 2030 | − if (of_phy_is_fixed_link(slave_node)) { | |
| 2031 | − struct device_node *phy_node; | |
| 2032 | − struct phy_device *phy_dev; | |
| 2033 | − | |
| 2038 | + if (slave_data->phy_node) { | |
| 2039 | + dev_dbg(&pdev->dev, | |
| 2040 | + "slave[%d] using phy-handle=\"%s\"\n", | |
| 2041 | + i, slave_data->phy_node->full_name); | |
| 2042 | + } else if (of_phy_is_fixed_link(slave_node)) { | |
| 2034 | 2043 | /* In the case of a fixed PHY, the DT node associated |
| 2035 | 2044 | * to the PHY is the Ethernet MAC DT node. |
| 2036 | 2045 | */ |
| 2037 | 2046 | ret = of_phy_register_fixed_link(slave_node); |
| 2038 | 2047 | if (ret) |
| 2039 | 2048 | return ret; |
| 2040 | − phy_node = of_node_get(slave_node); | |
| 2041 | − phy_dev = of_phy_find_device(phy_node); | |
| 2042 | − if (!phy_dev) | |
| 2043 | − return -ENODEV; | |
| 2044 | − snprintf(slave_data->phy_id, sizeof(slave_data->phy_id), | |
| 2045 | − PHY_ID_FMT, phy_dev->mdio.bus->id, | |
| 2046 | − phy_dev->mdio.addr); | |
| 2049 | + slave_data->phy_node = of_node_get(slave_node); | |
| 2047 | 2050 | } else if (parp) { |
| 2048 | 2051 | u32 phyid; |
| 2049 | 2052 | struct device_node *mdio_node; |
| @@ -2064,7 +2067,9 @@ static int cpsw_probe_dt(struct cpsw_priv *priv, · 14 unmodified lines | ||
| 2064 | 2067 | snprintf(slave_data->phy_id, sizeof(slave_data->phy_id), |
| 2065 | 2068 | PHY_ID_FMT, mdio->name, phyid); |
| 2066 | 2069 | } else { |
| 2067 | − dev_err(&pdev->dev, "No slave[%d] phy_id or fixed-link property\n", i); | |
| 2070 | + dev_err(&pdev->dev, | |
| 2071 | + "No slave[%d] phy_id, phy-handle, or fixed-link property\n", | |
| 2072 | + i); | |
| 2068 | 2073 | goto no_phy_slave; |
| 2069 | 2074 | } |
| 2070 | 2075 | slave_data->phy_if = of_get_phy_mode(slave_node); |
| @@ -2266,7 +2271,7 @@ static int cpsw_probe(struct platform_device *pdev) · 195 unmodified lines | ||
| 2266 | 2271 | /* Select default pin state */ |
| 2267 | 2272 | pinctrl_pm_select_default_state(&pdev->dev); |
| 2268 | 2273 | |
| 2269 | − if (cpsw_probe_dt(priv, pdev)) { | |
| 2274 | + if (cpsw_probe_dt(&priv->data, pdev)) { | |
| 2270 | 2275 | dev_err(&pdev->dev, "cpsw: platform data missing\n"); |
| 2271 | 2276 | ret = -ENODEV; |
| 2272 | 2277 | goto clean_runtime_disable_ret; |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | #include <linux/phy.h> |
| 19 | 19 | |
| 20 | 20 | struct cpsw_slave_data { |
| 21 | + struct device_node *phy_node; | |
| 21 | 22 | char phy_id[MII_BUS_ID_SIZE]; |
| 22 | 23 | int phy_if; |
| 23 | 24 | u8 mac_addr[ETH_ALEN]; |
| @@ -1512,7 +1512,10 @@ static int emac_devioctl(struct net_device *ndev, struct ifreq *ifrq, int cmd) · 1511 unmodified lines | ||
| 1512 | 1512 | |
| 1513 | 1513 | /* TODO: Add phy read and write and private statistics get feature */ |
| 1514 | 1514 | |
| 1515 | − return phy_mii_ioctl(priv->phydev, ifrq, cmd); | |
| 1515 | + if (priv->phydev) | |
| 1516 | + return phy_mii_ioctl(priv->phydev, ifrq, cmd); | |
| 1517 | + else | |
| 1518 | + return -EOPNOTSUPP; | |
| 1516 | 1519 | } |
| 1517 | 1520 | |
| 1518 | 1521 | static int match_first_device(struct device *dev, void *data) |
| @@ -1622,7 +1622,7 @@ static void gelic_wl_scan_complete_event(struct gelic_wl_info *wl) · 1621 unmodified lines | ||
| 1622 | 1622 | continue; |
| 1623 | 1623 | |
| 1624 | 1624 | /* copy hw scan info */ |
| 1625 | − memcpy(target->hwinfo, scan_info, scan_info->size); | |
| 1625 | + memcpy(target->hwinfo, scan_info, be16_to_cpu(scan_info->size)); | |
| 1626 | 1626 | target->essid_len = strnlen(scan_info->essid, |
| 1627 | 1627 | sizeof(scan_info->essid)); |
| 1628 | 1628 | target->rate_len = 0; |
| @@ -359,27 +359,25 @@ static void at803x_link_change_notify(struct phy_device *phydev) · 358 unmodified lines | ||
| 359 | 359 | * in the FIFO. In such cases, the FIFO enters an error mode it |
| 360 | 360 | * cannot recover from by software. |
| 361 | 361 | */ |
| 362 | − if (phydev->drv->phy_id == ATH8030_PHY_ID) { | |
| 363 | − if (phydev->state == PHY_NOLINK) { | |
| 364 | − if (priv->gpiod_reset && !priv->phy_reset) { | |
| 365 | − struct at803x_context context; | |
| 366 | − | |
| 367 | − at803x_context_save(phydev, &context); | |
| 368 | − | |
| 369 | − gpiod_set_value(priv->gpiod_reset, 1); | |
| 370 | − msleep(1); | |
| 371 | − gpiod_set_value(priv->gpiod_reset, 0); | |
| 372 | − msleep(1); | |
| 373 | − | |
| 374 | − at803x_context_restore(phydev, &context); | |
| 375 | − | |
| 376 | − phydev_dbg(phydev, "%s(): phy was reset\n", | |
| 377 | − __func__); | |
| 378 | − priv->phy_reset = true; | |
| 379 | − } | |
| 380 | − } else { | |
| 381 | − priv->phy_reset = false; | |
| 362 | + if (phydev->state == PHY_NOLINK) { | |
| 363 | + if (priv->gpiod_reset && !priv->phy_reset) { | |
| 364 | + struct at803x_context context; | |
| 365 | + | |
| 366 | + at803x_context_save(phydev, &context); | |
| 367 | + | |
| 368 | + gpiod_set_value(priv->gpiod_reset, 1); | |
| 369 | + msleep(1); | |
| 370 | + gpiod_set_value(priv->gpiod_reset, 0); | |
| 371 | + msleep(1); | |
| 372 | + | |
| 373 | + at803x_context_restore(phydev, &context); | |
| 374 | + | |
| 375 | + phydev_dbg(phydev, "%s(): phy was reset\n", | |
| 376 | + __func__); | |
| 377 | + priv->phy_reset = true; | |
| 382 | 378 | } |
| 379 | + } else { | |
| 380 | + priv->phy_reset = false; | |
| 383 | 381 | } |
| 384 | 382 | } |
| 385 | 383 | |
| @@ -391,7 +389,6 @@ static struct phy_driver at803x_driver[] = { · 5 unmodified lines | ||
| 391 | 389 | .phy_id_mask = 0xffffffef, |
| 392 | 390 | .probe = at803x_probe, |
| 393 | 391 | .config_init = at803x_config_init, |
| 394 | − .link_change_notify = at803x_link_change_notify, | |
| 395 | 392 | .set_wol = at803x_set_wol, |
| 396 | 393 | .get_wol = at803x_get_wol, |
| 397 | 394 | .suspend = at803x_suspend, |
| @@ -427,7 +424,6 @@ static struct phy_driver at803x_driver[] = { · 29 unmodified lines | ||
| 427 | 424 | .phy_id_mask = 0xffffffef, |
| 428 | 425 | .probe = at803x_probe, |
| 429 | 426 | .config_init = at803x_config_init, |
| 430 | − .link_change_notify = at803x_link_change_notify, | |
| 431 | 427 | .set_wol = at803x_set_wol, |
| 432 | 428 | .get_wol = at803x_get_wol, |
| 433 | 429 | .suspend = at803x_suspend, |
| @@ -269,6 +269,7 @@ struct skb_data { /* skb->cb is one of these */ · 268 unmodified lines | ||
| 269 | 269 | struct lan78xx_net *dev; |
| 270 | 270 | enum skb_state state; |
| 271 | 271 | size_t length; |
| 272 | + int num_of_packet; | |
| 272 | 273 | }; |
| 273 | 274 | |
| 274 | 275 | struct usb_context { |
| @@ -1803,7 +1804,34 @@ static void lan78xx_remove_mdio(struct lan78xx_net *dev) · 1528 unmodified lines | ||
| 1803 | 1804 | |
| 1804 | 1805 | static void lan78xx_link_status_change(struct net_device *net) |
| 1805 | 1806 | { |
| 1806 | − /* nothing to do */ | |
| 1807 | + struct phy_device *phydev = net->phydev; | |
| 1808 | + int ret, temp; | |
| 1809 | + | |
| 1810 | + /* At forced 100 F/H mode, chip may fail to set mode correctly | |
| 1811 | + * when cable is switched between long(~50+m) and short one. | |
| 1812 | + * As workaround, set to 10 before setting to 100 | |
| 1813 | + * at forced 100 F/H mode. | |
| 1814 | + */ | |
| 1815 | + if (!phydev->autoneg && (phydev->speed == 100)) { | |
| 1816 | + /* disable phy interrupt */ | |
| 1817 | + temp = phy_read(phydev, LAN88XX_INT_MASK); | |
| 1818 | + temp &= ~LAN88XX_INT_MASK_MDINTPIN_EN_; | |
| 1819 | + ret = phy_write(phydev, LAN88XX_INT_MASK, temp); | |
| 1820 | + | |
| 1821 | + temp = phy_read(phydev, MII_BMCR); | |
| 1822 | + temp &= ~(BMCR_SPEED100 | BMCR_SPEED1000); | |
| 1823 | + phy_write(phydev, MII_BMCR, temp); /* set to 10 first */ | |
| 1824 | + temp |= BMCR_SPEED100; | |
| 1825 | + phy_write(phydev, MII_BMCR, temp); /* set to 100 later */ | |
| 1826 | + | |
| 1827 | + /* clear pending interrupt generated while workaround */ | |
| 1828 | + temp = phy_read(phydev, LAN88XX_INT_STS); | |
| 1829 | + | |
| 1830 | + /* enable phy interrupt back */ | |
| 1831 | + temp = phy_read(phydev, LAN88XX_INT_MASK); | |
| 1832 | + temp |= LAN88XX_INT_MASK_MDINTPIN_EN_; | |
| 1833 | + ret = phy_write(phydev, LAN88XX_INT_MASK, temp); | |
| 1834 | + } | |
| 1807 | 1835 | } |
| 1808 | 1836 | |
| 1809 | 1837 | static int lan78xx_phy_init(struct lan78xx_net *dev) |
| @@ -2464,7 +2492,7 @@ static void tx_complete(struct urb *urb) · 654 unmodified lines | ||
| 2464 | 2492 | struct lan78xx_net *dev = entry->dev; |
| 2465 | 2493 | |
| 2466 | 2494 | if (urb->status == 0) { |
| 2467 | − dev->net->stats.tx_packets++; | |
| 2495 | + dev->net->stats.tx_packets += entry->num_of_packet; | |
| 2468 | 2496 | dev->net->stats.tx_bytes += entry->length; |
| 2469 | 2497 | } else { |
| 2470 | 2498 | dev->net->stats.tx_errors++; |
| @@ -2681,10 +2709,11 @@ void lan78xx_skb_return(struct lan78xx_net *dev, struct sk_buff *skb) · 210 unmodified lines | ||
| 2681 | 2709 | return; |
| 2682 | 2710 | } |
| 2683 | 2711 | |
| 2684 | − skb->protocol = eth_type_trans(skb, dev->net); | |
| 2685 | 2712 | dev->net->stats.rx_packets++; |
| 2686 | 2713 | dev->net->stats.rx_bytes += skb->len; |
| 2687 | 2714 | |
| 2715 | + skb->protocol = eth_type_trans(skb, dev->net); | |
| 2716 | + | |
| 2688 | 2717 | netif_dbg(dev, rx_status, dev->net, "< rx, len %zu, type 0x%x\n", |
| 2689 | 2718 | skb->len + sizeof(struct ethhdr), skb->protocol); |
| 2690 | 2719 | memset(skb->cb, 0, sizeof(struct skb_data)); |
| @@ -2934,13 +2963,16 @@ static void lan78xx_tx_bh(struct lan78xx_net *dev) · 243 unmodified lines | ||
| 2934 | 2963 | |
| 2935 | 2964 | skb_totallen = 0; |
| 2936 | 2965 | pkt_cnt = 0; |
| 2966 | + count = 0; | |
| 2967 | + length = 0; | |
| 2937 | 2968 | for (skb = tqp->next; pkt_cnt < tqp->qlen; skb = skb->next) { |
| 2938 | 2969 | if (skb_is_gso(skb)) { |
| 2939 | 2970 | if (pkt_cnt) { |
| 2940 | 2971 | /* handle previous packets first */ |
| 2941 | 2972 | break; |
| 2942 | 2973 | } |
| 2943 | − length = skb->len; | |
| 2974 | + count = 1; | |
| 2975 | + length = skb->len - TX_OVERHEAD; | |
| 2944 | 2976 | skb2 = skb_dequeue(tqp); |
| 2945 | 2977 | goto gso_skb; |
| 2946 | 2978 | } |
| @@ -2961,14 +2993,13 @@ static void lan78xx_tx_bh(struct lan78xx_net *dev) · 14 unmodified lines | ||
| 2961 | 2993 | for (count = pos = 0; count < pkt_cnt; count++) { |
| 2962 | 2994 | skb2 = skb_dequeue(tqp); |
| 2963 | 2995 | if (skb2) { |
| 2996 | + length += (skb2->len - TX_OVERHEAD); | |
| 2964 | 2997 | memcpy(skb->data + pos, skb2->data, skb2->len); |
| 2965 | 2998 | pos += roundup(skb2->len, sizeof(u32)); |
| 2966 | 2999 | dev_kfree_skb(skb2); |
| 2967 | 3000 | } |
| 2968 | 3001 | } |
| 2969 | 3002 | |
| 2970 | − length = skb_totallen; | |
| 2971 | − | |
| 2972 | 3003 | gso_skb: |
| 2973 | 3004 | urb = usb_alloc_urb(0, GFP_ATOMIC); |
| 2974 | 3005 | if (!urb) { |
| @@ -2980,6 +3011,7 @@ gso_skb: · 5 unmodified lines | ||
| 2980 | 3011 | entry->urb = urb; |
| 2981 | 3012 | entry->dev = dev; |
| 2982 | 3013 | entry->length = length; |
| 3014 | + entry->num_of_packet = count; | |
| 2983 | 3015 | |
| 2984 | 3016 | spin_lock_irqsave(&dev->txq.lock, flags); |
| 2985 | 3017 | ret = usb_autopm_get_interface_async(dev->intf); |
| @@ -411,7 +411,7 @@ static int enable_net_traffic(struct net_device *dev, struct usb_device *usb) · 410 unmodified lines | ||
| 411 | 411 | int ret; |
| 412 | 412 | |
| 413 | 413 | read_mii_word(pegasus, pegasus->phy, MII_LPA, &linkpart); |
| 414 | − data[0] = 0xc9; | |
| 414 | + data[0] = 0xc8; /* TX & RX enable, append status, no CRC */ | |
| 415 | 415 | data[1] = 0; |
| 416 | 416 | if (linkpart & (ADVERTISE_100FULL | ADVERTISE_10FULL)) |
| 417 | 417 | data[1] |= 0x20; /* set full duplex */ |
| @@ -497,7 +497,7 @@ static void read_bulk_callback(struct urb *urb) · 79 unmodified lines | ||
| 497 | 497 | pkt_len = buf[count - 3] << 8; |
| 498 | 498 | pkt_len += buf[count - 4]; |
| 499 | 499 | pkt_len &= 0xfff; |
| 500 | − pkt_len -= 8; | |
| 500 | + pkt_len -= 4; | |
| 501 | 501 | } |
| 502 | 502 | |
| 503 | 503 | /* |
| @@ -528,7 +528,7 @@ static void read_bulk_callback(struct urb *urb) · 24 unmodified lines | ||
| 528 | 528 | goon: |
| 529 | 529 | usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, |
| 530 | 530 | usb_rcvbulkpipe(pegasus->usb, 1), |
| 531 | − pegasus->rx_skb->data, PEGASUS_MTU + 8, | |
| 531 | + pegasus->rx_skb->data, PEGASUS_MTU, | |
| 532 | 532 | read_bulk_callback, pegasus); |
| 533 | 533 | rx_status = usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC); |
| 534 | 534 | if (rx_status == -ENODEV) |
| @@ -569,7 +569,7 @@ static void rx_fixup(unsigned long data) · 34 unmodified lines | ||
| 569 | 569 | } |
| 570 | 570 | usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, |
| 571 | 571 | usb_rcvbulkpipe(pegasus->usb, 1), |
| 572 | − pegasus->rx_skb->data, PEGASUS_MTU + 8, | |
| 572 | + pegasus->rx_skb->data, PEGASUS_MTU, | |
| 573 | 573 | read_bulk_callback, pegasus); |
| 574 | 574 | try_again: |
| 575 | 575 | status = usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC); |
| @@ -823,7 +823,7 @@ static int pegasus_open(struct net_device *net) · 247 unmodified lines | ||
| 823 | 823 | |
| 824 | 824 | usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, |
| 825 | 825 | usb_rcvbulkpipe(pegasus->usb, 1), |
| 826 | − pegasus->rx_skb->data, PEGASUS_MTU + 8, | |
| 826 | + pegasus->rx_skb->data, PEGASUS_MTU, | |
| 827 | 827 | read_bulk_callback, pegasus); |
| 828 | 828 | if ((res = usb_submit_urb(pegasus->rx_urb, GFP_KERNEL))) { |
| 829 | 829 | if (res == -ENODEV) |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | #include <linux/crc32.h> |
| 30 | 30 | #include <linux/usb/usbnet.h> |
| 31 | 31 | #include <linux/slab.h> |
| 32 | +#include <linux/of_net.h> | |
| 32 | 33 | #include "smsc75xx.h" |
| 33 | 34 | |
| 34 | 35 | #define SMSC_CHIPNAME "smsc75xx" |
| @@ -761,6 +762,15 @@ static int smsc75xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) · 726 unmodified lines | ||
| 761 | 762 | |
| 762 | 763 | static void smsc75xx_init_mac_address(struct usbnet *dev) |
| 763 | 764 | { |
| 765 | + const u8 *mac_addr; | |
| 766 | + | |
| 767 | + /* maybe the boot loader passed the MAC address in devicetree */ | |
| 768 | + mac_addr = of_get_mac_address(dev->udev->dev.of_node); | |
| 769 | + if (mac_addr) { | |
| 770 | + memcpy(dev->net->dev_addr, mac_addr, ETH_ALEN); | |
| 771 | + return; | |
| 772 | + } | |
| 773 | + | |
| 764 | 774 | /* try reading mac address from EEPROM */ |
| 765 | 775 | if (smsc75xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, |
| 766 | 776 | dev->net->dev_addr) == 0) { |
| @@ -772,7 +782,7 @@ static void smsc75xx_init_mac_address(struct usbnet *dev) · 5 unmodified lines | ||
| 772 | 782 | } |
| 773 | 783 | } |
| 774 | 784 | |
| 775 | − /* no eeprom, or eeprom values are invalid. generate random MAC */ | |
| 785 | + /* no useful static MAC address found. generate a random one */ | |
| 776 | 786 | eth_hw_addr_random(dev->net); |
| 777 | 787 | netif_dbg(dev, ifup, dev->net, "MAC address set to eth_random_addr\n"); |
| 778 | 788 | } |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | #include <linux/crc32.h> |
| 30 | 30 | #include <linux/usb/usbnet.h> |
| 31 | 31 | #include <linux/slab.h> |
| 32 | +#include <linux/of_net.h> | |
| 32 | 33 | #include "smsc95xx.h" |
| 33 | 34 | |
| 34 | 35 | #define SMSC_CHIPNAME "smsc95xx" |
| @@ -765,6 +766,15 @@ static int smsc95xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) · 730 unmodified lines | ||
| 765 | 766 | |
| 766 | 767 | static void smsc95xx_init_mac_address(struct usbnet *dev) |
| 767 | 768 | { |
| 769 | + const u8 *mac_addr; | |
| 770 | + | |
| 771 | + /* maybe the boot loader passed the MAC address in devicetree */ | |
| 772 | + mac_addr = of_get_mac_address(dev->udev->dev.of_node); | |
| 773 | + if (mac_addr) { | |
| 774 | + memcpy(dev->net->dev_addr, mac_addr, ETH_ALEN); | |
| 775 | + return; | |
| 776 | + } | |
| 777 | + | |
| 768 | 778 | /* try reading mac address from EEPROM */ |
| 769 | 779 | if (smsc95xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, |
| 770 | 780 | dev->net->dev_addr) == 0) { |
| @@ -775,7 +785,7 @@ static void smsc95xx_init_mac_address(struct usbnet *dev) · 4 unmodified lines | ||
| 775 | 785 | } |
| 776 | 786 | } |
| 777 | 787 | |
| 778 | − /* no eeprom, or eeprom values are invalid. generate random MAC */ | |
| 788 | + /* no useful static MAC address found. generate a random one */ | |
| 779 | 789 | eth_hw_addr_random(dev->net); |
| 780 | 790 | netif_dbg(dev, ifup, dev->net, "MAC address set to eth_random_addr\n"); |
| 781 | 791 | } |
| @@ -274,6 +274,9 @@ void ar5008_hw_cmn_spur_mitigate(struct ath_hw *ah, · 273 unmodified lines | ||
| 274 | 274 | }; |
| 275 | 275 | static const int inc[4] = { 0, 100, 0, 0 }; |
| 276 | 276 | |
| 277 | + memset(&mask_m, 0, sizeof(int8_t) * 123); | |
| 278 | + memset(&mask_p, 0, sizeof(int8_t) * 123); | |
| 279 | + | |
| 277 | 280 | cur_bin = -6000; |
| 278 | 281 | upper = bin + 100; |
| 279 | 282 | lower = bin - 100; |
| @@ -424,14 +427,9 @@ static void ar5008_hw_spur_mitigate(struct ath_hw *ah, · 144 unmodified lines | ||
| 424 | 427 | int tmp, new; |
| 425 | 428 | int i; |
| 426 | 429 | |
| 427 | − int8_t mask_m[123]; | |
| 428 | − int8_t mask_p[123]; | |
| 429 | 430 | int cur_bb_spur; |
| 430 | 431 | bool is2GHz = IS_CHAN_2GHZ(chan); |
| 431 | 432 | |
| 432 | − memset(&mask_m, 0, sizeof(int8_t) * 123); | |
| 433 | − memset(&mask_p, 0, sizeof(int8_t) * 123); | |
| 434 | − | |
| 435 | 433 | for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { |
| 436 | 434 | cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz); |
| 437 | 435 | if (AR_NO_SPUR == cur_bb_spur) |
| @@ -178,14 +178,9 @@ static void ar9002_hw_spur_mitigate(struct ath_hw *ah, · 177 unmodified lines | ||
| 178 | 178 | int i; |
| 179 | 179 | struct chan_centers centers; |
| 180 | 180 | |
| 181 | − int8_t mask_m[123]; | |
| 182 | − int8_t mask_p[123]; | |
| 183 | 181 | int cur_bb_spur; |
| 184 | 182 | bool is2GHz = IS_CHAN_2GHZ(chan); |
| 185 | 183 | |
| 186 | − memset(&mask_m, 0, sizeof(int8_t) * 123); | |
| 187 | − memset(&mask_p, 0, sizeof(int8_t) * 123); | |
| 188 | − | |
| 189 | 184 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); |
| 190 | 185 | freq = centers.synth_center; |
| 191 | 186 | |
| @@ -89,7 +89,7 @@ · 88 unmodified lines | ||
| 89 | 89 | #define IWL8260_SMEM_OFFSET 0x400000 |
| 90 | 90 | #define IWL8260_SMEM_LEN 0x68000 |
| 91 | 91 | |
| 92 | −#define IWL8000_FW_PRE "iwlwifi-8000" | |
| 92 | +#define IWL8000_FW_PRE "iwlwifi-8000C-" | |
| 93 | 93 | #define IWL8000_MODULE_FIRMWARE(api) \ |
| 94 | 94 | IWL8000_FW_PRE "-" __stringify(api) ".ucode" |
| 95 | 95 | |
| @@ -240,19 +240,6 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first) · 239 unmodified lines | ||
| 240 | 240 | snprintf(drv->firmware_name, sizeof(drv->firmware_name), "%s%s.ucode", |
| 241 | 241 | name_pre, tag); |
| 242 | 242 | |
| 243 | − /* | |
| 244 | − * Starting 8000B - FW name format has changed. This overwrites the | |
| 245 | − * previous name and uses the new format. | |
| 246 | − */ | |
| 247 | − if (drv->trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) { | |
| 248 | − char rev_step = 'A' + CSR_HW_REV_STEP(drv->trans->hw_rev); | |
| 249 | − | |
| 250 | − if (rev_step != 'A') | |
| 251 | − snprintf(drv->firmware_name, | |
| 252 | − sizeof(drv->firmware_name), "%s%c-%s.ucode", | |
| 253 | − name_pre, rev_step, tag); | |
| 254 | − } | |
| 255 | − | |
| 256 | 243 | IWL_DEBUG_INFO(drv, "attempting to load firmware %s'%s'\n", |
| 257 | 244 | (drv->fw_index == UCODE_EXPERIMENTAL_INDEX) |
| 258 | 245 | ? "EXPERIMENTAL " : "", |
| @@ -609,7 +609,8 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) · 608 unmodified lines | ||
| 609 | 609 | } |
| 610 | 610 | |
| 611 | 611 | /* Make room for fw's virtual image pages, if it exists */ |
| 612 | − if (mvm->fw->img[mvm->cur_ucode].paging_mem_size) | |
| 612 | + if (mvm->fw->img[mvm->cur_ucode].paging_mem_size && | |
| 613 | + mvm->fw_paging_db[0].fw_paging_block) | |
| 613 | 614 | file_len += mvm->num_of_paging_blk * |
| 614 | 615 | (sizeof(*dump_data) + |
| 615 | 616 | sizeof(struct iwl_fw_error_dump_paging) + |
| @@ -750,7 +751,8 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) · 134 unmodified lines | ||
| 750 | 751 | } |
| 751 | 752 | |
| 752 | 753 | /* Dump fw's virtual image */ |
| 753 | − if (mvm->fw->img[mvm->cur_ucode].paging_mem_size) { | |
| 754 | + if (mvm->fw->img[mvm->cur_ucode].paging_mem_size && | |
| 755 | + mvm->fw_paging_db[0].fw_paging_block) { | |
| 754 | 756 | for (i = 1; i < mvm->num_of_paging_blk + 1; i++) { |
| 755 | 757 | struct iwl_fw_error_dump_paging *paging; |
| 756 | 758 | struct page *pages = |
| @@ -149,9 +149,11 @@ void iwl_free_fw_paging(struct iwl_mvm *mvm) · 148 unmodified lines | ||
| 149 | 149 | |
| 150 | 150 | __free_pages(mvm->fw_paging_db[i].fw_paging_block, |
| 151 | 151 | get_order(mvm->fw_paging_db[i].fw_paging_size)); |
| 152 | + mvm->fw_paging_db[i].fw_paging_block = NULL; | |
| 152 | 153 | } |
| 153 | 154 | kfree(mvm->trans->paging_download_buf); |
| 154 | 155 | mvm->trans->paging_download_buf = NULL; |
| 156 | + mvm->trans->paging_db = NULL; | |
| 155 | 157 | |
| 156 | 158 | memset(mvm->fw_paging_db, 0, sizeof(mvm->fw_paging_db)); |
| 157 | 159 | } |
| @@ -479,8 +479,18 @@ static const struct pci_device_id iwl_hw_card_ids[] = { · 478 unmodified lines | ||
| 479 | 479 | {IWL_PCI_DEVICE(0x24F3, 0x0930, iwl8260_2ac_cfg)}, |
| 480 | 480 | {IWL_PCI_DEVICE(0x24F3, 0x0000, iwl8265_2ac_cfg)}, |
| 481 | 481 | {IWL_PCI_DEVICE(0x24FD, 0x0010, iwl8265_2ac_cfg)}, |
| 482 | + {IWL_PCI_DEVICE(0x24FD, 0x0110, iwl8265_2ac_cfg)}, | |
| 483 | + {IWL_PCI_DEVICE(0x24FD, 0x1110, iwl8265_2ac_cfg)}, | |
| 484 | + {IWL_PCI_DEVICE(0x24FD, 0x1010, iwl8265_2ac_cfg)}, | |
| 485 | + {IWL_PCI_DEVICE(0x24FD, 0x0050, iwl8265_2ac_cfg)}, | |
| 486 | + {IWL_PCI_DEVICE(0x24FD, 0x0150, iwl8265_2ac_cfg)}, | |
| 487 | + {IWL_PCI_DEVICE(0x24FD, 0x9010, iwl8265_2ac_cfg)}, | |
| 488 | + {IWL_PCI_DEVICE(0x24FD, 0x8110, iwl8265_2ac_cfg)}, | |
| 489 | + {IWL_PCI_DEVICE(0x24FD, 0x8050, iwl8265_2ac_cfg)}, | |
| 482 | 490 | {IWL_PCI_DEVICE(0x24FD, 0x8010, iwl8265_2ac_cfg)}, |
| 483 | 491 | {IWL_PCI_DEVICE(0x24FD, 0x0810, iwl8265_2ac_cfg)}, |
| 492 | + {IWL_PCI_DEVICE(0x24FD, 0x9110, iwl8265_2ac_cfg)}, | |
| 493 | + {IWL_PCI_DEVICE(0x24FD, 0x8130, iwl8265_2ac_cfg)}, | |
| 484 | 494 | |
| 485 | 495 | /* 9000 Series */ |
| 486 | 496 | {IWL_PCI_DEVICE(0x9DF0, 0x0A10, iwl9560_2ac_cfg)}, |
| @@ -135,7 +135,7 @@ MODULE_LICENSE("GPL"); · 134 unmodified lines | ||
| 135 | 135 | /* Field definitions */ |
| 136 | 136 | #define HCI_ACCEL_MASK 0x7fff |
| 137 | 137 | #define HCI_HOTKEY_DISABLE 0x0b |
| 138 | −#define HCI_HOTKEY_ENABLE 0x01 | |
| 138 | +#define HCI_HOTKEY_ENABLE 0x09 | |
| 139 | 139 | #define HCI_HOTKEY_SPECIAL_FUNCTIONS 0x10 |
| 140 | 140 | #define HCI_LCD_BRIGHTNESS_BITS 3 |
| 141 | 141 | #define HCI_LCD_BRIGHTNESS_SHIFT (16-HCI_LCD_BRIGHTNESS_BITS) |
| @@ -2669,9 +2669,9 @@ static int __init mport_init(void) · 2668 unmodified lines | ||
| 2669 | 2669 | |
| 2670 | 2670 | /* Create device class needed by udev */ |
| 2671 | 2671 | dev_class = class_create(THIS_MODULE, DRV_NAME); |
| 2672 | − if (!dev_class) { | |
| 2672 | + if (IS_ERR(dev_class)) { | |
| 2673 | 2673 | rmcd_error("Unable to create " DRV_NAME " class"); |
| 2674 | − return -EINVAL; | |
| 2674 | + return PTR_ERR(dev_class); | |
| 2675 | 2675 | } |
| 2676 | 2676 | |
| 2677 | 2677 | ret = alloc_chrdev_region(&dev_number, 0, RIO_MAX_MPORTS, DRV_NAME); |
| @@ -56,6 +56,7 @@ static int sclp_ctl_ioctl_sccb(void __user *user_area) · 55 unmodified lines | ||
| 56 | 56 | { |
| 57 | 57 | struct sclp_ctl_sccb ctl_sccb; |
| 58 | 58 | struct sccb_header *sccb; |
| 59 | + unsigned long copied; | |
| 59 | 60 | int rc; |
| 60 | 61 | |
| 61 | 62 | if (copy_from_user(&ctl_sccb, user_area, sizeof(ctl_sccb))) |
| @@ -65,14 +66,15 @@ static int sclp_ctl_ioctl_sccb(void __user *user_area) · 3 unmodified lines | ||
| 65 | 66 | sccb = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA); |
| 66 | 67 | if (!sccb) |
| 67 | 68 | return -ENOMEM; |
| 68 | − if (copy_from_user(sccb, u64_to_uptr(ctl_sccb.sccb), sizeof(*sccb))) { | |
| 69 | + copied = PAGE_SIZE - | |
| 70 | + copy_from_user(sccb, u64_to_uptr(ctl_sccb.sccb), PAGE_SIZE); | |
| 71 | + if (offsetof(struct sccb_header, length) + | |
| 72 | + sizeof(sccb->length) > copied || sccb->length > copied) { | |
| 69 | 73 | rc = -EFAULT; |
| 70 | 74 | goto out_free; |
| 71 | 75 | } |
| 72 | − if (sccb->length > PAGE_SIZE || sccb->length < 8) | |
| 73 | − return -EINVAL; | |
| 74 | − if (copy_from_user(sccb, u64_to_uptr(ctl_sccb.sccb), sccb->length)) { | |
| 75 | − rc = -EFAULT; | |
| 76 | + if (sccb->length < 8) { | |
| 77 | + rc = -EINVAL; | |
| 76 | 78 | goto out_free; |
| 77 | 79 | } |
| 78 | 80 | rc = sclp_sync_request(ctl_sccb.cmdw, sccb); |
| @@ -172,9 +172,11 @@ static int vpfe_prepare_pipeline(struct vpfe_video_device *video) · 171 unmodified lines | ||
| 172 | 172 | static int vpfe_update_pipe_state(struct vpfe_video_device *video) |
| 173 | 173 | { |
| 174 | 174 | struct vpfe_pipeline *pipe = &video->pipe; |
| 175 | + int ret; | |
| 175 | 176 | |
| 176 | − if (vpfe_prepare_pipeline(video)) | |
| 177 | − return vpfe_prepare_pipeline(video); | |
| 177 | + ret = vpfe_prepare_pipeline(video); | |
| 178 | + if (ret) | |
| 179 | + return ret; | |
| 178 | 180 | |
| 179 | 181 | /* |
| 180 | 182 | * Find out if there is any input video |
| @@ -182,9 +184,10 @@ static int vpfe_update_pipe_state(struct vpfe_video_device *video) · 1 unmodified line | ||
| 182 | 184 | */ |
| 183 | 185 | if (pipe->input_num == 0) { |
| 184 | 186 | pipe->state = VPFE_PIPELINE_STREAM_CONTINUOUS; |
| 185 | − if (vpfe_update_current_ext_subdev(video)) { | |
| 187 | + ret = vpfe_update_current_ext_subdev(video); | |
| 188 | + if (ret) { | |
| 186 | 189 | pr_err("Invalid external subdev\n"); |
| 187 | − return vpfe_update_current_ext_subdev(video); | |
| 190 | + return ret; | |
| 188 | 191 | } |
| 189 | 192 | } else { |
| 190 | 193 | pipe->state = VPFE_PIPELINE_STREAM_SINGLESHOT; |
| @@ -667,6 +670,7 @@ static int vpfe_enum_fmt(struct file *file, void *priv, · 476 unmodified lines | ||
| 667 | 670 | struct v4l2_subdev *subdev; |
| 668 | 671 | struct v4l2_format format; |
| 669 | 672 | struct media_pad *remote; |
| 673 | + int ret; | |
| 670 | 674 | |
| 671 | 675 | v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_enum_fmt\n"); |
| 672 | 676 | |
| @@ -695,10 +699,11 @@ static int vpfe_enum_fmt(struct file *file, void *priv, · 22 unmodified lines | ||
| 695 | 699 | sd_fmt.pad = remote->index; |
| 696 | 700 | sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; |
| 697 | 701 | /* get output format of remote subdev */ |
| 698 | − if (v4l2_subdev_call(subdev, pad, get_fmt, NULL, &sd_fmt)) { | |
| 702 | + ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &sd_fmt); | |
| 703 | + if (ret) { | |
| 699 | 704 | v4l2_err(&vpfe_dev->v4l2_dev, |
| 700 | 705 | "invalid remote subdev for video node\n"); |
| 701 | − return v4l2_subdev_call(subdev, pad, get_fmt, NULL, &sd_fmt); | |
| 706 | + return ret; | |
| 702 | 707 | } |
| 703 | 708 | /* convert to pix format */ |
| 704 | 709 | mbus.code = sd_fmt.format.code; |
| @@ -725,6 +730,7 @@ static int vpfe_s_fmt(struct file *file, void *priv, · 20 unmodified lines | ||
| 725 | 730 | struct vpfe_video_device *video = video_drvdata(file); |
| 726 | 731 | struct vpfe_device *vpfe_dev = video->vpfe_dev; |
| 727 | 732 | struct v4l2_format format; |
| 733 | + int ret; | |
| 728 | 734 | |
| 729 | 735 | v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_fmt\n"); |
| 730 | 736 | /* If streaming is started, return error */ |
| @@ -733,8 +739,9 @@ static int vpfe_s_fmt(struct file *file, void *priv, · 2 unmodified lines | ||
| 733 | 739 | return -EBUSY; |
| 734 | 740 | } |
| 735 | 741 | /* get adjacent subdev's output pad format */ |
| 736 | − if (__vpfe_video_get_format(video, &format)) | |
| 737 | − return __vpfe_video_get_format(video, &format); | |
| 742 | + ret = __vpfe_video_get_format(video, &format); | |
| 743 | + if (ret) | |
| 744 | + return ret; | |
| 738 | 745 | *fmt = format; |
| 739 | 746 | video->fmt = *fmt; |
| 740 | 747 | return 0; |
| @@ -757,11 +764,13 @@ static int vpfe_try_fmt(struct file *file, void *priv, · 16 unmodified lines | ||
| 757 | 764 | struct vpfe_video_device *video = video_drvdata(file); |
| 758 | 765 | struct vpfe_device *vpfe_dev = video->vpfe_dev; |
| 759 | 766 | struct v4l2_format format; |
| 767 | + int ret; | |
| 760 | 768 | |
| 761 | 769 | v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_try_fmt\n"); |
| 762 | 770 | /* get adjacent subdev's output pad format */ |
| 763 | − if (__vpfe_video_get_format(video, &format)) | |
| 764 | − return __vpfe_video_get_format(video, &format); | |
| 771 | + ret = __vpfe_video_get_format(video, &format); | |
| 772 | + if (ret) | |
| 773 | + return ret; | |
| 765 | 774 | |
| 766 | 775 | *fmt = format; |
| 767 | 776 | return 0; |
| @@ -838,8 +847,9 @@ static int vpfe_s_input(struct file *file, void *priv, unsigned int index) · 70 unmodified lines | ||
| 838 | 847 | |
| 839 | 848 | v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_input\n"); |
| 840 | 849 | |
| 841 | − if (mutex_lock_interruptible(&video->lock)) | |
| 842 | − return mutex_lock_interruptible(&video->lock); | |
| 850 | + ret = mutex_lock_interruptible(&video->lock); | |
| 851 | + if (ret) | |
| 852 | + return ret; | |
| 843 | 853 | /* |
| 844 | 854 | * If streaming is started return device busy |
| 845 | 855 | * error |
| @@ -940,8 +950,9 @@ static int vpfe_s_std(struct file *file, void *priv, v4l2_std_id std_id) · 94 unmodified lines | ||
| 940 | 950 | v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_std\n"); |
| 941 | 951 | |
| 942 | 952 | /* Call decoder driver function to set the standard */ |
| 943 | − if (mutex_lock_interruptible(&video->lock)) | |
| 944 | − return mutex_lock_interruptible(&video->lock); | |
| 953 | + ret = mutex_lock_interruptible(&video->lock); | |
| 954 | + if (ret) | |
| 955 | + return ret; | |
| 945 | 956 | sdinfo = video->current_ext_subdev; |
| 946 | 957 | /* If streaming is started, return device busy error */ |
| 947 | 958 | if (video->started) { |
| @@ -1327,8 +1338,9 @@ static int vpfe_reqbufs(struct file *file, void *priv, · 379 unmodified lines | ||
| 1327 | 1338 | return -EINVAL; |
| 1328 | 1339 | } |
| 1329 | 1340 | |
| 1330 | − if (mutex_lock_interruptible(&video->lock)) | |
| 1331 | − return mutex_lock_interruptible(&video->lock); | |
| 1341 | + ret = mutex_lock_interruptible(&video->lock); | |
| 1342 | + if (ret) | |
| 1343 | + return ret; | |
| 1332 | 1344 | |
| 1333 | 1345 | if (video->io_usrs != 0) { |
| 1334 | 1346 | v4l2_err(&vpfe_dev->v4l2_dev, "Only one IO user allowed\n"); |
| @@ -1354,10 +1366,11 @@ static int vpfe_reqbufs(struct file *file, void *priv, · 19 unmodified lines | ||
| 1354 | 1366 | q->buf_struct_size = sizeof(struct vpfe_cap_buffer); |
| 1355 | 1367 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; |
| 1356 | 1368 | |
| 1357 | − if (vb2_queue_init(q)) { | |
| 1369 | + ret = vb2_queue_init(q); | |
| 1370 | + if (ret) { | |
| 1358 | 1371 | v4l2_err(&vpfe_dev->v4l2_dev, "vb2_queue_init() failed\n"); |
| 1359 | 1372 | vb2_dma_contig_cleanup_ctx(vpfe_dev->pdev); |
| 1360 | − return vb2_queue_init(q); | |
| 1373 | + return ret; | |
| 1361 | 1374 | } |
| 1362 | 1375 | |
| 1363 | 1376 | fh->io_allowed = 1; |
| @@ -1533,8 +1546,9 @@ static int vpfe_streamoff(struct file *file, void *priv, · 169 unmodified lines | ||
| 1533 | 1546 | return -EINVAL; |
| 1534 | 1547 | } |
| 1535 | 1548 | |
| 1536 | − if (mutex_lock_interruptible(&video->lock)) | |
| 1537 | − return mutex_lock_interruptible(&video->lock); | |
| 1549 | + ret = mutex_lock_interruptible(&video->lock); | |
| 1550 | + if (ret) | |
| 1551 | + return ret; | |
| 1538 | 1552 | |
| 1539 | 1553 | vpfe_stop_capture(video); |
| 1540 | 1554 | ret = vb2_streamoff(&video->buffer_queue, buf_type); |
| @@ -3,4 +3,4 @@ July, 2015 · 2 unmodified lines | ||
| 3 | 3 | - Remove unneeded file entries in sysfs |
| 4 | 4 | - Remove software processing of IB protocol and place in library for use |
| 5 | 5 | by qib, ipath (if still present), hfi1, and eventually soft-roce |
| 6 | − | |
| 6 | +- Replace incorrect uAPI | |
| @@ -49,6 +49,8 @@ · 48 unmodified lines | ||
| 49 | 49 | #include <linux/vmalloc.h> |
| 50 | 50 | #include <linux/io.h> |
| 51 | 51 | |
| 52 | +#include <rdma/ib.h> | |
| 53 | + | |
| 52 | 54 | #include "hfi.h" |
| 53 | 55 | #include "pio.h" |
| 54 | 56 | #include "device.h" |
| @@ -190,6 +192,10 @@ static ssize_t hfi1_file_write(struct file *fp, const char __user *data, · 135 unmodified lines | ||
| 190 | 192 | int uctxt_required = 1; |
| 191 | 193 | int must_be_root = 0; |
| 192 | 194 | |
| 195 | + /* FIXME: This interface cannot continue out of staging */ | |
| 196 | + if (WARN_ON_ONCE(!ib_safe_file_access(fp))) | |
| 197 | + return -EACCES; | |
| 198 | + | |
| 193 | 199 | if (count < sizeof(cmd)) { |
| 194 | 200 | ret = -EINVAL; |
| 195 | 201 | goto bail; |
| @@ -791,15 +797,16 @@ static int hfi1_file_close(struct inode *inode, struct file *fp) · 595 unmodified lines | ||
| 791 | 797 | spin_unlock_irqrestore(&dd->uctxt_lock, flags); |
| 792 | 798 | |
| 793 | 799 | dd->rcd[uctxt->ctxt] = NULL; |
| 800 | + | |
| 801 | + hfi1_user_exp_rcv_free(fdata); | |
| 802 | + hfi1_clear_ctxt_pkey(dd, uctxt->ctxt); | |
| 803 | + | |
| 794 | 804 | uctxt->rcvwait_to = 0; |
| 795 | 805 | uctxt->piowait_to = 0; |
| 796 | 806 | uctxt->rcvnowait = 0; |
| 797 | 807 | uctxt->pionowait = 0; |
| 798 | 808 | uctxt->event_flags = 0; |
| 799 | 809 | |
| 800 | − hfi1_user_exp_rcv_free(fdata); | |
| 801 | − hfi1_clear_ctxt_pkey(dd, uctxt->ctxt); | |
| 802 | − | |
| 803 | 810 | hfi1_stats.sps_ctxts--; |
| 804 | 811 | if (++dd->freectxts == dd->num_user_contexts) |
| 805 | 812 | aspm_enable_all(dd); |
| @@ -1127,27 +1134,13 @@ bail: · 321 unmodified lines | ||
| 1127 | 1134 | |
| 1128 | 1135 | static int user_init(struct file *fp) |
| 1129 | 1136 | { |
| 1130 | − int ret; | |
| 1131 | 1137 | unsigned int rcvctrl_ops = 0; |
| 1132 | 1138 | struct hfi1_filedata *fd = fp->private_data; |
| 1133 | 1139 | struct hfi1_ctxtdata *uctxt = fd->uctxt; |
| 1134 | 1140 | |
| 1135 | 1141 | /* make sure that the context has already been setup */ |
| 1136 | − if (!test_bit(HFI1_CTXT_SETUP_DONE, &uctxt->event_flags)) { | |
| 1137 | − ret = -EFAULT; | |
| 1138 | − goto done; | |
| 1139 | − } | |
| 1140 | − | |
| 1141 | − /* | |
| 1142 | − * Subctxts don't need to initialize anything since master | |
| 1143 | − * has done it. | |
| 1144 | − */ | |
| 1145 | − if (fd->subctxt) { | |
| 1146 | − ret = wait_event_interruptible(uctxt->wait, !test_bit( | |
| 1147 | − HFI1_CTXT_MASTER_UNINIT, | |
| 1148 | − &uctxt->event_flags)); | |
| 1149 | − goto expected; | |
| 1150 | − } | |
| 1142 | + if (!test_bit(HFI1_CTXT_SETUP_DONE, &uctxt->event_flags)) | |
| 1143 | + return -EFAULT; | |
| 1151 | 1144 | |
| 1152 | 1145 | /* initialize poll variables... */ |
| 1153 | 1146 | uctxt->urgent = 0; |
| @@ -1202,19 +1195,7 @@ static int user_init(struct file *fp) · 48 unmodified lines | ||
| 1202 | 1195 | wake_up(&uctxt->wait); |
| 1203 | 1196 | } |
| 1204 | 1197 | |
| 1205 | −expected: | |
| 1206 | − /* | |
| 1207 | − * Expected receive has to be setup for all processes (including | |
| 1208 | − * shared contexts). However, it has to be done after the master | |
| 1209 | − * context has been fully configured as it depends on the | |
| 1210 | − * eager/expected split of the RcvArray entries. | |
| 1211 | − * Setting it up here ensures that the subcontexts will be waiting | |
| 1212 | − * (due to the above wait_event_interruptible() until the master | |
| 1213 | − * is setup. | |
| 1214 | − */ | |
| 1215 | − ret = hfi1_user_exp_rcv_init(fp); | |
| 1216 | −done: | |
| 1217 | − return ret; | |
| 1198 | + return 0; | |
| 1218 | 1199 | } |
| 1219 | 1200 | |
| 1220 | 1201 | static int get_ctxt_info(struct file *fp, void __user *ubase, __u32 len) |
| @@ -1261,7 +1242,7 @@ static int setup_ctxt(struct file *fp) · 40 unmodified lines | ||
| 1261 | 1242 | int ret = 0; |
| 1262 | 1243 | |
| 1263 | 1244 | /* |
| 1264 | − * Context should be set up only once (including allocation and | |
| 1245 | + * Context should be set up only once, including allocation and | |
| 1265 | 1246 | * programming of eager buffers. This is done if context sharing |
| 1266 | 1247 | * is not requested or by the master process. |
| 1267 | 1248 | */ |
| @@ -1282,8 +1263,27 @@ static int setup_ctxt(struct file *fp) · 14 unmodified lines | ||
| 1282 | 1263 | if (ret) |
| 1283 | 1264 | goto done; |
| 1284 | 1265 | } |
| 1266 | + } else { | |
| 1267 | + ret = wait_event_interruptible(uctxt->wait, !test_bit( | |
| 1268 | + HFI1_CTXT_MASTER_UNINIT, | |
| 1269 | + &uctxt->event_flags)); | |
| 1270 | + if (ret) | |
| 1271 | + goto done; | |
| 1285 | 1272 | } |
| 1273 | + | |
| 1286 | 1274 | ret = hfi1_user_sdma_alloc_queues(uctxt, fp); |
| 1275 | + if (ret) | |
| 1276 | + goto done; | |
| 1277 | + /* | |
| 1278 | + * Expected receive has to be setup for all processes (including | |
| 1279 | + * shared contexts). However, it has to be done after the master | |
| 1280 | + * context has been fully configured as it depends on the | |
| 1281 | + * eager/expected split of the RcvArray entries. | |
| 1282 | + * Setting it up here ensures that the subcontexts will be waiting | |
| 1283 | + * (due to the above wait_event_interruptible() until the master | |
| 1284 | + * is setup. | |
| 1285 | + */ | |
| 1286 | + ret = hfi1_user_exp_rcv_init(fp); | |
| 1287 | 1287 | if (ret) |
| 1288 | 1288 | goto done; |
| 1289 | 1289 | |
| @@ -1565,29 +1565,8 @@ static loff_t ui_lseek(struct file *filp, loff_t offset, int whence) · 275 unmodified lines | ||
| 1565 | 1565 | { |
| 1566 | 1566 | struct hfi1_devdata *dd = filp->private_data; |
| 1567 | 1567 | |
| 1568 | − switch (whence) { | |
| 1569 | − case SEEK_SET: | |
| 1570 | − break; | |
| 1571 | − case SEEK_CUR: | |
| 1572 | − offset += filp->f_pos; | |
| 1573 | − break; | |
| 1574 | − case SEEK_END: | |
| 1575 | − offset = ((dd->kregend - dd->kregbase) + DC8051_DATA_MEM_SIZE) - | |
| 1576 | − offset; | |
| 1577 | − break; | |
| 1578 | − default: | |
| 1579 | − return -EINVAL; | |
| 1580 | − } | |
| 1581 | − | |
| 1582 | − if (offset < 0) | |
| 1583 | − return -EINVAL; | |
| 1584 | − | |
| 1585 | − if (offset >= (dd->kregend - dd->kregbase) + DC8051_DATA_MEM_SIZE) | |
| 1586 | − return -EINVAL; | |
| 1587 | − | |
| 1588 | − filp->f_pos = offset; | |
| 1589 | − | |
| 1590 | − return filp->f_pos; | |
| 1568 | + return fixed_size_llseek(filp, offset, whence, | |
| 1569 | + (dd->kregend - dd->kregbase) + DC8051_DATA_MEM_SIZE); | |
| 1591 | 1570 | } |
| 1592 | 1571 | |
| 1593 | 1572 | /* NOTE: assumes unsigned long is 8 bytes */ |
| @@ -71,6 +71,7 @@ static inline void mmu_notifier_range_start(struct mmu_notifier *, · 70 unmodified lines | ||
| 71 | 71 | struct mm_struct *, |
| 72 | 72 | unsigned long, unsigned long); |
| 73 | 73 | static void mmu_notifier_mem_invalidate(struct mmu_notifier *, |
| 74 | + struct mm_struct *, | |
| 74 | 75 | unsigned long, unsigned long); |
| 75 | 76 | static struct mmu_rb_node *__mmu_rb_search(struct mmu_rb_handler *, |
| 76 | 77 | unsigned long, unsigned long); |
| @@ -137,7 +138,7 @@ void hfi1_mmu_rb_unregister(struct rb_root *root) · 60 unmodified lines | ||
| 137 | 138 | rbnode = rb_entry(node, struct mmu_rb_node, node); |
| 138 | 139 | rb_erase(node, root); |
| 139 | 140 | if (handler->ops->remove) |
| 140 | − handler->ops->remove(root, rbnode, false); | |
| 141 | + handler->ops->remove(root, rbnode, NULL); | |
| 141 | 142 | } |
| 142 | 143 | } |
| 143 | 144 | |
| @@ -176,7 +177,7 @@ unlock: · 32 unmodified lines | ||
| 176 | 177 | return ret; |
| 177 | 178 | } |
| 178 | 179 | |
| 179 | −/* Caller must host handler lock */ | |
| 180 | +/* Caller must hold handler lock */ | |
| 180 | 181 | static struct mmu_rb_node *__mmu_rb_search(struct mmu_rb_handler *handler, |
| 181 | 182 | unsigned long addr, |
| 182 | 183 | unsigned long len) |
| @@ -200,15 +201,21 @@ static struct mmu_rb_node *__mmu_rb_search(struct mmu_rb_handler *handler, · 17 unmodified lines | ||
| 200 | 201 | return node; |
| 201 | 202 | } |
| 202 | 203 | |
| 204 | +/* Caller must *not* hold handler lock. */ | |
| 203 | 205 | static void __mmu_rb_remove(struct mmu_rb_handler *handler, |
| 204 | − struct mmu_rb_node *node, bool arg) | |
| 206 | + struct mmu_rb_node *node, struct mm_struct *mm) | |
| 205 | 207 | { |
| 208 | + unsigned long flags; | |
| 209 | + | |
| 206 | 210 | /* Validity of handler and node pointers has been checked by caller. */ |
| 207 | 211 | hfi1_cdbg(MMU, "Removing node addr 0x%llx, len %u", node->addr, |
| 208 | 212 | node->len); |
| 213 | + spin_lock_irqsave(&handler->lock, flags); | |
| 209 | 214 | __mmu_int_rb_remove(node, handler->root); |
| 215 | + spin_unlock_irqrestore(&handler->lock, flags); | |
| 216 | + | |
| 210 | 217 | if (handler->ops->remove) |
| 211 | − handler->ops->remove(handler->root, node, arg); | |
| 218 | + handler->ops->remove(handler->root, node, mm); | |
| 212 | 219 | } |
| 213 | 220 | |
| 214 | 221 | struct mmu_rb_node *hfi1_mmu_rb_search(struct rb_root *root, unsigned long addr, |
| @@ -231,14 +238,11 @@ struct mmu_rb_node *hfi1_mmu_rb_search(struct rb_root *root, unsigned long addr, · 16 unmodified lines | ||
| 231 | 238 | void hfi1_mmu_rb_remove(struct rb_root *root, struct mmu_rb_node *node) |
| 232 | 239 | { |
| 233 | 240 | struct mmu_rb_handler *handler = find_mmu_handler(root); |
| 234 | − unsigned long flags; | |
| 235 | 241 | |
| 236 | 242 | if (!handler || !node) |
| 237 | 243 | return; |
| 238 | 244 | |
| 239 | − spin_lock_irqsave(&handler->lock, flags); | |
| 240 | − __mmu_rb_remove(handler, node, false); | |
| 241 | − spin_unlock_irqrestore(&handler->lock, flags); | |
| 245 | + __mmu_rb_remove(handler, node, NULL); | |
| 242 | 246 | } |
| 243 | 247 | |
| 244 | 248 | static struct mmu_rb_handler *find_mmu_handler(struct rb_root *root) |
| @@ -260,7 +264,7 @@ unlock: · 15 unmodified lines | ||
| 260 | 264 | static inline void mmu_notifier_page(struct mmu_notifier *mn, |
| 261 | 265 | struct mm_struct *mm, unsigned long addr) |
| 262 | 266 | { |
| 263 | − mmu_notifier_mem_invalidate(mn, addr, addr + PAGE_SIZE); | |
| 267 | + mmu_notifier_mem_invalidate(mn, mm, addr, addr + PAGE_SIZE); | |
| 264 | 268 | } |
| 265 | 269 | |
| 266 | 270 | static inline void mmu_notifier_range_start(struct mmu_notifier *mn, |
| @@ -268,25 +272,31 @@ static inline void mmu_notifier_range_start(struct mmu_notifier *mn, · 1 unmodified line | ||
| 268 | 272 | unsigned long start, |
| 269 | 273 | unsigned long end) |
| 270 | 274 | { |
| 271 | − mmu_notifier_mem_invalidate(mn, start, end); | |
| 275 | + mmu_notifier_mem_invalidate(mn, mm, start, end); | |
| 272 | 276 | } |
| 273 | 277 | |
| 274 | 278 | static void mmu_notifier_mem_invalidate(struct mmu_notifier *mn, |
| 279 | + struct mm_struct *mm, | |
| 275 | 280 | unsigned long start, unsigned long end) |
| 276 | 281 | { |
| 277 | 282 | struct mmu_rb_handler *handler = |
| 278 | 283 | container_of(mn, struct mmu_rb_handler, mn); |
| 279 | 284 | struct rb_root *root = handler->root; |
| 280 | − struct mmu_rb_node *node; | |
| 285 | + struct mmu_rb_node *node, *ptr = NULL; | |
| 281 | 286 | unsigned long flags; |
| 282 | 287 | |
| 283 | 288 | spin_lock_irqsave(&handler->lock, flags); |
| 284 | − for (node = __mmu_int_rb_iter_first(root, start, end - 1); node; | |
| 285 | − node = __mmu_int_rb_iter_next(node, start, end - 1)) { | |
| 289 | + for (node = __mmu_int_rb_iter_first(root, start, end - 1); | |
| 290 | + node; node = ptr) { | |
| 291 | + /* Guard against node removal. */ | |
| 292 | + ptr = __mmu_int_rb_iter_next(node, start, end - 1); | |
| 286 | 293 | hfi1_cdbg(MMU, "Invalidating node addr 0x%llx, len %u", |
| 287 | 294 | node->addr, node->len); |
| 288 | − if (handler->ops->invalidate(root, node)) | |
| 289 | − __mmu_rb_remove(handler, node, true); | |
| 295 | + if (handler->ops->invalidate(root, node)) { | |
| 296 | + spin_unlock_irqrestore(&handler->lock, flags); | |
| 297 | + __mmu_rb_remove(handler, node, mm); | |
| 298 | + spin_lock_irqsave(&handler->lock, flags); | |
| 299 | + } | |
| 290 | 300 | } |
| 291 | 301 | spin_unlock_irqrestore(&handler->lock, flags); |
| 292 | 302 | } |
| @@ -59,7 +59,8 @@ struct mmu_rb_node { · 58 unmodified lines | ||
| 59 | 59 | struct mmu_rb_ops { |
| 60 | 60 | bool (*filter)(struct mmu_rb_node *, unsigned long, unsigned long); |
| 61 | 61 | int (*insert)(struct rb_root *, struct mmu_rb_node *); |
| 62 | − void (*remove)(struct rb_root *, struct mmu_rb_node *, bool); | |
| 62 | + void (*remove)(struct rb_root *, struct mmu_rb_node *, | |
| 63 | + struct mm_struct *); | |
| 63 | 64 | int (*invalidate)(struct rb_root *, struct mmu_rb_node *); |
| 64 | 65 | }; |
| 65 | 66 | |
| @@ -519,10 +519,12 @@ static void iowait_sdma_drained(struct iowait *wait) · 518 unmodified lines | ||
| 519 | 519 | * do the flush work until that QP's |
| 520 | 520 | * sdma work has finished. |
| 521 | 521 | */ |
| 522 | + spin_lock(&qp->s_lock); | |
| 522 | 523 | if (qp->s_flags & RVT_S_WAIT_DMA) { |
| 523 | 524 | qp->s_flags &= ~RVT_S_WAIT_DMA; |
| 524 | 525 | hfi1_schedule_send(qp); |
| 525 | 526 | } |
| 527 | + spin_unlock(&qp->s_lock); | |
| 526 | 528 | } |
| 527 | 529 | |
| 528 | 530 | /** |
| @@ -87,7 +87,8 @@ static u32 find_phys_blocks(struct page **, unsigned, struct tid_pageset *); · 86 unmodified lines | ||
| 87 | 87 | static int set_rcvarray_entry(struct file *, unsigned long, u32, |
| 88 | 88 | struct tid_group *, struct page **, unsigned); |
| 89 | 89 | static int mmu_rb_insert(struct rb_root *, struct mmu_rb_node *); |
| 90 | −static void mmu_rb_remove(struct rb_root *, struct mmu_rb_node *, bool); | |
| 90 | +static void mmu_rb_remove(struct rb_root *, struct mmu_rb_node *, | |
| 91 | + struct mm_struct *); | |
| 91 | 92 | static int mmu_rb_invalidate(struct rb_root *, struct mmu_rb_node *); |
| 92 | 93 | static int program_rcvarray(struct file *, unsigned long, struct tid_group *, |
| 93 | 94 | struct tid_pageset *, unsigned, u16, struct page **, |
| @@ -254,6 +255,8 @@ int hfi1_user_exp_rcv_free(struct hfi1_filedata *fd) · 160 unmodified lines | ||
| 254 | 255 | struct hfi1_ctxtdata *uctxt = fd->uctxt; |
| 255 | 256 | struct tid_group *grp, *gptr; |
| 256 | 257 | |
| 258 | + if (!test_bit(HFI1_CTXT_SETUP_DONE, &uctxt->event_flags)) | |
| 259 | + return 0; | |
| 257 | 260 | /* |
| 258 | 261 | * The notifier would have been removed when the process'es mm |
| 259 | 262 | * was freed. |
| @@ -899,7 +902,7 @@ static int unprogram_rcvarray(struct file *fp, u32 tidinfo, · 639 unmodified lines | ||
| 899 | 902 | if (!node || node->rcventry != (uctxt->expected_base + rcventry)) |
| 900 | 903 | return -EBADF; |
| 901 | 904 | if (HFI1_CAP_IS_USET(TID_UNMAP)) |
| 902 | − mmu_rb_remove(&fd->tid_rb_root, &node->mmu, false); | |
| 905 | + mmu_rb_remove(&fd->tid_rb_root, &node->mmu, NULL); | |
| 903 | 906 | else |
| 904 | 907 | hfi1_mmu_rb_remove(&fd->tid_rb_root, &node->mmu); |
| 905 | 908 | |
| @@ -965,7 +968,7 @@ static void unlock_exp_tids(struct hfi1_ctxtdata *uctxt, · 59 unmodified lines | ||
| 965 | 968 | continue; |
| 966 | 969 | if (HFI1_CAP_IS_USET(TID_UNMAP)) |
| 967 | 970 | mmu_rb_remove(&fd->tid_rb_root, |
| 968 | − &node->mmu, false); | |
| 971 | + &node->mmu, NULL); | |
| 969 | 972 | else |
| 970 | 973 | hfi1_mmu_rb_remove(&fd->tid_rb_root, |
| 971 | 974 | &node->mmu); |
| @@ -1032,7 +1035,7 @@ static int mmu_rb_insert(struct rb_root *root, struct mmu_rb_node *node) · 60 unmodified lines | ||
| 1032 | 1035 | } |
| 1033 | 1036 | |
| 1034 | 1037 | static void mmu_rb_remove(struct rb_root *root, struct mmu_rb_node *node, |
| 1035 | − bool notifier) | |
| 1038 | + struct mm_struct *mm) | |
| 1036 | 1039 | { |
| 1037 | 1040 | struct hfi1_filedata *fdata = |
| 1038 | 1041 | container_of(root, struct hfi1_filedata, tid_rb_root); |
| @@ -278,7 +278,8 @@ static inline void pq_update(struct hfi1_user_sdma_pkt_q *); · 277 unmodified lines | ||
| 278 | 278 | static void user_sdma_free_request(struct user_sdma_request *, bool); |
| 279 | 279 | static int pin_vector_pages(struct user_sdma_request *, |
| 280 | 280 | struct user_sdma_iovec *); |
| 281 | −static void unpin_vector_pages(struct mm_struct *, struct page **, unsigned); | |
| 281 | +static void unpin_vector_pages(struct mm_struct *, struct page **, unsigned, | |
| 282 | + unsigned); | |
| 282 | 283 | static int check_header_template(struct user_sdma_request *, |
| 283 | 284 | struct hfi1_pkt_header *, u32, u32); |
| 284 | 285 | static int set_txreq_header(struct user_sdma_request *, |
| @@ -299,7 +300,8 @@ static int defer_packet_queue( · 14 unmodified lines | ||
| 299 | 300 | static void activate_packet_queue(struct iowait *, int); |
| 300 | 301 | static bool sdma_rb_filter(struct mmu_rb_node *, unsigned long, unsigned long); |
| 301 | 302 | static int sdma_rb_insert(struct rb_root *, struct mmu_rb_node *); |
| 302 | −static void sdma_rb_remove(struct rb_root *, struct mmu_rb_node *, bool); | |
| 303 | +static void sdma_rb_remove(struct rb_root *, struct mmu_rb_node *, | |
| 304 | + struct mm_struct *); | |
| 303 | 305 | static int sdma_rb_invalidate(struct rb_root *, struct mmu_rb_node *); |
| 304 | 306 | |
| 305 | 307 | static struct mmu_rb_ops sdma_rb_ops = { |
| @@ -1063,8 +1065,10 @@ static int pin_vector_pages(struct user_sdma_request *req, · 757 unmodified lines | ||
| 1063 | 1065 | rb_node = hfi1_mmu_rb_search(&pq->sdma_rb_root, |
| 1064 | 1066 | (unsigned long)iovec->iov.iov_base, |
| 1065 | 1067 | iovec->iov.iov_len); |
| 1066 | − if (rb_node) | |
| 1068 | + if (rb_node && !IS_ERR(rb_node)) | |
| 1067 | 1069 | node = container_of(rb_node, struct sdma_mmu_node, rb); |
| 1070 | + else | |
| 1071 | + rb_node = NULL; | |
| 1068 | 1072 | |
| 1069 | 1073 | if (!node) { |
| 1070 | 1074 | node = kzalloc(sizeof(*node), GFP_KERNEL); |
| @@ -1107,7 +1111,8 @@ retry: · 36 unmodified lines | ||
| 1107 | 1111 | goto bail; |
| 1108 | 1112 | } |
| 1109 | 1113 | if (pinned != npages) { |
| 1110 | − unpin_vector_pages(current->mm, pages, pinned); | |
| 1114 | + unpin_vector_pages(current->mm, pages, node->npages, | |
| 1115 | + pinned); | |
| 1111 | 1116 | ret = -EFAULT; |
| 1112 | 1117 | goto bail; |
| 1113 | 1118 | } |
| @@ -1147,9 +1152,9 @@ bail: · 33 unmodified lines | ||
| 1147 | 1152 | } |
| 1148 | 1153 | |
| 1149 | 1154 | static void unpin_vector_pages(struct mm_struct *mm, struct page **pages, |
| 1150 | − unsigned npages) | |
| 1155 | + unsigned start, unsigned npages) | |
| 1151 | 1156 | { |
| 1152 | − hfi1_release_user_pages(mm, pages, npages, 0); | |
| 1157 | + hfi1_release_user_pages(mm, pages + start, npages, 0); | |
| 1153 | 1158 | kfree(pages); |
| 1154 | 1159 | } |
| 1155 | 1160 | |
| @@ -1502,7 +1507,7 @@ static void user_sdma_free_request(struct user_sdma_request *req, bool unpin) · 346 unmodified lines | ||
| 1502 | 1507 | &req->pq->sdma_rb_root, |
| 1503 | 1508 | (unsigned long)req->iovs[i].iov.iov_base, |
| 1504 | 1509 | req->iovs[i].iov.iov_len); |
| 1505 | − if (!mnode) | |
| 1510 | + if (!mnode || IS_ERR(mnode)) | |
| 1506 | 1511 | continue; |
| 1507 | 1512 | |
| 1508 | 1513 | node = container_of(mnode, struct sdma_mmu_node, rb); |
| @@ -1547,7 +1552,7 @@ static int sdma_rb_insert(struct rb_root *root, struct mmu_rb_node *mnode) · 38 unmodified lines | ||
| 1547 | 1552 | } |
| 1548 | 1553 | |
| 1549 | 1554 | static void sdma_rb_remove(struct rb_root *root, struct mmu_rb_node *mnode, |
| 1550 | − bool notifier) | |
| 1555 | + struct mm_struct *mm) | |
| 1551 | 1556 | { |
| 1552 | 1557 | struct sdma_mmu_node *node = |
| 1553 | 1558 | container_of(mnode, struct sdma_mmu_node, rb); |
| @@ -1557,14 +1562,20 @@ static void sdma_rb_remove(struct rb_root *root, struct mmu_rb_node *mnode, · 3 unmodified lines | ||
| 1557 | 1562 | node->pq->n_locked -= node->npages; |
| 1558 | 1563 | spin_unlock(&node->pq->evict_lock); |
| 1559 | 1564 | |
| 1560 | − unpin_vector_pages(notifier ? NULL : current->mm, node->pages, | |
| 1565 | + /* | |
| 1566 | + * If mm is set, we are being called by the MMU notifier and we | |
| 1567 | + * should not pass a mm_struct to unpin_vector_page(). This is to | |
| 1568 | + * prevent a deadlock when hfi1_release_user_pages() attempts to | |
| 1569 | + * take the mmap_sem, which the MMU notifier has already taken. | |
| 1570 | + */ | |
| 1571 | + unpin_vector_pages(mm ? NULL : current->mm, node->pages, 0, | |
| 1561 | 1572 | node->npages); |
| 1562 | 1573 | /* |
| 1563 | 1574 | * If called by the MMU notifier, we have to adjust the pinned |
| 1564 | 1575 | * page count ourselves. |
| 1565 | 1576 | */ |
| 1566 | − if (notifier) | |
| 1567 | − current->mm->pinned_vm -= node->npages; | |
| 1577 | + if (mm) | |
| 1578 | + mm->pinned_vm -= node->npages; | |
| 1568 | 1579 | kfree(node); |
| 1569 | 1580 | } |
| 1570 | 1581 | |
| @@ -68,12 +68,12 @@ static inline int _step_to_temp(int step) · 67 unmodified lines | ||
| 68 | 68 | * Every step equals (1 * 200) / 255 celsius, and finally |
| 69 | 69 | * need convert to millicelsius. |
| 70 | 70 | */ |
| 71 | − return (HISI_TEMP_BASE + (step * 200 / 255)) * 1000; | |
| 71 | + return (HISI_TEMP_BASE * 1000 + (step * 200000 / 255)); | |
| 72 | 72 | } |
| 73 | 73 | |
| 74 | 74 | static inline long _temp_to_step(long temp) |
| 75 | 75 | { |
| 76 | − return ((temp / 1000 - HISI_TEMP_BASE) * 255 / 200); | |
| 76 | + return ((temp - HISI_TEMP_BASE * 1000) * 255) / 200000; | |
| 77 | 77 | } |
| 78 | 78 | |
| 79 | 79 | static long hisi_thermal_get_sensor_temp(struct hisi_thermal_data *data, |
| @@ -959,7 +959,7 @@ static DEVICE_ATTR(sustainable_power, S_IWUSR | S_IRUGO, sustainable_power_show, · 958 unmodified lines | ||
| 959 | 959 | struct thermal_zone_device *tz = to_thermal_zone(dev); \ |
| 960 | 960 | \ |
| 961 | 961 | if (tz->tzp) \ |
| 962 | − return sprintf(buf, "%u\n", tz->tzp->name); \ | |
| 962 | + return sprintf(buf, "%d\n", tz->tzp->name); \ | |
| 963 | 963 | else \ |
| 964 | 964 | return -EIO; \ |
| 965 | 965 | } \ |
| @@ -386,9 +386,7 @@ void ceph_put_mds_session(struct ceph_mds_session *s) · 385 unmodified lines | ||
| 386 | 386 | atomic_read(&s->s_ref), atomic_read(&s->s_ref)-1); |
| 387 | 387 | if (atomic_dec_and_test(&s->s_ref)) { |
| 388 | 388 | if (s->s_auth.authorizer) |
| 389 | − ceph_auth_destroy_authorizer( | |
| 390 | − s->s_mdsc->fsc->client->monc.auth, | |
| 391 | − s->s_auth.authorizer); | |
| 389 | + ceph_auth_destroy_authorizer(s->s_auth.authorizer); | |
| 392 | 390 | kfree(s); |
| 393 | 391 | } |
| 394 | 392 | } |
| @@ -3900,7 +3898,7 @@ static struct ceph_auth_handshake *get_authorizer(struct ceph_connection *con, · 3505 unmodified lines | ||
| 3900 | 3898 | struct ceph_auth_handshake *auth = &s->s_auth; |
| 3901 | 3899 | |
| 3902 | 3900 | if (force_new && auth->authorizer) { |
| 3903 | − ceph_auth_destroy_authorizer(ac, auth->authorizer); | |
| 3901 | + ceph_auth_destroy_authorizer(auth->authorizer); | |
| 3904 | 3902 | auth->authorizer = NULL; |
| 3905 | 3903 | } |
| 3906 | 3904 | if (!auth->authorizer) { |
| @@ -1295,7 +1295,7 @@ static int fuse_get_user_pages(struct fuse_req *req, struct iov_iter *ii, · 1294 unmodified lines | ||
| 1295 | 1295 | |
| 1296 | 1296 | *nbytesp = nbytes; |
| 1297 | 1297 | |
| 1298 | − return ret; | |
| 1298 | + return ret < 0 ? ret : 0; | |
| 1299 | 1299 | } |
| 1300 | 1300 | |
| 1301 | 1301 | static inline int fuse_iter_npages(const struct iov_iter *ii_p) |
| @@ -2455,6 +2455,8 @@ int dlm_deref_lockres_done_handler(struct o2net_msg *msg, u32 len, void *data, · 2454 unmodified lines | ||
| 2455 | 2455 | |
| 2456 | 2456 | spin_unlock(&dlm->spinlock); |
| 2457 | 2457 | |
| 2458 | + ret = 0; | |
| 2459 | + | |
| 2458 | 2460 | done: |
| 2459 | 2461 | dlm_put(dlm); |
| 2460 | 2462 | return ret; |
| @@ -1518,6 +1518,32 @@ static struct page *can_gather_numa_stats(pte_t pte, struct vm_area_struct *vma, · 1517 unmodified lines | ||
| 1518 | 1518 | return page; |
| 1519 | 1519 | } |
| 1520 | 1520 | |
| 1521 | +#ifdef CONFIG_TRANSPARENT_HUGEPAGE | |
| 1522 | +static struct page *can_gather_numa_stats_pmd(pmd_t pmd, | |
| 1523 | + struct vm_area_struct *vma, | |
| 1524 | + unsigned long addr) | |
| 1525 | +{ | |
| 1526 | + struct page *page; | |
| 1527 | + int nid; | |
| 1528 | + | |
| 1529 | + if (!pmd_present(pmd)) | |
| 1530 | + return NULL; | |
| 1531 | + | |
| 1532 | + page = vm_normal_page_pmd(vma, addr, pmd); | |
| 1533 | + if (!page) | |
| 1534 | + return NULL; | |
| 1535 | + | |
| 1536 | + if (PageReserved(page)) | |
| 1537 | + return NULL; | |
| 1538 | + | |
| 1539 | + nid = page_to_nid(page); | |
| 1540 | + if (!node_isset(nid, node_states[N_MEMORY])) | |
| 1541 | + return NULL; | |
| 1542 | + | |
| 1543 | + return page; | |
| 1544 | +} | |
| 1545 | +#endif | |
| 1546 | + | |
| 1521 | 1547 | static int gather_pte_stats(pmd_t *pmd, unsigned long addr, |
| 1522 | 1548 | unsigned long end, struct mm_walk *walk) |
| 1523 | 1549 | { |
| @@ -1527,14 +1553,14 @@ static int gather_pte_stats(pmd_t *pmd, unsigned long addr, · 3 unmodified lines | ||
| 1527 | 1553 | pte_t *orig_pte; |
| 1528 | 1554 | pte_t *pte; |
| 1529 | 1555 | |
| 1556 | +#ifdef CONFIG_TRANSPARENT_HUGEPAGE | |
| 1530 | 1557 | ptl = pmd_trans_huge_lock(pmd, vma); |
| 1531 | 1558 | if (ptl) { |
| 1532 | − pte_t huge_pte = *(pte_t *)pmd; | |
| 1533 | 1559 | struct page *page; |
| 1534 | 1560 | |
| 1535 | − page = can_gather_numa_stats(huge_pte, vma, addr); | |
| 1561 | + page = can_gather_numa_stats_pmd(*pmd, vma, addr); | |
| 1536 | 1562 | if (page) |
| 1537 | − gather_stats(page, md, pte_dirty(huge_pte), | |
| 1563 | + gather_stats(page, md, pmd_dirty(*pmd), | |
| 1538 | 1564 | HPAGE_PMD_SIZE/PAGE_SIZE); |
| 1539 | 1565 | spin_unlock(ptl); |
| 1540 | 1566 | return 0; |
| @@ -1542,6 +1568,7 @@ static int gather_pte_stats(pmd_t *pmd, unsigned long addr, · 1 unmodified line | ||
| 1542 | 1568 | |
| 1543 | 1569 | if (pmd_trans_unstable(pmd)) |
| 1544 | 1570 | return 0; |
| 1571 | +#endif | |
| 1545 | 1572 | orig_pte = pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl); |
| 1546 | 1573 | do { |
| 1547 | 1574 | struct page *page = can_gather_numa_stats(*pte, vma, addr); |
| @@ -919,14 +919,14 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block) · 918 unmodified lines | ||
| 919 | 919 | #endif |
| 920 | 920 | } |
| 921 | 921 | |
| 922 | − ret = udf_CS0toUTF8(outstr, 31, pvoldesc->volIdent, 32); | |
| 922 | + ret = udf_dstrCS0toUTF8(outstr, 31, pvoldesc->volIdent, 32); | |
| 923 | 923 | if (ret < 0) |
| 924 | 924 | goto out_bh; |
| 925 | 925 | |
| 926 | 926 | strncpy(UDF_SB(sb)->s_volume_ident, outstr, ret); |
| 927 | 927 | udf_debug("volIdent[] = '%s'\n", UDF_SB(sb)->s_volume_ident); |
| 928 | 928 | |
| 929 | − ret = udf_CS0toUTF8(outstr, 127, pvoldesc->volSetIdent, 128); | |
| 929 | + ret = udf_dstrCS0toUTF8(outstr, 127, pvoldesc->volSetIdent, 128); | |
| 930 | 930 | if (ret < 0) |
| 931 | 931 | goto out_bh; |
| 932 | 932 | |
| @@ -212,7 +212,7 @@ extern int udf_get_filename(struct super_block *, const uint8_t *, int, · 211 unmodified lines | ||
| 212 | 212 | uint8_t *, int); |
| 213 | 213 | extern int udf_put_filename(struct super_block *, const uint8_t *, int, |
| 214 | 214 | uint8_t *, int); |
| 215 | −extern int udf_CS0toUTF8(uint8_t *, int, const uint8_t *, int); | |
| 215 | +extern int udf_dstrCS0toUTF8(uint8_t *, int, const uint8_t *, int); | |
| 216 | 216 | |
| 217 | 217 | /* ialloc.c */ |
| 218 | 218 | extern void udf_free_inode(struct inode *); |
| @@ -335,9 +335,21 @@ try_again: · 334 unmodified lines | ||
| 335 | 335 | return u_len; |
| 336 | 336 | } |
| 337 | 337 | |
| 338 | −int udf_CS0toUTF8(uint8_t *utf_o, int o_len, const uint8_t *ocu_i, int i_len) | |
| 338 | +int udf_dstrCS0toUTF8(uint8_t *utf_o, int o_len, | |
| 339 | + const uint8_t *ocu_i, int i_len) | |
| 339 | 340 | { |
| 340 | − return udf_name_from_CS0(utf_o, o_len, ocu_i, i_len, | |
| 341 | + int s_len = 0; | |
| 342 | + | |
| 343 | + if (i_len > 0) { | |
| 344 | + s_len = ocu_i[i_len - 1]; | |
| 345 | + if (s_len >= i_len) { | |
| 346 | + pr_err("incorrect dstring lengths (%d/%d)\n", | |
| 347 | + s_len, i_len); | |
| 348 | + return -EINVAL; | |
| 349 | + } | |
| 350 | + } | |
| 351 | + | |
| 352 | + return udf_name_from_CS0(utf_o, o_len, ocu_i, s_len, | |
| 341 | 353 | udf_uni2char_utf8, 0); |
| 342 | 354 | } |
| 343 | 355 | |
| @@ -180,12 +180,13 @@ void bpf_register_prog_type(struct bpf_prog_type_list *tl); · 179 unmodified lines | ||
| 180 | 180 | void bpf_register_map_type(struct bpf_map_type_list *tl); |
| 181 | 181 | |
| 182 | 182 | struct bpf_prog *bpf_prog_get(u32 ufd); |
| 183 | +struct bpf_prog *bpf_prog_inc(struct bpf_prog *prog); | |
| 183 | 184 | void bpf_prog_put(struct bpf_prog *prog); |
| 184 | 185 | void bpf_prog_put_rcu(struct bpf_prog *prog); |
| 185 | 186 | |
| 186 | 187 | struct bpf_map *bpf_map_get_with_uref(u32 ufd); |
| 187 | 188 | struct bpf_map *__bpf_map_get(struct fd f); |
| 188 | −void bpf_map_inc(struct bpf_map *map, bool uref); | |
| 189 | +struct bpf_map *bpf_map_inc(struct bpf_map *map, bool uref); | |
| 189 | 190 | void bpf_map_put_with_uref(struct bpf_map *map); |
| 190 | 191 | void bpf_map_put(struct bpf_map *map); |
| 191 | 192 | int bpf_map_precharge_memlock(u32 pages); |
| @@ -12,9 +12,12 @@ · 11 unmodified lines | ||
| 12 | 12 | */ |
| 13 | 13 | |
| 14 | 14 | struct ceph_auth_client; |
| 15 | −struct ceph_authorizer; | |
| 16 | 15 | struct ceph_msg; |
| 17 | 16 | |
| 17 | +struct ceph_authorizer { | |
| 18 | + void (*destroy)(struct ceph_authorizer *); | |
| 19 | +}; | |
| 20 | + | |
| 18 | 21 | struct ceph_auth_handshake { |
| 19 | 22 | struct ceph_authorizer *authorizer; |
| 20 | 23 | void *authorizer_buf; |
| @@ -62,8 +65,6 @@ struct ceph_auth_client_ops { · 41 unmodified lines | ||
| 62 | 65 | struct ceph_auth_handshake *auth); |
| 63 | 66 | int (*verify_authorizer_reply)(struct ceph_auth_client *ac, |
| 64 | 67 | struct ceph_authorizer *a, size_t len); |
| 65 | − void (*destroy_authorizer)(struct ceph_auth_client *ac, | |
| 66 | − struct ceph_authorizer *a); | |
| 67 | 68 | void (*invalidate_authorizer)(struct ceph_auth_client *ac, |
| 68 | 69 | int peer_type); |
| 69 | 70 | |
| @@ -112,8 +113,7 @@ extern int ceph_auth_is_authenticated(struct ceph_auth_client *ac); · 42 unmodified lines | ||
| 112 | 113 | extern int ceph_auth_create_authorizer(struct ceph_auth_client *ac, |
| 113 | 114 | int peer_type, |
| 114 | 115 | struct ceph_auth_handshake *auth); |
| 115 | −extern void ceph_auth_destroy_authorizer(struct ceph_auth_client *ac, | |
| 116 | − struct ceph_authorizer *a); | |
| 116 | +void ceph_auth_destroy_authorizer(struct ceph_authorizer *a); | |
| 117 | 117 | extern int ceph_auth_update_authorizer(struct ceph_auth_client *ac, |
| 118 | 118 | int peer_type, |
| 119 | 119 | struct ceph_auth_handshake *a); |
| @@ -16,7 +16,6 @@ struct ceph_msg; · 15 unmodified lines | ||
| 16 | 16 | struct ceph_snap_context; |
| 17 | 17 | struct ceph_osd_request; |
| 18 | 18 | struct ceph_osd_client; |
| 19 | −struct ceph_authorizer; | |
| 20 | 19 | |
| 21 | 20 | /* |
| 22 | 21 | * completion callback for async writepages |
| @@ -444,6 +444,7 @@ struct cgroup_subsys { · 443 unmodified lines | ||
| 444 | 444 | int (*can_attach)(struct cgroup_taskset *tset); |
| 445 | 445 | void (*cancel_attach)(struct cgroup_taskset *tset); |
| 446 | 446 | void (*attach)(struct cgroup_taskset *tset); |
| 447 | + void (*post_attach)(void); | |
| 447 | 448 | int (*can_fork)(struct task_struct *task); |
| 448 | 449 | void (*cancel_fork)(struct task_struct *task); |
| 449 | 450 | void (*fork)(struct task_struct *task); |
| @@ -137,8 +137,6 @@ static inline void set_mems_allowed(nodemask_t nodemask) · 136 unmodified lines | ||
| 137 | 137 | task_unlock(current); |
| 138 | 138 | } |
| 139 | 139 | |
| 140 | −extern void cpuset_post_attach_flush(void); | |
| 141 | − | |
| 142 | 140 | #else /* !CONFIG_CPUSETS */ |
| 143 | 141 | |
| 144 | 142 | static inline bool cpusets_enabled(void) { return false; } |
| @@ -245,10 +243,6 @@ static inline bool read_mems_allowed_retry(unsigned int seq) · 100 unmodified lines | ||
| 245 | 243 | return false; |
| 246 | 244 | } |
| 247 | 245 | |
| 248 | −static inline void cpuset_post_attach_flush(void) | |
| 249 | −{ | |
| 250 | −} | |
| 251 | − | |
| 252 | 246 | #endif /* !CONFIG_CPUSETS */ |
| 253 | 247 | |
| 254 | 248 | #endif /* _LINUX_CPUSET_H */ |
| @@ -32,12 +32,28 @@ · 31 unmodified lines | ||
| 32 | 32 | #error Wordsize not 32 or 64 |
| 33 | 33 | #endif |
| 34 | 34 | |
| 35 | +/* | |
| 36 | + * The above primes are actively bad for hashing, since they are | |
| 37 | + * too sparse. The 32-bit one is mostly ok, the 64-bit one causes | |
| 38 | + * real problems. Besides, the "prime" part is pointless for the | |
| 39 | + * multiplicative hash. | |
| 40 | + * | |
| 41 | + * Although a random odd number will do, it turns out that the golden | |
| 42 | + * ratio phi = (sqrt(5)-1)/2, or its negative, has particularly nice | |
| 43 | + * properties. | |
| 44 | + * | |
| 45 | + * These are the negative, (1 - phi) = (phi^2) = (3 - sqrt(5))/2. | |
| 46 | + * (See Knuth vol 3, section 6.4, exercise 9.) | |
| 47 | + */ | |
| 48 | +#define GOLDEN_RATIO_32 0x61C88647 | |
| 49 | +#define GOLDEN_RATIO_64 0x61C8864680B583EBull | |
| 50 | + | |
| 35 | 51 | static __always_inline u64 hash_64(u64 val, unsigned int bits) |
| 36 | 52 | { |
| 37 | 53 | u64 hash = val; |
| 38 | 54 | |
| 39 | −#if defined(CONFIG_ARCH_HAS_FAST_MULTIPLIER) && BITS_PER_LONG == 64 | |
| 40 | − hash = hash * GOLDEN_RATIO_PRIME_64; | |
| 55 | +#if BITS_PER_LONG == 64 | |
| 56 | + hash = hash * GOLDEN_RATIO_64; | |
| 41 | 57 | #else |
| 42 | 58 | /* Sigh, gcc can't optimise this alone like it does for 32 bits. */ |
| 43 | 59 | u64 n = hash; |
| @@ -152,6 +152,7 @@ static inline bool is_huge_zero_pmd(pmd_t pmd) · 151 unmodified lines | ||
| 152 | 152 | } |
| 153 | 153 | |
| 154 | 154 | struct page *get_huge_zero_page(void); |
| 155 | +void put_huge_zero_page(void); | |
| 155 | 156 | |
| 156 | 157 | #else /* CONFIG_TRANSPARENT_HUGEPAGE */ |
| 157 | 158 | #define HPAGE_PMD_SHIFT ({ BUILD_BUG(); 0; }) |
| @@ -208,6 +209,10 @@ static inline bool is_huge_zero_page(struct page *page) · 50 unmodified lines | ||
| 208 | 209 | return false; |
| 209 | 210 | } |
| 210 | 211 | |
| 212 | +static inline void put_huge_zero_page(void) | |
| 213 | +{ | |
| 214 | + BUILD_BUG(); | |
| 215 | +} | |
| 211 | 216 | |
| 212 | 217 | static inline struct page *follow_devmap_pmd(struct vm_area_struct *vma, |
| 213 | 218 | unsigned long addr, pmd_t *pmd, int flags) |
| @@ -28,6 +28,11 @@ static inline struct ethhdr *eth_hdr(const struct sk_buff *skb) · 27 unmodified lines | ||
| 28 | 28 | return (struct ethhdr *)skb_mac_header(skb); |
| 29 | 29 | } |
| 30 | 30 | |
| 31 | +static inline struct ethhdr *inner_eth_hdr(const struct sk_buff *skb) | |
| 32 | +{ | |
| 33 | + return (struct ethhdr *)skb_inner_mac_header(skb); | |
| 34 | +} | |
| 35 | + | |
| 31 | 36 | int eth_header_parse(const struct sk_buff *skb, unsigned char *haddr); |
| 32 | 37 | |
| 33 | 38 | extern ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len); |
| @@ -196,9 +196,11 @@ struct lock_list { · 195 unmodified lines | ||
| 196 | 196 | * We record lock dependency chains, so that we can cache them: |
| 197 | 197 | */ |
| 198 | 198 | struct lock_chain { |
| 199 | − u8 irq_context; | |
| 200 | − u8 depth; | |
| 201 | − u16 base; | |
| 199 | + /* see BUILD_BUG_ON()s in lookup_chain_cache() */ | |
| 200 | + unsigned int irq_context : 2, | |
| 201 | + depth : 6, | |
| 202 | + base : 24; | |
| 203 | + /* 4 byte hole */ | |
| 202 | 204 | struct hlist_node entry; |
| 203 | 205 | u64 chain_key; |
| 204 | 206 | }; |
| @@ -393,6 +393,17 @@ enum { · 392 unmodified lines | ||
| 393 | 393 | MLX5_CAP_OFF_CMDIF_CSUM = 46, |
| 394 | 394 | }; |
| 395 | 395 | |
| 396 | +enum { | |
| 397 | + /* | |
| 398 | + * Max wqe size for rdma read is 512 bytes, so this | |
| 399 | + * limits our max_sge_rd as the wqe needs to fit: | |
| 400 | + * - ctrl segment (16 bytes) | |
| 401 | + * - rdma segment (16 bytes) | |
| 402 | + * - scatter elements (16 bytes each) | |
| 403 | + */ | |
| 404 | + MLX5_MAX_SGE_RD = (512 - 16 - 16) / 16 | |
| 405 | +}; | |
| 406 | + | |
| 396 | 407 | struct mlx5_inbox_hdr { |
| 397 | 408 | __be16 opcode; |
| 398 | 409 | u8 rsvd[4]; |
| @@ -1031,6 +1031,8 @@ static inline bool page_mapped(struct page *page) · 1030 unmodified lines | ||
| 1031 | 1031 | page = compound_head(page); |
| 1032 | 1032 | if (atomic_read(compound_mapcount_ptr(page)) >= 0) |
| 1033 | 1033 | return true; |
| 1034 | + if (PageHuge(page)) | |
| 1035 | + return false; | |
| 1034 | 1036 | for (i = 0; i < hpage_nr_pages(page); i++) { |
| 1035 | 1037 | if (atomic_read(&page[i]._mapcount) >= 0) |
| 1036 | 1038 | return true; |
| @@ -1138,6 +1140,8 @@ struct zap_details { · 101 unmodified lines | ||
| 1138 | 1140 | |
| 1139 | 1141 | struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, |
| 1140 | 1142 | pte_t pte); |
| 1143 | +struct page *vm_normal_page_pmd(struct vm_area_struct *vma, unsigned long addr, | |
| 1144 | + pmd_t pmd); | |
| 1141 | 1145 | |
| 1142 | 1146 | int zap_vma_ptes(struct vm_area_struct *vma, unsigned long address, |
| 1143 | 1147 | unsigned long size); |
| @@ -245,7 +245,15 @@ do { \ · 244 unmodified lines | ||
| 245 | 245 | net_ratelimited_function(pr_warn, fmt, ##__VA_ARGS__) |
| 246 | 246 | #define net_info_ratelimited(fmt, ...) \ |
| 247 | 247 | net_ratelimited_function(pr_info, fmt, ##__VA_ARGS__) |
| 248 | −#if defined(DEBUG) | |
| 248 | +#if defined(CONFIG_DYNAMIC_DEBUG) | |
| 249 | +#define net_dbg_ratelimited(fmt, ...) \ | |
| 250 | +do { \ | |
| 251 | + DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ | |
| 252 | + if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT) && \ | |
| 253 | + net_ratelimit()) \ | |
| 254 | + __dynamic_pr_debug(&descriptor, fmt, ##__VA_ARGS__); \ | |
| 255 | +} while (0) | |
| 256 | +#elif defined(DEBUG) | |
| 249 | 257 | #define net_dbg_ratelimited(fmt, ...) \ |
| 250 | 258 | net_ratelimited_function(pr_debug, fmt, ##__VA_ARGS__) |
| 251 | 259 | #else |
| @@ -3992,7 +3992,7 @@ netdev_features_t netif_skb_features(struct sk_buff *skb); · 3991 unmodified lines | ||
| 3992 | 3992 | |
| 3993 | 3993 | static inline bool net_gso_ok(netdev_features_t features, int gso_type) |
| 3994 | 3994 | { |
| 3995 | − netdev_features_t feature = gso_type << NETIF_F_GSO_SHIFT; | |
| 3995 | + netdev_features_t feature = (netdev_features_t)gso_type << NETIF_F_GSO_SHIFT; | |
| 3996 | 3996 | |
| 3997 | 3997 | /* check flags correspondence */ |
| 3998 | 3998 | BUILD_BUG_ON(SKB_GSO_TCPV4 != (NETIF_F_TSO >> NETIF_F_GSO_SHIFT)); |
| @@ -375,6 +375,9 @@ struct vb2_ops { · 374 unmodified lines | ||
| 375 | 375 | /** |
| 376 | 376 | * struct vb2_ops - driver-specific callbacks |
| 377 | 377 | * |
| 378 | + * @verify_planes_array: Verify that a given user space structure contains | |
| 379 | + * enough planes for the buffer. This is called | |
| 380 | + * for each dequeued buffer. | |
| 378 | 381 | * @fill_user_buffer: given a vb2_buffer fill in the userspace structure. |
| 379 | 382 | * For V4L2 this is a struct v4l2_buffer. |
| 380 | 383 | * @fill_vb2_buffer: given a userspace structure, fill in the vb2_buffer. |
| @@ -384,6 +387,7 @@ struct vb2_ops { · 3 unmodified lines | ||
| 384 | 387 | * the vb2_buffer struct. |
| 385 | 388 | */ |
| 386 | 389 | struct vb2_buf_ops { |
| 390 | + int (*verify_planes_array)(struct vb2_buffer *vb, const void *pb); | |
| 387 | 391 | void (*fill_user_buffer)(struct vb2_buffer *vb, void *pb); |
| 388 | 392 | int (*fill_vb2_buffer)(struct vb2_buffer *vb, const void *pb, |
| 389 | 393 | struct vb2_plane *planes); |
| @@ -400,6 +404,9 @@ struct vb2_buf_ops { · 10 unmodified lines | ||
| 400 | 404 | * @fileio_read_once: report EOF after reading the first buffer |
| 401 | 405 | * @fileio_write_immediately: queue buffer after each write() call |
| 402 | 406 | * @allow_zero_bytesused: allow bytesused == 0 to be passed to the driver |
| 407 | + * @quirk_poll_must_check_waiting_for_buffers: Return POLLERR at poll when QBUF | |
| 408 | + * has not been called. This is a vb1 idiom that has been adopted | |
| 409 | + * also by vb2. | |
| 403 | 410 | * @lock: pointer to a mutex that protects the vb2_queue struct. The |
| 404 | 411 | * driver can set this to a mutex to let the v4l2 core serialize |
| 405 | 412 | * the queuing ioctls. If the driver wants to handle locking |
| @@ -463,6 +470,7 @@ struct vb2_queue { · 57 unmodified lines | ||
| 463 | 470 | unsigned fileio_read_once:1; |
| 464 | 471 | unsigned fileio_write_immediately:1; |
| 465 | 472 | unsigned allow_zero_bytesused:1; |
| 473 | + unsigned quirk_poll_must_check_waiting_for_buffers:1; | |
| 466 | 474 | |
| 467 | 475 | struct mutex *lock; |
| 468 | 476 | void *owner; |
| @@ -317,7 +317,9 @@ static inline netdev_features_t vxlan_features_check(struct sk_buff *skb, · 316 unmodified lines | ||
| 317 | 317 | (skb->inner_protocol_type != ENCAP_TYPE_ETHER || |
| 318 | 318 | skb->inner_protocol != htons(ETH_P_TEB) || |
| 319 | 319 | (skb_inner_mac_header(skb) - skb_transport_header(skb) != |
| 320 | − sizeof(struct udphdr) + sizeof(struct vxlanhdr)))) | |
| 320 | + sizeof(struct udphdr) + sizeof(struct vxlanhdr)) || | |
| 321 | + (skb->ip_summed != CHECKSUM_NONE && | |
| 322 | + !can_checksum_protocol(features, inner_eth_hdr(skb)->h_proto)))) | |
| 321 | 323 | return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK); |
| 322 | 324 | |
| 323 | 325 | return features; |
| @@ -34,6 +34,7 @@ · 33 unmodified lines | ||
| 34 | 34 | #define _RDMA_IB_H |
| 35 | 35 | |
| 36 | 36 | #include <linux/types.h> |
| 37 | +#include <linux/sched.h> | |
| 37 | 38 | |
| 38 | 39 | struct ib_addr { |
| 39 | 40 | union { |
| @@ -86,4 +87,19 @@ struct sockaddr_ib { · 46 unmodified lines | ||
| 86 | 87 | __u64 sib_scope_id; |
| 87 | 88 | }; |
| 88 | 89 | |
| 90 | +/* | |
| 91 | + * The IB interfaces that use write() as bi-directional ioctl() are | |
| 92 | + * fundamentally unsafe, since there are lots of ways to trigger "write()" | |
| 93 | + * calls from various contexts with elevated privileges. That includes the | |
| 94 | + * traditional suid executable error message writes, but also various kernel | |
| 95 | + * interfaces that can write to file descriptors. | |
| 96 | + * | |
| 97 | + * This function provides protection for the legacy API by restricting the | |
| 98 | + * calling context. | |
| 99 | + */ | |
| 100 | +static inline bool ib_safe_file_access(struct file *filp) | |
| 101 | +{ | |
| 102 | + return filp->f_cred == current_cred() && segment_eq(get_fs(), USER_DS); | |
| 103 | +} | |
| 104 | + | |
| 89 | 105 | #endif /* _RDMA_IB_H */ |
| @@ -9,7 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | #ifdef CONFIG_SND_HDA_I915 |
| 10 | 10 | int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable); |
| 11 | 11 | int snd_hdac_display_power(struct hdac_bus *bus, bool enable); |
| 12 | −int snd_hdac_get_display_clk(struct hdac_bus *bus); | |
| 12 | +void snd_hdac_i915_set_bclk(struct hdac_bus *bus); | |
| 13 | 13 | int snd_hdac_sync_audio_rate(struct hdac_bus *bus, hda_nid_t nid, int rate); |
| 14 | 14 | int snd_hdac_acomp_get_eld(struct hdac_bus *bus, hda_nid_t nid, |
| 15 | 15 | bool *audio_enabled, char *buffer, int max_bytes); |
| @@ -25,9 +25,8 @@ static inline int snd_hdac_display_power(struct hdac_bus *bus, bool enable) · 9 unmodified lines | ||
| 25 | 25 | { |
| 26 | 26 | return 0; |
| 27 | 27 | } |
| 28 | −static inline int snd_hdac_get_display_clk(struct hdac_bus *bus) | |
| 28 | +static inline void snd_hdac_i915_set_bclk(struct hdac_bus *bus) | |
| 29 | 29 | { |
| 30 | − return 0; | |
| 31 | 30 | } |
| 32 | 31 | static inline int snd_hdac_sync_audio_rate(struct hdac_bus *bus, hda_nid_t nid, |
| 33 | 32 | int rate) |
| @@ -183,7 +183,8 @@ · 182 unmodified lines | ||
| 183 | 183 | |
| 184 | 184 | #define V4L2_DV_BT_CEA_3840X2160P24 { \ |
| 185 | 185 | .type = V4L2_DV_BT_656_1120, \ |
| 186 | − V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ | |
| 186 | + V4L2_INIT_BT_TIMINGS(3840, 2160, 0, \ | |
| 187 | + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ | |
| 187 | 188 | 297000000, 1276, 88, 296, 8, 10, 72, 0, 0, 0, \ |
| 188 | 189 | V4L2_DV_BT_STD_CEA861, \ |
| 189 | 190 | V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ |
| @@ -191,14 +192,16 @@ · 1 unmodified line | ||
| 191 | 192 | |
| 192 | 193 | #define V4L2_DV_BT_CEA_3840X2160P25 { \ |
| 193 | 194 | .type = V4L2_DV_BT_656_1120, \ |
| 194 | − V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ | |
| 195 | + V4L2_INIT_BT_TIMINGS(3840, 2160, 0, \ | |
| 196 | + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ | |
| 195 | 197 | 297000000, 1056, 88, 296, 8, 10, 72, 0, 0, 0, \ |
| 196 | 198 | V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ |
| 197 | 199 | } |
| 198 | 200 | |
| 199 | 201 | #define V4L2_DV_BT_CEA_3840X2160P30 { \ |
| 200 | 202 | .type = V4L2_DV_BT_656_1120, \ |
| 201 | − V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ | |
| 203 | + V4L2_INIT_BT_TIMINGS(3840, 2160, 0, \ | |
| 204 | + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ | |
| 202 | 205 | 297000000, 176, 88, 296, 8, 10, 72, 0, 0, 0, \ |
| 203 | 206 | V4L2_DV_BT_STD_CEA861, \ |
| 204 | 207 | V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ |
| @@ -206,14 +209,16 @@ · 1 unmodified line | ||
| 206 | 209 | |
| 207 | 210 | #define V4L2_DV_BT_CEA_3840X2160P50 { \ |
| 208 | 211 | .type = V4L2_DV_BT_656_1120, \ |
| 209 | − V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ | |
| 212 | + V4L2_INIT_BT_TIMINGS(3840, 2160, 0, \ | |
| 213 | + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ | |
| 210 | 214 | 594000000, 1056, 88, 296, 8, 10, 72, 0, 0, 0, \ |
| 211 | 215 | V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ |
| 212 | 216 | } |
| 213 | 217 | |
| 214 | 218 | #define V4L2_DV_BT_CEA_3840X2160P60 { \ |
| 215 | 219 | .type = V4L2_DV_BT_656_1120, \ |
| 216 | − V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ | |
| 220 | + V4L2_INIT_BT_TIMINGS(3840, 2160, 0, \ | |
| 221 | + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ | |
| 217 | 222 | 594000000, 176, 88, 296, 8, 10, 72, 0, 0, 0, \ |
| 218 | 223 | V4L2_DV_BT_STD_CEA861, \ |
| 219 | 224 | V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ |
| @@ -221,7 +226,8 @@ · 1 unmodified line | ||
| 221 | 226 | |
| 222 | 227 | #define V4L2_DV_BT_CEA_4096X2160P24 { \ |
| 223 | 228 | .type = V4L2_DV_BT_656_1120, \ |
| 224 | − V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ | |
| 229 | + V4L2_INIT_BT_TIMINGS(4096, 2160, 0, \ | |
| 230 | + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ | |
| 225 | 231 | 297000000, 1020, 88, 296, 8, 10, 72, 0, 0, 0, \ |
| 226 | 232 | V4L2_DV_BT_STD_CEA861, \ |
| 227 | 233 | V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ |
| @@ -229,14 +235,16 @@ · 1 unmodified line | ||
| 229 | 235 | |
| 230 | 236 | #define V4L2_DV_BT_CEA_4096X2160P25 { \ |
| 231 | 237 | .type = V4L2_DV_BT_656_1120, \ |
| 232 | − V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ | |
| 238 | + V4L2_INIT_BT_TIMINGS(4096, 2160, 0, \ | |
| 239 | + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ | |
| 233 | 240 | 297000000, 968, 88, 128, 8, 10, 72, 0, 0, 0, \ |
| 234 | 241 | V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ |
| 235 | 242 | } |
| 236 | 243 | |
| 237 | 244 | #define V4L2_DV_BT_CEA_4096X2160P30 { \ |
| 238 | 245 | .type = V4L2_DV_BT_656_1120, \ |
| 239 | − V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ | |
| 246 | + V4L2_INIT_BT_TIMINGS(4096, 2160, 0, \ | |
| 247 | + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ | |
| 240 | 248 | 297000000, 88, 88, 128, 8, 10, 72, 0, 0, 0, \ |
| 241 | 249 | V4L2_DV_BT_STD_CEA861, \ |
| 242 | 250 | V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ |
| @@ -244,14 +252,16 @@ · 1 unmodified line | ||
| 244 | 252 | |
| 245 | 253 | #define V4L2_DV_BT_CEA_4096X2160P50 { \ |
| 246 | 254 | .type = V4L2_DV_BT_656_1120, \ |
| 247 | − V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ | |
| 255 | + V4L2_INIT_BT_TIMINGS(4096, 2160, 0, \ | |
| 256 | + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ | |
| 248 | 257 | 594000000, 968, 88, 128, 8, 10, 72, 0, 0, 0, \ |
| 249 | 258 | V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ |
| 250 | 259 | } |
| 251 | 260 | |
| 252 | 261 | #define V4L2_DV_BT_CEA_4096X2160P60 { \ |
| 253 | 262 | .type = V4L2_DV_BT_656_1120, \ |
| 254 | − V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ | |
| 263 | + V4L2_INIT_BT_TIMINGS(4096, 2160, 0, \ | |
| 264 | + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ | |
| 255 | 265 | 594000000, 88, 88, 128, 8, 10, 72, 0, 0, 0, \ |
| 256 | 266 | V4L2_DV_BT_STD_CEA861, \ |
| 257 | 267 | V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ |
| @@ -31,10 +31,10 @@ static void *bpf_any_get(void *raw, enum bpf_type type) · 30 unmodified lines | ||
| 31 | 31 | { |
| 32 | 32 | switch (type) { |
| 33 | 33 | case BPF_TYPE_PROG: |
| 34 | − atomic_inc(&((struct bpf_prog *)raw)->aux->refcnt); | |
| 34 | + raw = bpf_prog_inc(raw); | |
| 35 | 35 | break; |
| 36 | 36 | case BPF_TYPE_MAP: |
| 37 | − bpf_map_inc(raw, true); | |
| 37 | + raw = bpf_map_inc(raw, true); | |
| 38 | 38 | break; |
| 39 | 39 | default: |
| 40 | 40 | WARN_ON_ONCE(1); |
| @@ -297,7 +297,8 @@ static void *bpf_obj_do_get(const struct filename *pathname, · 256 unmodified lines | ||
| 297 | 297 | goto out; |
| 298 | 298 | |
| 299 | 299 | raw = bpf_any_get(inode->i_private, *type); |
| 300 | − touch_atime(&path); | |
| 300 | + if (!IS_ERR(raw)) | |
| 301 | + touch_atime(&path); | |
| 301 | 302 | |
| 302 | 303 | path_put(&path); |
| 303 | 304 | return raw; |
| @@ -218,11 +218,18 @@ struct bpf_map *__bpf_map_get(struct fd f) · 217 unmodified lines | ||
| 218 | 218 | return f.file->private_data; |
| 219 | 219 | } |
| 220 | 220 | |
| 221 | −void bpf_map_inc(struct bpf_map *map, bool uref) | |
| 221 | +/* prog's and map's refcnt limit */ | |
| 222 | +#define BPF_MAX_REFCNT 32768 | |
| 223 | + | |
| 224 | +struct bpf_map *bpf_map_inc(struct bpf_map *map, bool uref) | |
| 222 | 225 | { |
| 223 | − atomic_inc(&map->refcnt); | |
| 226 | + if (atomic_inc_return(&map->refcnt) > BPF_MAX_REFCNT) { | |
| 227 | + atomic_dec(&map->refcnt); | |
| 228 | + return ERR_PTR(-EBUSY); | |
| 229 | + } | |
| 224 | 230 | if (uref) |
| 225 | 231 | atomic_inc(&map->usercnt); |
| 232 | + return map; | |
| 226 | 233 | } |
| 227 | 234 | |
| 228 | 235 | struct bpf_map *bpf_map_get_with_uref(u32 ufd) |
| @@ -234,7 +241,7 @@ struct bpf_map *bpf_map_get_with_uref(u32 ufd) · 5 unmodified lines | ||
| 234 | 241 | if (IS_ERR(map)) |
| 235 | 242 | return map; |
| 236 | 243 | |
| 237 | − bpf_map_inc(map, true); | |
| 244 | + map = bpf_map_inc(map, true); | |
| 238 | 245 | fdput(f); |
| 239 | 246 | |
| 240 | 247 | return map; |
| @@ -658,6 +665,15 @@ static struct bpf_prog *__bpf_prog_get(struct fd f) · 417 unmodified lines | ||
| 658 | 665 | return f.file->private_data; |
| 659 | 666 | } |
| 660 | 667 | |
| 668 | +struct bpf_prog *bpf_prog_inc(struct bpf_prog *prog) | |
| 669 | +{ | |
| 670 | + if (atomic_inc_return(&prog->aux->refcnt) > BPF_MAX_REFCNT) { | |
| 671 | + atomic_dec(&prog->aux->refcnt); | |
| 672 | + return ERR_PTR(-EBUSY); | |
| 673 | + } | |
| 674 | + return prog; | |
| 675 | +} | |
| 676 | + | |
| 661 | 677 | /* called by sockets/tracing/seccomp before attaching program to an event |
| 662 | 678 | * pairs with bpf_prog_put() |
| 663 | 679 | */ |
| @@ -670,7 +686,7 @@ struct bpf_prog *bpf_prog_get(u32 ufd) · 6 unmodified lines | ||
| 670 | 686 | if (IS_ERR(prog)) |
| 671 | 687 | return prog; |
| 672 | 688 | |
| 673 | − atomic_inc(&prog->aux->refcnt); | |
| 689 | + prog = bpf_prog_inc(prog); | |
| 674 | 690 | fdput(f); |
| 675 | 691 | |
| 676 | 692 | return prog; |
| @@ -249,16 +249,6 @@ static const char * const reg_type_str[] = { · 248 unmodified lines | ||
| 249 | 249 | [CONST_IMM] = "imm", |
| 250 | 250 | }; |
| 251 | 251 | |
| 252 | −static const struct { | |
| 253 | − int map_type; | |
| 254 | − int func_id; | |
| 255 | −} func_limit[] = { | |
| 256 | − {BPF_MAP_TYPE_PROG_ARRAY, BPF_FUNC_tail_call}, | |
| 257 | − {BPF_MAP_TYPE_PERF_EVENT_ARRAY, BPF_FUNC_perf_event_read}, | |
| 258 | − {BPF_MAP_TYPE_PERF_EVENT_ARRAY, BPF_FUNC_perf_event_output}, | |
| 259 | − {BPF_MAP_TYPE_STACK_TRACE, BPF_FUNC_get_stackid}, | |
| 260 | −}; | |
| 261 | − | |
| 262 | 252 | static void print_verifier_state(struct verifier_env *env) |
| 263 | 253 | { |
| 264 | 254 | enum bpf_reg_type t; |
| @@ -943,27 +933,52 @@ static int check_func_arg(struct verifier_env *env, u32 regno, · 678 unmodified lines | ||
| 943 | 933 | |
| 944 | 934 | static int check_map_func_compatibility(struct bpf_map *map, int func_id) |
| 945 | 935 | { |
| 946 | − bool bool_map, bool_func; | |
| 947 | − int i; | |
| 948 | − | |
| 949 | 936 | if (!map) |
| 950 | 937 | return 0; |
| 951 | 938 | |
| 952 | − for (i = 0; i < ARRAY_SIZE(func_limit); i++) { | |
| 953 | − bool_map = (map->map_type == func_limit[i].map_type); | |
| 954 | − bool_func = (func_id == func_limit[i].func_id); | |
| 955 | − /* only when map & func pair match it can continue. | |
| 956 | − * don't allow any other map type to be passed into | |
| 957 | − * the special func; | |
| 958 | − */ | |
| 959 | − if (bool_func && bool_map != bool_func) { | |
| 960 | − verbose("cannot pass map_type %d into func %d\n", | |
| 961 | − map->map_type, func_id); | |
| 962 | − return -EINVAL; | |
| 963 | − } | |
| 939 | + /* We need a two way check, first is from map perspective ... */ | |
| 940 | + switch (map->map_type) { | |
| 941 | + case BPF_MAP_TYPE_PROG_ARRAY: | |
| 942 | + if (func_id != BPF_FUNC_tail_call) | |
| 943 | + goto error; | |
| 944 | + break; | |
| 945 | + case BPF_MAP_TYPE_PERF_EVENT_ARRAY: | |
| 946 | + if (func_id != BPF_FUNC_perf_event_read && | |
| 947 | + func_id != BPF_FUNC_perf_event_output) | |
| 948 | + goto error; | |
| 949 | + break; | |
| 950 | + case BPF_MAP_TYPE_STACK_TRACE: | |
| 951 | + if (func_id != BPF_FUNC_get_stackid) | |
| 952 | + goto error; | |
| 953 | + break; | |
| 954 | + default: | |
| 955 | + break; | |
| 956 | + } | |
| 957 | + | |
| 958 | + /* ... and second from the function itself. */ | |
| 959 | + switch (func_id) { | |
| 960 | + case BPF_FUNC_tail_call: | |
| 961 | + if (map->map_type != BPF_MAP_TYPE_PROG_ARRAY) | |
| 962 | + goto error; | |
| 963 | + break; | |
| 964 | + case BPF_FUNC_perf_event_read: | |
| 965 | + case BPF_FUNC_perf_event_output: | |
| 966 | + if (map->map_type != BPF_MAP_TYPE_PERF_EVENT_ARRAY) | |
| 967 | + goto error; | |
| 968 | + break; | |
| 969 | + case BPF_FUNC_get_stackid: | |
| 970 | + if (map->map_type != BPF_MAP_TYPE_STACK_TRACE) | |
| 971 | + goto error; | |
| 972 | + break; | |
| 973 | + default: | |
| 974 | + break; | |
| 964 | 975 | } |
| 965 | 976 | |
| 966 | 977 | return 0; |
| 978 | +error: | |
| 979 | + verbose("cannot pass map_type %d into func %d\n", | |
| 980 | + map->map_type, func_id); | |
| 981 | + return -EINVAL; | |
| 967 | 982 | } |
| 968 | 983 | |
| 969 | 984 | static int check_raw_mode(const struct bpf_func_proto *fn) |
| @@ -2111,15 +2126,18 @@ static int replace_map_fd_with_map_ptr(struct verifier_env *env) · 1141 unmodified lines | ||
| 2111 | 2126 | return -E2BIG; |
| 2112 | 2127 | } |
| 2113 | 2128 | |
| 2114 | − /* remember this map */ | |
| 2115 | − env->used_maps[env->used_map_cnt++] = map; | |
| 2116 | − | |
| 2117 | 2129 | /* hold the map. If the program is rejected by verifier, |
| 2118 | 2130 | * the map will be released by release_maps() or it |
| 2119 | 2131 | * will be used by the valid program until it's unloaded |
| 2120 | 2132 | * and all maps are released in free_bpf_prog_info() |
| 2121 | 2133 | */ |
| 2122 | − bpf_map_inc(map, false); | |
| 2134 | + map = bpf_map_inc(map, false); | |
| 2135 | + if (IS_ERR(map)) { | |
| 2136 | + fdput(f); | |
| 2137 | + return PTR_ERR(map); | |
| 2138 | + } | |
| 2139 | + env->used_maps[env->used_map_cnt++] = map; | |
| 2140 | + | |
| 2123 | 2141 | fdput(f); |
| 2124 | 2142 | next_insn: |
| 2125 | 2143 | insn++; |
| @@ -2825,9 +2825,10 @@ static ssize_t __cgroup_procs_write(struct kernfs_open_file *of, char *buf, · 2824 unmodified lines | ||
| 2825 | 2825 | size_t nbytes, loff_t off, bool threadgroup) |
| 2826 | 2826 | { |
| 2827 | 2827 | struct task_struct *tsk; |
| 2828 | + struct cgroup_subsys *ss; | |
| 2828 | 2829 | struct cgroup *cgrp; |
| 2829 | 2830 | pid_t pid; |
| 2830 | − int ret; | |
| 2831 | + int ssid, ret; | |
| 2831 | 2832 | |
| 2832 | 2833 | if (kstrtoint(strstrip(buf), 0, &pid) || pid < 0) |
| 2833 | 2834 | return -EINVAL; |
| @@ -2875,8 +2876,10 @@ out_unlock_rcu: · 41 unmodified lines | ||
| 2875 | 2876 | rcu_read_unlock(); |
| 2876 | 2877 | out_unlock_threadgroup: |
| 2877 | 2878 | percpu_up_write(&cgroup_threadgroup_rwsem); |
| 2879 | + for_each_subsys(ss, ssid) | |
| 2880 | + if (ss->post_attach) | |
| 2881 | + ss->post_attach(); | |
| 2878 | 2882 | cgroup_kn_unlock(of->kn); |
| 2879 | − cpuset_post_attach_flush(); | |
| 2880 | 2883 | return ret ?: nbytes; |
| 2881 | 2884 | } |
| 2882 | 2885 | |
| @@ -58,7 +58,6 @@ · 57 unmodified lines | ||
| 58 | 58 | #include <asm/uaccess.h> |
| 59 | 59 | #include <linux/atomic.h> |
| 60 | 60 | #include <linux/mutex.h> |
| 61 | −#include <linux/workqueue.h> | |
| 62 | 61 | #include <linux/cgroup.h> |
| 63 | 62 | #include <linux/wait.h> |
| 64 | 63 | |
| @@ -1016,7 +1015,7 @@ static void cpuset_migrate_mm(struct mm_struct *mm, const nodemask_t *from, · 951 unmodified lines | ||
| 1016 | 1015 | } |
| 1017 | 1016 | } |
| 1018 | 1017 | |
| 1019 | −void cpuset_post_attach_flush(void) | |
| 1018 | +static void cpuset_post_attach(void) | |
| 1020 | 1019 | { |
| 1021 | 1020 | flush_workqueue(cpuset_migrate_mm_wq); |
| 1022 | 1021 | } |
| @@ -2087,6 +2086,7 @@ struct cgroup_subsys cpuset_cgrp_subsys = { · 1064 unmodified lines | ||
| 2087 | 2086 | .can_attach = cpuset_can_attach, |
| 2088 | 2087 | .cancel_attach = cpuset_cancel_attach, |
| 2089 | 2088 | .attach = cpuset_attach, |
| 2089 | + .post_attach = cpuset_post_attach, | |
| 2090 | 2090 | .bind = cpuset_bind, |
| 2091 | 2091 | .legacy_cftypes = files, |
| 2092 | 2092 | .early_init = true, |
| @@ -412,7 +412,8 @@ int perf_cpu_time_max_percent_handler(struct ctl_table *table, int write, · 411 unmodified lines | ||
| 412 | 412 | if (ret || !write) |
| 413 | 413 | return ret; |
| 414 | 414 | |
| 415 | − if (sysctl_perf_cpu_time_max_percent == 100) { | |
| 415 | + if (sysctl_perf_cpu_time_max_percent == 100 || | |
| 416 | + sysctl_perf_cpu_time_max_percent == 0) { | |
| 416 | 417 | printk(KERN_WARNING |
| 417 | 418 | "perf: Dynamic interrupt throttling disabled, can hang your system!\n"); |
| 418 | 419 | WRITE_ONCE(perf_sample_allowed_ns, 0); |
| @@ -1105,6 +1106,7 @@ static void put_ctx(struct perf_event_context *ctx) · 686 unmodified lines | ||
| 1105 | 1106 | * function. |
| 1106 | 1107 | * |
| 1107 | 1108 | * Lock order: |
| 1109 | + * cred_guard_mutex | |
| 1108 | 1110 | * task_struct::perf_event_mutex |
| 1109 | 1111 | * perf_event_context::mutex |
| 1110 | 1112 | * perf_event::child_mutex; |
| @@ -3420,7 +3422,6 @@ static struct task_struct * · 2309 unmodified lines | ||
| 3420 | 3422 | find_lively_task_by_vpid(pid_t vpid) |
| 3421 | 3423 | { |
| 3422 | 3424 | struct task_struct *task; |
| 3423 | − int err; | |
| 3424 | 3425 | |
| 3425 | 3426 | rcu_read_lock(); |
| 3426 | 3427 | if (!vpid) |
| @@ -3434,16 +3435,7 @@ find_lively_task_by_vpid(pid_t vpid) · 7 unmodified lines | ||
| 3434 | 3435 | if (!task) |
| 3435 | 3436 | return ERR_PTR(-ESRCH); |
| 3436 | 3437 | |
| 3437 | − /* Reuse ptrace permission checks for now. */ | |
| 3438 | − err = -EACCES; | |
| 3439 | − if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS)) | |
| 3440 | − goto errout; | |
| 3441 | − | |
| 3442 | 3438 | return task; |
| 3443 | −errout: | |
| 3444 | − put_task_struct(task); | |
| 3445 | − return ERR_PTR(err); | |
| 3446 | − | |
| 3447 | 3439 | } |
| 3448 | 3440 | |
| 3449 | 3441 | /* |
| @@ -8446,6 +8438,24 @@ SYSCALL_DEFINE5(perf_event_open, · 4996 unmodified lines | ||
| 8446 | 8438 | |
| 8447 | 8439 | get_online_cpus(); |
| 8448 | 8440 | |
| 8441 | + if (task) { | |
| 8442 | + err = mutex_lock_interruptible(&task->signal->cred_guard_mutex); | |
| 8443 | + if (err) | |
| 8444 | + goto err_cpus; | |
| 8445 | + | |
| 8446 | + /* | |
| 8447 | + * Reuse ptrace permission checks for now. | |
| 8448 | + * | |
| 8449 | + * We must hold cred_guard_mutex across this and any potential | |
| 8450 | + * perf_install_in_context() call for this new event to | |
| 8451 | + * serialize against exec() altering our credentials (and the | |
| 8452 | + * perf_event_exit_task() that could imply). | |
| 8453 | + */ | |
| 8454 | + err = -EACCES; | |
| 8455 | + if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS)) | |
| 8456 | + goto err_cred; | |
| 8457 | + } | |
| 8458 | + | |
| 8449 | 8459 | if (flags & PERF_FLAG_PID_CGROUP) |
| 8450 | 8460 | cgroup_fd = pid; |
| 8451 | 8461 | |
| @@ -8453,7 +8463,7 @@ SYSCALL_DEFINE5(perf_event_open, · 1 unmodified line | ||
| 8453 | 8463 | NULL, NULL, cgroup_fd); |
| 8454 | 8464 | if (IS_ERR(event)) { |
| 8455 | 8465 | err = PTR_ERR(event); |
| 8456 | − goto err_cpus; | |
| 8466 | + goto err_cred; | |
| 8457 | 8467 | } |
| 8458 | 8468 | |
| 8459 | 8469 | if (is_sampling_event(event)) { |
| @@ -8512,11 +8522,6 @@ SYSCALL_DEFINE5(perf_event_open, · 52 unmodified lines | ||
| 8512 | 8522 | goto err_context; |
| 8513 | 8523 | } |
| 8514 | 8524 | |
| 8515 | − if (task) { | |
| 8516 | − put_task_struct(task); | |
| 8517 | − task = NULL; | |
| 8518 | − } | |
| 8519 | − | |
| 8520 | 8525 | /* |
| 8521 | 8526 | * Look up the group leader (we will attach this event to it): |
| 8522 | 8527 | */ |
| @@ -8614,6 +8619,11 @@ SYSCALL_DEFINE5(perf_event_open, · 91 unmodified lines | ||
| 8614 | 8619 | |
| 8615 | 8620 | WARN_ON_ONCE(ctx->parent_ctx); |
| 8616 | 8621 | |
| 8622 | + /* | |
| 8623 | + * This is the point on no return; we cannot fail hereafter. This is | |
| 8624 | + * where we start modifying current state. | |
| 8625 | + */ | |
| 8626 | + | |
| 8617 | 8627 | if (move_group) { |
| 8618 | 8628 | /* |
| 8619 | 8629 | * See perf_event_ctx_lock() for comments on the details |
| @@ -8685,6 +8695,11 @@ SYSCALL_DEFINE5(perf_event_open, · 65 unmodified lines | ||
| 8685 | 8695 | mutex_unlock(&gctx->mutex); |
| 8686 | 8696 | mutex_unlock(&ctx->mutex); |
| 8687 | 8697 | |
| 8698 | + if (task) { | |
| 8699 | + mutex_unlock(&task->signal->cred_guard_mutex); | |
| 8700 | + put_task_struct(task); | |
| 8701 | + } | |
| 8702 | + | |
| 8688 | 8703 | put_online_cpus(); |
| 8689 | 8704 | |
| 8690 | 8705 | mutex_lock(¤t->perf_event_mutex); |
| @@ -8717,6 +8732,9 @@ err_alloc: · 26 unmodified lines | ||
| 8717 | 8732 | */ |
| 8718 | 8733 | if (!event_file) |
| 8719 | 8734 | free_event(event); |
| 8735 | +err_cred: | |
| 8736 | + if (task) | |
| 8737 | + mutex_unlock(&task->signal->cred_guard_mutex); | |
| 8720 | 8738 | err_cpus: |
| 8721 | 8739 | put_online_cpus(); |
| 8722 | 8740 | err_task: |
| @@ -9001,6 +9019,9 @@ static void perf_event_exit_task_context(struct task_struct *child, int ctxn) · 278 unmodified lines | ||
| 9001 | 9019 | |
| 9002 | 9020 | /* |
| 9003 | 9021 | * When a child task exits, feed back event values to parent events. |
| 9022 | + * | |
| 9023 | + * Can be called with cred_guard_mutex held when called from | |
| 9024 | + * install_exec_creds(). | |
| 9004 | 9025 | */ |
| 9005 | 9026 | void perf_event_exit_task(struct task_struct *child) |
| 9006 | 9027 | { |
| @@ -1,5 +1,6 @@ | ||
| 1 | 1 | #define pr_fmt(fmt) "kcov: " fmt |
| 2 | 2 | |
| 3 | +#define DISABLE_BRANCH_PROFILING | |
| 3 | 4 | #include <linux/compiler.h> |
| 4 | 5 | #include <linux/types.h> |
| 5 | 6 | #include <linux/file.h> |
| @@ -43,7 +44,7 @@ struct kcov { · 37 unmodified lines | ||
| 43 | 44 | * Entry point from instrumented code. |
| 44 | 45 | * This is called once per basic-block/edge. |
| 45 | 46 | */ |
| 46 | −void __sanitizer_cov_trace_pc(void) | |
| 47 | +void notrace __sanitizer_cov_trace_pc(void) | |
| 47 | 48 | { |
| 48 | 49 | struct task_struct *t; |
| 49 | 50 | enum kcov_mode mode; |
| @@ -1415,6 +1415,9 @@ static int __init crash_save_vmcoreinfo_init(void) · 1414 unmodified lines | ||
| 1415 | 1415 | VMCOREINFO_OFFSET(page, lru); |
| 1416 | 1416 | VMCOREINFO_OFFSET(page, _mapcount); |
| 1417 | 1417 | VMCOREINFO_OFFSET(page, private); |
| 1418 | + VMCOREINFO_OFFSET(page, compound_dtor); | |
| 1419 | + VMCOREINFO_OFFSET(page, compound_order); | |
| 1420 | + VMCOREINFO_OFFSET(page, compound_head); | |
| 1418 | 1421 | VMCOREINFO_OFFSET(pglist_data, node_zones); |
| 1419 | 1422 | VMCOREINFO_OFFSET(pglist_data, nr_zones); |
| 1420 | 1423 | #ifdef CONFIG_FLAT_NODE_MEM_MAP |
| @@ -1447,8 +1450,8 @@ static int __init crash_save_vmcoreinfo_init(void) · 26 unmodified lines | ||
| 1447 | 1450 | #ifdef CONFIG_X86 |
| 1448 | 1451 | VMCOREINFO_NUMBER(KERNEL_IMAGE_SIZE); |
| 1449 | 1452 | #endif |
| 1450 | −#ifdef CONFIG_HUGETLBFS | |
| 1451 | − VMCOREINFO_SYMBOL(free_huge_page); | |
| 1453 | +#ifdef CONFIG_HUGETLB_PAGE | |
| 1454 | + VMCOREINFO_NUMBER(HUGETLB_PAGE_DTOR); | |
| 1452 | 1455 | #endif |
| 1453 | 1456 | |
| 1454 | 1457 | arch_crash_save_vmcoreinfo(); |
| @@ -2176,15 +2176,37 @@ cache_hit: · 2175 unmodified lines | ||
| 2176 | 2176 | chain->irq_context = hlock->irq_context; |
| 2177 | 2177 | i = get_first_held_lock(curr, hlock); |
| 2178 | 2178 | chain->depth = curr->lockdep_depth + 1 - i; |
| 2179 | + | |
| 2180 | + BUILD_BUG_ON((1UL << 24) <= ARRAY_SIZE(chain_hlocks)); | |
| 2181 | + BUILD_BUG_ON((1UL << 6) <= ARRAY_SIZE(curr->held_locks)); | |
| 2182 | + BUILD_BUG_ON((1UL << 8*sizeof(chain_hlocks[0])) <= ARRAY_SIZE(lock_classes)); | |
| 2183 | + | |
| 2179 | 2184 | if (likely(nr_chain_hlocks + chain->depth <= MAX_LOCKDEP_CHAIN_HLOCKS)) { |
| 2180 | 2185 | chain->base = nr_chain_hlocks; |
| 2181 | − nr_chain_hlocks += chain->depth; | |
| 2182 | 2186 | for (j = 0; j < chain->depth - 1; j++, i++) { |
| 2183 | 2187 | int lock_id = curr->held_locks[i].class_idx - 1; |
| 2184 | 2188 | chain_hlocks[chain->base + j] = lock_id; |
| 2185 | 2189 | } |
| 2186 | 2190 | chain_hlocks[chain->base + j] = class - lock_classes; |
| 2187 | 2191 | } |
| 2192 | + | |
| 2193 | + if (nr_chain_hlocks < MAX_LOCKDEP_CHAIN_HLOCKS) | |
| 2194 | + nr_chain_hlocks += chain->depth; | |
| 2195 | + | |
| 2196 | +#ifdef CONFIG_DEBUG_LOCKDEP | |
| 2197 | + /* | |
| 2198 | + * Important for check_no_collision(). | |
| 2199 | + */ | |
| 2200 | + if (unlikely(nr_chain_hlocks > MAX_LOCKDEP_CHAIN_HLOCKS)) { | |
| 2201 | + if (debug_locks_off_graph_unlock()) | |
| 2202 | + return 0; | |
| 2203 | + | |
| 2204 | + print_lockdep_off("BUG: MAX_LOCKDEP_CHAIN_HLOCKS too low!"); | |
| 2205 | + dump_stack(); | |
| 2206 | + return 0; | |
| 2207 | + } | |
| 2208 | +#endif | |
| 2209 | + | |
| 2188 | 2210 | hlist_add_head_rcu(&chain->entry, hash_head); |
| 2189 | 2211 | debug_atomic_inc(chain_lookup_misses); |
| 2190 | 2212 | inc_chains(); |
| @@ -2932,6 +2954,11 @@ static int mark_irqflags(struct task_struct *curr, struct held_lock *hlock) · 741 unmodified lines | ||
| 2932 | 2954 | return 1; |
| 2933 | 2955 | } |
| 2934 | 2956 | |
| 2957 | +static inline unsigned int task_irq_context(struct task_struct *task) | |
| 2958 | +{ | |
| 2959 | + return 2 * !!task->hardirq_context + !!task->softirq_context; | |
| 2960 | +} | |
| 2961 | + | |
| 2935 | 2962 | static int separate_irq_context(struct task_struct *curr, |
| 2936 | 2963 | struct held_lock *hlock) |
| 2937 | 2964 | { |
| @@ -2940,8 +2967,6 @@ static int separate_irq_context(struct task_struct *curr, · 2 unmodified lines | ||
| 2940 | 2967 | /* |
| 2941 | 2968 | * Keep track of points where we cross into an interrupt context: |
| 2942 | 2969 | */ |
| 2943 | − hlock->irq_context = 2*(curr->hardirq_context ? 1 : 0) + | |
| 2944 | − curr->softirq_context; | |
| 2945 | 2970 | if (depth) { |
| 2946 | 2971 | struct held_lock *prev_hlock; |
| 2947 | 2972 | |
| @@ -2973,6 +2998,11 @@ static inline int mark_irqflags(struct task_struct *curr, · 25 unmodified lines | ||
| 2973 | 2998 | return 1; |
| 2974 | 2999 | } |
| 2975 | 3000 | |
| 3001 | +static inline unsigned int task_irq_context(struct task_struct *task) | |
| 3002 | +{ | |
| 3003 | + return 0; | |
| 3004 | +} | |
| 3005 | + | |
| 2976 | 3006 | static inline int separate_irq_context(struct task_struct *curr, |
| 2977 | 3007 | struct held_lock *hlock) |
| 2978 | 3008 | { |
| @@ -3241,6 +3271,7 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass, · 262 unmodified lines | ||
| 3241 | 3271 | hlock->acquire_ip = ip; |
| 3242 | 3272 | hlock->instance = lock; |
| 3243 | 3273 | hlock->nest_lock = nest_lock; |
| 3274 | + hlock->irq_context = task_irq_context(curr); | |
| 3244 | 3275 | hlock->trylock = trylock; |
| 3245 | 3276 | hlock->read = read; |
| 3246 | 3277 | hlock->check = check; |
| @@ -141,6 +141,8 @@ static int lc_show(struct seq_file *m, void *v) · 140 unmodified lines | ||
| 141 | 141 | int i; |
| 142 | 142 | |
| 143 | 143 | if (v == SEQ_START_TOKEN) { |
| 144 | + if (nr_chain_hlocks > MAX_LOCKDEP_CHAIN_HLOCKS) | |
| 145 | + seq_printf(m, "(buggered) "); | |
| 144 | 146 | seq_printf(m, "all lock chains:\n"); |
| 145 | 147 | return 0; |
| 146 | 148 | } |
| @@ -666,6 +666,35 @@ static void set_work_pool_and_clear_pending(struct work_struct *work, · 665 unmodified lines | ||
| 666 | 666 | */ |
| 667 | 667 | smp_wmb(); |
| 668 | 668 | set_work_data(work, (unsigned long)pool_id << WORK_OFFQ_POOL_SHIFT, 0); |
| 669 | + /* | |
| 670 | + * The following mb guarantees that previous clear of a PENDING bit | |
| 671 | + * will not be reordered with any speculative LOADS or STORES from | |
| 672 | + * work->current_func, which is executed afterwards. This possible | |
| 673 | + * reordering can lead to a missed execution on attempt to qeueue | |
| 674 | + * the same @work. E.g. consider this case: | |
| 675 | + * | |
| 676 | + * CPU#0 CPU#1 | |
| 677 | + * ---------------------------- -------------------------------- | |
| 678 | + * | |
| 679 | + * 1 STORE event_indicated | |
| 680 | + * 2 queue_work_on() { | |
| 681 | + * 3 test_and_set_bit(PENDING) | |
| 682 | + * 4 } set_..._and_clear_pending() { | |
| 683 | + * 5 set_work_data() # clear bit | |
| 684 | + * 6 smp_mb() | |
| 685 | + * 7 work->current_func() { | |
| 686 | + * 8 LOAD event_indicated | |
| 687 | + * } | |
| 688 | + * | |
| 689 | + * Without an explicit full barrier speculative LOAD on line 8 can | |
| 690 | + * be executed before CPU#0 does STORE on line 1. If that happens, | |
| 691 | + * CPU#0 observes the PENDING bit is still set and new execution of | |
| 692 | + * a @work is not queued in a hope, that CPU#1 will eventually | |
| 693 | + * finish the queued @work. Meanwhile CPU#1 does not see | |
| 694 | + * event_indicated is set, because speculative LOAD was executed | |
| 695 | + * before actual STORE. | |
| 696 | + */ | |
| 697 | + smp_mb(); | |
| 669 | 698 | } |
| 670 | 699 | |
| 671 | 700 | static void clear_work_data(struct work_struct *work) |
| @@ -210,10 +210,6 @@ depot_stack_handle_t depot_save_stack(struct stack_trace *trace, · 209 unmodified lines | ||
| 210 | 210 | goto fast_exit; |
| 211 | 211 | |
| 212 | 212 | hash = hash_stack(trace->entries, trace->nr_entries); |
| 213 | − /* Bad luck, we won't store this stack. */ | |
| 214 | − if (hash == 0) | |
| 215 | − goto exit; | |
| 216 | − | |
| 217 | 213 | bucket = &stack_table[hash & STACK_HASH_MASK]; |
| 218 | 214 | |
| 219 | 215 | /* |
| @@ -232,7 +232,7 @@ retry: · 231 unmodified lines | ||
| 232 | 232 | return READ_ONCE(huge_zero_page); |
| 233 | 233 | } |
| 234 | 234 | |
| 235 | −static void put_huge_zero_page(void) | |
| 235 | +void put_huge_zero_page(void) | |
| 236 | 236 | { |
| 237 | 237 | /* |
| 238 | 238 | * Counter should never go to zero here. Only shrinker can put |
| @@ -1684,12 +1684,12 @@ int zap_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma, · 1445 unmodified lines | ||
| 1684 | 1684 | if (vma_is_dax(vma)) { |
| 1685 | 1685 | spin_unlock(ptl); |
| 1686 | 1686 | if (is_huge_zero_pmd(orig_pmd)) |
| 1687 | − put_huge_zero_page(); | |
| 1687 | + tlb_remove_page(tlb, pmd_page(orig_pmd)); | |
| 1688 | 1688 | } else if (is_huge_zero_pmd(orig_pmd)) { |
| 1689 | 1689 | pte_free(tlb->mm, pgtable_trans_huge_withdraw(tlb->mm, pmd)); |
| 1690 | 1690 | atomic_long_dec(&tlb->mm->nr_ptes); |
| 1691 | 1691 | spin_unlock(ptl); |
| 1692 | − put_huge_zero_page(); | |
| 1692 | + tlb_remove_page(tlb, pmd_page(orig_pmd)); | |
| 1693 | 1693 | } else { |
| 1694 | 1694 | struct page *page = pmd_page(orig_pmd); |
| 1695 | 1695 | page_remove_rmap(page, true); |
| @@ -1960,10 +1960,9 @@ int khugepaged_enter_vma_merge(struct vm_area_struct *vma, · 264 unmodified lines | ||
| 1960 | 1960 | * page fault if needed. |
| 1961 | 1961 | */ |
| 1962 | 1962 | return 0; |
| 1963 | − if (vma->vm_ops) | |
| 1963 | + if (vma->vm_ops || (vm_flags & VM_NO_THP)) | |
| 1964 | 1964 | /* khugepaged not yet working on file or special mappings */ |
| 1965 | 1965 | return 0; |
| 1966 | − VM_BUG_ON_VMA(vm_flags & VM_NO_THP, vma); | |
| 1967 | 1966 | hstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK; |
| 1968 | 1967 | hend = vma->vm_end & HPAGE_PMD_MASK; |
| 1969 | 1968 | if (hstart < hend) |
| @@ -2352,8 +2351,7 @@ static bool hugepage_vma_check(struct vm_area_struct *vma) · 382 unmodified lines | ||
| 2352 | 2351 | return false; |
| 2353 | 2352 | if (is_vma_temporary_stack(vma)) |
| 2354 | 2353 | return false; |
| 2355 | − VM_BUG_ON_VMA(vma->vm_flags & VM_NO_THP, vma); | |
| 2356 | − return true; | |
| 2354 | + return !(vma->vm_flags & VM_NO_THP); | |
| 2357 | 2355 | } |
| 2358 | 2356 | |
| 2359 | 2357 | static void collapse_huge_page(struct mm_struct *mm, |
| @@ -207,6 +207,7 @@ static void mem_cgroup_oom_notify(struct mem_cgroup *memcg); · 206 unmodified lines | ||
| 207 | 207 | /* "mc" and its members are protected by cgroup_mutex */ |
| 208 | 208 | static struct move_charge_struct { |
| 209 | 209 | spinlock_t lock; /* for from, to */ |
| 210 | + struct mm_struct *mm; | |
| 210 | 211 | struct mem_cgroup *from; |
| 211 | 212 | struct mem_cgroup *to; |
| 212 | 213 | unsigned long flags; |
| @@ -4667,6 +4668,8 @@ static void __mem_cgroup_clear_mc(void) · 4454 unmodified lines | ||
| 4667 | 4668 | |
| 4668 | 4669 | static void mem_cgroup_clear_mc(void) |
| 4669 | 4670 | { |
| 4671 | + struct mm_struct *mm = mc.mm; | |
| 4672 | + | |
| 4670 | 4673 | /* |
| 4671 | 4674 | * we must clear moving_task before waking up waiters at the end of |
| 4672 | 4675 | * task migration. |
| @@ -4676,7 +4679,10 @@ static void mem_cgroup_clear_mc(void) · 3 unmodified lines | ||
| 4676 | 4679 | spin_lock(&mc.lock); |
| 4677 | 4680 | mc.from = NULL; |
| 4678 | 4681 | mc.to = NULL; |
| 4682 | + mc.mm = NULL; | |
| 4679 | 4683 | spin_unlock(&mc.lock); |
| 4684 | + | |
| 4685 | + mmput(mm); | |
| 4680 | 4686 | } |
| 4681 | 4687 | |
| 4682 | 4688 | static int mem_cgroup_can_attach(struct cgroup_taskset *tset) |
| @@ -4733,6 +4739,7 @@ static int mem_cgroup_can_attach(struct cgroup_taskset *tset) · 50 unmodified lines | ||
| 4733 | 4739 | VM_BUG_ON(mc.moved_swap); |
| 4734 | 4740 | |
| 4735 | 4741 | spin_lock(&mc.lock); |
| 4742 | + mc.mm = mm; | |
| 4736 | 4743 | mc.from = from; |
| 4737 | 4744 | mc.to = memcg; |
| 4738 | 4745 | mc.flags = move_flags; |
| @@ -4742,8 +4749,9 @@ static int mem_cgroup_can_attach(struct cgroup_taskset *tset) · 3 unmodified lines | ||
| 4742 | 4749 | ret = mem_cgroup_precharge_mc(mm); |
| 4743 | 4750 | if (ret) |
| 4744 | 4751 | mem_cgroup_clear_mc(); |
| 4752 | + } else { | |
| 4753 | + mmput(mm); | |
| 4745 | 4754 | } |
| 4746 | − mmput(mm); | |
| 4747 | 4755 | return ret; |
| 4748 | 4756 | } |
| 4749 | 4757 | |
| @@ -4852,11 +4860,11 @@ put: /* get_mctgt_type() gets the page */ · 102 unmodified lines | ||
| 4852 | 4860 | return ret; |
| 4853 | 4861 | } |
| 4854 | 4862 | |
| 4855 | −static void mem_cgroup_move_charge(struct mm_struct *mm) | |
| 4863 | +static void mem_cgroup_move_charge(void) | |
| 4856 | 4864 | { |
| 4857 | 4865 | struct mm_walk mem_cgroup_move_charge_walk = { |
| 4858 | 4866 | .pmd_entry = mem_cgroup_move_charge_pte_range, |
| 4859 | − .mm = mm, | |
| 4867 | + .mm = mc.mm, | |
| 4860 | 4868 | }; |
| 4861 | 4869 | |
| 4862 | 4870 | lru_add_drain_all(); |
| @@ -4868,7 +4876,7 @@ static void mem_cgroup_move_charge(struct mm_struct *mm) · 5 unmodified lines | ||
| 4868 | 4876 | atomic_inc(&mc.from->moving_account); |
| 4869 | 4877 | synchronize_rcu(); |
| 4870 | 4878 | retry: |
| 4871 | − if (unlikely(!down_read_trylock(&mm->mmap_sem))) { | |
| 4879 | + if (unlikely(!down_read_trylock(&mc.mm->mmap_sem))) { | |
| 4872 | 4880 | /* |
| 4873 | 4881 | * Someone who are holding the mmap_sem might be waiting in |
| 4874 | 4882 | * waitq. So we cancel all extra charges, wake up all waiters, |
| @@ -4885,23 +4893,16 @@ retry: · 10 unmodified lines | ||
| 4885 | 4893 | * additional charge, the page walk just aborts. |
| 4886 | 4894 | */ |
| 4887 | 4895 | walk_page_range(0, ~0UL, &mem_cgroup_move_charge_walk); |
| 4888 | − up_read(&mm->mmap_sem); | |
| 4896 | + up_read(&mc.mm->mmap_sem); | |
| 4889 | 4897 | atomic_dec(&mc.from->moving_account); |
| 4890 | 4898 | } |
| 4891 | 4899 | |
| 4892 | −static void mem_cgroup_move_task(struct cgroup_taskset *tset) | |
| 4900 | +static void mem_cgroup_move_task(void) | |
| 4893 | 4901 | { |
| 4894 | − struct cgroup_subsys_state *css; | |
| 4895 | − struct task_struct *p = cgroup_taskset_first(tset, &css); | |
| 4896 | − struct mm_struct *mm = get_task_mm(p); | |
| 4897 | − | |
| 4898 | − if (mm) { | |
| 4899 | − if (mc.to) | |
| 4900 | − mem_cgroup_move_charge(mm); | |
| 4901 | − mmput(mm); | |
| 4902 | − } | |
| 4903 | − if (mc.to) | |
| 4902 | + if (mc.to) { | |
| 4903 | + mem_cgroup_move_charge(); | |
| 4904 | 4904 | mem_cgroup_clear_mc(); |
| 4905 | + } | |
| 4905 | 4906 | } |
| 4906 | 4907 | #else /* !CONFIG_MMU */ |
| 4907 | 4908 | static int mem_cgroup_can_attach(struct cgroup_taskset *tset) |
| @@ -4911,7 +4912,7 @@ static int mem_cgroup_can_attach(struct cgroup_taskset *tset) · 3 unmodified lines | ||
| 4911 | 4912 | static void mem_cgroup_cancel_attach(struct cgroup_taskset *tset) |
| 4912 | 4913 | { |
| 4913 | 4914 | } |
| 4914 | −static void mem_cgroup_move_task(struct cgroup_taskset *tset) | |
| 4915 | +static void mem_cgroup_move_task(void) | |
| 4915 | 4916 | { |
| 4916 | 4917 | } |
| 4917 | 4918 | #endif |
| @@ -5195,7 +5196,7 @@ struct cgroup_subsys memory_cgrp_subsys = { · 277 unmodified lines | ||
| 5195 | 5196 | .css_reset = mem_cgroup_css_reset, |
| 5196 | 5197 | .can_attach = mem_cgroup_can_attach, |
| 5197 | 5198 | .cancel_attach = mem_cgroup_cancel_attach, |
| 5198 | − .attach = mem_cgroup_move_task, | |
| 5199 | + .post_attach = mem_cgroup_move_task, | |
| 5199 | 5200 | .bind = mem_cgroup_bind, |
| 5200 | 5201 | .dfl_cftypes = memory_files, |
| 5201 | 5202 | .legacy_cftypes = mem_cgroup_legacy_files, |
| @@ -888,7 +888,15 @@ int get_hwpoison_page(struct page *page) · 887 unmodified lines | ||
| 888 | 888 | } |
| 889 | 889 | } |
| 890 | 890 | |
| 891 | − return get_page_unless_zero(head); | |
| 891 | + if (get_page_unless_zero(head)) { | |
| 892 | + if (head == compound_head(page)) | |
| 893 | + return 1; | |
| 894 | + | |
| 895 | + pr_info("MCE: %#lx cannot catch tail\n", page_to_pfn(page)); | |
| 896 | + put_page(head); | |
| 897 | + } | |
| 898 | + | |
| 899 | + return 0; | |
| 892 | 900 | } |
| 893 | 901 | EXPORT_SYMBOL_GPL(get_hwpoison_page); |
| 894 | 902 | |
| @@ -789,6 +789,46 @@ out: · 788 unmodified lines | ||
| 789 | 789 | return pfn_to_page(pfn); |
| 790 | 790 | } |
| 791 | 791 | |
| 792 | +#ifdef CONFIG_TRANSPARENT_HUGEPAGE | |
| 793 | +struct page *vm_normal_page_pmd(struct vm_area_struct *vma, unsigned long addr, | |
| 794 | + pmd_t pmd) | |
| 795 | +{ | |
| 796 | + unsigned long pfn = pmd_pfn(pmd); | |
| 797 | + | |
| 798 | + /* | |
| 799 | + * There is no pmd_special() but there may be special pmds, e.g. | |
| 800 | + * in a direct-access (dax) mapping, so let's just replicate the | |
| 801 | + * !HAVE_PTE_SPECIAL case from vm_normal_page() here. | |
| 802 | + */ | |
| 803 | + if (unlikely(vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP))) { | |
| 804 | + if (vma->vm_flags & VM_MIXEDMAP) { | |
| 805 | + if (!pfn_valid(pfn)) | |
| 806 | + return NULL; | |
| 807 | + goto out; | |
| 808 | + } else { | |
| 809 | + unsigned long off; | |
| 810 | + off = (addr - vma->vm_start) >> PAGE_SHIFT; | |
| 811 | + if (pfn == vma->vm_pgoff + off) | |
| 812 | + return NULL; | |
| 813 | + if (!is_cow_mapping(vma->vm_flags)) | |
| 814 | + return NULL; | |
| 815 | + } | |
| 816 | + } | |
| 817 | + | |
| 818 | + if (is_zero_pfn(pfn)) | |
| 819 | + return NULL; | |
| 820 | + if (unlikely(pfn > highest_memmap_pfn)) | |
| 821 | + return NULL; | |
| 822 | + | |
| 823 | + /* | |
| 824 | + * NOTE! We still have PageReserved() pages in the page tables. | |
| 825 | + * eg. VDSO mappings can cause them to exist. | |
| 826 | + */ | |
| 827 | +out: | |
| 828 | + return pfn_to_page(pfn); | |
| 829 | +} | |
| 830 | +#endif | |
| 831 | + | |
| 792 | 832 | /* |
| 793 | 833 | * copy one vm_area from one task to the other. Assumes the page tables |
| 794 | 834 | * already present in the new task to be cleared in the whole range |
| @@ -975,7 +975,13 @@ out: · 974 unmodified lines | ||
| 975 | 975 | dec_zone_page_state(page, NR_ISOLATED_ANON + |
| 976 | 976 | page_is_file_cache(page)); |
| 977 | 977 | /* Soft-offlined page shouldn't go through lru cache list */ |
| 978 | − if (reason == MR_MEMORY_FAILURE) { | |
| 978 | + if (reason == MR_MEMORY_FAILURE && rc == MIGRATEPAGE_SUCCESS) { | |
| 979 | + /* | |
| 980 | + * With this release, we free successfully migrated | |
| 981 | + * page and set PG_HWPoison on just freed page | |
| 982 | + * intentionally. Although it's rather weird, it's how | |
| 983 | + * HWPoison flag works at the moment. | |
| 984 | + */ | |
| 979 | 985 | put_page(page); |
| 980 | 986 | if (!test_set_page_hwpoison(page)) |
| 981 | 987 | num_poisoned_pages_inc(); |
| @@ -353,7 +353,11 @@ int swap_readpage(struct page *page) · 352 unmodified lines | ||
| 353 | 353 | |
| 354 | 354 | ret = bdev_read_page(sis->bdev, swap_page_sector(page), page); |
| 355 | 355 | if (!ret) { |
| 356 | − swap_slot_free_notify(page); | |
| 356 | + if (trylock_page(page)) { | |
| 357 | + swap_slot_free_notify(page); | |
| 358 | + unlock_page(page); | |
| 359 | + } | |
| 360 | + | |
| 357 | 361 | count_vm_event(PSWPIN); |
| 358 | 362 | return 0; |
| 359 | 363 | } |
| @@ -728,6 +728,11 @@ void release_pages(struct page **pages, int nr, bool cold) · 727 unmodified lines | ||
| 728 | 728 | zone = NULL; |
| 729 | 729 | } |
| 730 | 730 | |
| 731 | + if (is_huge_zero_page(page)) { | |
| 732 | + put_huge_zero_page(); | |
| 733 | + continue; | |
| 734 | + } | |
| 735 | + | |
| 731 | 736 | page = compound_head(page); |
| 732 | 737 | if (!put_page_testzero(page)) |
| 733 | 738 | continue; |
| @@ -2553,7 +2553,7 @@ static bool shrink_zones(struct zonelist *zonelist, struct scan_control *sc) · 2552 unmodified lines | ||
| 2553 | 2553 | sc->gfp_mask |= __GFP_HIGHMEM; |
| 2554 | 2554 | |
| 2555 | 2555 | for_each_zone_zonelist_nodemask(zone, z, zonelist, |
| 2556 | − requested_highidx, sc->nodemask) { | |
| 2556 | + gfp_zone(sc->gfp_mask), sc->nodemask) { | |
| 2557 | 2557 | enum zone_type classzone_idx; |
| 2558 | 2558 | |
| 2559 | 2559 | if (!populated_zone(zone)) |
| @@ -3318,6 +3318,20 @@ static void kswapd_try_to_sleep(pg_data_t *pgdat, int order, · 758 unmodified lines | ||
| 3318 | 3318 | /* Try to sleep for a short interval */ |
| 3319 | 3319 | if (prepare_kswapd_sleep(pgdat, order, remaining, |
| 3320 | 3320 | balanced_classzone_idx)) { |
| 3321 | + /* | |
| 3322 | + * Compaction records what page blocks it recently failed to | |
| 3323 | + * isolate pages from and skips them in the future scanning. | |
| 3324 | + * When kswapd is going to sleep, it is reasonable to assume | |
| 3325 | + * that pages and compaction may succeed so reset the cache. | |
| 3326 | + */ | |
| 3327 | + reset_isolation_suitable(pgdat); | |
| 3328 | + | |
| 3329 | + /* | |
| 3330 | + * We have freed the memory, now we should compact it to make | |
| 3331 | + * allocation of the requested order possible. | |
| 3332 | + */ | |
| 3333 | + wakeup_kcompactd(pgdat, order, classzone_idx); | |
| 3334 | + | |
| 3321 | 3335 | remaining = schedule_timeout(HZ/10); |
| 3322 | 3336 | finish_wait(&pgdat->kswapd_wait, &wait); |
| 3323 | 3337 | prepare_to_wait(&pgdat->kswapd_wait, &wait, TASK_INTERRUPTIBLE); |
| @@ -3341,20 +3355,6 @@ static void kswapd_try_to_sleep(pg_data_t *pgdat, int order, · 17 unmodified lines | ||
| 3341 | 3355 | */ |
| 3342 | 3356 | set_pgdat_percpu_threshold(pgdat, calculate_normal_threshold); |
| 3343 | 3357 | |
| 3344 | − /* | |
| 3345 | − * Compaction records what page blocks it recently failed to | |
| 3346 | − * isolate pages from and skips them in the future scanning. | |
| 3347 | − * When kswapd is going to sleep, it is reasonable to assume | |
| 3348 | − * that pages and compaction may succeed so reset the cache. | |
| 3349 | − */ | |
| 3350 | − reset_isolation_suitable(pgdat); | |
| 3351 | − | |
| 3352 | − /* | |
| 3353 | − * We have freed the memory, now we should compact it to make | |
| 3354 | − * allocation of the requested order possible. | |
| 3355 | − */ | |
| 3356 | − wakeup_kcompactd(pgdat, order, classzone_idx); | |
| 3357 | − | |
| 3358 | 3358 | if (!kthread_should_stop()) |
| 3359 | 3359 | schedule(); |
| 3360 | 3360 | |
| @@ -32,10 +32,21 @@ · 31 unmodified lines | ||
| 32 | 32 | |
| 33 | 33 | #include "bat_v_elp.h" |
| 34 | 34 | #include "bat_v_ogm.h" |
| 35 | +#include "hard-interface.h" | |
| 35 | 36 | #include "hash.h" |
| 36 | 37 | #include "originator.h" |
| 37 | 38 | #include "packet.h" |
| 38 | 39 | |
| 40 | +static void batadv_v_iface_activate(struct batadv_hard_iface *hard_iface) | |
| 41 | +{ | |
| 42 | + /* B.A.T.M.A.N. V does not use any queuing mechanism, therefore it can | |
| 43 | + * set the interface as ACTIVE right away, without any risk of race | |
| 44 | + * condition | |
| 45 | + */ | |
| 46 | + if (hard_iface->if_status == BATADV_IF_TO_BE_ACTIVATED) | |
| 47 | + hard_iface->if_status = BATADV_IF_ACTIVE; | |
| 48 | +} | |
| 49 | + | |
| 39 | 50 | static int batadv_v_iface_enable(struct batadv_hard_iface *hard_iface) |
| 40 | 51 | { |
| 41 | 52 | int ret; |
| @@ -274,6 +285,7 @@ static bool batadv_v_neigh_is_sob(struct batadv_neigh_node *neigh1, · 232 unmodified lines | ||
| 274 | 285 | |
| 275 | 286 | static struct batadv_algo_ops batadv_batman_v __read_mostly = { |
| 276 | 287 | .name = "BATMAN_V", |
| 288 | + .bat_iface_activate = batadv_v_iface_activate, | |
| 277 | 289 | .bat_iface_enable = batadv_v_iface_enable, |
| 278 | 290 | .bat_iface_disable = batadv_v_iface_disable, |
| 279 | 291 | .bat_iface_update_mac = batadv_v_iface_update_mac, |
| @@ -568,6 +568,7 @@ static void batadv_choose_next_candidate(struct batadv_priv *bat_priv, · 567 unmodified lines | ||
| 568 | 568 | * be sent to |
| 569 | 569 | * @bat_priv: the bat priv with all the soft interface information |
| 570 | 570 | * @ip_dst: ipv4 to look up in the DHT |
| 571 | + * @vid: VLAN identifier | |
| 571 | 572 | * |
| 572 | 573 | * An originator O is selected if and only if its DHT_ID value is one of three |
| 573 | 574 | * closest values (from the LEFT, with wrap around if needed) then the hash |
| @@ -576,7 +577,8 @@ static void batadv_choose_next_candidate(struct batadv_priv *bat_priv, · 2 unmodified lines | ||
| 576 | 577 | * Return: the candidate array of size BATADV_DAT_CANDIDATE_NUM. |
| 577 | 578 | */ |
| 578 | 579 | static struct batadv_dat_candidate * |
| 579 | −batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst) | |
| 580 | +batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst, | |
| 581 | + unsigned short vid) | |
| 580 | 582 | { |
| 581 | 583 | int select; |
| 582 | 584 | batadv_dat_addr_t last_max = BATADV_DAT_ADDR_MAX, ip_key; |
| @@ -592,7 +594,7 @@ batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst) · 9 unmodified lines | ||
| 592 | 594 | return NULL; |
| 593 | 595 | |
| 594 | 596 | dat.ip = ip_dst; |
| 595 | − dat.vid = 0; | |
| 597 | + dat.vid = vid; | |
| 596 | 598 | ip_key = (batadv_dat_addr_t)batadv_hash_dat(&dat, |
| 597 | 599 | BATADV_DAT_ADDR_MAX); |
| 598 | 600 | |
| @@ -612,6 +614,7 @@ batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst) · 13 unmodified lines | ||
| 612 | 614 | * @bat_priv: the bat priv with all the soft interface information |
| 613 | 615 | * @skb: payload to send |
| 614 | 616 | * @ip: the DHT key |
| 617 | + * @vid: VLAN identifier | |
| 615 | 618 | * @packet_subtype: unicast4addr packet subtype to use |
| 616 | 619 | * |
| 617 | 620 | * This function copies the skb with pskb_copy() and is sent as unicast packet |
| @@ -622,7 +625,7 @@ batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst) · 4 unmodified lines | ||
| 622 | 625 | */ |
| 623 | 626 | static bool batadv_dat_send_data(struct batadv_priv *bat_priv, |
| 624 | 627 | struct sk_buff *skb, __be32 ip, |
| 625 | − int packet_subtype) | |
| 628 | + unsigned short vid, int packet_subtype) | |
| 626 | 629 | { |
| 627 | 630 | int i; |
| 628 | 631 | bool ret = false; |
| @@ -631,7 +634,7 @@ static bool batadv_dat_send_data(struct batadv_priv *bat_priv, · 2 unmodified lines | ||
| 631 | 634 | struct sk_buff *tmp_skb; |
| 632 | 635 | struct batadv_dat_candidate *cand; |
| 633 | 636 | |
| 634 | − cand = batadv_dat_select_candidates(bat_priv, ip); | |
| 637 | + cand = batadv_dat_select_candidates(bat_priv, ip, vid); | |
| 635 | 638 | if (!cand) |
| 636 | 639 | goto out; |
| 637 | 640 | |
| @@ -1022,7 +1025,7 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv, · 384 unmodified lines | ||
| 1022 | 1025 | ret = true; |
| 1023 | 1026 | } else { |
| 1024 | 1027 | /* Send the request to the DHT */ |
| 1025 | − ret = batadv_dat_send_data(bat_priv, skb, ip_dst, | |
| 1028 | + ret = batadv_dat_send_data(bat_priv, skb, ip_dst, vid, | |
| 1026 | 1029 | BATADV_P_DAT_DHT_GET); |
| 1027 | 1030 | } |
| 1028 | 1031 | out: |
| @@ -1150,8 +1153,8 @@ void batadv_dat_snoop_outgoing_arp_reply(struct batadv_priv *bat_priv, · 121 unmodified lines | ||
| 1150 | 1153 | /* Send the ARP reply to the candidates for both the IP addresses that |
| 1151 | 1154 | * the node obtained from the ARP reply |
| 1152 | 1155 | */ |
| 1153 | − batadv_dat_send_data(bat_priv, skb, ip_src, BATADV_P_DAT_DHT_PUT); | |
| 1154 | − batadv_dat_send_data(bat_priv, skb, ip_dst, BATADV_P_DAT_DHT_PUT); | |
| 1156 | + batadv_dat_send_data(bat_priv, skb, ip_src, vid, BATADV_P_DAT_DHT_PUT); | |
| 1157 | + batadv_dat_send_data(bat_priv, skb, ip_dst, vid, BATADV_P_DAT_DHT_PUT); | |
| 1155 | 1158 | } |
| 1156 | 1159 | |
| 1157 | 1160 | /** |
| @@ -407,6 +407,9 @@ batadv_hardif_activate_interface(struct batadv_hard_iface *hard_iface) · 406 unmodified lines | ||
| 407 | 407 | |
| 408 | 408 | batadv_update_min_mtu(hard_iface->soft_iface); |
| 409 | 409 | |
| 410 | + if (bat_priv->bat_algo_ops->bat_iface_activate) | |
| 411 | + bat_priv->bat_algo_ops->bat_iface_activate(hard_iface); | |
| 412 | + | |
| 410 | 413 | out: |
| 411 | 414 | if (primary_if) |
| 412 | 415 | batadv_hardif_put(primary_if); |
| @@ -572,8 +575,7 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface, · 159 unmodified lines | ||
| 572 | 575 | struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); |
| 573 | 576 | struct batadv_hard_iface *primary_if = NULL; |
| 574 | 577 | |
| 575 | − if (hard_iface->if_status == BATADV_IF_ACTIVE) | |
| 576 | − batadv_hardif_deactivate_interface(hard_iface); | |
| 578 | + batadv_hardif_deactivate_interface(hard_iface); | |
| 577 | 579 | |
| 578 | 580 | if (hard_iface->if_status != BATADV_IF_INACTIVE) |
| 579 | 581 | goto out; |
| @@ -250,7 +250,6 @@ static void batadv_neigh_node_release(struct kref *ref) · 249 unmodified lines | ||
| 250 | 250 | { |
| 251 | 251 | struct hlist_node *node_tmp; |
| 252 | 252 | struct batadv_neigh_node *neigh_node; |
| 253 | − struct batadv_hardif_neigh_node *hardif_neigh; | |
| 254 | 253 | struct batadv_neigh_ifinfo *neigh_ifinfo; |
| 255 | 254 | struct batadv_algo_ops *bao; |
| 256 | 255 | |
| @@ -262,13 +261,7 @@ static void batadv_neigh_node_release(struct kref *ref) · 5 unmodified lines | ||
| 262 | 261 | batadv_neigh_ifinfo_put(neigh_ifinfo); |
| 263 | 262 | } |
| 264 | 263 | |
| 265 | − hardif_neigh = batadv_hardif_neigh_get(neigh_node->if_incoming, | |
| 266 | − neigh_node->addr); | |
| 267 | − if (hardif_neigh) { | |
| 268 | − /* batadv_hardif_neigh_get() increases refcount too */ | |
| 269 | − batadv_hardif_neigh_put(hardif_neigh); | |
| 270 | − batadv_hardif_neigh_put(hardif_neigh); | |
| 271 | − } | |
| 264 | + batadv_hardif_neigh_put(neigh_node->hardif_neigh); | |
| 272 | 265 | |
| 273 | 266 | if (bao->bat_neigh_free) |
| 274 | 267 | bao->bat_neigh_free(neigh_node); |
| @@ -663,6 +656,11 @@ batadv_neigh_node_new(struct batadv_orig_node *orig_node, · 388 unmodified lines | ||
| 663 | 656 | ether_addr_copy(neigh_node->addr, neigh_addr); |
| 664 | 657 | neigh_node->if_incoming = hard_iface; |
| 665 | 658 | neigh_node->orig_node = orig_node; |
| 659 | + neigh_node->last_seen = jiffies; | |
| 660 | + | |
| 661 | + /* increment unique neighbor refcount */ | |
| 662 | + kref_get(&hardif_neigh->refcount); | |
| 663 | + neigh_node->hardif_neigh = hardif_neigh; | |
| 666 | 664 | |
| 667 | 665 | /* extra reference for return */ |
| 668 | 666 | kref_init(&neigh_node->refcount); |
| @@ -672,9 +670,6 @@ batadv_neigh_node_new(struct batadv_orig_node *orig_node, · 3 unmodified lines | ||
| 672 | 670 | hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list); |
| 673 | 671 | spin_unlock_bh(&orig_node->neigh_list_lock); |
| 674 | 672 | |
| 675 | − /* increment unique neighbor refcount */ | |
| 676 | − kref_get(&hardif_neigh->refcount); | |
| 677 | − | |
| 678 | 673 | batadv_dbg(BATADV_DBG_BATMAN, orig_node->bat_priv, |
| 679 | 674 | "Creating new neighbor %pM for orig_node %pM on interface %s\n", |
| 680 | 675 | neigh_addr, orig_node->orig, hard_iface->net_dev->name); |
| @@ -105,6 +105,15 @@ static void _batadv_update_route(struct batadv_priv *bat_priv, · 104 unmodified lines | ||
| 105 | 105 | neigh_node = NULL; |
| 106 | 106 | |
| 107 | 107 | spin_lock_bh(&orig_node->neigh_list_lock); |
| 108 | + /* curr_router used earlier may not be the current orig_ifinfo->router | |
| 109 | + * anymore because it was dereferenced outside of the neigh_list_lock | |
| 110 | + * protected region. After the new best neighbor has replace the current | |
| 111 | + * best neighbor the reference counter needs to decrease. Consequently, | |
| 112 | + * the code needs to ensure the curr_router variable contains a pointer | |
| 113 | + * to the replaced best neighbor. | |
| 114 | + */ | |
| 115 | + curr_router = rcu_dereference_protected(orig_ifinfo->router, true); | |
| 116 | + | |
| 108 | 117 | rcu_assign_pointer(orig_ifinfo->router, neigh_node); |
| 109 | 118 | spin_unlock_bh(&orig_node->neigh_list_lock); |
| 110 | 119 | batadv_orig_ifinfo_put(orig_ifinfo); |
| @@ -675,6 +675,9 @@ batadv_purge_outstanding_packets(struct batadv_priv *bat_priv, · 674 unmodified lines | ||
| 675 | 675 | |
| 676 | 676 | if (pending) { |
| 677 | 677 | hlist_del(&forw_packet->list); |
| 678 | + if (!forw_packet->own) | |
| 679 | + atomic_inc(&bat_priv->bcast_queue_left); | |
| 680 | + | |
| 678 | 681 | batadv_forw_packet_free(forw_packet); |
| 679 | 682 | } |
| 680 | 683 | } |
| @@ -702,6 +705,9 @@ batadv_purge_outstanding_packets(struct batadv_priv *bat_priv, · 21 unmodified lines | ||
| 702 | 705 | |
| 703 | 706 | if (pending) { |
| 704 | 707 | hlist_del(&forw_packet->list); |
| 708 | + if (!forw_packet->own) | |
| 709 | + atomic_inc(&bat_priv->batman_queue_left); | |
| 710 | + | |
| 705 | 711 | batadv_forw_packet_free(forw_packet); |
| 706 | 712 | } |
| 707 | 713 | } |
| @@ -408,11 +408,17 @@ void batadv_interface_rx(struct net_device *soft_iface, · 407 unmodified lines | ||
| 408 | 408 | */ |
| 409 | 409 | nf_reset(skb); |
| 410 | 410 | |
| 411 | + if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) | |
| 412 | + goto dropped; | |
| 413 | + | |
| 411 | 414 | vid = batadv_get_vid(skb, 0); |
| 412 | 415 | ethhdr = eth_hdr(skb); |
| 413 | 416 | |
| 414 | 417 | switch (ntohs(ethhdr->h_proto)) { |
| 415 | 418 | case ETH_P_8021Q: |
| 419 | + if (!pskb_may_pull(skb, VLAN_ETH_HLEN)) | |
| 420 | + goto dropped; | |
| 421 | + | |
| 416 | 422 | vhdr = (struct vlan_ethhdr *)skb->data; |
| 417 | 423 | |
| 418 | 424 | if (vhdr->h_vlan_encapsulated_proto != ethertype) |
| @@ -424,8 +430,6 @@ void batadv_interface_rx(struct net_device *soft_iface, · 5 unmodified lines | ||
| 424 | 430 | } |
| 425 | 431 | |
| 426 | 432 | /* skb->dev & skb->pkt_type are set here */ |
| 427 | − if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) | |
| 428 | − goto dropped; | |
| 429 | 433 | skb->protocol = eth_type_trans(skb, soft_iface); |
| 430 | 434 | |
| 431 | 435 | /* should not be necessary anymore as we use skb_pull_rcsum() |
| @@ -215,6 +215,8 @@ static void batadv_tt_local_entry_release(struct kref *ref) · 214 unmodified lines | ||
| 215 | 215 | tt_local_entry = container_of(ref, struct batadv_tt_local_entry, |
| 216 | 216 | common.refcount); |
| 217 | 217 | |
| 218 | + batadv_softif_vlan_put(tt_local_entry->vlan); | |
| 219 | + | |
| 218 | 220 | kfree_rcu(tt_local_entry, common.rcu); |
| 219 | 221 | } |
| 220 | 222 | |
| @@ -673,6 +675,7 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const u8 *addr, · 452 unmodified lines | ||
| 673 | 675 | kref_get(&tt_local->common.refcount); |
| 674 | 676 | tt_local->last_seen = jiffies; |
| 675 | 677 | tt_local->common.added_at = tt_local->last_seen; |
| 678 | + tt_local->vlan = vlan; | |
| 676 | 679 | |
| 677 | 680 | /* the batman interface mac and multicast addresses should never be |
| 678 | 681 | * purged |
| @@ -991,7 +994,6 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) · 312 unmodified lines | ||
| 991 | 994 | struct batadv_tt_common_entry *tt_common_entry; |
| 992 | 995 | struct batadv_tt_local_entry *tt_local; |
| 993 | 996 | struct batadv_hard_iface *primary_if; |
| 994 | − struct batadv_softif_vlan *vlan; | |
| 995 | 997 | struct hlist_head *head; |
| 996 | 998 | unsigned short vid; |
| 997 | 999 | u32 i; |
| @@ -1027,14 +1029,6 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) · 29 unmodified lines | ||
| 1027 | 1029 | last_seen_msecs = last_seen_msecs % 1000; |
| 1028 | 1030 | |
| 1029 | 1031 | no_purge = tt_common_entry->flags & np_flag; |
| 1030 | − | |
| 1031 | − vlan = batadv_softif_vlan_get(bat_priv, vid); | |
| 1032 | − if (!vlan) { | |
| 1033 | − seq_printf(seq, "Cannot retrieve VLAN %d\n", | |
| 1034 | − BATADV_PRINT_VID(vid)); | |
| 1035 | − continue; | |
| 1036 | − } | |
| 1037 | − | |
| 1038 | 1032 | seq_printf(seq, |
| 1039 | 1033 | " * %pM %4i [%c%c%c%c%c%c] %3u.%03u (%#.8x)\n", |
| 1040 | 1034 | tt_common_entry->addr, |
| @@ -1052,9 +1046,7 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) · 11 unmodified lines | ||
| 1052 | 1046 | BATADV_TT_CLIENT_ISOLA) ? 'I' : '.'), |
| 1053 | 1047 | no_purge ? 0 : last_seen_secs, |
| 1054 | 1048 | no_purge ? 0 : last_seen_msecs, |
| 1055 | − vlan->tt.crc); | |
| 1056 | − | |
| 1057 | − batadv_softif_vlan_put(vlan); | |
| 1049 | + tt_local->vlan->tt.crc); | |
| 1058 | 1050 | } |
| 1059 | 1051 | rcu_read_unlock(); |
| 1060 | 1052 | } |
| @@ -1099,7 +1091,6 @@ u16 batadv_tt_local_remove(struct batadv_priv *bat_priv, const u8 *addr, · 38 unmodified lines | ||
| 1099 | 1091 | { |
| 1100 | 1092 | struct batadv_tt_local_entry *tt_local_entry; |
| 1101 | 1093 | u16 flags, curr_flags = BATADV_NO_FLAGS; |
| 1102 | − struct batadv_softif_vlan *vlan; | |
| 1103 | 1094 | void *tt_entry_exists; |
| 1104 | 1095 | |
| 1105 | 1096 | tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid); |
| @@ -1139,14 +1130,6 @@ u16 batadv_tt_local_remove(struct batadv_priv *bat_priv, const u8 *addr, · 33 unmodified lines | ||
| 1139 | 1130 | /* extra call to free the local tt entry */ |
| 1140 | 1131 | batadv_tt_local_entry_put(tt_local_entry); |
| 1141 | 1132 | |
| 1142 | − /* decrease the reference held for this vlan */ | |
| 1143 | − vlan = batadv_softif_vlan_get(bat_priv, vid); | |
| 1144 | − if (!vlan) | |
| 1145 | − goto out; | |
| 1146 | − | |
| 1147 | − batadv_softif_vlan_put(vlan); | |
| 1148 | − batadv_softif_vlan_put(vlan); | |
| 1149 | − | |
| 1150 | 1133 | out: |
| 1151 | 1134 | if (tt_local_entry) |
| 1152 | 1135 | batadv_tt_local_entry_put(tt_local_entry); |
| @@ -1219,7 +1202,6 @@ static void batadv_tt_local_table_free(struct batadv_priv *bat_priv) · 66 unmodified lines | ||
| 1219 | 1202 | spinlock_t *list_lock; /* protects write access to the hash lists */ |
| 1220 | 1203 | struct batadv_tt_common_entry *tt_common_entry; |
| 1221 | 1204 | struct batadv_tt_local_entry *tt_local; |
| 1222 | − struct batadv_softif_vlan *vlan; | |
| 1223 | 1205 | struct hlist_node *node_tmp; |
| 1224 | 1206 | struct hlist_head *head; |
| 1225 | 1207 | u32 i; |
| @@ -1241,14 +1223,6 @@ static void batadv_tt_local_table_free(struct batadv_priv *bat_priv) · 15 unmodified lines | ||
| 1241 | 1223 | struct batadv_tt_local_entry, |
| 1242 | 1224 | common); |
| 1243 | 1225 | |
| 1244 | − /* decrease the reference held for this vlan */ | |
| 1245 | − vlan = batadv_softif_vlan_get(bat_priv, | |
| 1246 | − tt_common_entry->vid); | |
| 1247 | − if (vlan) { | |
| 1248 | − batadv_softif_vlan_put(vlan); | |
| 1249 | − batadv_softif_vlan_put(vlan); | |
| 1250 | − } | |
| 1251 | − | |
| 1252 | 1226 | batadv_tt_local_entry_put(tt_local); |
| 1253 | 1227 | } |
| 1254 | 1228 | spin_unlock_bh(list_lock); |
| @@ -3309,7 +3283,6 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv) · 2054 unmodified lines | ||
| 3309 | 3283 | struct batadv_hashtable *hash = bat_priv->tt.local_hash; |
| 3310 | 3284 | struct batadv_tt_common_entry *tt_common; |
| 3311 | 3285 | struct batadv_tt_local_entry *tt_local; |
| 3312 | − struct batadv_softif_vlan *vlan; | |
| 3313 | 3286 | struct hlist_node *node_tmp; |
| 3314 | 3287 | struct hlist_head *head; |
| 3315 | 3288 | spinlock_t *list_lock; /* protects write access to the hash lists */ |
| @@ -3339,13 +3312,6 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv) · 23 unmodified lines | ||
| 3339 | 3312 | struct batadv_tt_local_entry, |
| 3340 | 3313 | common); |
| 3341 | 3314 | |
| 3342 | − /* decrease the reference held for this vlan */ | |
| 3343 | − vlan = batadv_softif_vlan_get(bat_priv, tt_common->vid); | |
| 3344 | − if (vlan) { | |
| 3345 | − batadv_softif_vlan_put(vlan); | |
| 3346 | − batadv_softif_vlan_put(vlan); | |
| 3347 | − } | |
| 3348 | − | |
| 3349 | 3315 | batadv_tt_local_entry_put(tt_local); |
| 3350 | 3316 | } |
| 3351 | 3317 | spin_unlock_bh(list_lock); |
| @@ -433,6 +433,7 @@ struct batadv_hardif_neigh_node { · 432 unmodified lines | ||
| 433 | 433 | * @ifinfo_lock: lock protecting private ifinfo members and list |
| 434 | 434 | * @if_incoming: pointer to incoming hard-interface |
| 435 | 435 | * @last_seen: when last packet via this neighbor was received |
| 436 | + * @hardif_neigh: hardif_neigh of this neighbor | |
| 436 | 437 | * @refcount: number of contexts the object is used |
| 437 | 438 | * @rcu: struct used for freeing in an RCU-safe manner |
| 438 | 439 | */ |
| @@ -444,6 +445,7 @@ struct batadv_neigh_node { · 5 unmodified lines | ||
| 444 | 445 | spinlock_t ifinfo_lock; /* protects ifinfo_list and its members */ |
| 445 | 446 | struct batadv_hard_iface *if_incoming; |
| 446 | 447 | unsigned long last_seen; |
| 448 | + struct batadv_hardif_neigh_node *hardif_neigh; | |
| 447 | 449 | struct kref refcount; |
| 448 | 450 | struct rcu_head rcu; |
| 449 | 451 | }; |
| @@ -1073,10 +1075,12 @@ struct batadv_tt_common_entry { · 623 unmodified lines | ||
| 1073 | 1075 | * struct batadv_tt_local_entry - translation table local entry data |
| 1074 | 1076 | * @common: general translation table data |
| 1075 | 1077 | * @last_seen: timestamp used for purging stale tt local entries |
| 1078 | + * @vlan: soft-interface vlan of the entry | |
| 1076 | 1079 | */ |
| 1077 | 1080 | struct batadv_tt_local_entry { |
| 1078 | 1081 | struct batadv_tt_common_entry common; |
| 1079 | 1082 | unsigned long last_seen; |
| 1083 | + struct batadv_softif_vlan *vlan; | |
| 1080 | 1084 | }; |
| 1081 | 1085 | |
| 1082 | 1086 | /** |
| @@ -1250,6 +1254,8 @@ struct batadv_forw_packet { · 167 unmodified lines | ||
| 1250 | 1254 | * struct batadv_algo_ops - mesh algorithm callbacks |
| 1251 | 1255 | * @list: list node for the batadv_algo_list |
| 1252 | 1256 | * @name: name of the algorithm |
| 1257 | + * @bat_iface_activate: start routing mechanisms when hard-interface is brought | |
| 1258 | + * up | |
| 1253 | 1259 | * @bat_iface_enable: init routing info when hard-interface is enabled |
| 1254 | 1260 | * @bat_iface_disable: de-init routing info when hard-interface is disabled |
| 1255 | 1261 | * @bat_iface_update_mac: (re-)init mac addresses of the protocol information |
| @@ -1277,6 +1283,7 @@ struct batadv_forw_packet { · 21 unmodified lines | ||
| 1277 | 1283 | struct batadv_algo_ops { |
| 1278 | 1284 | struct hlist_node list; |
| 1279 | 1285 | char *name; |
| 1286 | + void (*bat_iface_activate)(struct batadv_hard_iface *hard_iface); | |
| 1280 | 1287 | int (*bat_iface_enable)(struct batadv_hard_iface *hard_iface); |
| 1281 | 1288 | void (*bat_iface_disable)(struct batadv_hard_iface *hard_iface); |
| 1282 | 1289 | void (*bat_iface_update_mac)(struct batadv_hard_iface *hard_iface); |
| @@ -293,13 +293,9 @@ int ceph_auth_create_authorizer(struct ceph_auth_client *ac, · 292 unmodified lines | ||
| 293 | 293 | } |
| 294 | 294 | EXPORT_SYMBOL(ceph_auth_create_authorizer); |
| 295 | 295 | |
| 296 | −void ceph_auth_destroy_authorizer(struct ceph_auth_client *ac, | |
| 297 | − struct ceph_authorizer *a) | |
| 296 | +void ceph_auth_destroy_authorizer(struct ceph_authorizer *a) | |
| 298 | 297 | { |
| 299 | − mutex_lock(&ac->mutex); | |
| 300 | − if (ac->ops && ac->ops->destroy_authorizer) | |
| 301 | − ac->ops->destroy_authorizer(ac, a); | |
| 302 | − mutex_unlock(&ac->mutex); | |
| 298 | + a->destroy(a); | |
| 303 | 299 | } |
| 304 | 300 | EXPORT_SYMBOL(ceph_auth_destroy_authorizer); |
| 305 | 301 | |
| @@ -16,7 +16,6 @@ static void reset(struct ceph_auth_client *ac) · 15 unmodified lines | ||
| 16 | 16 | struct ceph_auth_none_info *xi = ac->private; |
| 17 | 17 | |
| 18 | 18 | xi->starting = true; |
| 19 | − xi->built_authorizer = false; | |
| 20 | 19 | } |
| 21 | 20 | |
| 22 | 21 | static void destroy(struct ceph_auth_client *ac) |
| @@ -39,6 +38,27 @@ static int should_authenticate(struct ceph_auth_client *ac) · 16 unmodified lines | ||
| 39 | 38 | return xi->starting; |
| 40 | 39 | } |
| 41 | 40 | |
| 41 | +static int ceph_auth_none_build_authorizer(struct ceph_auth_client *ac, | |
| 42 | + struct ceph_none_authorizer *au) | |
| 43 | +{ | |
| 44 | + void *p = au->buf; | |
| 45 | + void *const end = p + sizeof(au->buf); | |
| 46 | + int ret; | |
| 47 | + | |
| 48 | + ceph_encode_8_safe(&p, end, 1, e_range); | |
| 49 | + ret = ceph_entity_name_encode(ac->name, &p, end); | |
| 50 | + if (ret < 0) | |
| 51 | + return ret; | |
| 52 | + | |
| 53 | + ceph_encode_64_safe(&p, end, ac->global_id, e_range); | |
| 54 | + au->buf_len = p - (void *)au->buf; | |
| 55 | + dout("%s built authorizer len %d\n", __func__, au->buf_len); | |
| 56 | + return 0; | |
| 57 | + | |
| 58 | +e_range: | |
| 59 | + return -ERANGE; | |
| 60 | +} | |
| 61 | + | |
| 42 | 62 | static int build_request(struct ceph_auth_client *ac, void *buf, void *end) |
| 43 | 63 | { |
| 44 | 64 | return 0; |
| @@ -57,32 +77,32 @@ static int handle_reply(struct ceph_auth_client *ac, int result, · 12 unmodified lines | ||
| 57 | 77 | return result; |
| 58 | 78 | } |
| 59 | 79 | |
| 80 | +static void ceph_auth_none_destroy_authorizer(struct ceph_authorizer *a) | |
| 81 | +{ | |
| 82 | + kfree(a); | |
| 83 | +} | |
| 84 | + | |
| 60 | 85 | /* |
| 61 | − * build an 'authorizer' with our entity_name and global_id. we can | |
| 62 | − * reuse a single static copy since it is identical for all services | |
| 63 | − * we connect to. | |
| 86 | + * build an 'authorizer' with our entity_name and global_id. it is | |
| 87 | + * identical for all services we connect to. | |
| 64 | 88 | */ |
| 65 | 89 | static int ceph_auth_none_create_authorizer( |
| 66 | 90 | struct ceph_auth_client *ac, int peer_type, |
| 67 | 91 | struct ceph_auth_handshake *auth) |
| 68 | 92 | { |
| 69 | − struct ceph_auth_none_info *ai = ac->private; | |
| 70 | − struct ceph_none_authorizer *au = &ai->au; | |
| 71 | − void *p, *end; | |
| 93 | + struct ceph_none_authorizer *au; | |
| 72 | 94 | int ret; |
| 73 | 95 | |
| 74 | − if (!ai->built_authorizer) { | |
| 75 | − p = au->buf; | |
| 76 | − end = p + sizeof(au->buf); | |
| 77 | − ceph_encode_8(&p, 1); | |
| 78 | − ret = ceph_entity_name_encode(ac->name, &p, end - 8); | |
| 79 | − if (ret < 0) | |
| 80 | − goto bad; | |
| 81 | − ceph_decode_need(&p, end, sizeof(u64), bad2); | |
| 82 | − ceph_encode_64(&p, ac->global_id); | |
| 83 | − au->buf_len = p - (void *)au->buf; | |
| 84 | − ai->built_authorizer = true; | |
| 85 | − dout("built authorizer len %d\n", au->buf_len); | |
| 96 | + au = kmalloc(sizeof(*au), GFP_NOFS); | |
| 97 | + if (!au) | |
| 98 | + return -ENOMEM; | |
| 99 | + | |
| 100 | + au->base.destroy = ceph_auth_none_destroy_authorizer; | |
| 101 | + | |
| 102 | + ret = ceph_auth_none_build_authorizer(ac, au); | |
| 103 | + if (ret) { | |
| 104 | + kfree(au); | |
| 105 | + return ret; | |
| 86 | 106 | } |
| 87 | 107 | |
| 88 | 108 | auth->authorizer = (struct ceph_authorizer *) au; |
| @@ -92,17 +112,6 @@ static int ceph_auth_none_create_authorizer( · 3 unmodified lines | ||
| 92 | 112 | auth->authorizer_reply_buf_len = sizeof (au->reply_buf); |
| 93 | 113 | |
| 94 | 114 | return 0; |
| 95 | − | |
| 96 | −bad2: | |
| 97 | − ret = -ERANGE; | |
| 98 | −bad: | |
| 99 | − return ret; | |
| 100 | −} | |
| 101 | − | |
| 102 | −static void ceph_auth_none_destroy_authorizer(struct ceph_auth_client *ac, | |
| 103 | − struct ceph_authorizer *a) | |
| 104 | −{ | |
| 105 | − /* nothing to do */ | |
| 106 | 115 | } |
| 107 | 116 | |
| 108 | 117 | static const struct ceph_auth_client_ops ceph_auth_none_ops = { |
| @@ -114,7 +123,6 @@ static const struct ceph_auth_client_ops ceph_auth_none_ops = { · 5 unmodified lines | ||
| 114 | 123 | .build_request = build_request, |
| 115 | 124 | .handle_reply = handle_reply, |
| 116 | 125 | .create_authorizer = ceph_auth_none_create_authorizer, |
| 117 | − .destroy_authorizer = ceph_auth_none_destroy_authorizer, | |
| 118 | 126 | }; |
| 119 | 127 | |
| 120 | 128 | int ceph_auth_none_init(struct ceph_auth_client *ac) |
| @@ -127,7 +135,6 @@ int ceph_auth_none_init(struct ceph_auth_client *ac) · 6 unmodified lines | ||
| 127 | 135 | return -ENOMEM; |
| 128 | 136 | |
| 129 | 137 | xi->starting = true; |
| 130 | − xi->built_authorizer = false; | |
| 131 | 138 | |
| 132 | 139 | ac->protocol = CEPH_AUTH_NONE; |
| 133 | 140 | ac->private = xi; |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | */ |
| 13 | 13 | |
| 14 | 14 | struct ceph_none_authorizer { |
| 15 | + struct ceph_authorizer base; | |
| 15 | 16 | char buf[128]; |
| 16 | 17 | int buf_len; |
| 17 | 18 | char reply_buf[0]; |
| @@ -19,8 +20,6 @@ struct ceph_none_authorizer { · 1 unmodified line | ||
| 19 | 20 | |
| 20 | 21 | struct ceph_auth_none_info { |
| 21 | 22 | bool starting; |
| 22 | − bool built_authorizer; | |
| 23 | − struct ceph_none_authorizer au; /* we only need one; it's static */ | |
| 24 | 23 | }; |
| 25 | 24 | |
| 26 | 25 | int ceph_auth_none_init(struct ceph_auth_client *ac); |
| @@ -565,6 +565,14 @@ static int ceph_x_handle_reply(struct ceph_auth_client *ac, int result, · 564 unmodified lines | ||
| 565 | 565 | return -EAGAIN; |
| 566 | 566 | } |
| 567 | 567 | |
| 568 | +static void ceph_x_destroy_authorizer(struct ceph_authorizer *a) | |
| 569 | +{ | |
| 570 | + struct ceph_x_authorizer *au = (void *)a; | |
| 571 | + | |
| 572 | + ceph_x_authorizer_cleanup(au); | |
| 573 | + kfree(au); | |
| 574 | +} | |
| 575 | + | |
| 568 | 576 | static int ceph_x_create_authorizer( |
| 569 | 577 | struct ceph_auth_client *ac, int peer_type, |
| 570 | 578 | struct ceph_auth_handshake *auth) |
| @@ -581,6 +589,8 @@ static int ceph_x_create_authorizer( · 10 unmodified lines | ||
| 581 | 589 | if (!au) |
| 582 | 590 | return -ENOMEM; |
| 583 | 591 | |
| 592 | + au->base.destroy = ceph_x_destroy_authorizer; | |
| 593 | + | |
| 584 | 594 | ret = ceph_x_build_authorizer(ac, th, au); |
| 585 | 595 | if (ret) { |
| 586 | 596 | kfree(au); |
| @@ -643,16 +653,6 @@ static int ceph_x_verify_authorizer_reply(struct ceph_auth_client *ac, · 56 unmodified lines | ||
| 643 | 653 | return ret; |
| 644 | 654 | } |
| 645 | 655 | |
| 646 | −static void ceph_x_destroy_authorizer(struct ceph_auth_client *ac, | |
| 647 | − struct ceph_authorizer *a) | |
| 648 | −{ | |
| 649 | − struct ceph_x_authorizer *au = (void *)a; | |
| 650 | − | |
| 651 | − ceph_x_authorizer_cleanup(au); | |
| 652 | − kfree(au); | |
| 653 | −} | |
| 654 | − | |
| 655 | − | |
| 656 | 656 | static void ceph_x_reset(struct ceph_auth_client *ac) |
| 657 | 657 | { |
| 658 | 658 | struct ceph_x_info *xi = ac->private; |
| @@ -770,7 +770,6 @@ static const struct ceph_auth_client_ops ceph_x_ops = { · 111 unmodified lines | ||
| 770 | 770 | .create_authorizer = ceph_x_create_authorizer, |
| 771 | 771 | .update_authorizer = ceph_x_update_authorizer, |
| 772 | 772 | .verify_authorizer_reply = ceph_x_verify_authorizer_reply, |
| 773 | − .destroy_authorizer = ceph_x_destroy_authorizer, | |
| 774 | 773 | .invalidate_authorizer = ceph_x_invalidate_authorizer, |
| 775 | 774 | .reset = ceph_x_reset, |
| 776 | 775 | .destroy = ceph_x_destroy, |
| @@ -26,6 +26,7 @@ struct ceph_x_ticket_handler { · 25 unmodified lines | ||
| 26 | 26 | |
| 27 | 27 | |
| 28 | 28 | struct ceph_x_authorizer { |
| 29 | + struct ceph_authorizer base; | |
| 29 | 30 | struct ceph_crypto_key session_key; |
| 30 | 31 | struct ceph_buffer *buf; |
| 31 | 32 | unsigned int service; |
| @@ -1087,10 +1087,8 @@ static void put_osd(struct ceph_osd *osd) · 1086 unmodified lines | ||
| 1087 | 1087 | dout("put_osd %p %d -> %d\n", osd, atomic_read(&osd->o_ref), |
| 1088 | 1088 | atomic_read(&osd->o_ref) - 1); |
| 1089 | 1089 | if (atomic_dec_and_test(&osd->o_ref)) { |
| 1090 | − struct ceph_auth_client *ac = osd->o_osdc->client->monc.auth; | |
| 1091 | − | |
| 1092 | 1090 | if (osd->o_auth.authorizer) |
| 1093 | − ceph_auth_destroy_authorizer(ac, osd->o_auth.authorizer); | |
| 1091 | + ceph_auth_destroy_authorizer(osd->o_auth.authorizer); | |
| 1094 | 1092 | kfree(osd); |
| 1095 | 1093 | } |
| 1096 | 1094 | } |
| @@ -2984,7 +2982,7 @@ static struct ceph_auth_handshake *get_authorizer(struct ceph_connection *con, · 1887 unmodified lines | ||
| 2984 | 2982 | struct ceph_auth_handshake *auth = &o->o_auth; |
| 2985 | 2983 | |
| 2986 | 2984 | if (force_new && auth->authorizer) { |
| 2987 | − ceph_auth_destroy_authorizer(ac, auth->authorizer); | |
| 2985 | + ceph_auth_destroy_authorizer(auth->authorizer); | |
| 2988 | 2986 | auth->authorizer = NULL; |
| 2989 | 2987 | } |
| 2990 | 2988 | if (!auth->authorizer) { |
| @@ -2815,7 +2815,7 @@ static netdev_features_t harmonize_features(struct sk_buff *skb, · 2814 unmodified lines | ||
| 2815 | 2815 | |
| 2816 | 2816 | if (skb->ip_summed != CHECKSUM_NONE && |
| 2817 | 2817 | !can_checksum_protocol(features, type)) { |
| 2818 | − features &= ~NETIF_F_CSUM_MASK; | |
| 2818 | + features &= ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK); | |
| 2819 | 2819 | } else if (illegal_highdma(skb->dev, skb)) { |
| 2820 | 2820 | features &= ~NETIF_F_SG; |
| 2821 | 2821 | } |
| @@ -438,6 +438,7 @@ static int inet_reuseport_add_sock(struct sock *sk, · 437 unmodified lines | ||
| 438 | 438 | const struct sock *sk2, |
| 439 | 439 | bool match_wildcard)) |
| 440 | 440 | { |
| 441 | + struct inet_bind_bucket *tb = inet_csk(sk)->icsk_bind_hash; | |
| 441 | 442 | struct sock *sk2; |
| 442 | 443 | kuid_t uid = sock_i_uid(sk); |
| 443 | 444 | |
| @@ -446,6 +447,7 @@ static int inet_reuseport_add_sock(struct sock *sk, · 2 unmodified lines | ||
| 446 | 447 | sk2->sk_family == sk->sk_family && |
| 447 | 448 | ipv6_only_sock(sk2) == ipv6_only_sock(sk) && |
| 448 | 449 | sk2->sk_bound_dev_if == sk->sk_bound_dev_if && |
| 450 | + inet_csk(sk2)->icsk_bind_hash == tb && | |
| 449 | 451 | sk2->sk_reuseport && uid_eq(uid, sock_i_uid(sk2)) && |
| 450 | 452 | saddr_same(sk, sk2, false)) |
| 451 | 453 | return reuseport_add_sock(sk, sk2); |
| @@ -369,7 +369,8 @@ static struct rtable *gre_get_rt(struct sk_buff *skb, · 368 unmodified lines | ||
| 369 | 369 | return ip_route_output_key(net, fl); |
| 370 | 370 | } |
| 371 | 371 | |
| 372 | −static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev) | |
| 372 | +static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev, | |
| 373 | + __be16 proto) | |
| 373 | 374 | { |
| 374 | 375 | struct ip_tunnel_info *tun_info; |
| 375 | 376 | const struct ip_tunnel_key *key; |
| @@ -418,7 +419,7 @@ static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev) · 42 unmodified lines | ||
| 418 | 419 | goto err_free_rt; |
| 419 | 420 | |
| 420 | 421 | flags = tun_info->key.tun_flags & (TUNNEL_CSUM | TUNNEL_KEY); |
| 421 | − gre_build_header(skb, tunnel_hlen, flags, htons(ETH_P_TEB), | |
| 422 | + gre_build_header(skb, tunnel_hlen, flags, proto, | |
| 422 | 423 | tunnel_id_to_key(tun_info->key.tun_id), 0); |
| 423 | 424 | |
| 424 | 425 | df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0; |
| @@ -459,7 +460,7 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb, · 34 unmodified lines | ||
| 459 | 460 | const struct iphdr *tnl_params; |
| 460 | 461 | |
| 461 | 462 | if (tunnel->collect_md) { |
| 462 | − gre_fb_xmit(skb, dev); | |
| 463 | + gre_fb_xmit(skb, dev, skb->protocol); | |
| 463 | 464 | return NETDEV_TX_OK; |
| 464 | 465 | } |
| 465 | 466 | |
| @@ -501,7 +502,7 @@ static netdev_tx_t gre_tap_xmit(struct sk_buff *skb, · 35 unmodified lines | ||
| 501 | 502 | struct ip_tunnel *tunnel = netdev_priv(dev); |
| 502 | 503 | |
| 503 | 504 | if (tunnel->collect_md) { |
| 504 | − gre_fb_xmit(skb, dev); | |
| 505 | + gre_fb_xmit(skb, dev, htons(ETH_P_TEB)); | |
| 505 | 506 | return NETDEV_TX_OK; |
| 506 | 507 | } |
| 507 | 508 | |
| @@ -732,7 +733,7 @@ static int ipgre_tunnel_init(struct net_device *dev) · 224 unmodified lines | ||
| 732 | 733 | netif_keep_dst(dev); |
| 733 | 734 | dev->addr_len = 4; |
| 734 | 735 | |
| 735 | − if (iph->daddr) { | |
| 736 | + if (iph->daddr && !tunnel->collect_md) { | |
| 736 | 737 | #ifdef CONFIG_NET_IPGRE_BROADCAST |
| 737 | 738 | if (ipv4_is_multicast(iph->daddr)) { |
| 738 | 739 | if (!iph->saddr) |
| @@ -741,8 +742,9 @@ static int ipgre_tunnel_init(struct net_device *dev) · 2 unmodified lines | ||
| 741 | 742 | dev->header_ops = &ipgre_header_ops; |
| 742 | 743 | } |
| 743 | 744 | #endif |
| 744 | − } else | |
| 745 | + } else if (!tunnel->collect_md) { | |
| 745 | 746 | dev->header_ops = &ipgre_header_ops; |
| 747 | + } | |
| 746 | 748 | |
| 747 | 749 | return ip_tunnel_init(dev); |
| 748 | 750 | } |
| @@ -785,6 +787,11 @@ static int ipgre_tunnel_validate(struct nlattr *tb[], struct nlattr *data[]) · 36 unmodified lines | ||
| 785 | 787 | if (flags & (GRE_VERSION|GRE_ROUTING)) |
| 786 | 788 | return -EINVAL; |
| 787 | 789 | |
| 790 | + if (data[IFLA_GRE_COLLECT_METADATA] && | |
| 791 | + data[IFLA_GRE_ENCAP_TYPE] && | |
| 792 | + nla_get_u16(data[IFLA_GRE_ENCAP_TYPE]) != TUNNEL_ENCAP_NONE) | |
| 793 | + return -EINVAL; | |
| 794 | + | |
| 788 | 795 | return 0; |
| 789 | 796 | } |
| 790 | 797 | |
| @@ -326,12 +326,12 @@ static int ip_tunnel_bind_dev(struct net_device *dev) · 325 unmodified lines | ||
| 326 | 326 | |
| 327 | 327 | if (!IS_ERR(rt)) { |
| 328 | 328 | tdev = rt->dst.dev; |
| 329 | − dst_cache_set_ip4(&tunnel->dst_cache, &rt->dst, | |
| 330 | − fl4.saddr); | |
| 331 | 329 | ip_rt_put(rt); |
| 332 | 330 | } |
| 333 | 331 | if (dev->type != ARPHRD_ETHER) |
| 334 | 332 | dev->flags |= IFF_POINTOPOINT; |
| 333 | + | |
| 334 | + dst_cache_reset(&tunnel->dst_cache); | |
| 335 | 335 | } |
| 336 | 336 | |
| 337 | 337 | if (!tdev && tunnel->parms.link) |
| @@ -144,8 +144,7 @@ nla_put_failure: · 143 unmodified lines | ||
| 144 | 144 | |
| 145 | 145 | static int ila_encap_nlsize(struct lwtunnel_state *lwtstate) |
| 146 | 146 | { |
| 147 | − /* No encapsulation overhead */ | |
| 148 | − return 0; | |
| 147 | + return nla_total_size(sizeof(u64)); /* ILA_ATTR_LOCATOR */ | |
| 149 | 148 | } |
| 150 | 149 | |
| 151 | 150 | static int ila_encap_cmp(struct lwtunnel_state *a, struct lwtunnel_state *b) |
| @@ -1376,9 +1376,9 @@ static int l2tp_tunnel_sock_create(struct net *net, · 1375 unmodified lines | ||
| 1376 | 1376 | memcpy(&udp_conf.peer_ip6, cfg->peer_ip6, |
| 1377 | 1377 | sizeof(udp_conf.peer_ip6)); |
| 1378 | 1378 | udp_conf.use_udp6_tx_checksums = |
| 1379 | − cfg->udp6_zero_tx_checksums; | |
| 1379 | + ! cfg->udp6_zero_tx_checksums; | |
| 1380 | 1380 | udp_conf.use_udp6_rx_checksums = |
| 1381 | − cfg->udp6_zero_rx_checksums; | |
| 1381 | + ! cfg->udp6_zero_rx_checksums; | |
| 1382 | 1382 | } else |
| 1383 | 1383 | #endif |
| 1384 | 1384 | { |
| @@ -1761,7 +1761,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, · 1760 unmodified lines | ||
| 1761 | 1761 | |
| 1762 | 1762 | ret = dev_alloc_name(ndev, ndev->name); |
| 1763 | 1763 | if (ret < 0) { |
| 1764 | − free_netdev(ndev); | |
| 1764 | + ieee80211_if_free(ndev); | |
| 1765 | 1765 | return ret; |
| 1766 | 1766 | } |
| 1767 | 1767 | |
| @@ -1847,7 +1847,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, · 79 unmodified lines | ||
| 1847 | 1847 | |
| 1848 | 1848 | ret = register_netdevice(ndev); |
| 1849 | 1849 | if (ret) { |
| 1850 | − free_netdev(ndev); | |
| 1850 | + ieee80211_if_free(ndev); | |
| 1851 | 1851 | return ret; |
| 1852 | 1852 | } |
| 1853 | 1853 | } |
| @@ -127,7 +127,7 @@ void rds_tcp_restore_callbacks(struct socket *sock, · 126 unmodified lines | ||
| 127 | 127 | |
| 128 | 128 | /* |
| 129 | 129 | * This is the only path that sets tc->t_sock. Send and receive trust that |
| 130 | − * it is set. The RDS_CONN_CONNECTED bit protects those paths from being | |
| 130 | + * it is set. The RDS_CONN_UP bit protects those paths from being | |
| 131 | 131 | * called while it isn't set. |
| 132 | 132 | */ |
| 133 | 133 | void rds_tcp_set_callbacks(struct socket *sock, struct rds_connection *conn) |
| @@ -216,6 +216,7 @@ static int rds_tcp_conn_alloc(struct rds_connection *conn, gfp_t gfp) · 82 unmodified lines | ||
| 216 | 216 | if (!tc) |
| 217 | 217 | return -ENOMEM; |
| 218 | 218 | |
| 219 | + mutex_init(&tc->t_conn_lock); | |
| 219 | 220 | tc->t_sock = NULL; |
| 220 | 221 | tc->t_tinc = NULL; |
| 221 | 222 | tc->t_tinc_hdr_rem = sizeof(struct rds_header); |
| @@ -12,6 +12,10 @@ struct rds_tcp_connection { · 11 unmodified lines | ||
| 12 | 12 | |
| 13 | 13 | struct list_head t_tcp_node; |
| 14 | 14 | struct rds_connection *conn; |
| 15 | + /* t_conn_lock synchronizes the connection establishment between | |
| 16 | + * rds_tcp_accept_one and rds_tcp_conn_connect | |
| 17 | + */ | |
| 18 | + struct mutex t_conn_lock; | |
| 15 | 19 | struct socket *t_sock; |
| 16 | 20 | void *t_orig_write_space; |
| 17 | 21 | void *t_orig_data_ready; |
| @@ -78,7 +78,14 @@ int rds_tcp_conn_connect(struct rds_connection *conn) · 77 unmodified lines | ||
| 78 | 78 | struct socket *sock = NULL; |
| 79 | 79 | struct sockaddr_in src, dest; |
| 80 | 80 | int ret; |
| 81 | + struct rds_tcp_connection *tc = conn->c_transport_data; | |
| 82 | + | |
| 83 | + mutex_lock(&tc->t_conn_lock); | |
| 81 | 84 | |
| 85 | + if (rds_conn_up(conn)) { | |
| 86 | + mutex_unlock(&tc->t_conn_lock); | |
| 87 | + return 0; | |
| 88 | + } | |
| 82 | 89 | ret = sock_create_kern(rds_conn_net(conn), PF_INET, |
| 83 | 90 | SOCK_STREAM, IPPROTO_TCP, &sock); |
| 84 | 91 | if (ret < 0) |
| @@ -120,6 +127,7 @@ int rds_tcp_conn_connect(struct rds_connection *conn) · 35 unmodified lines | ||
| 120 | 127 | } |
| 121 | 128 | |
| 122 | 129 | out: |
| 130 | + mutex_unlock(&tc->t_conn_lock); | |
| 123 | 131 | if (sock) |
| 124 | 132 | sock_release(sock); |
| 125 | 133 | return ret; |
| @@ -76,7 +76,9 @@ int rds_tcp_accept_one(struct socket *sock) · 75 unmodified lines | ||
| 76 | 76 | struct rds_connection *conn; |
| 77 | 77 | int ret; |
| 78 | 78 | struct inet_sock *inet; |
| 79 | − struct rds_tcp_connection *rs_tcp; | |
| 79 | + struct rds_tcp_connection *rs_tcp = NULL; | |
| 80 | + int conn_state; | |
| 81 | + struct sock *nsk; | |
| 80 | 82 | |
| 81 | 83 | ret = sock_create_kern(sock_net(sock->sk), sock->sk->sk_family, |
| 82 | 84 | sock->sk->sk_type, sock->sk->sk_protocol, |
| @@ -115,28 +117,44 @@ int rds_tcp_accept_one(struct socket *sock) · 32 unmodified lines | ||
| 115 | 117 | * rds_tcp_state_change() will do that cleanup |
| 116 | 118 | */ |
| 117 | 119 | rs_tcp = (struct rds_tcp_connection *)conn->c_transport_data; |
| 118 | − if (rs_tcp->t_sock && | |
| 119 | − ntohl(inet->inet_saddr) < ntohl(inet->inet_daddr)) { | |
| 120 | − struct sock *nsk = new_sock->sk; | |
| 121 | − | |
| 122 | − nsk->sk_user_data = NULL; | |
| 123 | − nsk->sk_prot->disconnect(nsk, 0); | |
| 124 | − tcp_done(nsk); | |
| 125 | − new_sock = NULL; | |
| 126 | − ret = 0; | |
| 127 | − goto out; | |
| 128 | − } else if (rs_tcp->t_sock) { | |
| 129 | − rds_tcp_restore_callbacks(rs_tcp->t_sock, rs_tcp); | |
| 130 | − conn->c_outgoing = 0; | |
| 131 | − } | |
| 132 | − | |
| 133 | 120 | rds_conn_transition(conn, RDS_CONN_DOWN, RDS_CONN_CONNECTING); |
| 121 | + mutex_lock(&rs_tcp->t_conn_lock); | |
| 122 | + conn_state = rds_conn_state(conn); | |
| 123 | + if (conn_state != RDS_CONN_CONNECTING && conn_state != RDS_CONN_UP) | |
| 124 | + goto rst_nsk; | |
| 125 | + if (rs_tcp->t_sock) { | |
| 126 | + /* Need to resolve a duelling SYN between peers. | |
| 127 | + * We have an outstanding SYN to this peer, which may | |
| 128 | + * potentially have transitioned to the RDS_CONN_UP state, | |
| 129 | + * so we must quiesce any send threads before resetting | |
| 130 | + * c_transport_data. | |
| 131 | + */ | |
| 132 | + wait_event(conn->c_waitq, | |
| 133 | + !test_bit(RDS_IN_XMIT, &conn->c_flags)); | |
| 134 | + if (ntohl(inet->inet_saddr) < ntohl(inet->inet_daddr)) { | |
| 135 | + goto rst_nsk; | |
| 136 | + } else if (rs_tcp->t_sock) { | |
| 137 | + rds_tcp_restore_callbacks(rs_tcp->t_sock, rs_tcp); | |
| 138 | + conn->c_outgoing = 0; | |
| 139 | + } | |
| 140 | + } | |
| 134 | 141 | rds_tcp_set_callbacks(new_sock, conn); |
| 135 | − rds_connect_complete(conn); | |
| 142 | + rds_connect_complete(conn); /* marks RDS_CONN_UP */ | |
| 143 | + new_sock = NULL; | |
| 144 | + ret = 0; | |
| 145 | + goto out; | |
| 146 | +rst_nsk: | |
| 147 | + /* reset the newly returned accept sock and bail */ | |
| 148 | + nsk = new_sock->sk; | |
| 149 | + rds_tcp_stats_inc(s_tcp_listen_closed_stale); | |
| 150 | + nsk->sk_user_data = NULL; | |
| 151 | + nsk->sk_prot->disconnect(nsk, 0); | |
| 152 | + tcp_done(nsk); | |
| 136 | 153 | new_sock = NULL; |
| 137 | 154 | ret = 0; |
| 138 | − | |
| 139 | 155 | out: |
| 156 | + if (rs_tcp) | |
| 157 | + mutex_unlock(&rs_tcp->t_conn_lock); | |
| 140 | 158 | if (new_sock) |
| 141 | 159 | sock_release(new_sock); |
| 142 | 160 | return ret; |
| @@ -395,6 +395,25 @@ static void tfifo_enqueue(struct sk_buff *nskb, struct Qdisc *sch) · 394 unmodified lines | ||
| 395 | 395 | sch->q.qlen++; |
| 396 | 396 | } |
| 397 | 397 | |
| 398 | +/* netem can't properly corrupt a megapacket (like we get from GSO), so instead | |
| 399 | + * when we statistically choose to corrupt one, we instead segment it, returning | |
| 400 | + * the first packet to be corrupted, and re-enqueue the remaining frames | |
| 401 | + */ | |
| 402 | +static struct sk_buff *netem_segment(struct sk_buff *skb, struct Qdisc *sch) | |
| 403 | +{ | |
| 404 | + struct sk_buff *segs; | |
| 405 | + netdev_features_t features = netif_skb_features(skb); | |
| 406 | + | |
| 407 | + segs = skb_gso_segment(skb, features & ~NETIF_F_GSO_MASK); | |
| 408 | + | |
| 409 | + if (IS_ERR_OR_NULL(segs)) { | |
| 410 | + qdisc_reshape_fail(skb, sch); | |
| 411 | + return NULL; | |
| 412 | + } | |
| 413 | + consume_skb(skb); | |
| 414 | + return segs; | |
| 415 | +} | |
| 416 | + | |
| 398 | 417 | /* |
| 399 | 418 | * Insert one skb into qdisc. |
| 400 | 419 | * Note: parent depends on return value to account for queue length. |
| @@ -407,7 +426,11 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) · 6 unmodified lines | ||
| 407 | 426 | /* We don't fill cb now as skb_unshare() may invalidate it */ |
| 408 | 427 | struct netem_skb_cb *cb; |
| 409 | 428 | struct sk_buff *skb2; |
| 429 | + struct sk_buff *segs = NULL; | |
| 430 | + unsigned int len = 0, last_len, prev_len = qdisc_pkt_len(skb); | |
| 431 | + int nb = 0; | |
| 410 | 432 | int count = 1; |
| 433 | + int rc = NET_XMIT_SUCCESS; | |
| 411 | 434 | |
| 412 | 435 | /* Random duplication */ |
| 413 | 436 | if (q->duplicate && q->duplicate >= get_crandom(&q->dup_cor)) |
| @@ -453,10 +476,23 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) · 39 unmodified lines | ||
| 453 | 476 | * do it now in software before we mangle it. |
| 454 | 477 | */ |
| 455 | 478 | if (q->corrupt && q->corrupt >= get_crandom(&q->corrupt_cor)) { |
| 479 | + if (skb_is_gso(skb)) { | |
| 480 | + segs = netem_segment(skb, sch); | |
| 481 | + if (!segs) | |
| 482 | + return NET_XMIT_DROP; | |
| 483 | + } else { | |
| 484 | + segs = skb; | |
| 485 | + } | |
| 486 | + | |
| 487 | + skb = segs; | |
| 488 | + segs = segs->next; | |
| 489 | + | |
| 456 | 490 | if (!(skb = skb_unshare(skb, GFP_ATOMIC)) || |
| 457 | 491 | (skb->ip_summed == CHECKSUM_PARTIAL && |
| 458 | − skb_checksum_help(skb))) | |
| 459 | − return qdisc_drop(skb, sch); | |
| 492 | + skb_checksum_help(skb))) { | |
| 493 | + rc = qdisc_drop(skb, sch); | |
| 494 | + goto finish_segs; | |
| 495 | + } | |
| 460 | 496 | |
| 461 | 497 | skb->data[prandom_u32() % skb_headlen(skb)] ^= |
| 462 | 498 | 1<<(prandom_u32() % 8); |
| @@ -516,6 +552,27 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) · 53 unmodified lines | ||
| 516 | 552 | sch->qstats.requeues++; |
| 517 | 553 | } |
| 518 | 554 | |
| 555 | +finish_segs: | |
| 556 | + if (segs) { | |
| 557 | + while (segs) { | |
| 558 | + skb2 = segs->next; | |
| 559 | + segs->next = NULL; | |
| 560 | + qdisc_skb_cb(segs)->pkt_len = segs->len; | |
| 561 | + last_len = segs->len; | |
| 562 | + rc = qdisc_enqueue(segs, sch); | |
| 563 | + if (rc != NET_XMIT_SUCCESS) { | |
| 564 | + if (net_xmit_drop_count(rc)) | |
| 565 | + qdisc_qstats_drop(sch); | |
| 566 | + } else { | |
| 567 | + nb++; | |
| 568 | + len += last_len; | |
| 569 | + } | |
| 570 | + segs = skb2; | |
| 571 | + } | |
| 572 | + sch->q.qlen += nb; | |
| 573 | + if (nb > 1) | |
| 574 | + qdisc_tree_reduce_backlog(sch, 1 - nb, prev_len - len); | |
| 575 | + } | |
| 519 | 576 | return NET_XMIT_SUCCESS; |
| 520 | 577 | } |
| 521 | 578 | |
| @@ -1469,6 +1469,7 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b) · 1468 unmodified lines | ||
| 1469 | 1469 | int bearer_id = b->identity; |
| 1470 | 1470 | struct tipc_link_entry *le; |
| 1471 | 1471 | u16 bc_ack = msg_bcast_ack(hdr); |
| 1472 | + u32 self = tipc_own_addr(net); | |
| 1472 | 1473 | int rc = 0; |
| 1473 | 1474 | |
| 1474 | 1475 | __skb_queue_head_init(&xmitq); |
| @@ -1485,6 +1486,10 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b) · 10 unmodified lines | ||
| 1485 | 1486 | return tipc_node_bc_rcv(net, skb, bearer_id); |
| 1486 | 1487 | } |
| 1487 | 1488 | |
| 1489 | + /* Discard unicast link messages destined for another node */ | |
| 1490 | + if (unlikely(!msg_short(hdr) && (msg_destnode(hdr) != self))) | |
| 1491 | + goto discard; | |
| 1492 | + | |
| 1488 | 1493 | /* Locate neighboring node that sent packet */ |
| 1489 | 1494 | n = tipc_node_find(net, msg_prevnode(hdr)); |
| 1490 | 1495 | if (unlikely(!n)) |
| @@ -18,7 +18,6 @@ int bpf_prog1(struct pt_regs *ctx) · 17 unmodified lines | ||
| 18 | 18 | u64 cookie; |
| 19 | 19 | } data; |
| 20 | 20 | |
| 21 | − memset(&data, 0, sizeof(data)); | |
| 22 | 21 | data.pid = bpf_get_current_pid_tgid(); |
| 23 | 22 | data.cookie = 0x12345678; |
| 24 | 23 | |
| @@ -104,12 +104,11 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_init_all); · 103 unmodified lines | ||
| 104 | 104 | */ |
| 105 | 105 | void snd_hdac_stream_free_all(struct hdac_ext_bus *ebus) |
| 106 | 106 | { |
| 107 | − struct hdac_stream *s; | |
| 107 | + struct hdac_stream *s, *_s; | |
| 108 | 108 | struct hdac_ext_stream *stream; |
| 109 | 109 | struct hdac_bus *bus = ebus_to_hbus(ebus); |
| 110 | 110 | |
| 111 | − while (!list_empty(&bus->stream_list)) { | |
| 112 | − s = list_first_entry(&bus->stream_list, struct hdac_stream, list); | |
| 111 | + list_for_each_entry_safe(s, _s, &bus->stream_list, list) { | |
| 113 | 112 | stream = stream_to_hdac_ext_stream(s); |
| 114 | 113 | snd_hdac_ext_stream_decouple(ebus, stream, false); |
| 115 | 114 | list_del(&s->list); |
| @@ -20,6 +20,7 @@ · 19 unmodified lines | ||
| 20 | 20 | #include <sound/core.h> |
| 21 | 21 | #include <sound/hdaudio.h> |
| 22 | 22 | #include <sound/hda_i915.h> |
| 23 | +#include <sound/hda_register.h> | |
| 23 | 24 | |
| 24 | 25 | static struct i915_audio_component *hdac_acomp; |
| 25 | 26 | |
| @@ -97,26 +98,65 @@ int snd_hdac_display_power(struct hdac_bus *bus, bool enable) · 71 unmodified lines | ||
| 97 | 98 | } |
| 98 | 99 | EXPORT_SYMBOL_GPL(snd_hdac_display_power); |
| 99 | 100 | |
| 101 | +#define CONTROLLER_IN_GPU(pci) (((pci)->device == 0x0a0c) || \ | |
| 102 | + ((pci)->device == 0x0c0c) || \ | |
| 103 | + ((pci)->device == 0x0d0c) || \ | |
| 104 | + ((pci)->device == 0x160c)) | |
| 105 | + | |
| 100 | 106 | /** |
| 101 | − * snd_hdac_get_display_clk - Get CDCLK in kHz | |
| 107 | + * snd_hdac_i915_set_bclk - Reprogram BCLK for HSW/BDW | |
| 102 | 108 | * @bus: HDA core bus |
| 103 | 109 | * |
| 104 | − * This function is supposed to be used only by a HD-audio controller | |
| 105 | − * driver that needs the interaction with i915 graphics. | |
| 110 | + * Intel HSW/BDW display HDA controller is in GPU. Both its power and link BCLK | |
| 111 | + * depends on GPU. Two Extended Mode registers EM4 (M value) and EM5 (N Value) | |
| 112 | + * are used to convert CDClk (Core Display Clock) to 24MHz BCLK: | |
| 113 | + * BCLK = CDCLK * M / N | |
| 114 | + * The values will be lost when the display power well is disabled and need to | |
| 115 | + * be restored to avoid abnormal playback speed. | |
| 106 | 116 | * |
| 107 | − * This function queries CDCLK value in kHz from the graphics driver and | |
| 108 | − * returns the value. A negative code is returned in error. | |
| 117 | + * Call this function at initializing and changing power well, as well as | |
| 118 | + * at ELD notifier for the hotplug. | |
| 109 | 119 | */ |
| 110 | −int snd_hdac_get_display_clk(struct hdac_bus *bus) | |
| 120 | +void snd_hdac_i915_set_bclk(struct hdac_bus *bus) | |
| 111 | 121 | { |
| 112 | 122 | struct i915_audio_component *acomp = bus->audio_component; |
| 123 | + struct pci_dev *pci = to_pci_dev(bus->dev); | |
| 124 | + int cdclk_freq; | |
| 125 | + unsigned int bclk_m, bclk_n; | |
| 126 | + | |
| 127 | + if (!acomp || !acomp->ops || !acomp->ops->get_cdclk_freq) | |
| 128 | + return; /* only for i915 binding */ | |
| 129 | + if (!CONTROLLER_IN_GPU(pci)) | |
| 130 | + return; /* only HSW/BDW */ | |
| 131 | + | |
| 132 | + cdclk_freq = acomp->ops->get_cdclk_freq(acomp->dev); | |
| 133 | + switch (cdclk_freq) { | |
| 134 | + case 337500: | |
| 135 | + bclk_m = 16; | |
| 136 | + bclk_n = 225; | |
| 137 | + break; | |
| 138 | + | |
| 139 | + case 450000: | |
| 140 | + default: /* default CDCLK 450MHz */ | |
| 141 | + bclk_m = 4; | |
| 142 | + bclk_n = 75; | |
| 143 | + break; | |
| 144 | + | |
| 145 | + case 540000: | |
| 146 | + bclk_m = 4; | |
| 147 | + bclk_n = 90; | |
| 148 | + break; | |
| 149 | + | |
| 150 | + case 675000: | |
| 151 | + bclk_m = 8; | |
| 152 | + bclk_n = 225; | |
| 153 | + break; | |
| 154 | + } | |
| 113 | 155 | |
| 114 | − if (!acomp || !acomp->ops) | |
| 115 | − return -ENODEV; | |
| 116 | − | |
| 117 | − return acomp->ops->get_cdclk_freq(acomp->dev); | |
| 156 | + snd_hdac_chip_writew(bus, HSW_EM4, bclk_m); | |
| 157 | + snd_hdac_chip_writew(bus, HSW_EM5, bclk_n); | |
| 118 | 158 | } |
| 119 | −EXPORT_SYMBOL_GPL(snd_hdac_get_display_clk); | |
| 159 | +EXPORT_SYMBOL_GPL(snd_hdac_i915_set_bclk); | |
| 120 | 160 | |
| 121 | 161 | /* There is a fixed mapping between audio pin node and display port |
| 122 | 162 | * on current Intel platforms: |
| @@ -857,50 +857,6 @@ static int param_set_xint(const char *val, const struct kernel_param *kp) · 856 unmodified lines | ||
| 857 | 857 | #define azx_del_card_list(chip) /* NOP */ |
| 858 | 858 | #endif /* CONFIG_PM */ |
| 859 | 859 | |
| 860 | −/* Intel HSW/BDW display HDA controller is in GPU. Both its power and link BCLK | |
| 861 | − * depends on GPU. Two Extended Mode registers EM4 (M value) and EM5 (N Value) | |
| 862 | − * are used to convert CDClk (Core Display Clock) to 24MHz BCLK: | |
| 863 | − * BCLK = CDCLK * M / N | |
| 864 | − * The values will be lost when the display power well is disabled and need to | |
| 865 | − * be restored to avoid abnormal playback speed. | |
| 866 | − */ | |
| 867 | −static void haswell_set_bclk(struct hda_intel *hda) | |
| 868 | −{ | |
| 869 | − struct azx *chip = &hda->chip; | |
| 870 | − int cdclk_freq; | |
| 871 | − unsigned int bclk_m, bclk_n; | |
| 872 | − | |
| 873 | − if (!hda->need_i915_power) | |
| 874 | − return; | |
| 875 | − | |
| 876 | − cdclk_freq = snd_hdac_get_display_clk(azx_bus(chip)); | |
| 877 | − switch (cdclk_freq) { | |
| 878 | − case 337500: | |
| 879 | − bclk_m = 16; | |
| 880 | − bclk_n = 225; | |
| 881 | − break; | |
| 882 | − | |
| 883 | − case 450000: | |
| 884 | − default: /* default CDCLK 450MHz */ | |
| 885 | − bclk_m = 4; | |
| 886 | − bclk_n = 75; | |
| 887 | − break; | |
| 888 | − | |
| 889 | − case 540000: | |
| 890 | − bclk_m = 4; | |
| 891 | − bclk_n = 90; | |
| 892 | − break; | |
| 893 | − | |
| 894 | − case 675000: | |
| 895 | − bclk_m = 8; | |
| 896 | − bclk_n = 225; | |
| 897 | − break; | |
| 898 | − } | |
| 899 | − | |
| 900 | − azx_writew(chip, HSW_EM4, bclk_m); | |
| 901 | − azx_writew(chip, HSW_EM5, bclk_n); | |
| 902 | −} | |
| 903 | − | |
| 904 | 860 | #if defined(CONFIG_PM_SLEEP) || defined(SUPPORT_VGA_SWITCHEROO) |
| 905 | 861 | /* |
| 906 | 862 | * power management |
| @@ -958,7 +914,7 @@ static int azx_resume(struct device *dev) · 51 unmodified lines | ||
| 958 | 914 | if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL |
| 959 | 915 | && hda->need_i915_power) { |
| 960 | 916 | snd_hdac_display_power(azx_bus(chip), true); |
| 961 | − haswell_set_bclk(hda); | |
| 917 | + snd_hdac_i915_set_bclk(azx_bus(chip)); | |
| 962 | 918 | } |
| 963 | 919 | if (chip->msi) |
| 964 | 920 | if (pci_enable_msi(pci) < 0) |
| @@ -1058,7 +1014,7 @@ static int azx_runtime_resume(struct device *dev) · 93 unmodified lines | ||
| 1058 | 1014 | bus = azx_bus(chip); |
| 1059 | 1015 | if (hda->need_i915_power) { |
| 1060 | 1016 | snd_hdac_display_power(bus, true); |
| 1061 | − haswell_set_bclk(hda); | |
| 1017 | + snd_hdac_i915_set_bclk(bus); | |
| 1062 | 1018 | } else { |
| 1063 | 1019 | /* toggle codec wakeup bit for STATESTS read */ |
| 1064 | 1020 | snd_hdac_set_codec_wakeup(bus, true); |
| @@ -1796,12 +1752,8 @@ static int azx_first_init(struct azx *chip) · 731 unmodified lines | ||
| 1796 | 1752 | /* initialize chip */ |
| 1797 | 1753 | azx_init_pci(chip); |
| 1798 | 1754 | |
| 1799 | − if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { | |
| 1800 | − struct hda_intel *hda; | |
| 1801 | − | |
| 1802 | − hda = container_of(chip, struct hda_intel, chip); | |
| 1803 | − haswell_set_bclk(hda); | |
| 1804 | − } | |
| 1755 | + if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) | |
| 1756 | + snd_hdac_i915_set_bclk(bus); | |
| 1805 | 1757 | |
| 1806 | 1758 | hda_intel_init_chip(chip, (probe_only[dev] & 2) == 0); |
| 1807 | 1759 | |
| @@ -2232,6 +2232,7 @@ static void intel_pin_eld_notify(void *audio_ptr, int port) · 2231 unmodified lines | ||
| 2232 | 2232 | if (atomic_read(&(codec)->core.in_pm)) |
| 2233 | 2233 | return; |
| 2234 | 2234 | |
| 2235 | + snd_hdac_i915_set_bclk(&codec->bus->core); | |
| 2235 | 2236 | check_presence_and_report(codec, pin_nid); |
| 2236 | 2237 | } |
| 2237 | 2238 | |
| @@ -5584,6 +5584,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 5583 unmodified lines | ||
| 5584 | 5584 | SND_PCI_QUIRK(0x17aa, 0x5034, "Thinkpad T450", ALC292_FIXUP_TPT440_DOCK), |
| 5585 | 5585 | SND_PCI_QUIRK(0x17aa, 0x5036, "Thinkpad T450s", ALC292_FIXUP_TPT440_DOCK), |
| 5586 | 5586 | SND_PCI_QUIRK(0x17aa, 0x503c, "Thinkpad L450", ALC292_FIXUP_TPT440_DOCK), |
| 5587 | + SND_PCI_QUIRK(0x17aa, 0x504a, "ThinkPad X260", ALC292_FIXUP_TPT440_DOCK), | |
| 5587 | 5588 | SND_PCI_QUIRK(0x17aa, 0x504b, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE), |
| 5588 | 5589 | SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
| 5589 | 5590 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), |
| @@ -629,6 +629,7 @@ config SND_SOC_RT5514 · 628 unmodified lines | ||
| 629 | 629 | |
| 630 | 630 | config SND_SOC_RT5616 |
| 631 | 631 | tristate "Realtek RT5616 CODEC" |
| 632 | + depends on I2C | |
| 632 | 633 | |
| 633 | 634 | config SND_SOC_RT5631 |
| 634 | 635 | tristate "Realtek ALC5631/RT5631 CODEC" |
| @@ -249,6 +249,18 @@ int arizona_init_spk(struct snd_soc_codec *codec) · 248 unmodified lines | ||
| 249 | 249 | } |
| 250 | 250 | EXPORT_SYMBOL_GPL(arizona_init_spk); |
| 251 | 251 | |
| 252 | +int arizona_free_spk(struct snd_soc_codec *codec) | |
| 253 | +{ | |
| 254 | + struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); | |
| 255 | + struct arizona *arizona = priv->arizona; | |
| 256 | + | |
| 257 | + arizona_free_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT_WARN, arizona); | |
| 258 | + arizona_free_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT, arizona); | |
| 259 | + | |
| 260 | + return 0; | |
| 261 | +} | |
| 262 | +EXPORT_SYMBOL_GPL(arizona_free_spk); | |
| 263 | + | |
| 252 | 264 | static const struct snd_soc_dapm_route arizona_mono_routes[] = { |
| 253 | 265 | { "OUT1R", NULL, "OUT1L" }, |
| 254 | 266 | { "OUT2R", NULL, "OUT2L" }, |
| @@ -307,6 +307,8 @@ extern int arizona_init_spk(struct snd_soc_codec *codec); · 306 unmodified lines | ||
| 307 | 307 | extern int arizona_init_gpio(struct snd_soc_codec *codec); |
| 308 | 308 | extern int arizona_init_mono(struct snd_soc_codec *codec); |
| 309 | 309 | |
| 310 | +extern int arizona_free_spk(struct snd_soc_codec *codec); | |
| 311 | + | |
| 310 | 312 | extern int arizona_init_dai(struct arizona_priv *priv, int dai); |
| 311 | 313 | |
| 312 | 314 | int arizona_set_output_mode(struct snd_soc_codec *codec, int output, |
| @@ -274,7 +274,9 @@ static int cs35l32_handle_of_data(struct i2c_client *i2c_client, · 273 unmodified lines | ||
| 274 | 274 | if (of_property_read_u32(np, "cirrus,sdout-share", &val) >= 0) |
| 275 | 275 | pdata->sdout_share = val; |
| 276 | 276 | |
| 277 | − of_property_read_u32(np, "cirrus,boost-manager", &val); | |
| 277 | + if (of_property_read_u32(np, "cirrus,boost-manager", &val)) | |
| 278 | + val = -1u; | |
| 279 | + | |
| 278 | 280 | switch (val) { |
| 279 | 281 | case CS35L32_BOOST_MGR_AUTO: |
| 280 | 282 | case CS35L32_BOOST_MGR_AUTO_AUDIO: |
| @@ -282,13 +284,15 @@ static int cs35l32_handle_of_data(struct i2c_client *i2c_client, · 1 unmodified line | ||
| 282 | 284 | case CS35L32_BOOST_MGR_FIXED: |
| 283 | 285 | pdata->boost_mng = val; |
| 284 | 286 | break; |
| 287 | + case -1u: | |
| 285 | 288 | default: |
| 286 | 289 | dev_err(&i2c_client->dev, |
| 287 | 290 | "Wrong cirrus,boost-manager DT value %d\n", val); |
| 288 | 291 | pdata->boost_mng = CS35L32_BOOST_MGR_BYPASS; |
| 289 | 292 | } |
| 290 | 293 | |
| 291 | − of_property_read_u32(np, "cirrus,sdout-datacfg", &val); | |
| 294 | + if (of_property_read_u32(np, "cirrus,sdout-datacfg", &val)) | |
| 295 | + val = -1u; | |
| 292 | 296 | switch (val) { |
| 293 | 297 | case CS35L32_DATA_CFG_LR_VP: |
| 294 | 298 | case CS35L32_DATA_CFG_LR_STAT: |
| @@ -296,13 +300,15 @@ static int cs35l32_handle_of_data(struct i2c_client *i2c_client, · 1 unmodified line | ||
| 296 | 300 | case CS35L32_DATA_CFG_LR_VPSTAT: |
| 297 | 301 | pdata->sdout_datacfg = val; |
| 298 | 302 | break; |
| 303 | + case -1u: | |
| 299 | 304 | default: |
| 300 | 305 | dev_err(&i2c_client->dev, |
| 301 | 306 | "Wrong cirrus,sdout-datacfg DT value %d\n", val); |
| 302 | 307 | pdata->sdout_datacfg = CS35L32_DATA_CFG_LR; |
| 303 | 308 | } |
| 304 | 309 | |
| 305 | − of_property_read_u32(np, "cirrus,battery-threshold", &val); | |
| 310 | + if (of_property_read_u32(np, "cirrus,battery-threshold", &val)) | |
| 311 | + val = -1u; | |
| 306 | 312 | switch (val) { |
| 307 | 313 | case CS35L32_BATT_THRESH_3_1V: |
| 308 | 314 | case CS35L32_BATT_THRESH_3_2V: |
| @@ -310,13 +316,15 @@ static int cs35l32_handle_of_data(struct i2c_client *i2c_client, · 1 unmodified line | ||
| 310 | 316 | case CS35L32_BATT_THRESH_3_4V: |
| 311 | 317 | pdata->batt_thresh = val; |
| 312 | 318 | break; |
| 319 | + case -1u: | |
| 313 | 320 | default: |
| 314 | 321 | dev_err(&i2c_client->dev, |
| 315 | 322 | "Wrong cirrus,battery-threshold DT value %d\n", val); |
| 316 | 323 | pdata->batt_thresh = CS35L32_BATT_THRESH_3_3V; |
| 317 | 324 | } |
| 318 | 325 | |
| 319 | − of_property_read_u32(np, "cirrus,battery-recovery", &val); | |
| 326 | + if (of_property_read_u32(np, "cirrus,battery-recovery", &val)) | |
| 327 | + val = -1u; | |
| 320 | 328 | switch (val) { |
| 321 | 329 | case CS35L32_BATT_RECOV_3_1V: |
| 322 | 330 | case CS35L32_BATT_RECOV_3_2V: |
| @@ -326,6 +334,7 @@ static int cs35l32_handle_of_data(struct i2c_client *i2c_client, · 3 unmodified lines | ||
| 326 | 334 | case CS35L32_BATT_RECOV_3_6V: |
| 327 | 335 | pdata->batt_recov = val; |
| 328 | 336 | break; |
| 337 | + case -1u: | |
| 329 | 338 | default: |
| 330 | 339 | dev_err(&i2c_client->dev, |
| 331 | 340 | "Wrong cirrus,battery-recovery DT value %d\n", val); |
| @@ -1108,6 +1108,9 @@ static int cs47l24_codec_remove(struct snd_soc_codec *codec) · 1107 unmodified lines | ||
| 1108 | 1108 | priv->core.arizona->dapm = NULL; |
| 1109 | 1109 | |
| 1110 | 1110 | arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, priv); |
| 1111 | + | |
| 1112 | + arizona_free_spk(codec); | |
| 1113 | + | |
| 1111 | 1114 | return 0; |
| 1112 | 1115 | } |
| 1113 | 1116 | |
| @@ -1420,32 +1420,39 @@ static int hdmi_codec_remove(struct snd_soc_codec *codec) · 1419 unmodified lines | ||
| 1420 | 1420 | } |
| 1421 | 1421 | |
| 1422 | 1422 | #ifdef CONFIG_PM |
| 1423 | −static int hdmi_codec_resume(struct snd_soc_codec *codec) | |
| 1423 | +static int hdmi_codec_prepare(struct device *dev) | |
| 1424 | 1424 | { |
| 1425 | − struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec); | |
| 1425 | + struct hdac_ext_device *edev = to_hda_ext_device(dev); | |
| 1426 | + struct hdac_device *hdac = &edev->hdac; | |
| 1427 | + | |
| 1428 | + pm_runtime_get_sync(&edev->hdac.dev); | |
| 1429 | + | |
| 1430 | + /* | |
| 1431 | + * Power down afg. | |
| 1432 | + * codec_read is preferred over codec_write to set the power state. | |
| 1433 | + * This way verb is send to set the power state and response | |
| 1434 | + * is received. So setting power state is ensured without using loop | |
| 1435 | + * to read the state. | |
| 1436 | + */ | |
| 1437 | + snd_hdac_codec_read(hdac, hdac->afg, 0, AC_VERB_SET_POWER_STATE, | |
| 1438 | + AC_PWRST_D3); | |
| 1439 | + | |
| 1440 | + return 0; | |
| 1441 | +} | |
| 1442 | + | |
| 1443 | +static void hdmi_codec_complete(struct device *dev) | |
| 1444 | +{ | |
| 1445 | + struct hdac_ext_device *edev = to_hda_ext_device(dev); | |
| 1426 | 1446 | struct hdac_hdmi_priv *hdmi = edev->private_data; |
| 1427 | 1447 | struct hdac_hdmi_pin *pin; |
| 1428 | 1448 | struct hdac_device *hdac = &edev->hdac; |
| 1429 | − struct hdac_bus *bus = hdac->bus; | |
| 1430 | − int err; | |
| 1431 | − unsigned long timeout; | |
| 1432 | − | |
| 1433 | − hdac_hdmi_skl_enable_all_pins(&edev->hdac); | |
| 1434 | − hdac_hdmi_skl_enable_dp12(&edev->hdac); | |
| 1435 | 1449 | |
| 1436 | 1450 | /* Power up afg */ |
| 1437 | − if (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D0)) { | |
| 1438 | − | |
| 1439 | − snd_hdac_codec_write(hdac, hdac->afg, 0, | |
| 1440 | − AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | |
| 1451 | + snd_hdac_codec_read(hdac, hdac->afg, 0, AC_VERB_SET_POWER_STATE, | |
| 1452 | + AC_PWRST_D0); | |
| 1441 | 1453 | |
| 1442 | − /* Wait till power state is set to D0 */ | |
| 1443 | − timeout = jiffies + msecs_to_jiffies(1000); | |
| 1444 | − while (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D0) | |
| 1445 | − && time_before(jiffies, timeout)) { | |
| 1446 | − msleep(50); | |
| 1447 | − } | |
| 1448 | − } | |
| 1454 | + hdac_hdmi_skl_enable_all_pins(&edev->hdac); | |
| 1455 | + hdac_hdmi_skl_enable_dp12(&edev->hdac); | |
| 1449 | 1456 | |
| 1450 | 1457 | /* |
| 1451 | 1458 | * As the ELD notify callback request is not entertained while the |
| @@ -1455,28 +1462,16 @@ static int hdmi_codec_resume(struct snd_soc_codec *codec) · 3 unmodified lines | ||
| 1455 | 1462 | list_for_each_entry(pin, &hdmi->pin_list, head) |
| 1456 | 1463 | hdac_hdmi_present_sense(pin, 1); |
| 1457 | 1464 | |
| 1458 | − /* | |
| 1459 | − * Codec power is turned ON during controller resume. | |
| 1460 | − * Turn it OFF here | |
| 1461 | − */ | |
| 1462 | − err = snd_hdac_display_power(bus, false); | |
| 1463 | − if (err < 0) { | |
| 1464 | − dev_err(bus->dev, | |
| 1465 | − "Cannot turn OFF display power on i915, err: %d\n", | |
| 1466 | − err); | |
| 1467 | − return err; | |
| 1468 | − } | |
| 1469 | − | |
| 1470 | − return 0; | |
| 1465 | + pm_runtime_put_sync(&edev->hdac.dev); | |
| 1471 | 1466 | } |
| 1472 | 1467 | #else |
| 1473 | −#define hdmi_codec_resume NULL | |
| 1468 | +#define hdmi_codec_prepare NULL | |
| 1469 | +#define hdmi_codec_complete NULL | |
| 1474 | 1470 | #endif |
| 1475 | 1471 | |
| 1476 | 1472 | static struct snd_soc_codec_driver hdmi_hda_codec = { |
| 1477 | 1473 | .probe = hdmi_codec_probe, |
| 1478 | 1474 | .remove = hdmi_codec_remove, |
| 1479 | − .resume = hdmi_codec_resume, | |
| 1480 | 1475 | .idle_bias_off = true, |
| 1481 | 1476 | }; |
| 1482 | 1477 | |
| @@ -1561,7 +1556,6 @@ static int hdac_hdmi_runtime_suspend(struct device *dev) · 78 unmodified lines | ||
| 1561 | 1556 | struct hdac_ext_device *edev = to_hda_ext_device(dev); |
| 1562 | 1557 | struct hdac_device *hdac = &edev->hdac; |
| 1563 | 1558 | struct hdac_bus *bus = hdac->bus; |
| 1564 | − unsigned long timeout; | |
| 1565 | 1559 | int err; |
| 1566 | 1560 | |
| 1567 | 1561 | dev_dbg(dev, "Enter: %s\n", __func__); |
| @@ -1570,20 +1564,15 @@ static int hdac_hdmi_runtime_suspend(struct device *dev) · 2 unmodified lines | ||
| 1570 | 1564 | if (!bus) |
| 1571 | 1565 | return 0; |
| 1572 | 1566 | |
| 1573 | − /* Power down afg */ | |
| 1574 | − if (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D3)) { | |
| 1575 | − snd_hdac_codec_write(hdac, hdac->afg, 0, | |
| 1576 | − AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | |
| 1577 | − | |
| 1578 | − /* Wait till power state is set to D3 */ | |
| 1579 | − timeout = jiffies + msecs_to_jiffies(1000); | |
| 1580 | − while (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D3) | |
| 1581 | − && time_before(jiffies, timeout)) { | |
| 1582 | − | |
| 1583 | − msleep(50); | |
| 1584 | − } | |
| 1585 | − } | |
| 1586 | − | |
| 1567 | + /* | |
| 1568 | + * Power down afg. | |
| 1569 | + * codec_read is preferred over codec_write to set the power state. | |
| 1570 | + * This way verb is send to set the power state and response | |
| 1571 | + * is received. So setting power state is ensured without using loop | |
| 1572 | + * to read the state. | |
| 1573 | + */ | |
| 1574 | + snd_hdac_codec_read(hdac, hdac->afg, 0, AC_VERB_SET_POWER_STATE, | |
| 1575 | + AC_PWRST_D3); | |
| 1587 | 1576 | err = snd_hdac_display_power(bus, false); |
| 1588 | 1577 | if (err < 0) { |
| 1589 | 1578 | dev_err(bus->dev, "Cannot turn on display power on i915\n"); |
| @@ -1616,9 +1605,8 @@ static int hdac_hdmi_runtime_resume(struct device *dev) · 26 unmodified lines | ||
| 1616 | 1605 | hdac_hdmi_skl_enable_dp12(&edev->hdac); |
| 1617 | 1606 | |
| 1618 | 1607 | /* Power up afg */ |
| 1619 | − if (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D0)) | |
| 1620 | − snd_hdac_codec_write(hdac, hdac->afg, 0, | |
| 1621 | − AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | |
| 1608 | + snd_hdac_codec_read(hdac, hdac->afg, 0, AC_VERB_SET_POWER_STATE, | |
| 1609 | + AC_PWRST_D0); | |
| 1622 | 1610 | |
| 1623 | 1611 | return 0; |
| 1624 | 1612 | } |
| @@ -1629,6 +1617,8 @@ static int hdac_hdmi_runtime_resume(struct device *dev) · 4 unmodified lines | ||
| 1629 | 1617 | |
| 1630 | 1618 | static const struct dev_pm_ops hdac_hdmi_pm = { |
| 1631 | 1619 | SET_RUNTIME_PM_OPS(hdac_hdmi_runtime_suspend, hdac_hdmi_runtime_resume, NULL) |
| 1620 | + .prepare = hdmi_codec_prepare, | |
| 1621 | + .complete = hdmi_codec_complete, | |
| 1632 | 1622 | }; |
| 1633 | 1623 | |
| 1634 | 1624 | static const struct hda_device_id hdmi_list[] = { |
| @@ -343,9 +343,12 @@ static const struct snd_soc_dapm_widget nau8825_dapm_widgets[] = { · 342 unmodified lines | ||
| 343 | 343 | SND_SOC_DAPM_SUPPLY("ADC Power", NAU8825_REG_ANALOG_ADC_2, 6, 0, NULL, |
| 344 | 344 | 0), |
| 345 | 345 | |
| 346 | − /* ADC for button press detection */ | |
| 347 | − SND_SOC_DAPM_ADC("SAR", NULL, NAU8825_REG_SAR_CTRL, | |
| 348 | − NAU8825_SAR_ADC_EN_SFT, 0), | |
| 346 | + /* ADC for button press detection. A dapm supply widget is used to | |
| 347 | + * prevent dapm_power_widgets keeping the codec at SND_SOC_BIAS_ON | |
| 348 | + * during suspend. | |
| 349 | + */ | |
| 350 | + SND_SOC_DAPM_SUPPLY("SAR", NAU8825_REG_SAR_CTRL, | |
| 351 | + NAU8825_SAR_ADC_EN_SFT, 0, NULL, 0), | |
| 349 | 352 | |
| 350 | 353 | SND_SOC_DAPM_PGA_S("ADACL", 2, NAU8825_REG_RDAC, 12, 0, NULL, 0), |
| 351 | 354 | SND_SOC_DAPM_PGA_S("ADACR", 2, NAU8825_REG_RDAC, 13, 0, NULL, 0), |
| @@ -607,6 +610,16 @@ static bool nau8825_is_jack_inserted(struct regmap *regmap) · 255 unmodified lines | ||
| 607 | 610 | |
| 608 | 611 | static void nau8825_restart_jack_detection(struct regmap *regmap) |
| 609 | 612 | { |
| 613 | + /* Chip needs one FSCLK cycle in order to generate interrupts, | |
| 614 | + * as we cannot guarantee one will be provided by the system. Turning | |
| 615 | + * master mode on then off enables us to generate that FSCLK cycle | |
| 616 | + * with a minimum of contention on the clock bus. | |
| 617 | + */ | |
| 618 | + regmap_update_bits(regmap, NAU8825_REG_I2S_PCM_CTRL2, | |
| 619 | + NAU8825_I2S_MS_MASK, NAU8825_I2S_MS_MASTER); | |
| 620 | + regmap_update_bits(regmap, NAU8825_REG_I2S_PCM_CTRL2, | |
| 621 | + NAU8825_I2S_MS_MASK, NAU8825_I2S_MS_SLAVE); | |
| 622 | + | |
| 610 | 623 | /* this will restart the entire jack detection process including MIC/GND |
| 611 | 624 | * switching and create interrupts. We have to go from 0 to 1 and back |
| 612 | 625 | * to 0 to restart. |
| @@ -728,7 +741,10 @@ static irqreturn_t nau8825_interrupt(int irq, void *data) · 115 unmodified lines | ||
| 728 | 741 | struct regmap *regmap = nau8825->regmap; |
| 729 | 742 | int active_irq, clear_irq = 0, event = 0, event_mask = 0; |
| 730 | 743 | |
| 731 | − regmap_read(regmap, NAU8825_REG_IRQ_STATUS, &active_irq); | |
| 744 | + if (regmap_read(regmap, NAU8825_REG_IRQ_STATUS, &active_irq)) { | |
| 745 | + dev_err(nau8825->dev, "failed to read irq status\n"); | |
| 746 | + return IRQ_NONE; | |
| 747 | + } | |
| 732 | 748 | |
| 733 | 749 | if ((active_irq & NAU8825_JACK_EJECTION_IRQ_MASK) == |
| 734 | 750 | NAU8825_JACK_EJECTION_DETECTED) { |
| @@ -1141,33 +1157,74 @@ static int nau8825_set_bias_level(struct snd_soc_codec *codec, · 406 unmodified lines | ||
| 1141 | 1157 | return ret; |
| 1142 | 1158 | } |
| 1143 | 1159 | } |
| 1144 | − | |
| 1145 | − ret = regcache_sync(nau8825->regmap); | |
| 1146 | − if (ret) { | |
| 1147 | − dev_err(codec->dev, | |
| 1148 | − "Failed to sync cache: %d\n", ret); | |
| 1149 | − return ret; | |
| 1150 | − } | |
| 1151 | 1160 | } |
| 1152 | − | |
| 1153 | 1161 | break; |
| 1154 | 1162 | |
| 1155 | 1163 | case SND_SOC_BIAS_OFF: |
| 1156 | 1164 | if (nau8825->mclk_freq) |
| 1157 | 1165 | clk_disable_unprepare(nau8825->mclk); |
| 1158 | − | |
| 1159 | − regcache_mark_dirty(nau8825->regmap); | |
| 1160 | 1166 | break; |
| 1161 | 1167 | } |
| 1162 | 1168 | return 0; |
| 1163 | 1169 | } |
| 1164 | 1170 | |
| 1171 | +#ifdef CONFIG_PM | |
| 1172 | +static int nau8825_suspend(struct snd_soc_codec *codec) | |
| 1173 | +{ | |
| 1174 | + struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec); | |
| 1175 | + | |
| 1176 | + disable_irq(nau8825->irq); | |
| 1177 | + regcache_cache_only(nau8825->regmap, true); | |
| 1178 | + regcache_mark_dirty(nau8825->regmap); | |
| 1179 | + | |
| 1180 | + return 0; | |
| 1181 | +} | |
| 1182 | + | |
| 1183 | +static int nau8825_resume(struct snd_soc_codec *codec) | |
| 1184 | +{ | |
| 1185 | + struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec); | |
| 1186 | + | |
| 1187 | + /* The chip may lose power and reset in S3. regcache_sync restores | |
| 1188 | + * register values including configurations for sysclk, irq, and | |
| 1189 | + * jack/button detection. | |
| 1190 | + */ | |
| 1191 | + regcache_cache_only(nau8825->regmap, false); | |
| 1192 | + regcache_sync(nau8825->regmap); | |
| 1193 | + | |
| 1194 | + /* Check the jack plug status directly. If the headset is unplugged | |
| 1195 | + * during S3 when the chip has no power, there will be no jack | |
| 1196 | + * detection irq even after the nau8825_restart_jack_detection below, | |
| 1197 | + * because the chip just thinks no headset has ever been plugged in. | |
| 1198 | + */ | |
| 1199 | + if (!nau8825_is_jack_inserted(nau8825->regmap)) { | |
| 1200 | + nau8825_eject_jack(nau8825); | |
| 1201 | + snd_soc_jack_report(nau8825->jack, 0, SND_JACK_HEADSET); | |
| 1202 | + } | |
| 1203 | + | |
| 1204 | + enable_irq(nau8825->irq); | |
| 1205 | + | |
| 1206 | + /* Run jack detection to check the type (OMTP or CTIA) of the headset | |
| 1207 | + * if there is one. This handles the case where a different type of | |
| 1208 | + * headset is plugged in during S3. This triggers an IRQ iff a headset | |
| 1209 | + * is already plugged in. | |
| 1210 | + */ | |
| 1211 | + nau8825_restart_jack_detection(nau8825->regmap); | |
| 1212 | + | |
| 1213 | + return 0; | |
| 1214 | +} | |
| 1215 | +#else | |
| 1216 | +#define nau8825_suspend NULL | |
| 1217 | +#define nau8825_resume NULL | |
| 1218 | +#endif | |
| 1219 | + | |
| 1165 | 1220 | static struct snd_soc_codec_driver nau8825_codec_driver = { |
| 1166 | 1221 | .probe = nau8825_codec_probe, |
| 1167 | 1222 | .set_sysclk = nau8825_set_sysclk, |
| 1168 | 1223 | .set_pll = nau8825_set_pll, |
| 1169 | 1224 | .set_bias_level = nau8825_set_bias_level, |
| 1170 | 1225 | .suspend_bias_off = true, |
| 1226 | + .suspend = nau8825_suspend, | |
| 1227 | + .resume = nau8825_resume, | |
| 1171 | 1228 | |
| 1172 | 1229 | .controls = nau8825_controls, |
| 1173 | 1230 | .num_controls = ARRAY_SIZE(nau8825_controls), |
| @@ -1277,16 +1334,6 @@ static int nau8825_setup_irq(struct nau8825 *nau8825) · 103 unmodified lines | ||
| 1277 | 1334 | regmap_update_bits(regmap, NAU8825_REG_ENA_CTRL, |
| 1278 | 1335 | NAU8825_ENABLE_DACR, NAU8825_ENABLE_DACR); |
| 1279 | 1336 | |
| 1280 | − /* Chip needs one FSCLK cycle in order to generate interrupts, | |
| 1281 | − * as we cannot guarantee one will be provided by the system. Turning | |
| 1282 | − * master mode on then off enables us to generate that FSCLK cycle | |
| 1283 | − * with a minimum of contention on the clock bus. | |
| 1284 | − */ | |
| 1285 | − regmap_update_bits(regmap, NAU8825_REG_I2S_PCM_CTRL2, | |
| 1286 | − NAU8825_I2S_MS_MASK, NAU8825_I2S_MS_MASTER); | |
| 1287 | − regmap_update_bits(regmap, NAU8825_REG_I2S_PCM_CTRL2, | |
| 1288 | − NAU8825_I2S_MS_MASK, NAU8825_I2S_MS_SLAVE); | |
| 1289 | − | |
| 1290 | 1337 | ret = devm_request_threaded_irq(nau8825->dev, nau8825->irq, NULL, |
| 1291 | 1338 | nau8825_interrupt, IRQF_TRIGGER_LOW | IRQF_ONESHOT, |
| 1292 | 1339 | "nau8825", nau8825); |
| @@ -1354,36 +1401,6 @@ static int nau8825_i2c_remove(struct i2c_client *client) · 61 unmodified lines | ||
| 1354 | 1401 | return 0; |
| 1355 | 1402 | } |
| 1356 | 1403 | |
| 1357 | −#ifdef CONFIG_PM_SLEEP | |
| 1358 | −static int nau8825_suspend(struct device *dev) | |
| 1359 | −{ | |
| 1360 | − struct i2c_client *client = to_i2c_client(dev); | |
| 1361 | − struct nau8825 *nau8825 = dev_get_drvdata(dev); | |
| 1362 | − | |
| 1363 | − disable_irq(client->irq); | |
| 1364 | − regcache_cache_only(nau8825->regmap, true); | |
| 1365 | − regcache_mark_dirty(nau8825->regmap); | |
| 1366 | − | |
| 1367 | − return 0; | |
| 1368 | −} | |
| 1369 | − | |
| 1370 | −static int nau8825_resume(struct device *dev) | |
| 1371 | −{ | |
| 1372 | − struct i2c_client *client = to_i2c_client(dev); | |
| 1373 | − struct nau8825 *nau8825 = dev_get_drvdata(dev); | |
| 1374 | − | |
| 1375 | − regcache_cache_only(nau8825->regmap, false); | |
| 1376 | − regcache_sync(nau8825->regmap); | |
| 1377 | − enable_irq(client->irq); | |
| 1378 | − | |
| 1379 | − return 0; | |
| 1380 | −} | |
| 1381 | −#endif | |
| 1382 | − | |
| 1383 | −static const struct dev_pm_ops nau8825_pm = { | |
| 1384 | − SET_SYSTEM_SLEEP_PM_OPS(nau8825_suspend, nau8825_resume) | |
| 1385 | −}; | |
| 1386 | − | |
| 1387 | 1404 | static const struct i2c_device_id nau8825_i2c_ids[] = { |
| 1388 | 1405 | { "nau8825", 0 }, |
| 1389 | 1406 | { } |
| @@ -1410,7 +1427,6 @@ static struct i2c_driver nau8825_driver = { · 20 unmodified lines | ||
| 1410 | 1427 | .name = "nau8825", |
| 1411 | 1428 | .of_match_table = of_match_ptr(nau8825_of_ids), |
| 1412 | 1429 | .acpi_match_table = ACPI_PTR(nau8825_acpi_match), |
| 1413 | − .pm = &nau8825_pm, | |
| 1414 | 1430 | }, |
| 1415 | 1431 | .probe = nau8825_i2c_probe, |
| 1416 | 1432 | .remove = nau8825_i2c_remove, |
| @@ -359,7 +359,7 @@ static const DECLARE_TLV_DB_RANGE(bst_tlv, · 358 unmodified lines | ||
| 359 | 359 | |
| 360 | 360 | /* Interface data select */ |
| 361 | 361 | static const char * const rt5640_data_select[] = { |
| 362 | − "Normal", "left copy to right", "right copy to left", "Swap"}; | |
| 362 | + "Normal", "Swap", "left copy to right", "right copy to left"}; | |
| 363 | 363 | |
| 364 | 364 | static SOC_ENUM_SINGLE_DECL(rt5640_if1_dac_enum, RT5640_DIG_INF_DATA, |
| 365 | 365 | RT5640_IF1_DAC_SEL_SFT, rt5640_data_select); |
| @@ -443,39 +443,39 @@ · 442 unmodified lines | ||
| 443 | 443 | #define RT5640_IF1_DAC_SEL_MASK (0x3 << 14) |
| 444 | 444 | #define RT5640_IF1_DAC_SEL_SFT 14 |
| 445 | 445 | #define RT5640_IF1_DAC_SEL_NOR (0x0 << 14) |
| 446 | −#define RT5640_IF1_DAC_SEL_L2R (0x1 << 14) | |
| 447 | −#define RT5640_IF1_DAC_SEL_R2L (0x2 << 14) | |
| 448 | −#define RT5640_IF1_DAC_SEL_SWAP (0x3 << 14) | |
| 446 | +#define RT5640_IF1_DAC_SEL_SWAP (0x1 << 14) | |
| 447 | +#define RT5640_IF1_DAC_SEL_L2R (0x2 << 14) | |
| 448 | +#define RT5640_IF1_DAC_SEL_R2L (0x3 << 14) | |
| 449 | 449 | #define RT5640_IF1_ADC_SEL_MASK (0x3 << 12) |
| 450 | 450 | #define RT5640_IF1_ADC_SEL_SFT 12 |
| 451 | 451 | #define RT5640_IF1_ADC_SEL_NOR (0x0 << 12) |
| 452 | −#define RT5640_IF1_ADC_SEL_L2R (0x1 << 12) | |
| 453 | −#define RT5640_IF1_ADC_SEL_R2L (0x2 << 12) | |
| 454 | −#define RT5640_IF1_ADC_SEL_SWAP (0x3 << 12) | |
| 452 | +#define RT5640_IF1_ADC_SEL_SWAP (0x1 << 12) | |
| 453 | +#define RT5640_IF1_ADC_SEL_L2R (0x2 << 12) | |
| 454 | +#define RT5640_IF1_ADC_SEL_R2L (0x3 << 12) | |
| 455 | 455 | #define RT5640_IF2_DAC_SEL_MASK (0x3 << 10) |
| 456 | 456 | #define RT5640_IF2_DAC_SEL_SFT 10 |
| 457 | 457 | #define RT5640_IF2_DAC_SEL_NOR (0x0 << 10) |
| 458 | −#define RT5640_IF2_DAC_SEL_L2R (0x1 << 10) | |
| 459 | −#define RT5640_IF2_DAC_SEL_R2L (0x2 << 10) | |
| 460 | −#define RT5640_IF2_DAC_SEL_SWAP (0x3 << 10) | |
| 458 | +#define RT5640_IF2_DAC_SEL_SWAP (0x1 << 10) | |
| 459 | +#define RT5640_IF2_DAC_SEL_L2R (0x2 << 10) | |
| 460 | +#define RT5640_IF2_DAC_SEL_R2L (0x3 << 10) | |
| 461 | 461 | #define RT5640_IF2_ADC_SEL_MASK (0x3 << 8) |
| 462 | 462 | #define RT5640_IF2_ADC_SEL_SFT 8 |
| 463 | 463 | #define RT5640_IF2_ADC_SEL_NOR (0x0 << 8) |
| 464 | −#define RT5640_IF2_ADC_SEL_L2R (0x1 << 8) | |
| 465 | −#define RT5640_IF2_ADC_SEL_R2L (0x2 << 8) | |
| 466 | −#define RT5640_IF2_ADC_SEL_SWAP (0x3 << 8) | |
| 464 | +#define RT5640_IF2_ADC_SEL_SWAP (0x1 << 8) | |
| 465 | +#define RT5640_IF2_ADC_SEL_L2R (0x2 << 8) | |
| 466 | +#define RT5640_IF2_ADC_SEL_R2L (0x3 << 8) | |
| 467 | 467 | #define RT5640_IF3_DAC_SEL_MASK (0x3 << 6) |
| 468 | 468 | #define RT5640_IF3_DAC_SEL_SFT 6 |
| 469 | 469 | #define RT5640_IF3_DAC_SEL_NOR (0x0 << 6) |
| 470 | −#define RT5640_IF3_DAC_SEL_L2R (0x1 << 6) | |
| 471 | −#define RT5640_IF3_DAC_SEL_R2L (0x2 << 6) | |
| 472 | −#define RT5640_IF3_DAC_SEL_SWAP (0x3 << 6) | |
| 470 | +#define RT5640_IF3_DAC_SEL_SWAP (0x1 << 6) | |
| 471 | +#define RT5640_IF3_DAC_SEL_L2R (0x2 << 6) | |
| 472 | +#define RT5640_IF3_DAC_SEL_R2L (0x3 << 6) | |
| 473 | 473 | #define RT5640_IF3_ADC_SEL_MASK (0x3 << 4) |
| 474 | 474 | #define RT5640_IF3_ADC_SEL_SFT 4 |
| 475 | 475 | #define RT5640_IF3_ADC_SEL_NOR (0x0 << 4) |
| 476 | −#define RT5640_IF3_ADC_SEL_L2R (0x1 << 4) | |
| 477 | −#define RT5640_IF3_ADC_SEL_R2L (0x2 << 4) | |
| 478 | −#define RT5640_IF3_ADC_SEL_SWAP (0x3 << 4) | |
| 476 | +#define RT5640_IF3_ADC_SEL_SWAP (0x1 << 4) | |
| 477 | +#define RT5640_IF3_ADC_SEL_L2R (0x2 << 4) | |
| 478 | +#define RT5640_IF3_ADC_SEL_R2L (0x3 << 4) | |
| 479 | 479 | |
| 480 | 480 | /* REC Left Mixer Control 1 (0x3b) */ |
| 481 | 481 | #define RT5640_G_HP_L_RM_L_MASK (0x7 << 13) |
| @@ -1955,11 +1955,16 @@ err_adsp2_codec_probe: · 1954 unmodified lines | ||
| 1955 | 1955 | static int wm5102_codec_remove(struct snd_soc_codec *codec) |
| 1956 | 1956 | { |
| 1957 | 1957 | struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec); |
| 1958 | + struct arizona *arizona = priv->core.arizona; | |
| 1958 | 1959 | |
| 1959 | 1960 | wm_adsp2_codec_remove(&priv->core.adsp[0], codec); |
| 1960 | 1961 | |
| 1961 | 1962 | priv->core.arizona->dapm = NULL; |
| 1962 | 1963 | |
| 1964 | + arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, priv); | |
| 1965 | + | |
| 1966 | + arizona_free_spk(codec); | |
| 1967 | + | |
| 1963 | 1968 | return 0; |
| 1964 | 1969 | } |
| 1965 | 1970 | |
| @@ -2298,6 +2298,8 @@ static int wm5110_codec_remove(struct snd_soc_codec *codec) · 2297 unmodified lines | ||
| 2298 | 2298 | |
| 2299 | 2299 | arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, priv); |
| 2300 | 2300 | |
| 2301 | + arizona_free_spk(codec); | |
| 2302 | + | |
| 2301 | 2303 | return 0; |
| 2302 | 2304 | } |
| 2303 | 2305 | |
| @@ -2471,7 +2471,7 @@ static void wm8962_configure_bclk(struct snd_soc_codec *codec) · 2470 unmodified lines | ||
| 2471 | 2471 | break; |
| 2472 | 2472 | default: |
| 2473 | 2473 | dev_warn(codec->dev, "Unknown DSPCLK divisor read back\n"); |
| 2474 | − dspclk = wm8962->sysclk; | |
| 2474 | + dspclk = wm8962->sysclk_rate; | |
| 2475 | 2475 | } |
| 2476 | 2476 | |
| 2477 | 2477 | dev_dbg(codec->dev, "DSPCLK is %dHz, BCLK %d\n", dspclk, wm8962->bclk); |
| @@ -1072,6 +1072,8 @@ static int wm8997_codec_remove(struct snd_soc_codec *codec) · 1071 unmodified lines | ||
| 1072 | 1072 | |
| 1073 | 1073 | priv->core.arizona->dapm = NULL; |
| 1074 | 1074 | |
| 1075 | + arizona_free_spk(codec); | |
| 1076 | + | |
| 1075 | 1077 | return 0; |
| 1076 | 1078 | } |
| 1077 | 1079 | |
| @@ -1324,6 +1324,8 @@ static int wm8998_codec_remove(struct snd_soc_codec *codec) · 1323 unmodified lines | ||
| 1324 | 1324 | |
| 1325 | 1325 | priv->core.arizona->dapm = NULL; |
| 1326 | 1326 | |
| 1327 | + arizona_free_spk(codec); | |
| 1328 | + | |
| 1327 | 1329 | return 0; |
| 1328 | 1330 | } |
| 1329 | 1331 | |
| @@ -163,7 +163,6 @@ config SND_SOC_INTEL_SKYLAKE · 162 unmodified lines | ||
| 163 | 163 | tristate |
| 164 | 164 | select SND_HDA_EXT_CORE |
| 165 | 165 | select SND_SOC_TOPOLOGY |
| 166 | − select SND_HDA_I915 | |
| 167 | 166 | select SND_SOC_INTEL_SST |
| 168 | 167 | |
| 169 | 168 | config SND_SOC_INTEL_SKL_RT286_MACH |
| @@ -1345,7 +1345,7 @@ int sst_hsw_stream_reset(struct sst_hsw *hsw, struct sst_hsw_stream *stream) · 1344 unmodified lines | ||
| 1345 | 1345 | return 0; |
| 1346 | 1346 | |
| 1347 | 1347 | /* wait for pause to complete before we reset the stream */ |
| 1348 | − while (stream->running && tries--) | |
| 1348 | + while (stream->running && --tries) | |
| 1349 | 1349 | msleep(1); |
| 1350 | 1350 | if (!tries) { |
| 1351 | 1351 | dev_err(hsw->dev, "error: reset stream %d still running\n", |
| @@ -336,6 +336,11 @@ void skl_dsp_free(struct sst_dsp *dsp) · 335 unmodified lines | ||
| 336 | 336 | skl_ipc_int_disable(dsp); |
| 337 | 337 | |
| 338 | 338 | free_irq(dsp->irq, dsp); |
| 339 | + dsp->cl_dev.ops.cl_cleanup_controller(dsp); | |
| 340 | + skl_cldma_int_disable(dsp); | |
| 341 | + skl_ipc_op_int_disable(dsp); | |
| 342 | + skl_ipc_int_disable(dsp); | |
| 343 | + | |
| 339 | 344 | skl_dsp_disable_core(dsp); |
| 340 | 345 | } |
| 341 | 346 | EXPORT_SYMBOL_GPL(skl_dsp_free); |
| @@ -239,6 +239,7 @@ static void skl_tplg_update_buffer_size(struct skl_sst *ctx, · 238 unmodified lines | ||
| 239 | 239 | { |
| 240 | 240 | int multiplier = 1; |
| 241 | 241 | struct skl_module_fmt *in_fmt, *out_fmt; |
| 242 | + int in_rate, out_rate; | |
| 242 | 243 | |
| 243 | 244 | |
| 244 | 245 | /* Since fixups is applied to pin 0 only, ibs, obs needs |
| @@ -249,15 +250,24 @@ static void skl_tplg_update_buffer_size(struct skl_sst *ctx, · 4 unmodified lines | ||
| 249 | 250 | |
| 250 | 251 | if (mcfg->m_type == SKL_MODULE_TYPE_SRCINT) |
| 251 | 252 | multiplier = 5; |
| 252 | − mcfg->ibs = (in_fmt->s_freq / 1000) * | |
| 253 | − (mcfg->in_fmt->channels) * | |
| 254 | − (mcfg->in_fmt->bit_depth >> 3) * | |
| 255 | − multiplier; | |
| 256 | − | |
| 257 | − mcfg->obs = (mcfg->out_fmt->s_freq / 1000) * | |
| 258 | − (mcfg->out_fmt->channels) * | |
| 259 | − (mcfg->out_fmt->bit_depth >> 3) * | |
| 260 | − multiplier; | |
| 253 | + | |
| 254 | + if (in_fmt->s_freq % 1000) | |
| 255 | + in_rate = (in_fmt->s_freq / 1000) + 1; | |
| 256 | + else | |
| 257 | + in_rate = (in_fmt->s_freq / 1000); | |
| 258 | + | |
| 259 | + mcfg->ibs = in_rate * (mcfg->in_fmt->channels) * | |
| 260 | + (mcfg->in_fmt->bit_depth >> 3) * | |
| 261 | + multiplier; | |
| 262 | + | |
| 263 | + if (mcfg->out_fmt->s_freq % 1000) | |
| 264 | + out_rate = (mcfg->out_fmt->s_freq / 1000) + 1; | |
| 265 | + else | |
| 266 | + out_rate = (mcfg->out_fmt->s_freq / 1000); | |
| 267 | + | |
| 268 | + mcfg->obs = out_rate * (mcfg->out_fmt->channels) * | |
| 269 | + (mcfg->out_fmt->bit_depth >> 3) * | |
| 270 | + multiplier; | |
| 261 | 271 | } |
| 262 | 272 | |
| 263 | 273 | static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w, |
| @@ -485,11 +495,15 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe) · 221 unmodified lines | ||
| 485 | 495 | if (!skl_is_pipe_mcps_avail(skl, mconfig)) |
| 486 | 496 | return -ENOMEM; |
| 487 | 497 | |
| 498 | + skl_tplg_alloc_pipe_mcps(skl, mconfig); | |
| 499 | + | |
| 488 | 500 | if (mconfig->is_loadable && ctx->dsp->fw_ops.load_mod) { |
| 489 | 501 | ret = ctx->dsp->fw_ops.load_mod(ctx->dsp, |
| 490 | 502 | mconfig->id.module_id, mconfig->guid); |
| 491 | 503 | if (ret < 0) |
| 492 | 504 | return ret; |
| 505 | + | |
| 506 | + mconfig->m_state = SKL_MODULE_LOADED; | |
| 493 | 507 | } |
| 494 | 508 | |
| 495 | 509 | /* update blob if blob is null for be with default value */ |
| @@ -509,7 +523,6 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe) · 13 unmodified lines | ||
| 509 | 523 | ret = skl_tplg_set_module_params(w, ctx); |
| 510 | 524 | if (ret < 0) |
| 511 | 525 | return ret; |
| 512 | − skl_tplg_alloc_pipe_mcps(skl, mconfig); | |
| 513 | 526 | } |
| 514 | 527 | |
| 515 | 528 | return 0; |
| @@ -524,7 +537,8 @@ static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx, · 8 unmodified lines | ||
| 524 | 537 | list_for_each_entry(w_module, &pipe->w_list, node) { |
| 525 | 538 | mconfig = w_module->w->priv; |
| 526 | 539 | |
| 527 | − if (mconfig->is_loadable && ctx->dsp->fw_ops.unload_mod) | |
| 540 | + if (mconfig->is_loadable && ctx->dsp->fw_ops.unload_mod && | |
| 541 | + mconfig->m_state > SKL_MODULE_UNINIT) | |
| 528 | 542 | return ctx->dsp->fw_ops.unload_mod(ctx->dsp, |
| 529 | 543 | mconfig->id.module_id); |
| 530 | 544 | } |
| @@ -558,6 +572,9 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, · 27 unmodified lines | ||
| 558 | 572 | if (!skl_is_pipe_mem_avail(skl, mconfig)) |
| 559 | 573 | return -ENOMEM; |
| 560 | 574 | |
| 575 | + skl_tplg_alloc_pipe_mem(skl, mconfig); | |
| 576 | + skl_tplg_alloc_pipe_mcps(skl, mconfig); | |
| 577 | + | |
| 561 | 578 | /* |
| 562 | 579 | * Create a list of modules for pipe. |
| 563 | 580 | * This list contains modules from source to sink |
| @@ -601,9 +618,6 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, · 37 unmodified lines | ||
| 601 | 618 | src_module = dst_module; |
| 602 | 619 | } |
| 603 | 620 | |
| 604 | − skl_tplg_alloc_pipe_mem(skl, mconfig); | |
| 605 | − skl_tplg_alloc_pipe_mcps(skl, mconfig); | |
| 606 | − | |
| 607 | 621 | return 0; |
| 608 | 622 | } |
| 609 | 623 | |
| @@ -274,10 +274,10 @@ struct skl_pipe { · 273 unmodified lines | ||
| 274 | 274 | |
| 275 | 275 | enum skl_module_state { |
| 276 | 276 | SKL_MODULE_UNINIT = 0, |
| 277 | − SKL_MODULE_INIT_DONE = 1, | |
| 278 | − SKL_MODULE_LOADED = 2, | |
| 279 | − SKL_MODULE_UNLOADED = 3, | |
| 280 | − SKL_MODULE_BIND_DONE = 4 | |
| 277 | + SKL_MODULE_LOADED = 1, | |
| 278 | + SKL_MODULE_INIT_DONE = 2, | |
| 279 | + SKL_MODULE_BIND_DONE = 3, | |
| 280 | + SKL_MODULE_UNLOADED = 4, | |
| 281 | 281 | }; |
| 282 | 282 | |
| 283 | 283 | struct skl_module_cfg { |
| @@ -222,6 +222,7 @@ static int skl_suspend(struct device *dev) · 221 unmodified lines | ||
| 222 | 222 | struct hdac_ext_bus *ebus = pci_get_drvdata(pci); |
| 223 | 223 | struct skl *skl = ebus_to_skl(ebus); |
| 224 | 224 | struct hdac_bus *bus = ebus_to_hbus(ebus); |
| 225 | + int ret = 0; | |
| 225 | 226 | |
| 226 | 227 | /* |
| 227 | 228 | * Do not suspend if streams which are marked ignore suspend are |
| @@ -232,10 +233,20 @@ static int skl_suspend(struct device *dev) · 4 unmodified lines | ||
| 232 | 233 | enable_irq_wake(bus->irq); |
| 233 | 234 | pci_save_state(pci); |
| 234 | 235 | pci_disable_device(pci); |
| 235 | − return 0; | |
| 236 | 236 | } else { |
| 237 | − return _skl_suspend(ebus); | |
| 237 | + ret = _skl_suspend(ebus); | |
| 238 | + if (ret < 0) | |
| 239 | + return ret; | |
| 240 | + } | |
| 241 | + | |
| 242 | + if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) { | |
| 243 | + ret = snd_hdac_display_power(bus, false); | |
| 244 | + if (ret < 0) | |
| 245 | + dev_err(bus->dev, | |
| 246 | + "Cannot turn OFF display power on i915\n"); | |
| 238 | 247 | } |
| 248 | + | |
| 249 | + return ret; | |
| 239 | 250 | } |
| 240 | 251 | |
| 241 | 252 | static int skl_resume(struct device *dev) |
| @@ -316,17 +327,20 @@ static int skl_free(struct hdac_ext_bus *ebus) · 74 unmodified lines | ||
| 316 | 327 | |
| 317 | 328 | if (bus->irq >= 0) |
| 318 | 329 | free_irq(bus->irq, (void *)bus); |
| 319 | − if (bus->remap_addr) | |
| 320 | − iounmap(bus->remap_addr); | |
| 321 | − | |
| 322 | 330 | snd_hdac_bus_free_stream_pages(bus); |
| 323 | 331 | snd_hdac_stream_free_all(ebus); |
| 324 | 332 | snd_hdac_link_free_all(ebus); |
| 333 | + | |
| 334 | + if (bus->remap_addr) | |
| 335 | + iounmap(bus->remap_addr); | |
| 336 | + | |
| 325 | 337 | pci_release_regions(skl->pci); |
| 326 | 338 | pci_disable_device(skl->pci); |
| 327 | 339 | |
| 328 | 340 | snd_hdac_ext_bus_exit(ebus); |
| 329 | 341 | |
| 342 | + if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) | |
| 343 | + snd_hdac_i915_exit(&ebus->bus); | |
| 330 | 344 | return 0; |
| 331 | 345 | } |
| 332 | 346 | |
| @@ -719,12 +733,12 @@ static void skl_remove(struct pci_dev *pci) · 386 unmodified lines | ||
| 719 | 733 | if (skl->tplg) |
| 720 | 734 | release_firmware(skl->tplg); |
| 721 | 735 | |
| 722 | − if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) | |
| 723 | − snd_hdac_i915_exit(&ebus->bus); | |
| 724 | − | |
| 725 | 736 | if (pci_dev_run_wake(pci)) |
| 726 | 737 | pm_runtime_get_noresume(&pci->dev); |
| 727 | − pci_dev_put(pci); | |
| 738 | + | |
| 739 | + /* codec removal, invoke bus_device_remove */ | |
| 740 | + snd_hdac_ext_bus_device_remove(ebus); | |
| 741 | + | |
| 728 | 742 | skl_platform_unregister(&pci->dev); |
| 729 | 743 | skl_free_dsp(skl); |
| 730 | 744 | skl_machine_device_unregister(skl); |
| @@ -2188,6 +2188,13 @@ static ssize_t dapm_widget_show_component(struct snd_soc_component *cmpnt, · 2187 unmodified lines | ||
| 2188 | 2188 | int count = 0; |
| 2189 | 2189 | char *state = "not set"; |
| 2190 | 2190 | |
| 2191 | + /* card won't be set for the dummy component, as a spot fix | |
| 2192 | + * we're checking for that case specifically here but in future | |
| 2193 | + * we will ensure that the dummy component looks like others. | |
| 2194 | + */ | |
| 2195 | + if (!cmpnt->card) | |
| 2196 | + return 0; | |
| 2197 | + | |
| 2191 | 2198 | list_for_each_entry(w, &cmpnt->card->widgets, list) { |
| 2192 | 2199 | if (w->dapm != dapm) |
| 2193 | 2200 | continue; |