Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net

This commit is contained in:
David S. Miller 2016-01-06 22:54:18 -05:00
commit 9e0efaf6b4
32 changed files with 173 additions and 134 deletions

View File

@ -1,7 +1,7 @@
VERSION = 4 VERSION = 4
PATCHLEVEL = 4 PATCHLEVEL = 4
SUBLEVEL = 0 SUBLEVEL = 0
EXTRAVERSION = -rc7 EXTRAVERSION = -rc8
NAME = Blurry Fish Butt NAME = Blurry Fish Butt
# *DOCUMENTATION* # *DOCUMENTATION*

View File

@ -187,19 +187,6 @@ static inline int mem_words_used(struct jit_ctx *ctx)
return fls(ctx->seen & SEEN_MEM); return fls(ctx->seen & SEEN_MEM);
} }
static inline bool is_load_to_a(u16 inst)
{
switch (inst) {
case BPF_LD | BPF_W | BPF_LEN:
case BPF_LD | BPF_W | BPF_ABS:
case BPF_LD | BPF_H | BPF_ABS:
case BPF_LD | BPF_B | BPF_ABS:
return true;
default:
return false;
}
}
static void jit_fill_hole(void *area, unsigned int size) static void jit_fill_hole(void *area, unsigned int size)
{ {
u32 *ptr; u32 *ptr;
@ -211,7 +198,6 @@ static void jit_fill_hole(void *area, unsigned int size)
static void build_prologue(struct jit_ctx *ctx) static void build_prologue(struct jit_ctx *ctx)
{ {
u16 reg_set = saved_regs(ctx); u16 reg_set = saved_regs(ctx);
u16 first_inst = ctx->skf->insns[0].code;
u16 off; u16 off;
#ifdef CONFIG_FRAME_POINTER #ifdef CONFIG_FRAME_POINTER
@ -241,7 +227,7 @@ static void build_prologue(struct jit_ctx *ctx)
emit(ARM_MOV_I(r_X, 0), ctx); emit(ARM_MOV_I(r_X, 0), ctx);
/* do not leak kernel data to userspace */ /* do not leak kernel data to userspace */
if ((first_inst != (BPF_RET | BPF_K)) && !(is_load_to_a(first_inst))) if (bpf_needs_clear_a(&ctx->skf->insns[0]))
emit(ARM_MOV_I(r_A, 0), ctx); emit(ARM_MOV_I(r_A, 0), ctx);
/* stack space for the BPF_MEM words */ /* stack space for the BPF_MEM words */
@ -770,7 +756,8 @@ load_ind:
case BPF_ALU | BPF_RSH | BPF_K: case BPF_ALU | BPF_RSH | BPF_K:
if (unlikely(k > 31)) if (unlikely(k > 31))
return -1; return -1;
emit(ARM_LSR_I(r_A, r_A, k), ctx); if (k)
emit(ARM_LSR_I(r_A, r_A, k), ctx);
break; break;
case BPF_ALU | BPF_RSH | BPF_X: case BPF_ALU | BPF_RSH | BPF_X:
update_on_xread(ctx); update_on_xread(ctx);

View File

@ -521,19 +521,6 @@ static inline u16 align_sp(unsigned int num)
return num; return num;
} }
static bool is_load_to_a(u16 inst)
{
switch (inst) {
case BPF_LD | BPF_W | BPF_LEN:
case BPF_LD | BPF_W | BPF_ABS:
case BPF_LD | BPF_H | BPF_ABS:
case BPF_LD | BPF_B | BPF_ABS:
return true;
default:
return false;
}
}
static void save_bpf_jit_regs(struct jit_ctx *ctx, unsigned offset) static void save_bpf_jit_regs(struct jit_ctx *ctx, unsigned offset)
{ {
int i = 0, real_off = 0; int i = 0, real_off = 0;
@ -614,7 +601,6 @@ static unsigned int get_stack_depth(struct jit_ctx *ctx)
static void build_prologue(struct jit_ctx *ctx) static void build_prologue(struct jit_ctx *ctx)
{ {
u16 first_inst = ctx->skf->insns[0].code;
int sp_off; int sp_off;
/* Calculate the total offset for the stack pointer */ /* Calculate the total offset for the stack pointer */
@ -641,7 +627,7 @@ static void build_prologue(struct jit_ctx *ctx)
emit_jit_reg_move(r_X, r_zero, ctx); emit_jit_reg_move(r_X, r_zero, ctx);
/* Do not leak kernel data to userspace */ /* Do not leak kernel data to userspace */
if ((first_inst != (BPF_RET | BPF_K)) && !(is_load_to_a(first_inst))) if (bpf_needs_clear_a(&ctx->skf->insns[0]))
emit_jit_reg_move(r_A, r_zero, ctx); emit_jit_reg_move(r_A, r_zero, ctx);
} }

View File

@ -26,7 +26,7 @@ aflags-vdso := $(ccflags-vdso) \
# the comments on that file. # the comments on that file.
# #
ifndef CONFIG_CPU_MIPSR6 ifndef CONFIG_CPU_MIPSR6
ifeq ($(call ld-ifversion, -lt, 22500000, y),) ifeq ($(call ld-ifversion, -lt, 22500000, y),y)
$(warning MIPS VDSO requires binutils >= 2.25) $(warning MIPS VDSO requires binutils >= 2.25)
obj-vdso-y := $(filter-out gettimeofday.o, $(obj-vdso-y)) obj-vdso-y := $(filter-out gettimeofday.o, $(obj-vdso-y))
ccflags-vdso += -DDISABLE_MIPS_VDSO ccflags-vdso += -DDISABLE_MIPS_VDSO

View File

@ -78,18 +78,9 @@ static void bpf_jit_build_prologue(struct bpf_prog *fp, u32 *image,
PPC_LI(r_X, 0); PPC_LI(r_X, 0);
} }
switch (filter[0].code) { /* make sure we dont leak kernel information to user */
case BPF_RET | BPF_K: if (bpf_needs_clear_a(&filter[0]))
case BPF_LD | BPF_W | BPF_LEN:
case BPF_LD | BPF_W | BPF_ABS:
case BPF_LD | BPF_H | BPF_ABS:
case BPF_LD | BPF_B | BPF_ABS:
/* first instruction sets A register (or is RET 'constant') */
break;
default:
/* make sure we dont leak kernel information to user */
PPC_LI(r_A, 0); PPC_LI(r_A, 0);
}
} }
static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx) static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)

View File

@ -420,22 +420,9 @@ void bpf_jit_compile(struct bpf_prog *fp)
} }
emit_reg_move(O7, r_saved_O7); emit_reg_move(O7, r_saved_O7);
switch (filter[0].code) { /* Make sure we dont leak kernel information to the user. */
case BPF_RET | BPF_K: if (bpf_needs_clear_a(&filter[0]))
case BPF_LD | BPF_W | BPF_LEN:
case BPF_LD | BPF_W | BPF_ABS:
case BPF_LD | BPF_H | BPF_ABS:
case BPF_LD | BPF_B | BPF_ABS:
/* The first instruction sets the A register (or is
* a "RET 'constant'")
*/
break;
default:
/* Make sure we dont leak kernel information to the
* user.
*/
emit_clear(r_A); /* A = 0 */ emit_clear(r_A); /* A = 0 */
}
for (i = 0; i < flen; i++) { for (i = 0; i < flen; i++) {
unsigned int K = filter[i].k; unsigned int K = filter[i].k;

View File

@ -176,8 +176,6 @@ config NR_CPUS
smaller kernel memory footprint results from using a smaller smaller kernel memory footprint results from using a smaller
value on chips with fewer tiles. value on chips with fewer tiles.
if TILEGX
choice choice
prompt "Kernel page size" prompt "Kernel page size"
default PAGE_SIZE_64KB default PAGE_SIZE_64KB
@ -188,8 +186,11 @@ choice
connections, etc., it may be better to select 16KB, which uses connections, etc., it may be better to select 16KB, which uses
memory more efficiently at some cost in TLB performance. memory more efficiently at some cost in TLB performance.
Note that this option is TILE-Gx specific; currently Note that for TILEPro, you must also rebuild the hypervisor
TILEPro page size is set by rebuilding the hypervisor. with a matching page size.
config PAGE_SIZE_4KB
bool "4KB" if TILEPRO
config PAGE_SIZE_16KB config PAGE_SIZE_16KB
bool "16KB" bool "16KB"
@ -199,8 +200,6 @@ config PAGE_SIZE_64KB
endchoice endchoice
endif
source "kernel/Kconfig.hz" source "kernel/Kconfig.hz"
config KEXEC config KEXEC

View File

@ -20,15 +20,17 @@
#include <arch/chip.h> #include <arch/chip.h>
/* PAGE_SHIFT and HPAGE_SHIFT determine the page sizes. */ /* PAGE_SHIFT and HPAGE_SHIFT determine the page sizes. */
#if defined(CONFIG_PAGE_SIZE_16KB) #if defined(CONFIG_PAGE_SIZE_4KB) /* tilepro only */
#define PAGE_SHIFT 12
#define CTX_PAGE_FLAG HV_CTX_PG_SM_4K
#elif defined(CONFIG_PAGE_SIZE_16KB)
#define PAGE_SHIFT 14 #define PAGE_SHIFT 14
#define CTX_PAGE_FLAG HV_CTX_PG_SM_16K #define CTX_PAGE_FLAG HV_CTX_PG_SM_16K
#elif defined(CONFIG_PAGE_SIZE_64KB) #elif defined(CONFIG_PAGE_SIZE_64KB)
#define PAGE_SHIFT 16 #define PAGE_SHIFT 16
#define CTX_PAGE_FLAG HV_CTX_PG_SM_64K #define CTX_PAGE_FLAG HV_CTX_PG_SM_64K
#else #else
#define PAGE_SHIFT HV_LOG2_DEFAULT_PAGE_SIZE_SMALL #error Page size not specified in Kconfig
#define CTX_PAGE_FLAG 0
#endif #endif
#define HPAGE_SHIFT HV_LOG2_DEFAULT_PAGE_SIZE_LARGE #define HPAGE_SHIFT HV_LOG2_DEFAULT_PAGE_SIZE_LARGE

View File

@ -179,26 +179,21 @@ static int cn_call_callback(struct sk_buff *skb)
* *
* It checks skb, netlink header and msg sizes, and calls callback helper. * It checks skb, netlink header and msg sizes, and calls callback helper.
*/ */
static void cn_rx_skb(struct sk_buff *__skb) static void cn_rx_skb(struct sk_buff *skb)
{ {
struct nlmsghdr *nlh; struct nlmsghdr *nlh;
struct sk_buff *skb;
int len, err; int len, err;
skb = skb_get(__skb);
if (skb->len >= NLMSG_HDRLEN) { if (skb->len >= NLMSG_HDRLEN) {
nlh = nlmsg_hdr(skb); nlh = nlmsg_hdr(skb);
len = nlmsg_len(nlh); len = nlmsg_len(nlh);
if (len < (int)sizeof(struct cn_msg) || if (len < (int)sizeof(struct cn_msg) ||
skb->len < nlh->nlmsg_len || skb->len < nlh->nlmsg_len ||
len > CONNECTOR_MAX_MSG_SIZE) { len > CONNECTOR_MAX_MSG_SIZE)
kfree_skb(skb);
return; return;
}
err = cn_call_callback(skb); err = cn_call_callback(skb_get(skb));
if (err < 0) if (err < 0)
kfree_skb(skb); kfree_skb(skb);
} }

View File

@ -12123,18 +12123,22 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc,
static bool check_digital_port_conflicts(struct drm_atomic_state *state) static bool check_digital_port_conflicts(struct drm_atomic_state *state)
{ {
struct drm_device *dev = state->dev; struct drm_device *dev = state->dev;
struct intel_encoder *encoder;
struct drm_connector *connector; struct drm_connector *connector;
struct drm_connector_state *connector_state;
unsigned int used_ports = 0; unsigned int used_ports = 0;
int i;
/* /*
* Walk the connector list instead of the encoder * Walk the connector list instead of the encoder
* list to detect the problem on ddi platforms * list to detect the problem on ddi platforms
* where there's just one encoder per digital port. * where there's just one encoder per digital port.
*/ */
for_each_connector_in_state(state, connector, connector_state, i) { drm_for_each_connector(connector, dev) {
struct drm_connector_state *connector_state;
struct intel_encoder *encoder;
connector_state = drm_atomic_get_existing_connector_state(state, connector);
if (!connector_state)
connector_state = connector->state;
if (!connector_state->best_encoder) if (!connector_state->best_encoder)
continue; continue;

View File

@ -1381,7 +1381,7 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
for (try = 0; !live_status && try < 4; try++) { for (try = 0; !live_status && try < 9; try++) {
if (try) if (try)
msleep(10); msleep(10);
live_status = intel_digital_port_connected(dev_priv, live_status = intel_digital_port_connected(dev_priv,

View File

@ -306,6 +306,10 @@ struct clip_tbl *t4_init_clip_tbl(unsigned int clipt_start,
INIT_LIST_HEAD(&ctbl->hash_list[i]); INIT_LIST_HEAD(&ctbl->hash_list[i]);
cl_list = t4_alloc_mem(clipt_size*sizeof(struct clip_entry)); cl_list = t4_alloc_mem(clipt_size*sizeof(struct clip_entry));
if (!cl_list) {
t4_free_mem(ctbl);
return NULL;
}
ctbl->cl_list = (void *)cl_list; ctbl->cl_list = (void *)cl_list;
for (i = 0; i < clipt_size; i++) { for (i = 0; i < clipt_size; i++) {

View File

@ -772,8 +772,10 @@ int qlcnic_82xx_config_intrpt(struct qlcnic_adapter *adapter, u8 op_type)
int i, err = 0; int i, err = 0;
for (i = 0; i < ahw->num_msix; i++) { for (i = 0; i < ahw->num_msix; i++) {
qlcnic_alloc_mbx_args(&cmd, adapter, err = qlcnic_alloc_mbx_args(&cmd, adapter,
QLCNIC_CMD_MQ_TX_CONFIG_INTR); QLCNIC_CMD_MQ_TX_CONFIG_INTR);
if (err)
return err;
type = op_type ? QLCNIC_INTRPT_ADD : QLCNIC_INTRPT_DEL; type = op_type ? QLCNIC_INTRPT_ADD : QLCNIC_INTRPT_DEL;
val = type | (ahw->intr_tbl[i].type << 4); val = type | (ahw->intr_tbl[i].type << 4);
if (ahw->intr_tbl[i].type == QLCNIC_INTRPT_MSIX) if (ahw->intr_tbl[i].type == QLCNIC_INTRPT_MSIX)

View File

@ -683,6 +683,12 @@ static void sixpack_close(struct tty_struct *tty)
if (!atomic_dec_and_test(&sp->refcnt)) if (!atomic_dec_and_test(&sp->refcnt))
down(&sp->dead_sem); down(&sp->dead_sem);
/* We must stop the queue to avoid potentially scribbling
* on the free buffers. The sp->dead_sem is not sufficient
* to protect us from sp->xbuff access.
*/
netif_stop_queue(sp->dev);
del_timer_sync(&sp->tx_t); del_timer_sync(&sp->tx_t);
del_timer_sync(&sp->resync_t); del_timer_sync(&sp->resync_t);

View File

@ -797,6 +797,11 @@ static void mkiss_close(struct tty_struct *tty)
*/ */
if (!atomic_dec_and_test(&ax->refcnt)) if (!atomic_dec_and_test(&ax->refcnt))
down(&ax->dead_sem); down(&ax->dead_sem);
/*
* Halt the transmit queue so that a new transmit cannot scribble
* on our buffers
*/
netif_stop_queue(ax->dev);
/* Free all AX25 frame buffers. */ /* Free all AX25 frame buffers. */
kfree(ax->rbuff); kfree(ax->rbuff);

View File

@ -885,6 +885,7 @@ static const struct usb_device_id products[] = {
{QMI_FIXED_INTF(0x413c, 0x81a9, 8)}, /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card */ {QMI_FIXED_INTF(0x413c, 0x81a9, 8)}, /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card */
{QMI_FIXED_INTF(0x413c, 0x81b1, 8)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card */ {QMI_FIXED_INTF(0x413c, 0x81b1, 8)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card */
{QMI_FIXED_INTF(0x03f0, 0x4e1d, 8)}, /* HP lt4111 LTE/EV-DO/HSPA+ Gobi 4G Module */ {QMI_FIXED_INTF(0x03f0, 0x4e1d, 8)}, /* HP lt4111 LTE/EV-DO/HSPA+ Gobi 4G Module */
{QMI_FIXED_INTF(0x22de, 0x9061, 3)}, /* WeTelecom WPD-600N */
/* 4. Gobi 1000 devices */ /* 4. Gobi 1000 devices */
{QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */

View File

@ -3525,6 +3525,14 @@ static int rtl8152_resume(struct usb_interface *intf)
return 0; return 0;
} }
static int rtl8152_reset_resume(struct usb_interface *intf)
{
struct r8152 *tp = usb_get_intfdata(intf);
clear_bit(SELECTIVE_SUSPEND, &tp->flags);
return rtl8152_resume(intf);
}
static void rtl8152_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) static void rtl8152_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{ {
struct r8152 *tp = netdev_priv(dev); struct r8152 *tp = netdev_priv(dev);
@ -4276,7 +4284,7 @@ static struct usb_driver rtl8152_driver = {
.disconnect = rtl8152_disconnect, .disconnect = rtl8152_disconnect,
.suspend = rtl8152_suspend, .suspend = rtl8152_suspend,
.resume = rtl8152_resume, .resume = rtl8152_resume,
.reset_resume = rtl8152_resume, .reset_resume = rtl8152_reset_resume,
.pre_reset = rtl8152_pre_reset, .pre_reset = rtl8152_pre_reset,
.post_reset = rtl8152_post_reset, .post_reset = rtl8152_post_reset,
.supports_autosuspend = 1, .supports_autosuspend = 1,

View File

@ -1380,10 +1380,10 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
skip_page_frags = true; skip_page_frags = true;
goto rcd_done; goto rcd_done;
} }
new_dma_addr = dma_map_page(&adapter->pdev->dev new_dma_addr = dma_map_page(&adapter->pdev->dev,
, rbi->page, new_page,
0, PAGE_SIZE, 0, PAGE_SIZE,
PCI_DMA_FROMDEVICE); PCI_DMA_FROMDEVICE);
if (dma_mapping_error(&adapter->pdev->dev, if (dma_mapping_error(&adapter->pdev->dev,
new_dma_addr)) { new_dma_addr)) {
put_page(new_page); put_page(new_page);

View File

@ -69,10 +69,10 @@
/* /*
* Version numbers * Version numbers
*/ */
#define VMXNET3_DRIVER_VERSION_STRING "1.4.4.0-k" #define VMXNET3_DRIVER_VERSION_STRING "1.4.5.0-k"
/* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */ /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */
#define VMXNET3_DRIVER_VERSION_NUM 0x01040400 #define VMXNET3_DRIVER_VERSION_NUM 0x01040500
#if defined(CONFIG_PCI_MSI) #if defined(CONFIG_PCI_MSI)
/* RSS only makes sense if MSI-X is supported. */ /* RSS only makes sense if MSI-X is supported. */

View File

@ -742,7 +742,7 @@ static struct rtable *vrf_get_rtable(const struct net_device *dev,
} }
/* called under rcu_read_lock */ /* called under rcu_read_lock */
static void vrf_get_saddr(struct net_device *dev, struct flowi4 *fl4) static int vrf_get_saddr(struct net_device *dev, struct flowi4 *fl4)
{ {
struct fib_result res = { .tclassid = 0 }; struct fib_result res = { .tclassid = 0 };
struct net *net = dev_net(dev); struct net *net = dev_net(dev);
@ -750,9 +750,10 @@ static void vrf_get_saddr(struct net_device *dev, struct flowi4 *fl4)
u8 flags = fl4->flowi4_flags; u8 flags = fl4->flowi4_flags;
u8 scope = fl4->flowi4_scope; u8 scope = fl4->flowi4_scope;
u8 tos = RT_FL_TOS(fl4); u8 tos = RT_FL_TOS(fl4);
int rc;
if (unlikely(!fl4->daddr)) if (unlikely(!fl4->daddr))
return; return 0;
fl4->flowi4_flags |= FLOWI_FLAG_SKIP_NH_OIF; fl4->flowi4_flags |= FLOWI_FLAG_SKIP_NH_OIF;
fl4->flowi4_iif = LOOPBACK_IFINDEX; fl4->flowi4_iif = LOOPBACK_IFINDEX;
@ -760,7 +761,8 @@ static void vrf_get_saddr(struct net_device *dev, struct flowi4 *fl4)
fl4->flowi4_scope = ((tos & RTO_ONLINK) ? fl4->flowi4_scope = ((tos & RTO_ONLINK) ?
RT_SCOPE_LINK : RT_SCOPE_UNIVERSE); RT_SCOPE_LINK : RT_SCOPE_UNIVERSE);
if (!fib_lookup(net, fl4, &res, 0)) { rc = fib_lookup(net, fl4, &res, 0);
if (!rc) {
if (res.type == RTN_LOCAL) if (res.type == RTN_LOCAL)
fl4->saddr = res.fi->fib_prefsrc ? : fl4->daddr; fl4->saddr = res.fi->fib_prefsrc ? : fl4->daddr;
else else
@ -770,6 +772,8 @@ static void vrf_get_saddr(struct net_device *dev, struct flowi4 *fl4)
fl4->flowi4_flags = flags; fl4->flowi4_flags = flags;
fl4->flowi4_tos = orig_tos; fl4->flowi4_tos = orig_tos;
fl4->flowi4_scope = scope; fl4->flowi4_scope = scope;
return rc;
} }
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)

View File

@ -495,6 +495,25 @@ static inline void bpf_jit_free(struct bpf_prog *fp)
#define BPF_ANC BIT(15) #define BPF_ANC BIT(15)
static inline bool bpf_needs_clear_a(const struct sock_filter *first)
{
switch (first->code) {
case BPF_RET | BPF_K:
case BPF_LD | BPF_W | BPF_LEN:
return false;
case BPF_LD | BPF_W | BPF_ABS:
case BPF_LD | BPF_H | BPF_ABS:
case BPF_LD | BPF_B | BPF_ABS:
if (first->k == SKF_AD_OFF + SKF_AD_ALU_XOR_X)
return true;
return false;
default:
return true;
}
}
static inline u16 bpf_anc_helper(const struct sock_filter *ftest) static inline u16 bpf_anc_helper(const struct sock_filter *ftest)
{ {
BUG_ON(ftest->code & BPF_ANC); BUG_ON(ftest->code & BPF_ANC);

View File

@ -29,7 +29,7 @@ struct l3mdev_ops {
/* IPv4 ops */ /* IPv4 ops */
struct rtable * (*l3mdev_get_rtable)(const struct net_device *dev, struct rtable * (*l3mdev_get_rtable)(const struct net_device *dev,
const struct flowi4 *fl4); const struct flowi4 *fl4);
void (*l3mdev_get_saddr)(struct net_device *dev, int (*l3mdev_get_saddr)(struct net_device *dev,
struct flowi4 *fl4); struct flowi4 *fl4);
/* IPv6 ops */ /* IPv6 ops */
@ -130,10 +130,11 @@ static inline bool netif_index_is_l3_master(struct net *net, int ifindex)
return rc; return rc;
} }
static inline void l3mdev_get_saddr(struct net *net, int ifindex, static inline int l3mdev_get_saddr(struct net *net, int ifindex,
struct flowi4 *fl4) struct flowi4 *fl4)
{ {
struct net_device *dev; struct net_device *dev;
int rc = 0;
if (ifindex) { if (ifindex) {
@ -142,11 +143,13 @@ static inline void l3mdev_get_saddr(struct net *net, int ifindex,
dev = dev_get_by_index_rcu(net, ifindex); dev = dev_get_by_index_rcu(net, ifindex);
if (dev && netif_is_l3_master(dev) && if (dev && netif_is_l3_master(dev) &&
dev->l3mdev_ops->l3mdev_get_saddr) { dev->l3mdev_ops->l3mdev_get_saddr) {
dev->l3mdev_ops->l3mdev_get_saddr(dev, fl4); rc = dev->l3mdev_ops->l3mdev_get_saddr(dev, fl4);
} }
rcu_read_unlock(); rcu_read_unlock();
} }
return rc;
} }
static inline struct dst_entry *l3mdev_get_rt6_dst(const struct net_device *dev, static inline struct dst_entry *l3mdev_get_rt6_dst(const struct net_device *dev,
@ -223,9 +226,10 @@ static inline bool netif_index_is_l3_master(struct net *net, int ifindex)
return false; return false;
} }
static inline void l3mdev_get_saddr(struct net *net, int ifindex, static inline int l3mdev_get_saddr(struct net *net, int ifindex,
struct flowi4 *fl4) struct flowi4 *fl4)
{ {
return 0;
} }
static inline static inline

View File

@ -283,7 +283,12 @@ static inline struct rtable *ip_route_connect(struct flowi4 *fl4,
sport, dport, sk); sport, dport, sk);
if (!src && oif) { if (!src && oif) {
l3mdev_get_saddr(net, oif, fl4); int rc;
rc = l3mdev_get_saddr(net, oif, fl4);
if (rc < 0)
return ERR_PTR(rc);
src = fl4->saddr; src = fl4->saddr;
} }
if (!dst || !src) { if (!dst || !src) {

View File

@ -273,6 +273,7 @@ static const char **find_next(void *v, loff_t *pos)
if (*pos < last_index + start_index) if (*pos < last_index + start_index)
return __start___tracepoint_str + (*pos - last_index); return __start___tracepoint_str + (*pos - last_index);
start_index += last_index;
return find_next_mod_format(start_index, v, fmt, pos); return find_next_mod_format(start_index, v, fmt, pos);
} }

View File

@ -143,7 +143,10 @@ static void br_stp_start(struct net_bridge *br)
char *envp[] = { NULL }; char *envp[] = { NULL };
struct net_bridge_port *p; struct net_bridge_port *p;
r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC); if (net_eq(dev_net(br->dev), &init_net))
r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC);
else
r = -ENOENT;
spin_lock_bh(&br->lock); spin_lock_bh(&br->lock);

View File

@ -301,12 +301,13 @@ void dst_release(struct dst_entry *dst)
{ {
if (dst) { if (dst) {
int newrefcnt; int newrefcnt;
unsigned short nocache = dst->flags & DST_NOCACHE;
newrefcnt = atomic_dec_return(&dst->__refcnt); newrefcnt = atomic_dec_return(&dst->__refcnt);
if (unlikely(newrefcnt < 0)) if (unlikely(newrefcnt < 0))
net_warn_ratelimited("%s: dst:%p refcnt:%d\n", net_warn_ratelimited("%s: dst:%p refcnt:%d\n",
__func__, dst, newrefcnt); __func__, dst, newrefcnt);
if (!newrefcnt && unlikely(dst->flags & DST_NOCACHE)) if (!newrefcnt && unlikely(nocache))
call_rcu(&dst->rcu_head, dst_destroy_rcu); call_rcu(&dst->rcu_head, dst_destroy_rcu);
} }
} }

View File

@ -601,8 +601,11 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
(inet->hdrincl ? FLOWI_FLAG_KNOWN_NH : 0), (inet->hdrincl ? FLOWI_FLAG_KNOWN_NH : 0),
daddr, saddr, 0, 0); daddr, saddr, 0, 0);
if (!saddr && ipc.oif) if (!saddr && ipc.oif) {
l3mdev_get_saddr(net, ipc.oif, &fl4); err = l3mdev_get_saddr(net, ipc.oif, &fl4);
if (err < 0)
goto done;
}
if (!inet->hdrincl) { if (!inet->hdrincl) {
rfv.msg = msg; rfv.msg = msg;

View File

@ -2478,6 +2478,9 @@ static void tcp_cwnd_reduction(struct sock *sk, const int prior_unsacked,
int newly_acked_sacked = prior_unsacked - int newly_acked_sacked = prior_unsacked -
(tp->packets_out - tp->sacked_out); (tp->packets_out - tp->sacked_out);
if (newly_acked_sacked <= 0 || WARN_ON_ONCE(!tp->prior_cwnd))
return;
tp->prr_delivered += newly_acked_sacked; tp->prr_delivered += newly_acked_sacked;
if (delta < 0) { if (delta < 0) {
u64 dividend = (u64)tp->snd_ssthresh * tp->prr_delivered + u64 dividend = (u64)tp->snd_ssthresh * tp->prr_delivered +

View File

@ -1097,8 +1097,11 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
flow_flags, flow_flags,
faddr, saddr, dport, inet->inet_sport); faddr, saddr, dport, inet->inet_sport);
if (!saddr && ipc.oif) if (!saddr && ipc.oif) {
l3mdev_get_saddr(net, ipc.oif, fl4); err = l3mdev_get_saddr(net, ipc.oif, fl4);
if (err < 0)
goto out;
}
security_sk_classify_flow(sk, flowi4_to_flowi(fl4)); security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
rt = ip_route_output_flow(net, fl4, sk); rt = ip_route_output_flow(net, fl4, sk);

View File

@ -658,8 +658,10 @@ static void qdisc_rcu_free(struct rcu_head *head)
{ {
struct Qdisc *qdisc = container_of(head, struct Qdisc, rcu_head); struct Qdisc *qdisc = container_of(head, struct Qdisc, rcu_head);
if (qdisc_is_percpu_stats(qdisc)) if (qdisc_is_percpu_stats(qdisc)) {
free_percpu(qdisc->cpu_bstats); free_percpu(qdisc->cpu_bstats);
free_percpu(qdisc->cpu_qstats);
}
kfree((char *) qdisc - qdisc->padded); kfree((char *) qdisc - qdisc->padded);
} }

View File

@ -953,32 +953,20 @@ fail:
return NULL; return NULL;
} }
static int unix_mknod(const char *sun_path, umode_t mode, struct path *res) static int unix_mknod(struct dentry *dentry, struct path *path, umode_t mode,
struct path *res)
{ {
struct dentry *dentry; int err;
struct path path;
int err = 0;
/*
* Get the parent directory, calculate the hash for last
* component.
*/
dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0);
err = PTR_ERR(dentry);
if (IS_ERR(dentry))
return err;
/* err = security_path_mknod(path, dentry, mode, 0);
* All right, let's create it.
*/
err = security_path_mknod(&path, dentry, mode, 0);
if (!err) { if (!err) {
err = vfs_mknod(d_inode(path.dentry), dentry, mode, 0); err = vfs_mknod(d_inode(path->dentry), dentry, mode, 0);
if (!err) { if (!err) {
res->mnt = mntget(path.mnt); res->mnt = mntget(path->mnt);
res->dentry = dget(dentry); res->dentry = dget(dentry);
} }
} }
done_path_create(&path, dentry);
return err; return err;
} }
@ -989,10 +977,12 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
struct unix_sock *u = unix_sk(sk); struct unix_sock *u = unix_sk(sk);
struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr; struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr;
char *sun_path = sunaddr->sun_path; char *sun_path = sunaddr->sun_path;
int err; int err, name_err;
unsigned int hash; unsigned int hash;
struct unix_address *addr; struct unix_address *addr;
struct hlist_head *list; struct hlist_head *list;
struct path path;
struct dentry *dentry;
err = -EINVAL; err = -EINVAL;
if (sunaddr->sun_family != AF_UNIX) if (sunaddr->sun_family != AF_UNIX)
@ -1008,14 +998,34 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
goto out; goto out;
addr_len = err; addr_len = err;
name_err = 0;
dentry = NULL;
if (sun_path[0]) {
/* Get the parent directory, calculate the hash for last
* component.
*/
dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0);
if (IS_ERR(dentry)) {
/* delay report until after 'already bound' check */
name_err = PTR_ERR(dentry);
dentry = NULL;
}
}
err = mutex_lock_interruptible(&u->readlock); err = mutex_lock_interruptible(&u->readlock);
if (err) if (err)
goto out; goto out_path;
err = -EINVAL; err = -EINVAL;
if (u->addr) if (u->addr)
goto out_up; goto out_up;
if (name_err) {
err = name_err == -EEXIST ? -EADDRINUSE : name_err;
goto out_up;
}
err = -ENOMEM; err = -ENOMEM;
addr = kmalloc(sizeof(*addr)+addr_len, GFP_KERNEL); addr = kmalloc(sizeof(*addr)+addr_len, GFP_KERNEL);
if (!addr) if (!addr)
@ -1026,11 +1036,11 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
addr->hash = hash ^ sk->sk_type; addr->hash = hash ^ sk->sk_type;
atomic_set(&addr->refcnt, 1); atomic_set(&addr->refcnt, 1);
if (sun_path[0]) { if (dentry) {
struct path path; struct path u_path;
umode_t mode = S_IFSOCK | umode_t mode = S_IFSOCK |
(SOCK_INODE(sock)->i_mode & ~current_umask()); (SOCK_INODE(sock)->i_mode & ~current_umask());
err = unix_mknod(sun_path, mode, &path); err = unix_mknod(dentry, &path, mode, &u_path);
if (err) { if (err) {
if (err == -EEXIST) if (err == -EEXIST)
err = -EADDRINUSE; err = -EADDRINUSE;
@ -1038,9 +1048,9 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
goto out_up; goto out_up;
} }
addr->hash = UNIX_HASH_SIZE; addr->hash = UNIX_HASH_SIZE;
hash = d_backing_inode(path.dentry)->i_ino & (UNIX_HASH_SIZE-1); hash = d_backing_inode(dentry)->i_ino & (UNIX_HASH_SIZE - 1);
spin_lock(&unix_table_lock); spin_lock(&unix_table_lock);
u->path = path; u->path = u_path;
list = &unix_socket_table[hash]; list = &unix_socket_table[hash];
} else { } else {
spin_lock(&unix_table_lock); spin_lock(&unix_table_lock);
@ -1063,6 +1073,10 @@ out_unlock:
spin_unlock(&unix_table_lock); spin_unlock(&unix_table_lock);
out_up: out_up:
mutex_unlock(&u->readlock); mutex_unlock(&u->readlock);
out_path:
if (dentry)
done_path_create(&path, dentry);
out: out:
return err; return err;
} }

View File

@ -586,7 +586,7 @@ main(int argc, char *argv[])
do_file(file); do_file(file);
break; break;
case SJ_FAIL: /* error in do_file or below */ case SJ_FAIL: /* error in do_file or below */
sprintf("%s: failed\n", file); fprintf(stderr, "%s: failed\n", file);
++n_error; ++n_error;
break; break;
case SJ_SUCCEED: /* premature success */ case SJ_SUCCEED: /* premature success */