Skip to content

Commit

Permalink
Merge remote-tracking branch 'stable/linux-4.4.y' into rpi-4.4.y
Browse files Browse the repository at this point in the history
  • Loading branch information
popcornmix committed Dec 15, 2016
2 parents ac27205 + c95b7f1 commit 03f35fe
Show file tree
Hide file tree
Showing 35 changed files with 242 additions and 80 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
VERSION = 4
PATCHLEVEL = 4
SUBLEVEL = 37
SUBLEVEL = 38
EXTRAVERSION =
NAME = Blurry Fish Butt

Expand Down
4 changes: 2 additions & 2 deletions arch/sparc/kernel/signal_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ asmlinkage void do_sigreturn(struct pt_regs *regs)
sf = (struct signal_frame __user *) regs->u_regs[UREG_FP];

/* 1. Make sure we are not getting garbage from the user */
if (!invalid_frame_pointer(sf, sizeof(*sf)))
if (invalid_frame_pointer(sf, sizeof(*sf)))
goto segv_and_exit;

if (get_user(ufp, &sf->info.si_regs.u_regs[UREG_FP]))
Expand Down Expand Up @@ -150,7 +150,7 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)

synchronize_user_stack();
sf = (struct rt_signal_frame __user *) regs->u_regs[UREG_FP];
if (!invalid_frame_pointer(sf, sizeof(*sf)))
if (invalid_frame_pointer(sf, sizeof(*sf)))
goto segv;

if (get_user(ufp, &sf->regs.u_regs[UREG_FP]))
Expand Down
71 changes: 64 additions & 7 deletions arch/sparc/mm/init_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -800,8 +800,10 @@ struct mdesc_mblock {
};
static struct mdesc_mblock *mblocks;
static int num_mblocks;
static int find_numa_node_for_addr(unsigned long pa,
struct node_mem_mask *pnode_mask);

static unsigned long ra_to_pa(unsigned long addr)
static unsigned long __init ra_to_pa(unsigned long addr)
{
int i;

Expand All @@ -817,8 +819,11 @@ static unsigned long ra_to_pa(unsigned long addr)
return addr;
}

static int find_node(unsigned long addr)
static int __init find_node(unsigned long addr)
{
static bool search_mdesc = true;
static struct node_mem_mask last_mem_mask = { ~0UL, ~0UL };
static int last_index;
int i;

addr = ra_to_pa(addr);
Expand All @@ -828,13 +833,30 @@ static int find_node(unsigned long addr)
if ((addr & p->mask) == p->val)
return i;
}
/* The following condition has been observed on LDOM guests.*/
WARN_ONCE(1, "find_node: A physical address doesn't match a NUMA node"
" rule. Some physical memory will be owned by node 0.");
return 0;
/* The following condition has been observed on LDOM guests because
* node_masks only contains the best latency mask and value.
* LDOM guest's mdesc can contain a single latency group to
* cover multiple address range. Print warning message only if the
* address cannot be found in node_masks nor mdesc.
*/
if ((search_mdesc) &&
((addr & last_mem_mask.mask) != last_mem_mask.val)) {
/* find the available node in the mdesc */
last_index = find_numa_node_for_addr(addr, &last_mem_mask);
numadbg("find_node: latency group for address 0x%lx is %d\n",
addr, last_index);
if ((last_index < 0) || (last_index >= num_node_masks)) {
/* WARN_ONCE() and use default group 0 */
WARN_ONCE(1, "find_node: A physical address doesn't match a NUMA node rule. Some physical memory will be owned by node 0.");
search_mdesc = false;
last_index = 0;
}
}

return last_index;
}

static u64 memblock_nid_range(u64 start, u64 end, int *nid)
static u64 __init memblock_nid_range(u64 start, u64 end, int *nid)
{
*nid = find_node(start);
start += PAGE_SIZE;
Expand Down Expand Up @@ -1158,6 +1180,41 @@ int __node_distance(int from, int to)
return numa_latency[from][to];
}

static int find_numa_node_for_addr(unsigned long pa,
struct node_mem_mask *pnode_mask)
{
struct mdesc_handle *md = mdesc_grab();
u64 node, arc;
int i = 0;

node = mdesc_node_by_name(md, MDESC_NODE_NULL, "latency-groups");
if (node == MDESC_NODE_NULL)
goto out;

mdesc_for_each_node_by_name(md, node, "group") {
mdesc_for_each_arc(arc, md, node, MDESC_ARC_TYPE_FWD) {
u64 target = mdesc_arc_target(md, arc);
struct mdesc_mlgroup *m = find_mlgroup(target);

if (!m)
continue;
if ((pa & m->mask) == m->match) {
if (pnode_mask) {
pnode_mask->mask = m->mask;
pnode_mask->val = m->match;
}
mdesc_release(md);
return i;
}
}
i++;
}

out:
mdesc_release(md);
return -1;
}

static int find_best_numa_node_for_mlgroup(struct mdesc_mlgroup *grp)
{
int i;
Expand Down
3 changes: 3 additions & 0 deletions block/blk-map.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
if (!iter || !iter->count)
return -EINVAL;

if (!iter_is_iovec(iter))
return -EINVAL;

iov_for_each(iov, i, *iter) {
unsigned long uaddr = (unsigned long) iov.iov_base;

Expand Down
4 changes: 4 additions & 0 deletions drivers/net/dsa/bcm_sf2.c
Original file line number Diff line number Diff line change
Expand Up @@ -1137,6 +1137,7 @@ static void bcm_sf2_sw_adjust_link(struct dsa_switch *ds, int port,
struct phy_device *phydev)
{
struct bcm_sf2_priv *priv = ds_to_priv(ds);
struct ethtool_eee *p = &priv->port_sts[port].eee;
u32 id_mode_dis = 0, port_mode;
const char *str = NULL;
u32 reg;
Expand Down Expand Up @@ -1211,6 +1212,9 @@ static void bcm_sf2_sw_adjust_link(struct dsa_switch *ds, int port,
reg |= DUPLX_MODE;

core_writel(priv, reg, CORE_STS_OVERRIDE_GMIIP_PORT(port));

if (!phydev->is_pseudo_fixed_link)
p->eee_enabled = bcm_sf2_eee_init(ds, port, phydev);
}

static void bcm_sf2_sw_fixed_link_update(struct dsa_switch *ds, int port,
Expand Down
8 changes: 5 additions & 3 deletions drivers/net/ethernet/broadcom/genet/bcmgenet.c
Original file line number Diff line number Diff line change
Expand Up @@ -1168,6 +1168,7 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev,
struct bcmgenet_tx_ring *ring)
{
struct bcmgenet_priv *priv = netdev_priv(dev);
struct device *kdev = &priv->pdev->dev;
struct enet_cb *tx_cb_ptr;
struct netdev_queue *txq;
unsigned int pkts_compl = 0;
Expand Down Expand Up @@ -1195,15 +1196,15 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev,
pkts_compl++;
dev->stats.tx_packets++;
dev->stats.tx_bytes += tx_cb_ptr->skb->len;
dma_unmap_single(&dev->dev,
dma_unmap_single(kdev,
dma_unmap_addr(tx_cb_ptr, dma_addr),
dma_unmap_len(tx_cb_ptr, dma_len),
DMA_TO_DEVICE);
bcmgenet_free_cb(tx_cb_ptr);
} else if (dma_unmap_addr(tx_cb_ptr, dma_addr)) {
dev->stats.tx_bytes +=
dma_unmap_len(tx_cb_ptr, dma_len);
dma_unmap_page(&dev->dev,
dma_unmap_page(kdev,
dma_unmap_addr(tx_cb_ptr, dma_addr),
dma_unmap_len(tx_cb_ptr, dma_len),
DMA_TO_DEVICE);
Expand Down Expand Up @@ -1754,14 +1755,15 @@ static int bcmgenet_alloc_rx_buffers(struct bcmgenet_priv *priv,

static void bcmgenet_free_rx_buffers(struct bcmgenet_priv *priv)
{
struct device *kdev = &priv->pdev->dev;
struct enet_cb *cb;
int i;

for (i = 0; i < priv->num_rx_bds; i++) {
cb = &priv->rx_cbs[i];

if (dma_unmap_addr(cb, dma_addr)) {
dma_unmap_single(&priv->dev->dev,
dma_unmap_single(kdev,
dma_unmap_addr(cb, dma_addr),
priv->rx_buf_len, DMA_FROM_DEVICE);
dma_unmap_addr_set(cb, dma_addr, 0);
Expand Down
13 changes: 13 additions & 0 deletions drivers/net/ethernet/marvell/sky2.c
Original file line number Diff line number Diff line change
Expand Up @@ -5220,6 +5220,19 @@ static SIMPLE_DEV_PM_OPS(sky2_pm_ops, sky2_suspend, sky2_resume);

static void sky2_shutdown(struct pci_dev *pdev)
{
struct sky2_hw *hw = pci_get_drvdata(pdev);
int port;

for (port = 0; port < hw->ports; port++) {
struct net_device *ndev = hw->dev[port];

rtnl_lock();
if (netif_running(ndev)) {
dev_close(ndev);
netif_device_detach(ndev);
}
rtnl_unlock();
}
sky2_suspend(&pdev->dev);
pci_wake_from_d3(pdev, device_may_wakeup(&pdev->dev));
pci_set_power_state(pdev, PCI_D3hot);
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/renesas/sh_eth.c
Original file line number Diff line number Diff line change
Expand Up @@ -832,7 +832,7 @@ static struct sh_eth_cpu_data r7s72100_data = {

.ecsr_value = ECSR_ICD,
.ecsipr_value = ECSIPR_ICDIP,
.eesipr_value = 0xff7f009f,
.eesipr_value = 0xe77f009f,

.tx_check = EESR_TC1 | EESR_FTC,
.eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
Expand Down
14 changes: 4 additions & 10 deletions drivers/net/geneve.c
Original file line number Diff line number Diff line change
Expand Up @@ -815,7 +815,6 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
struct geneve_dev *geneve = netdev_priv(dev);
struct geneve_sock *gs4 = geneve->sock4;
struct rtable *rt = NULL;
const struct iphdr *iip; /* interior IP header */
int err = -EINVAL;
struct flowi4 fl4;
__u8 tos, ttl;
Expand All @@ -842,8 +841,6 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
skb_reset_mac_header(skb);

iip = ip_hdr(skb);

if (info) {
const struct ip_tunnel_key *key = &info->key;
u8 *opts = NULL;
Expand All @@ -859,7 +856,7 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
if (unlikely(err))
goto err;

tos = ip_tunnel_ecn_encap(key->tos, iip, skb);
tos = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb);
ttl = key->ttl;
df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
} else {
Expand All @@ -869,7 +866,7 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
if (unlikely(err))
goto err;

tos = ip_tunnel_ecn_encap(fl4.flowi4_tos, iip, skb);
tos = ip_tunnel_ecn_encap(fl4.flowi4_tos, ip_hdr(skb), skb);
ttl = geneve->ttl;
if (!ttl && IN_MULTICAST(ntohl(fl4.daddr)))
ttl = 1;
Expand Down Expand Up @@ -903,7 +900,6 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
struct geneve_dev *geneve = netdev_priv(dev);
struct geneve_sock *gs6 = geneve->sock6;
struct dst_entry *dst = NULL;
const struct iphdr *iip; /* interior IP header */
int err = -EINVAL;
struct flowi6 fl6;
__u8 prio, ttl;
Expand All @@ -927,8 +923,6 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
skb_reset_mac_header(skb);

iip = ip_hdr(skb);

if (info) {
const struct ip_tunnel_key *key = &info->key;
u8 *opts = NULL;
Expand All @@ -945,7 +939,7 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
if (unlikely(err))
goto err;

prio = ip_tunnel_ecn_encap(key->tos, iip, skb);
prio = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb);
ttl = key->ttl;
} else {
udp_csum = false;
Expand All @@ -954,7 +948,7 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
if (unlikely(err))
goto err;

prio = ip_tunnel_ecn_encap(fl6.flowi6_tos, iip, skb);
prio = ip_tunnel_ecn_encap(fl6.flowi6_tos, ip_hdr(skb), skb);
ttl = geneve->ttl;
if (!ttl && ipv6_addr_is_multicast(&fl6.daddr))
ttl = 1;
Expand Down
5 changes: 5 additions & 0 deletions drivers/net/virtio_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -1465,6 +1465,11 @@ static void virtnet_free_queues(struct virtnet_info *vi)
netif_napi_del(&vi->rq[i].napi);
}

/* We called napi_hash_del() before netif_napi_del(),
* we need to respect an RCU grace period before freeing vi->rq
*/
synchronize_net();

kfree(vi->rq);
kfree(vi->sq);
}
Expand Down
4 changes: 2 additions & 2 deletions include/linux/uio.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,12 @@ int iov_iter_npages(const struct iov_iter *i, int maxpages);

const void *dup_iter(struct iov_iter *new, struct iov_iter *old, gfp_t flags);

static inline size_t iov_iter_count(struct iov_iter *i)
static inline size_t iov_iter_count(const struct iov_iter *i)
{
return i->count;
}

static inline bool iter_is_iovec(struct iov_iter *i)
static inline bool iter_is_iovec(const struct iov_iter *i)
{
return !(i->type & (ITER_BVEC | ITER_KVEC));
}
Expand Down
2 changes: 2 additions & 0 deletions net/core/net_namespace.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,8 @@ int peernet2id_alloc(struct net *net, struct net *peer)
bool alloc;
int id;

if (atomic_read(&net->count) == 0)
return NETNSA_NSID_NOT_ASSIGNED;
spin_lock_irqsave(&net->nsid_lock, flags);
alloc = atomic_read(&peer->count) == 0 ? false : true;
id = __peernet2id_alloc(net, peer, &alloc);
Expand Down
5 changes: 4 additions & 1 deletion net/core/rtnetlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -2600,7 +2600,10 @@ static int nlmsg_populate_fdb_fill(struct sk_buff *skb,

static inline size_t rtnl_fdb_nlmsg_size(void)
{
return NLMSG_ALIGN(sizeof(struct ndmsg)) + nla_total_size(ETH_ALEN);
return NLMSG_ALIGN(sizeof(struct ndmsg)) +
nla_total_size(ETH_ALEN) + /* NDA_LLADDR */
nla_total_size(sizeof(u16)) + /* NDA_VLAN */
0;
}

static void rtnl_fdb_notify(struct net_device *dev, u8 *addr, u16 vid, int type)
Expand Down
4 changes: 2 additions & 2 deletions net/core/sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
val = min_t(u32, val, sysctl_wmem_max);
set_sndbuf:
sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
sk->sk_sndbuf = max_t(u32, val * 2, SOCK_MIN_SNDBUF);
sk->sk_sndbuf = max_t(int, val * 2, SOCK_MIN_SNDBUF);
/* Wake up sending tasks if we upped the value. */
sk->sk_write_space(sk);
break;
Expand Down Expand Up @@ -781,7 +781,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
* returning the value we actually used in getsockopt
* is the most desirable behavior.
*/
sk->sk_rcvbuf = max_t(u32, val * 2, SOCK_MIN_RCVBUF);
sk->sk_rcvbuf = max_t(int, val * 2, SOCK_MIN_RCVBUF);
break;

case SO_RCVBUFFORCE:
Expand Down
12 changes: 7 additions & 5 deletions net/dccp/ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -698,6 +698,7 @@ int dccp_invalid_packet(struct sk_buff *skb)
{
const struct dccp_hdr *dh;
unsigned int cscov;
u8 dccph_doff;

if (skb->pkt_type != PACKET_HOST)
return 1;
Expand All @@ -719,18 +720,19 @@ int dccp_invalid_packet(struct sk_buff *skb)
/*
* If P.Data Offset is too small for packet type, drop packet and return
*/
if (dh->dccph_doff < dccp_hdr_len(skb) / sizeof(u32)) {
DCCP_WARN("P.Data Offset(%u) too small\n", dh->dccph_doff);
dccph_doff = dh->dccph_doff;
if (dccph_doff < dccp_hdr_len(skb) / sizeof(u32)) {
DCCP_WARN("P.Data Offset(%u) too small\n", dccph_doff);
return 1;
}
/*
* If P.Data Offset is too too large for packet, drop packet and return
*/
if (!pskb_may_pull(skb, dh->dccph_doff * sizeof(u32))) {
DCCP_WARN("P.Data Offset(%u) too large\n", dh->dccph_doff);
if (!pskb_may_pull(skb, dccph_doff * sizeof(u32))) {
DCCP_WARN("P.Data Offset(%u) too large\n", dccph_doff);
return 1;
}

dh = dccp_hdr(skb);
/*
* If P.type is not Data, Ack, or DataAck and P.X == 0 (the packet
* has short sequence numbers), drop packet and return
Expand Down
Loading

0 comments on commit 03f35fe

Please sign in to comment.