Merge tag 'v3.10.90' into update
This is the 3.10.90 stable release
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
VERSION = 3
|
||||
PATCHLEVEL = 10
|
||||
SUBLEVEL = 89
|
||||
SUBLEVEL = 90
|
||||
EXTRAVERSION =
|
||||
NAME = TOSSUG Baby Fish
|
||||
|
||||
|
||||
@@ -74,6 +74,10 @@ config NO_IOPORT
|
||||
config STACKTRACE_SUPPORT
|
||||
def_bool y
|
||||
|
||||
config ILLEGAL_POINTER_VALUE
|
||||
hex
|
||||
default 0xdead000000000000
|
||||
|
||||
config LOCKDEP_SUPPORT
|
||||
def_bool y
|
||||
|
||||
|
||||
@@ -184,6 +184,11 @@ ENTRY(el2_setup)
|
||||
msr hstr_el2, xzr // Disable CP15 traps to EL2
|
||||
#endif
|
||||
|
||||
/* EL2 debug */
|
||||
mrs x0, pmcr_el0 // Disable debug access traps
|
||||
ubfx x0, x0, #11, #5 // to EL2 and allow access to
|
||||
msr mdcr_el2, x0 // all PMU counters from EL1
|
||||
|
||||
/* Stage-2 translation */
|
||||
msr vttbr_el2, xzr
|
||||
|
||||
|
||||
@@ -239,14 +239,32 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
|
||||
|
||||
/*
|
||||
* VFP save/restore code.
|
||||
*
|
||||
* We have to be careful with endianness, since the fpsimd context-switch
|
||||
* code operates on 128-bit (Q) register values whereas the compat ABI
|
||||
* uses an array of 64-bit (D) registers. Consequently, we need to swap
|
||||
* the two halves of each Q register when running on a big-endian CPU.
|
||||
*/
|
||||
union __fpsimd_vreg {
|
||||
__uint128_t raw;
|
||||
struct {
|
||||
#ifdef __AARCH64EB__
|
||||
u64 hi;
|
||||
u64 lo;
|
||||
#else
|
||||
u64 lo;
|
||||
u64 hi;
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
static int compat_preserve_vfp_context(struct compat_vfp_sigframe __user *frame)
|
||||
{
|
||||
struct fpsimd_state *fpsimd = ¤t->thread.fpsimd_state;
|
||||
compat_ulong_t magic = VFP_MAGIC;
|
||||
compat_ulong_t size = VFP_STORAGE_SIZE;
|
||||
compat_ulong_t fpscr, fpexc;
|
||||
int err = 0;
|
||||
int i, err = 0;
|
||||
|
||||
/*
|
||||
* Save the hardware registers to the fpsimd_state structure.
|
||||
@@ -262,10 +280,15 @@ static int compat_preserve_vfp_context(struct compat_vfp_sigframe __user *frame)
|
||||
/*
|
||||
* Now copy the FP registers. Since the registers are packed,
|
||||
* we can copy the prefix we want (V0-V15) as it is.
|
||||
* FIXME: Won't work if big endian.
|
||||
*/
|
||||
err |= __copy_to_user(&frame->ufp.fpregs, fpsimd->vregs,
|
||||
sizeof(frame->ufp.fpregs));
|
||||
for (i = 0; i < ARRAY_SIZE(frame->ufp.fpregs); i += 2) {
|
||||
union __fpsimd_vreg vreg = {
|
||||
.raw = fpsimd->vregs[i >> 1],
|
||||
};
|
||||
|
||||
__put_user_error(vreg.lo, &frame->ufp.fpregs[i], err);
|
||||
__put_user_error(vreg.hi, &frame->ufp.fpregs[i + 1], err);
|
||||
}
|
||||
|
||||
/* Create an AArch32 fpscr from the fpsr and the fpcr. */
|
||||
fpscr = (fpsimd->fpsr & VFP_FPSCR_STAT_MASK) |
|
||||
@@ -290,7 +313,7 @@ static int compat_restore_vfp_context(struct compat_vfp_sigframe __user *frame)
|
||||
compat_ulong_t magic = VFP_MAGIC;
|
||||
compat_ulong_t size = VFP_STORAGE_SIZE;
|
||||
compat_ulong_t fpscr;
|
||||
int err = 0;
|
||||
int i, err = 0;
|
||||
|
||||
__get_user_error(magic, &frame->magic, err);
|
||||
__get_user_error(size, &frame->size, err);
|
||||
@@ -300,12 +323,14 @@ static int compat_restore_vfp_context(struct compat_vfp_sigframe __user *frame)
|
||||
if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Copy the FP registers into the start of the fpsimd_state.
|
||||
* FIXME: Won't work if big endian.
|
||||
*/
|
||||
err |= __copy_from_user(fpsimd.vregs, frame->ufp.fpregs,
|
||||
sizeof(frame->ufp.fpregs));
|
||||
/* Copy the FP registers into the start of the fpsimd_state. */
|
||||
for (i = 0; i < ARRAY_SIZE(frame->ufp.fpregs); i += 2) {
|
||||
union __fpsimd_vreg vreg;
|
||||
|
||||
__get_user_error(vreg.lo, &frame->ufp.fpregs[i], err);
|
||||
__get_user_error(vreg.hi, &frame->ufp.fpregs[i + 1], err);
|
||||
fpsimd.vregs[i >> 1] = vreg.raw;
|
||||
}
|
||||
|
||||
/* Extract the fpsr and the fpcr from the fpscr */
|
||||
__get_user_error(fpscr, &frame->ufp.fpscr, err);
|
||||
|
||||
@@ -524,8 +524,8 @@ void do_cpu_irq_mask(struct pt_regs *regs)
|
||||
struct pt_regs *old_regs;
|
||||
unsigned long eirr_val;
|
||||
int irq, cpu = smp_processor_id();
|
||||
#ifdef CONFIG_SMP
|
||||
struct irq_desc *desc;
|
||||
#ifdef CONFIG_SMP
|
||||
cpumask_t dest;
|
||||
#endif
|
||||
|
||||
@@ -538,8 +538,12 @@ void do_cpu_irq_mask(struct pt_regs *regs)
|
||||
goto set_out;
|
||||
irq = eirr_to_irq(eirr_val);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* Filter out spurious interrupts, mostly from serial port at bootup */
|
||||
desc = irq_to_desc(irq);
|
||||
if (unlikely(!desc->action))
|
||||
goto set_out;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
cpumask_copy(&dest, desc->irq_data.affinity);
|
||||
if (irqd_is_per_cpu(&desc->irq_data) &&
|
||||
!cpu_isset(smp_processor_id(), dest)) {
|
||||
|
||||
@@ -130,7 +130,19 @@
|
||||
#define pte_iterate_hashed_end() } while(0)
|
||||
|
||||
#ifdef CONFIG_PPC_HAS_HASH_64K
|
||||
#define pte_pagesize_index(mm, addr, pte) get_slice_psize(mm, addr)
|
||||
/*
|
||||
* We expect this to be called only for user addresses or kernel virtual
|
||||
* addresses other than the linear mapping.
|
||||
*/
|
||||
#define pte_pagesize_index(mm, addr, pte) \
|
||||
({ \
|
||||
unsigned int psize; \
|
||||
if (is_kernel_addr(addr)) \
|
||||
psize = MMU_PAGE_4K; \
|
||||
else \
|
||||
psize = get_slice_psize(mm, addr); \
|
||||
psize; \
|
||||
})
|
||||
#else
|
||||
#define pte_pagesize_index(mm, addr, pte) MMU_PAGE_4K
|
||||
#endif
|
||||
|
||||
@@ -255,6 +255,7 @@ extern void rtas_power_off(void);
|
||||
extern void rtas_halt(void);
|
||||
extern void rtas_os_term(char *str);
|
||||
extern int rtas_get_sensor(int sensor, int index, int *state);
|
||||
extern int rtas_get_sensor_fast(int sensor, int index, int *state);
|
||||
extern int rtas_get_power_level(int powerdomain, int *level);
|
||||
extern int rtas_set_power_level(int powerdomain, int level, int *setlevel);
|
||||
extern bool rtas_indicator_present(int token, int *maxindex);
|
||||
|
||||
@@ -584,6 +584,23 @@ int rtas_get_sensor(int sensor, int index, int *state)
|
||||
}
|
||||
EXPORT_SYMBOL(rtas_get_sensor);
|
||||
|
||||
int rtas_get_sensor_fast(int sensor, int index, int *state)
|
||||
{
|
||||
int token = rtas_token("get-sensor-state");
|
||||
int rc;
|
||||
|
||||
if (token == RTAS_UNKNOWN_SERVICE)
|
||||
return -ENOENT;
|
||||
|
||||
rc = rtas_call(token, 2, 2, state, sensor, index);
|
||||
WARN_ON(rc == RTAS_BUSY || (rc >= RTAS_EXTENDED_DELAY_MIN &&
|
||||
rc <= RTAS_EXTENDED_DELAY_MAX));
|
||||
|
||||
if (rc < 0)
|
||||
return rtas_error_rc(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool rtas_indicator_present(int token, int *maxindex)
|
||||
{
|
||||
int proplen, count, i;
|
||||
|
||||
@@ -187,7 +187,8 @@ static irqreturn_t ras_epow_interrupt(int irq, void *dev_id)
|
||||
int state;
|
||||
int critical;
|
||||
|
||||
status = rtas_get_sensor(EPOW_SENSOR_TOKEN, EPOW_SENSOR_INDEX, &state);
|
||||
status = rtas_get_sensor_fast(EPOW_SENSOR_TOKEN, EPOW_SENSOR_INDEX,
|
||||
&state);
|
||||
|
||||
if (state > 3)
|
||||
critical = 1; /* Time Critical */
|
||||
|
||||
@@ -137,6 +137,7 @@ page_table_range_init_count(unsigned long start, unsigned long end)
|
||||
|
||||
vaddr = start;
|
||||
pgd_idx = pgd_index(vaddr);
|
||||
pmd_idx = pmd_index(vaddr);
|
||||
|
||||
for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd_idx++) {
|
||||
for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end);
|
||||
|
||||
@@ -176,7 +176,12 @@ void bpf_jit_compile(struct sk_filter *fp)
|
||||
}
|
||||
cleanup_addr = proglen; /* epilogue address */
|
||||
|
||||
for (pass = 0; pass < 10; pass++) {
|
||||
/* JITed image shrinks with every pass and the loop iterates
|
||||
* until the image stops shrinking. Very large bpf programs
|
||||
* may converge on the last pass. In such case do one more
|
||||
* pass to emit the final image
|
||||
*/
|
||||
for (pass = 0; pass < 10 || image; pass++) {
|
||||
u8 seen_or_pass0 = (pass == 0) ? (SEEN_XREG | SEEN_DATAREF | SEEN_MEM) : seen;
|
||||
/* no prologue/epilogue for trivial filters (RET something) */
|
||||
proglen = 0;
|
||||
|
||||
@@ -3403,6 +3403,14 @@ void radeon_combios_asic_init(struct drm_device *dev)
|
||||
rdev->pdev->subsystem_device == 0x30ae)
|
||||
return;
|
||||
|
||||
/* quirk for rs4xx HP Compaq dc5750 Small Form Factor to make it resume
|
||||
* - it hangs on resume inside the dynclk 1 table.
|
||||
*/
|
||||
if (rdev->family == CHIP_RS480 &&
|
||||
rdev->pdev->subsystem_vendor == 0x103c &&
|
||||
rdev->pdev->subsystem_device == 0x280a)
|
||||
return;
|
||||
|
||||
/* DYN CLK 1 */
|
||||
table = combios_get_table_offset(dev, COMBIOS_DYN_CLK_1_TABLE);
|
||||
if (table)
|
||||
|
||||
@@ -73,8 +73,7 @@ config IIO_ST_GYRO_SPI_3AXIS
|
||||
config ITG3200
|
||||
tristate "InvenSense ITG3200 Digital 3-Axis Gyroscope I2C driver"
|
||||
depends on I2C
|
||||
select IIO_BUFFER
|
||||
select IIO_TRIGGERED_BUFFER
|
||||
select IIO_TRIGGERED_BUFFER if IIO_BUFFER
|
||||
help
|
||||
Say yes here to add support for the InvenSense ITG3200 digital
|
||||
3-axis gyroscope sensor.
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
*/
|
||||
|
||||
struct ib_uverbs_device {
|
||||
struct kref ref;
|
||||
atomic_t refcount;
|
||||
int num_comp_vectors;
|
||||
struct completion comp;
|
||||
struct device *dev;
|
||||
@@ -78,6 +78,7 @@ struct ib_uverbs_device {
|
||||
struct cdev cdev;
|
||||
struct rb_root xrcd_tree;
|
||||
struct mutex xrcd_tree_mutex;
|
||||
struct kobject kobj;
|
||||
};
|
||||
|
||||
struct ib_uverbs_event_file {
|
||||
|
||||
@@ -2106,6 +2106,12 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
|
||||
next->send_flags = user_wr->send_flags;
|
||||
|
||||
if (is_ud) {
|
||||
if (next->opcode != IB_WR_SEND &&
|
||||
next->opcode != IB_WR_SEND_WITH_IMM) {
|
||||
ret = -EINVAL;
|
||||
goto out_put;
|
||||
}
|
||||
|
||||
next->wr.ud.ah = idr_read_ah(user_wr->wr.ud.ah,
|
||||
file->ucontext);
|
||||
if (!next->wr.ud.ah) {
|
||||
@@ -2142,9 +2148,11 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
|
||||
user_wr->wr.atomic.compare_add;
|
||||
next->wr.atomic.swap = user_wr->wr.atomic.swap;
|
||||
next->wr.atomic.rkey = user_wr->wr.atomic.rkey;
|
||||
case IB_WR_SEND:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
ret = -EINVAL;
|
||||
goto out_put;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -119,14 +119,18 @@ static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file,
|
||||
static void ib_uverbs_add_one(struct ib_device *device);
|
||||
static void ib_uverbs_remove_one(struct ib_device *device);
|
||||
|
||||
static void ib_uverbs_release_dev(struct kref *ref)
|
||||
static void ib_uverbs_release_dev(struct kobject *kobj)
|
||||
{
|
||||
struct ib_uverbs_device *dev =
|
||||
container_of(ref, struct ib_uverbs_device, ref);
|
||||
container_of(kobj, struct ib_uverbs_device, kobj);
|
||||
|
||||
complete(&dev->comp);
|
||||
kfree(dev);
|
||||
}
|
||||
|
||||
static struct kobj_type ib_uverbs_dev_ktype = {
|
||||
.release = ib_uverbs_release_dev,
|
||||
};
|
||||
|
||||
static void ib_uverbs_release_event_file(struct kref *ref)
|
||||
{
|
||||
struct ib_uverbs_event_file *file =
|
||||
@@ -282,13 +286,19 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file,
|
||||
return context->device->dealloc_ucontext(context);
|
||||
}
|
||||
|
||||
static void ib_uverbs_comp_dev(struct ib_uverbs_device *dev)
|
||||
{
|
||||
complete(&dev->comp);
|
||||
}
|
||||
|
||||
static void ib_uverbs_release_file(struct kref *ref)
|
||||
{
|
||||
struct ib_uverbs_file *file =
|
||||
container_of(ref, struct ib_uverbs_file, ref);
|
||||
|
||||
module_put(file->device->ib_dev->owner);
|
||||
kref_put(&file->device->ref, ib_uverbs_release_dev);
|
||||
if (atomic_dec_and_test(&file->device->refcount))
|
||||
ib_uverbs_comp_dev(file->device);
|
||||
|
||||
kfree(file);
|
||||
}
|
||||
@@ -629,9 +639,7 @@ static int ib_uverbs_open(struct inode *inode, struct file *filp)
|
||||
int ret;
|
||||
|
||||
dev = container_of(inode->i_cdev, struct ib_uverbs_device, cdev);
|
||||
if (dev)
|
||||
kref_get(&dev->ref);
|
||||
else
|
||||
if (!atomic_inc_not_zero(&dev->refcount))
|
||||
return -ENXIO;
|
||||
|
||||
if (!try_module_get(dev->ib_dev->owner)) {
|
||||
@@ -652,6 +660,7 @@ static int ib_uverbs_open(struct inode *inode, struct file *filp)
|
||||
mutex_init(&file->mutex);
|
||||
|
||||
filp->private_data = file;
|
||||
kobject_get(&dev->kobj);
|
||||
|
||||
return nonseekable_open(inode, filp);
|
||||
|
||||
@@ -659,13 +668,16 @@ err_module:
|
||||
module_put(dev->ib_dev->owner);
|
||||
|
||||
err:
|
||||
kref_put(&dev->ref, ib_uverbs_release_dev);
|
||||
if (atomic_dec_and_test(&dev->refcount))
|
||||
ib_uverbs_comp_dev(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ib_uverbs_close(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct ib_uverbs_file *file = filp->private_data;
|
||||
struct ib_uverbs_device *dev = file->device;
|
||||
|
||||
ib_uverbs_cleanup_ucontext(file, file->ucontext);
|
||||
|
||||
@@ -673,6 +685,7 @@ static int ib_uverbs_close(struct inode *inode, struct file *filp)
|
||||
kref_put(&file->async_file->ref, ib_uverbs_release_event_file);
|
||||
|
||||
kref_put(&file->ref, ib_uverbs_release_file);
|
||||
kobject_put(&dev->kobj);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -768,10 +781,11 @@ static void ib_uverbs_add_one(struct ib_device *device)
|
||||
if (!uverbs_dev)
|
||||
return;
|
||||
|
||||
kref_init(&uverbs_dev->ref);
|
||||
atomic_set(&uverbs_dev->refcount, 1);
|
||||
init_completion(&uverbs_dev->comp);
|
||||
uverbs_dev->xrcd_tree = RB_ROOT;
|
||||
mutex_init(&uverbs_dev->xrcd_tree_mutex);
|
||||
kobject_init(&uverbs_dev->kobj, &ib_uverbs_dev_ktype);
|
||||
|
||||
spin_lock(&map_lock);
|
||||
devnum = find_first_zero_bit(dev_map, IB_UVERBS_MAX_DEVICES);
|
||||
@@ -798,6 +812,7 @@ static void ib_uverbs_add_one(struct ib_device *device)
|
||||
cdev_init(&uverbs_dev->cdev, NULL);
|
||||
uverbs_dev->cdev.owner = THIS_MODULE;
|
||||
uverbs_dev->cdev.ops = device->mmap ? &uverbs_mmap_fops : &uverbs_fops;
|
||||
uverbs_dev->cdev.kobj.parent = &uverbs_dev->kobj;
|
||||
kobject_set_name(&uverbs_dev->cdev.kobj, "uverbs%d", uverbs_dev->devnum);
|
||||
if (cdev_add(&uverbs_dev->cdev, base, 1))
|
||||
goto err_cdev;
|
||||
@@ -828,9 +843,10 @@ err_cdev:
|
||||
clear_bit(devnum, overflow_map);
|
||||
|
||||
err:
|
||||
kref_put(&uverbs_dev->ref, ib_uverbs_release_dev);
|
||||
if (atomic_dec_and_test(&uverbs_dev->refcount))
|
||||
ib_uverbs_comp_dev(uverbs_dev);
|
||||
wait_for_completion(&uverbs_dev->comp);
|
||||
kfree(uverbs_dev);
|
||||
kobject_put(&uverbs_dev->kobj);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -850,9 +866,10 @@ static void ib_uverbs_remove_one(struct ib_device *device)
|
||||
else
|
||||
clear_bit(uverbs_dev->devnum - IB_UVERBS_MAX_DEVICES, overflow_map);
|
||||
|
||||
kref_put(&uverbs_dev->ref, ib_uverbs_release_dev);
|
||||
if (atomic_dec_and_test(&uverbs_dev->refcount))
|
||||
ib_uverbs_comp_dev(uverbs_dev);
|
||||
wait_for_completion(&uverbs_dev->comp);
|
||||
kfree(uverbs_dev);
|
||||
kobject_put(&uverbs_dev->kobj);
|
||||
}
|
||||
|
||||
static char *uverbs_devnode(struct device *dev, umode_t *mode)
|
||||
|
||||
@@ -169,9 +169,13 @@ int mlx4_ib_query_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr)
|
||||
enum rdma_link_layer ll;
|
||||
|
||||
memset(ah_attr, 0, sizeof *ah_attr);
|
||||
ah_attr->sl = be32_to_cpu(ah->av.ib.sl_tclass_flowlabel) >> 28;
|
||||
ah_attr->port_num = be32_to_cpu(ah->av.ib.port_pd) >> 24;
|
||||
ll = rdma_port_get_link_layer(ibah->device, ah_attr->port_num);
|
||||
if (ll == IB_LINK_LAYER_ETHERNET)
|
||||
ah_attr->sl = be32_to_cpu(ah->av.eth.sl_tclass_flowlabel) >> 29;
|
||||
else
|
||||
ah_attr->sl = be32_to_cpu(ah->av.ib.sl_tclass_flowlabel) >> 28;
|
||||
|
||||
ah_attr->dlid = ll == IB_LINK_LAYER_INFINIBAND ? be16_to_cpu(ah->av.ib.dlid) : 0;
|
||||
if (ah->av.ib.stat_rate)
|
||||
ah_attr->static_rate = ah->av.ib.stat_rate - MLX4_STAT_RATE_OFFSET;
|
||||
|
||||
@@ -563,6 +563,8 @@ static int add_port(struct mlx4_ib_dev *dev, int port_num, int slave)
|
||||
struct mlx4_port *p;
|
||||
int i;
|
||||
int ret;
|
||||
int is_eth = rdma_port_get_link_layer(&dev->ib_dev, port_num) ==
|
||||
IB_LINK_LAYER_ETHERNET;
|
||||
|
||||
p = kzalloc(sizeof *p, GFP_KERNEL);
|
||||
if (!p)
|
||||
@@ -580,7 +582,8 @@ static int add_port(struct mlx4_ib_dev *dev, int port_num, int slave)
|
||||
|
||||
p->pkey_group.name = "pkey_idx";
|
||||
p->pkey_group.attrs =
|
||||
alloc_group_attrs(show_port_pkey, store_port_pkey,
|
||||
alloc_group_attrs(show_port_pkey,
|
||||
is_eth ? NULL : store_port_pkey,
|
||||
dev->dev->caps.pkey_table_len[port_num]);
|
||||
if (!p->pkey_group.attrs)
|
||||
goto err_alloc;
|
||||
|
||||
@@ -524,9 +524,18 @@ gigaset_tty_open(struct tty_struct *tty)
|
||||
cs->hw.ser->tty = tty;
|
||||
atomic_set(&cs->hw.ser->refcnt, 1);
|
||||
init_completion(&cs->hw.ser->dead_cmp);
|
||||
|
||||
tty->disc_data = cs;
|
||||
|
||||
/* Set the amount of data we're willing to receive per call
|
||||
* from the hardware driver to half of the input buffer size
|
||||
* to leave some reserve.
|
||||
* Note: We don't do flow control towards the hardware driver.
|
||||
* If more data is received than will fit into the input buffer,
|
||||
* it will be dropped and an error will be logged. This should
|
||||
* never happen as the device is slow and the buffer size ample.
|
||||
*/
|
||||
tty->receive_room = RBUFSIZE/2;
|
||||
|
||||
/* OK.. Initialization of the datastructures and the HW is done.. Now
|
||||
* startup system and notify the LL that we are ready to run
|
||||
*/
|
||||
|
||||
+4
-1
@@ -3578,6 +3578,7 @@ static struct r10conf *setup_conf(struct mddev *mddev)
|
||||
/* far_copies must be 1 */
|
||||
conf->prev.stride = conf->dev_sectors;
|
||||
}
|
||||
conf->reshape_safe = conf->reshape_progress;
|
||||
spin_lock_init(&conf->device_lock);
|
||||
INIT_LIST_HEAD(&conf->retry_list);
|
||||
|
||||
@@ -3785,7 +3786,6 @@ static int run(struct mddev *mddev)
|
||||
}
|
||||
conf->offset_diff = min_offset_diff;
|
||||
|
||||
conf->reshape_safe = conf->reshape_progress;
|
||||
clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
|
||||
clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
|
||||
set_bit(MD_RECOVERY_RESHAPE, &mddev->recovery);
|
||||
@@ -4130,6 +4130,7 @@ static int raid10_start_reshape(struct mddev *mddev)
|
||||
conf->reshape_progress = size;
|
||||
} else
|
||||
conf->reshape_progress = 0;
|
||||
conf->reshape_safe = conf->reshape_progress;
|
||||
spin_unlock_irq(&conf->device_lock);
|
||||
|
||||
if (mddev->delta_disks && mddev->bitmap) {
|
||||
@@ -4196,6 +4197,7 @@ abort:
|
||||
rdev->new_data_offset = rdev->data_offset;
|
||||
smp_wmb();
|
||||
conf->reshape_progress = MaxSector;
|
||||
conf->reshape_safe = MaxSector;
|
||||
mddev->reshape_position = MaxSector;
|
||||
spin_unlock_irq(&conf->device_lock);
|
||||
return ret;
|
||||
@@ -4543,6 +4545,7 @@ static void end_reshape(struct r10conf *conf)
|
||||
md_finish_reshape(conf->mddev);
|
||||
smp_wmb();
|
||||
conf->reshape_progress = MaxSector;
|
||||
conf->reshape_safe = MaxSector;
|
||||
spin_unlock_irq(&conf->device_lock);
|
||||
|
||||
/* read-ahead size must cover two whole stripes, which is
|
||||
|
||||
@@ -943,9 +943,6 @@ static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct rc_dev *dev = to_rc_dev(device);
|
||||
|
||||
if (!dev || !dev->input_dev)
|
||||
return -ENODEV;
|
||||
|
||||
if (dev->rc_map.name)
|
||||
ADD_HOTPLUG_VAR("NAME=%s", dev->rc_map.name);
|
||||
if (dev->driver_name)
|
||||
|
||||
@@ -352,8 +352,10 @@ EXPORT_SYMBOL(mmc_start_bkops);
|
||||
*/
|
||||
static void mmc_wait_data_done(struct mmc_request *mrq)
|
||||
{
|
||||
mrq->host->context_info.is_done_rcv = true;
|
||||
wake_up_interruptible(&mrq->host->context_info.wait);
|
||||
struct mmc_context_info *context_info = &mrq->host->context_info;
|
||||
|
||||
context_info->is_done_rcv = true;
|
||||
wake_up_interruptible(&context_info->wait);
|
||||
}
|
||||
|
||||
static void mmc_wait_done(struct mmc_request *mrq)
|
||||
|
||||
@@ -2188,6 +2188,7 @@ static int bond_release_and_destroy(struct net_device *bond_dev,
|
||||
bond_dev->priv_flags |= IFF_DISABLE_NETPOLL;
|
||||
pr_info("%s: destroying bond %s.\n",
|
||||
bond_dev->name, bond_dev->name);
|
||||
bond_remove_proc_entry(bond);
|
||||
unregister_netdevice(bond_dev);
|
||||
}
|
||||
return ret;
|
||||
|
||||
@@ -10518,7 +10518,7 @@ static ssize_t tg3_show_temp(struct device *dev,
|
||||
tg3_ape_scratchpad_read(tp, &temperature, attr->index,
|
||||
sizeof(temperature));
|
||||
spin_unlock_bh(&tp->lock);
|
||||
return sprintf(buf, "%u\n", temperature);
|
||||
return sprintf(buf, "%u\n", temperature * 1000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -753,7 +753,7 @@ int usbnet_stop (struct net_device *net)
|
||||
{
|
||||
struct usbnet *dev = netdev_priv(net);
|
||||
struct driver_info *info = dev->driver_info;
|
||||
int retval, pm;
|
||||
int retval, pm, mpn;
|
||||
|
||||
clear_bit(EVENT_DEV_OPEN, &dev->flags);
|
||||
netif_stop_queue (net);
|
||||
@@ -784,6 +784,8 @@ int usbnet_stop (struct net_device *net)
|
||||
|
||||
usbnet_purge_paused_rxq(dev);
|
||||
|
||||
mpn = !test_and_clear_bit(EVENT_NO_RUNTIME_PM, &dev->flags);
|
||||
|
||||
/* deferred work (task, timer, softirq) must also stop.
|
||||
* can't flush_scheduled_work() until we drop rtnl (later),
|
||||
* else workers could deadlock; so make workers a NOP.
|
||||
@@ -794,8 +796,7 @@ int usbnet_stop (struct net_device *net)
|
||||
if (!pm)
|
||||
usb_autopm_put_interface(dev->intf);
|
||||
|
||||
if (info->manage_power &&
|
||||
!test_and_clear_bit(EVENT_NO_RUNTIME_PM, &dev->flags))
|
||||
if (info->manage_power && mpn)
|
||||
info->manage_power(dev, 0);
|
||||
else
|
||||
usb_autopm_put_interface(dev->intf);
|
||||
|
||||
@@ -313,6 +313,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = {
|
||||
{RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/
|
||||
{RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/
|
||||
{RTL_USB_DEVICE(0x0846, 0x9041, rtl92cu_hal_cfg)}, /*NetGear WNA1000M*/
|
||||
{RTL_USB_DEVICE(0x0846, 0x9043, rtl92cu_hal_cfg)}, /*NG WNA1000Mv2*/
|
||||
{RTL_USB_DEVICE(0x0b05, 0x17ba, rtl92cu_hal_cfg)}, /*ASUS-Edimax*/
|
||||
{RTL_USB_DEVICE(0x0bda, 0x5088, rtl92cu_hal_cfg)}, /*Thinkware-CC&C*/
|
||||
{RTL_USB_DEVICE(0x0df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/
|
||||
|
||||
@@ -1088,7 +1088,7 @@ static void tcm_vhost_send_evt(struct vhost_scsi *vs, struct tcm_vhost_tpg *tpg,
|
||||
* lun[4-7] need to be zero according to virtio-scsi spec.
|
||||
*/
|
||||
evt->event.lun[0] = 0x01;
|
||||
evt->event.lun[1] = tpg->tport_tpgt & 0xFF;
|
||||
evt->event.lun[1] = tpg->tport_tpgt;
|
||||
if (lun->unpacked_lun >= 256)
|
||||
evt->event.lun[2] = lun->unpacked_lun >> 8 | 0x40 ;
|
||||
evt->event.lun[3] = lun->unpacked_lun & 0xFF;
|
||||
@@ -1894,12 +1894,12 @@ static struct se_portal_group *tcm_vhost_make_tpg(struct se_wwn *wwn,
|
||||
struct tcm_vhost_tport, tport_wwn);
|
||||
|
||||
struct tcm_vhost_tpg *tpg;
|
||||
unsigned long tpgt;
|
||||
u16 tpgt;
|
||||
int ret;
|
||||
|
||||
if (strstr(name, "tpgt_") != name)
|
||||
return ERR_PTR(-EINVAL);
|
||||
if (kstrtoul(name + 5, 10, &tpgt) || tpgt > UINT_MAX)
|
||||
if (kstrtou16(name + 5, 10, &tpgt) || tpgt >= VHOST_SCSI_MAX_TARGET)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
tpg = kzalloc(sizeof(struct tcm_vhost_tpg), GFP_KERNEL);
|
||||
|
||||
+20
-20
@@ -65,7 +65,7 @@ struct gntdev_priv {
|
||||
* Only populated if populate_freeable_maps == 1 */
|
||||
struct list_head freeable_maps;
|
||||
/* lock protects maps and freeable_maps */
|
||||
spinlock_t lock;
|
||||
struct mutex lock;
|
||||
struct mm_struct *mm;
|
||||
struct mmu_notifier mn;
|
||||
};
|
||||
@@ -214,9 +214,9 @@ static void gntdev_put_map(struct gntdev_priv *priv, struct grant_map *map)
|
||||
}
|
||||
|
||||
if (populate_freeable_maps && priv) {
|
||||
spin_lock(&priv->lock);
|
||||
mutex_lock(&priv->lock);
|
||||
list_del(&map->next);
|
||||
spin_unlock(&priv->lock);
|
||||
mutex_unlock(&priv->lock);
|
||||
}
|
||||
|
||||
if (map->pages && !use_ptemod)
|
||||
@@ -392,9 +392,9 @@ static void gntdev_vma_close(struct vm_area_struct *vma)
|
||||
* not do any unmapping, since that has been done prior to
|
||||
* closing the vma, but it may still iterate the unmap_ops list.
|
||||
*/
|
||||
spin_lock(&priv->lock);
|
||||
mutex_lock(&priv->lock);
|
||||
map->vma = NULL;
|
||||
spin_unlock(&priv->lock);
|
||||
mutex_unlock(&priv->lock);
|
||||
}
|
||||
vma->vm_private_data = NULL;
|
||||
gntdev_put_map(priv, map);
|
||||
@@ -438,14 +438,14 @@ static void mn_invl_range_start(struct mmu_notifier *mn,
|
||||
struct gntdev_priv *priv = container_of(mn, struct gntdev_priv, mn);
|
||||
struct grant_map *map;
|
||||
|
||||
spin_lock(&priv->lock);
|
||||
mutex_lock(&priv->lock);
|
||||
list_for_each_entry(map, &priv->maps, next) {
|
||||
unmap_if_in_range(map, start, end);
|
||||
}
|
||||
list_for_each_entry(map, &priv->freeable_maps, next) {
|
||||
unmap_if_in_range(map, start, end);
|
||||
}
|
||||
spin_unlock(&priv->lock);
|
||||
mutex_unlock(&priv->lock);
|
||||
}
|
||||
|
||||
static void mn_invl_page(struct mmu_notifier *mn,
|
||||
@@ -462,7 +462,7 @@ static void mn_release(struct mmu_notifier *mn,
|
||||
struct grant_map *map;
|
||||
int err;
|
||||
|
||||
spin_lock(&priv->lock);
|
||||
mutex_lock(&priv->lock);
|
||||
list_for_each_entry(map, &priv->maps, next) {
|
||||
if (!map->vma)
|
||||
continue;
|
||||
@@ -481,7 +481,7 @@ static void mn_release(struct mmu_notifier *mn,
|
||||
err = unmap_grant_pages(map, /* offset */ 0, map->count);
|
||||
WARN_ON(err);
|
||||
}
|
||||
spin_unlock(&priv->lock);
|
||||
mutex_unlock(&priv->lock);
|
||||
}
|
||||
|
||||
static struct mmu_notifier_ops gntdev_mmu_ops = {
|
||||
@@ -503,7 +503,7 @@ static int gntdev_open(struct inode *inode, struct file *flip)
|
||||
|
||||
INIT_LIST_HEAD(&priv->maps);
|
||||
INIT_LIST_HEAD(&priv->freeable_maps);
|
||||
spin_lock_init(&priv->lock);
|
||||
mutex_init(&priv->lock);
|
||||
|
||||
if (use_ptemod) {
|
||||
priv->mm = get_task_mm(current);
|
||||
@@ -579,10 +579,10 @@ static long gntdev_ioctl_map_grant_ref(struct gntdev_priv *priv,
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
spin_lock(&priv->lock);
|
||||
mutex_lock(&priv->lock);
|
||||
gntdev_add_map(priv, map);
|
||||
op.index = map->index << PAGE_SHIFT;
|
||||
spin_unlock(&priv->lock);
|
||||
mutex_unlock(&priv->lock);
|
||||
|
||||
if (copy_to_user(u, &op, sizeof(op)) != 0)
|
||||
return -EFAULT;
|
||||
@@ -601,7 +601,7 @@ static long gntdev_ioctl_unmap_grant_ref(struct gntdev_priv *priv,
|
||||
return -EFAULT;
|
||||
pr_debug("priv %p, del %d+%d\n", priv, (int)op.index, (int)op.count);
|
||||
|
||||
spin_lock(&priv->lock);
|
||||
mutex_lock(&priv->lock);
|
||||
map = gntdev_find_map_index(priv, op.index >> PAGE_SHIFT, op.count);
|
||||
if (map) {
|
||||
list_del(&map->next);
|
||||
@@ -609,7 +609,7 @@ static long gntdev_ioctl_unmap_grant_ref(struct gntdev_priv *priv,
|
||||
list_add_tail(&map->next, &priv->freeable_maps);
|
||||
err = 0;
|
||||
}
|
||||
spin_unlock(&priv->lock);
|
||||
mutex_unlock(&priv->lock);
|
||||
if (map)
|
||||
gntdev_put_map(priv, map);
|
||||
return err;
|
||||
@@ -677,7 +677,7 @@ static long gntdev_ioctl_notify(struct gntdev_priv *priv, void __user *u)
|
||||
out_flags = op.action;
|
||||
out_event = op.event_channel_port;
|
||||
|
||||
spin_lock(&priv->lock);
|
||||
mutex_lock(&priv->lock);
|
||||
|
||||
list_for_each_entry(map, &priv->maps, next) {
|
||||
uint64_t begin = map->index << PAGE_SHIFT;
|
||||
@@ -705,7 +705,7 @@ static long gntdev_ioctl_notify(struct gntdev_priv *priv, void __user *u)
|
||||
rc = 0;
|
||||
|
||||
unlock_out:
|
||||
spin_unlock(&priv->lock);
|
||||
mutex_unlock(&priv->lock);
|
||||
|
||||
/* Drop the reference to the event channel we did not save in the map */
|
||||
if (out_flags & UNMAP_NOTIFY_SEND_EVENT)
|
||||
@@ -755,7 +755,7 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)
|
||||
pr_debug("map %d+%d at %lx (pgoff %lx)\n",
|
||||
index, count, vma->vm_start, vma->vm_pgoff);
|
||||
|
||||
spin_lock(&priv->lock);
|
||||
mutex_lock(&priv->lock);
|
||||
map = gntdev_find_map_index(priv, index, count);
|
||||
if (!map)
|
||||
goto unlock_out;
|
||||
@@ -790,7 +790,7 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)
|
||||
map->flags |= GNTMAP_readonly;
|
||||
}
|
||||
|
||||
spin_unlock(&priv->lock);
|
||||
mutex_unlock(&priv->lock);
|
||||
|
||||
if (use_ptemod) {
|
||||
err = apply_to_page_range(vma->vm_mm, vma->vm_start,
|
||||
@@ -818,11 +818,11 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)
|
||||
return 0;
|
||||
|
||||
unlock_out:
|
||||
spin_unlock(&priv->lock);
|
||||
mutex_unlock(&priv->lock);
|
||||
return err;
|
||||
|
||||
out_unlock_put:
|
||||
spin_unlock(&priv->lock);
|
||||
mutex_unlock(&priv->lock);
|
||||
out_put_map:
|
||||
if (use_ptemod)
|
||||
map->vma = NULL;
|
||||
|
||||
+32
-6
@@ -491,10 +491,10 @@ void do_coredump(siginfo_t *siginfo)
|
||||
const struct cred *old_cred;
|
||||
struct cred *cred;
|
||||
int retval = 0;
|
||||
int flag = 0;
|
||||
int ispipe;
|
||||
struct files_struct *displaced;
|
||||
bool need_nonrelative = false;
|
||||
/* require nonrelative corefile path and be extra careful */
|
||||
bool need_suid_safe = false;
|
||||
bool core_dumped = false;
|
||||
static atomic_t core_dump_count = ATOMIC_INIT(0);
|
||||
struct coredump_params cprm = {
|
||||
@@ -537,9 +537,8 @@ void do_coredump(siginfo_t *siginfo)
|
||||
*/
|
||||
if (__get_dumpable(cprm.mm_flags) == SUID_DUMP_ROOT) {
|
||||
/* Setuid core dump mode */
|
||||
flag = O_EXCL; /* Stop rewrite attacks */
|
||||
cred->fsuid = GLOBAL_ROOT_UID; /* Dump root private */
|
||||
need_nonrelative = true;
|
||||
need_suid_safe = true;
|
||||
}
|
||||
|
||||
retval = coredump_wait(siginfo->si_signo, &core_state);
|
||||
@@ -620,7 +619,7 @@ void do_coredump(siginfo_t *siginfo)
|
||||
if (cprm.limit < binfmt->min_coredump)
|
||||
goto fail_unlock;
|
||||
|
||||
if (need_nonrelative && cn.corename[0] != '/') {
|
||||
if (need_suid_safe && cn.corename[0] != '/') {
|
||||
printk(KERN_WARNING "Pid %d(%s) can only dump core "\
|
||||
"to fully qualified path!\n",
|
||||
task_tgid_vnr(current), current->comm);
|
||||
@@ -628,8 +627,35 @@ void do_coredump(siginfo_t *siginfo)
|
||||
goto fail_unlock;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unlink the file if it exists unless this is a SUID
|
||||
* binary - in that case, we're running around with root
|
||||
* privs and don't want to unlink another user's coredump.
|
||||
*/
|
||||
if (!need_suid_safe) {
|
||||
mm_segment_t old_fs;
|
||||
|
||||
old_fs = get_fs();
|
||||
set_fs(KERNEL_DS);
|
||||
/*
|
||||
* If it doesn't exist, that's fine. If there's some
|
||||
* other problem, we'll catch it at the filp_open().
|
||||
*/
|
||||
(void) sys_unlink((const char __user *)cn.corename);
|
||||
set_fs(old_fs);
|
||||
}
|
||||
|
||||
/*
|
||||
* There is a race between unlinking and creating the
|
||||
* file, but if that causes an EEXIST here, that's
|
||||
* fine - another process raced with us while creating
|
||||
* the corefile, and the other process won. To userspace,
|
||||
* what matters is that at least one of the two processes
|
||||
* writes its coredump successfully, not which one.
|
||||
*/
|
||||
cprm.file = filp_open(cn.corename,
|
||||
O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag,
|
||||
O_CREAT | 2 | O_NOFOLLOW |
|
||||
O_LARGEFILE | O_EXCL,
|
||||
0600);
|
||||
if (IS_ERR(cprm.file))
|
||||
goto fail_unlock;
|
||||
|
||||
@@ -2569,15 +2569,6 @@ static int prepend_path(const struct path *path,
|
||||
return error;
|
||||
|
||||
global_root:
|
||||
/*
|
||||
* Filesystems needing to implement special "root names"
|
||||
* should do so with ->d_dname()
|
||||
*/
|
||||
if (IS_ROOT(dentry) &&
|
||||
(dentry->d_name.len != 1 || dentry->d_name.name[0] != '/')) {
|
||||
WARN(1, "Root dentry has weird name <%.*s>\n",
|
||||
(int) dentry->d_name.len, dentry->d_name.name);
|
||||
}
|
||||
if (!slash)
|
||||
error = prepend(buffer, buflen, "/", 1);
|
||||
if (!error)
|
||||
|
||||
+4
-5
@@ -288,7 +288,6 @@ static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid)
|
||||
page_cache_release(page);
|
||||
goto fail;
|
||||
}
|
||||
page_cache_release(page);
|
||||
node->page[i] = page;
|
||||
}
|
||||
|
||||
@@ -398,11 +397,11 @@ node_error:
|
||||
|
||||
void hfs_bnode_free(struct hfs_bnode *node)
|
||||
{
|
||||
//int i;
|
||||
int i;
|
||||
|
||||
//for (i = 0; i < node->tree->pages_per_bnode; i++)
|
||||
// if (node->page[i])
|
||||
// page_cache_release(node->page[i]);
|
||||
for (i = 0; i < node->tree->pages_per_bnode; i++)
|
||||
if (node->page[i])
|
||||
page_cache_release(node->page[i]);
|
||||
kfree(node);
|
||||
}
|
||||
|
||||
|
||||
+11
-9
@@ -131,13 +131,16 @@ skip:
|
||||
hfs_bnode_write(node, entry, data_off + key_len, entry_len);
|
||||
hfs_bnode_dump(node);
|
||||
|
||||
if (new_node) {
|
||||
/* update parent key if we inserted a key
|
||||
* at the start of the first node
|
||||
*/
|
||||
if (!rec && new_node != node)
|
||||
hfs_brec_update_parent(fd);
|
||||
/*
|
||||
* update parent key if we inserted a key
|
||||
* at the start of the node and it is not the new node
|
||||
*/
|
||||
if (!rec && new_node != node) {
|
||||
hfs_bnode_read_key(node, fd->search_key, data_off + size);
|
||||
hfs_brec_update_parent(fd);
|
||||
}
|
||||
|
||||
if (new_node) {
|
||||
hfs_bnode_put(fd->bnode);
|
||||
if (!new_node->parent) {
|
||||
hfs_btree_inc_height(tree);
|
||||
@@ -166,9 +169,6 @@ skip:
|
||||
goto again;
|
||||
}
|
||||
|
||||
if (!rec)
|
||||
hfs_brec_update_parent(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -366,6 +366,8 @@ again:
|
||||
if (IS_ERR(parent))
|
||||
return PTR_ERR(parent);
|
||||
__hfs_brec_find(parent, fd);
|
||||
if (fd->record < 0)
|
||||
return -ENOENT;
|
||||
hfs_bnode_dump(parent);
|
||||
rec = fd->record;
|
||||
|
||||
|
||||
@@ -456,7 +456,6 @@ static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid)
|
||||
page_cache_release(page);
|
||||
goto fail;
|
||||
}
|
||||
page_cache_release(page);
|
||||
node->page[i] = page;
|
||||
}
|
||||
|
||||
@@ -568,13 +567,11 @@ node_error:
|
||||
|
||||
void hfs_bnode_free(struct hfs_bnode *node)
|
||||
{
|
||||
#if 0
|
||||
int i;
|
||||
|
||||
for (i = 0; i < node->tree->pages_per_bnode; i++)
|
||||
if (node->page[i])
|
||||
page_cache_release(node->page[i]);
|
||||
#endif
|
||||
kfree(node);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -2043,7 +2043,7 @@ static int _nfs4_do_open(struct inode *dir,
|
||||
if (status != 0)
|
||||
goto err_opendata_put;
|
||||
|
||||
if ((opendata->o_arg.open_flags & O_EXCL) &&
|
||||
if ((opendata->o_arg.open_flags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL) &&
|
||||
(opendata->o_arg.createmode != NFS4_CREATE_GUARDED)) {
|
||||
nfs4_exclusive_attrset(opendata, sattr);
|
||||
|
||||
|
||||
+2
-2
@@ -60,8 +60,8 @@ EXPORT_SYMBOL_GPL(nfs_pgheader_init);
|
||||
void nfs_set_pgio_error(struct nfs_pgio_header *hdr, int error, loff_t pos)
|
||||
{
|
||||
spin_lock(&hdr->lock);
|
||||
if (pos < hdr->io_start + hdr->good_bytes) {
|
||||
set_bit(NFS_IOHDR_ERROR, &hdr->flags);
|
||||
if (!test_and_set_bit(NFS_IOHDR_ERROR, &hdr->flags)
|
||||
|| pos < hdr->io_start + hdr->good_bytes) {
|
||||
clear_bit(NFS_IOHDR_EOF, &hdr->flags);
|
||||
hdr->good_bytes = pos - hdr->io_start;
|
||||
hdr->error = error;
|
||||
|
||||
@@ -141,6 +141,7 @@ static inline struct sk_buff *ip_finish_skb(struct sock *sk, struct flowi4 *fl4)
|
||||
}
|
||||
|
||||
/* datagram.c */
|
||||
int __ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len);
|
||||
extern int ip4_datagram_connect(struct sock *sk,
|
||||
struct sockaddr *uaddr, int addr_len);
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ struct netns_sctp {
|
||||
struct list_head addr_waitq;
|
||||
struct timer_list addr_wq_timer;
|
||||
struct list_head auto_asconf_splist;
|
||||
/* Lock that protects both addr_waitq and auto_asconf_splist */
|
||||
spinlock_t addr_wq_lock;
|
||||
|
||||
/* Lock that protects the local_addr_list writers */
|
||||
|
||||
@@ -228,6 +228,10 @@ struct sctp_sock {
|
||||
atomic_t pd_mode;
|
||||
/* Receive to here while partial delivery is in effect. */
|
||||
struct sk_buff_head pd_lobby;
|
||||
|
||||
/* These must be the last fields, as they will skipped on copies,
|
||||
* like on accept and peeloff operations
|
||||
*/
|
||||
struct list_head auto_asconf_list;
|
||||
int do_auto_asconf;
|
||||
};
|
||||
|
||||
+18
-10
@@ -1890,13 +1890,21 @@ static int check_unshare_flags(unsigned long unshare_flags)
|
||||
CLONE_NEWUSER|CLONE_NEWPID))
|
||||
return -EINVAL;
|
||||
/*
|
||||
* Not implemented, but pretend it works if there is nothing to
|
||||
* unshare. Note that unsharing CLONE_THREAD or CLONE_SIGHAND
|
||||
* needs to unshare vm.
|
||||
* Not implemented, but pretend it works if there is nothing
|
||||
* to unshare. Note that unsharing the address space or the
|
||||
* signal handlers also need to unshare the signal queues (aka
|
||||
* CLONE_THREAD).
|
||||
*/
|
||||
if (unshare_flags & (CLONE_THREAD | CLONE_SIGHAND | CLONE_VM)) {
|
||||
/* FIXME: get_task_mm() increments ->mm_users */
|
||||
if (atomic_read(¤t->mm->mm_users) > 1)
|
||||
if (!thread_group_empty(current))
|
||||
return -EINVAL;
|
||||
}
|
||||
if (unshare_flags & (CLONE_SIGHAND | CLONE_VM)) {
|
||||
if (atomic_read(¤t->sighand->count) > 1)
|
||||
return -EINVAL;
|
||||
}
|
||||
if (unshare_flags & CLONE_VM) {
|
||||
if (!current_is_single_threaded())
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -1969,16 +1977,16 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
|
||||
*/
|
||||
if (unshare_flags & CLONE_NEWPID)
|
||||
unshare_flags |= CLONE_THREAD;
|
||||
/*
|
||||
* If unsharing a thread from a thread group, must also unshare vm.
|
||||
*/
|
||||
if (unshare_flags & CLONE_THREAD)
|
||||
unshare_flags |= CLONE_VM;
|
||||
/*
|
||||
* If unsharing vm, must also unshare signal handlers.
|
||||
*/
|
||||
if (unshare_flags & CLONE_VM)
|
||||
unshare_flags |= CLONE_SIGHAND;
|
||||
/*
|
||||
* If unsharing a signal handlers, must also unshare the signal queues.
|
||||
*/
|
||||
if (unshare_flags & CLONE_SIGHAND)
|
||||
unshare_flags |= CLONE_THREAD;
|
||||
/*
|
||||
* If unsharing namespace, must also unshare filesystem information.
|
||||
*/
|
||||
|
||||
+1
-1
@@ -968,7 +968,7 @@ cull_mlocked:
|
||||
if (PageSwapCache(page))
|
||||
try_to_free_swap(page);
|
||||
unlock_page(page);
|
||||
putback_lru_page(page);
|
||||
list_add(&page->lru, &ret_pages);
|
||||
continue;
|
||||
|
||||
activate_locked:
|
||||
|
||||
+2
-1
@@ -345,7 +345,6 @@ static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port,
|
||||
return -ENOMEM;
|
||||
rcu_assign_pointer(*pp, p);
|
||||
|
||||
br_mdb_notify(br->dev, port, group, RTM_NEWMDB);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -368,6 +367,7 @@ static int __br_mdb_add(struct net *net, struct net_bridge *br,
|
||||
if (!p || p->br != br || p->state == BR_STATE_DISABLED)
|
||||
return -EINVAL;
|
||||
|
||||
memset(&ip, 0, sizeof(ip));
|
||||
ip.proto = entry->addr.proto;
|
||||
if (ip.proto == htons(ETH_P_IP))
|
||||
ip.u.ip4 = entry->addr.u.ip4;
|
||||
@@ -417,6 +417,7 @@ static int __br_mdb_del(struct net_bridge *br, struct br_mdb_entry *entry)
|
||||
if (timer_pending(&br->multicast_querier_timer))
|
||||
return -EBUSY;
|
||||
|
||||
memset(&ip, 0, sizeof(ip));
|
||||
ip.proto = entry->addr.proto;
|
||||
if (ip.proto == htons(ETH_P_IP))
|
||||
ip.u.ip4 = entry->addr.u.ip4;
|
||||
|
||||
+41
-4
@@ -128,6 +128,35 @@ out_noerr:
|
||||
goto out;
|
||||
}
|
||||
|
||||
static struct sk_buff *skb_set_peeked(struct sk_buff *skb)
|
||||
{
|
||||
struct sk_buff *nskb;
|
||||
|
||||
if (skb->peeked)
|
||||
return skb;
|
||||
|
||||
/* We have to unshare an skb before modifying it. */
|
||||
if (!skb_shared(skb))
|
||||
goto done;
|
||||
|
||||
nskb = skb_clone(skb, GFP_ATOMIC);
|
||||
if (!nskb)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
skb->prev->next = nskb;
|
||||
skb->next->prev = nskb;
|
||||
nskb->prev = skb->prev;
|
||||
nskb->next = skb->next;
|
||||
|
||||
consume_skb(skb);
|
||||
skb = nskb;
|
||||
|
||||
done:
|
||||
skb->peeked = 1;
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
/**
|
||||
* __skb_recv_datagram - Receive a datagram skbuff
|
||||
* @sk: socket
|
||||
@@ -162,7 +191,9 @@ out_noerr:
|
||||
struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags,
|
||||
int *peeked, int *off, int *err)
|
||||
{
|
||||
struct sk_buff_head *queue = &sk->sk_receive_queue;
|
||||
struct sk_buff *skb, *last;
|
||||
unsigned long cpu_flags;
|
||||
long timeo;
|
||||
/*
|
||||
* Caller is allowed not to check sk->sk_err before skb_recv_datagram()
|
||||
@@ -181,8 +212,6 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags,
|
||||
* Look at current nfs client by the way...
|
||||
* However, this function was correct in any case. 8)
|
||||
*/
|
||||
unsigned long cpu_flags;
|
||||
struct sk_buff_head *queue = &sk->sk_receive_queue;
|
||||
int _off = *off;
|
||||
|
||||
last = (struct sk_buff *)queue;
|
||||
@@ -196,7 +225,12 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags,
|
||||
_off -= skb->len;
|
||||
continue;
|
||||
}
|
||||
skb->peeked = 1;
|
||||
|
||||
skb = skb_set_peeked(skb);
|
||||
error = PTR_ERR(skb);
|
||||
if (IS_ERR(skb))
|
||||
goto unlock_err;
|
||||
|
||||
atomic_inc(&skb->users);
|
||||
} else
|
||||
__skb_unlink(skb, queue);
|
||||
@@ -216,6 +250,8 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags,
|
||||
|
||||
return NULL;
|
||||
|
||||
unlock_err:
|
||||
spin_unlock_irqrestore(&queue->lock, cpu_flags);
|
||||
no_packet:
|
||||
*err = error;
|
||||
return NULL;
|
||||
@@ -665,7 +701,8 @@ __sum16 __skb_checksum_complete_head(struct sk_buff *skb, int len)
|
||||
if (likely(!sum)) {
|
||||
if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE))
|
||||
netdev_rx_csum_fault(skb->dev);
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
if (!skb_shared(skb))
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
+14
-15
@@ -3464,8 +3464,6 @@ static int __netif_receive_skb_core(struct sk_buff *skb, bool pfmemalloc)
|
||||
|
||||
pt_prev = NULL;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
another_round:
|
||||
skb->skb_iif = skb->dev->ifindex;
|
||||
|
||||
@@ -3475,7 +3473,7 @@ another_round:
|
||||
skb->protocol == cpu_to_be16(ETH_P_8021AD)) {
|
||||
skb = vlan_untag(skb);
|
||||
if (unlikely(!skb))
|
||||
goto unlock;
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NET_CLS_ACT
|
||||
@@ -3500,7 +3498,7 @@ skip_taps:
|
||||
#ifdef CONFIG_NET_CLS_ACT
|
||||
skb = handle_ing(skb, &pt_prev, &ret, orig_dev);
|
||||
if (!skb)
|
||||
goto unlock;
|
||||
goto out;
|
||||
ncls:
|
||||
#endif
|
||||
|
||||
@@ -3515,7 +3513,7 @@ ncls:
|
||||
if (vlan_do_receive(&skb))
|
||||
goto another_round;
|
||||
else if (unlikely(!skb))
|
||||
goto unlock;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rx_handler = rcu_dereference(skb->dev->rx_handler);
|
||||
@@ -3527,7 +3525,7 @@ ncls:
|
||||
switch (rx_handler(&skb)) {
|
||||
case RX_HANDLER_CONSUMED:
|
||||
ret = NET_RX_SUCCESS;
|
||||
goto unlock;
|
||||
goto out;
|
||||
case RX_HANDLER_ANOTHER:
|
||||
goto another_round;
|
||||
case RX_HANDLER_EXACT:
|
||||
@@ -3579,8 +3577,6 @@ drop:
|
||||
ret = NET_RX_DROP;
|
||||
}
|
||||
|
||||
unlock:
|
||||
rcu_read_unlock();
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
@@ -3627,29 +3623,30 @@ static int __netif_receive_skb(struct sk_buff *skb)
|
||||
*/
|
||||
int netif_receive_skb(struct sk_buff *skb)
|
||||
{
|
||||
int ret;
|
||||
|
||||
net_timestamp_check(netdev_tstamp_prequeue, skb);
|
||||
|
||||
if (skb_defer_rx_timestamp(skb))
|
||||
return NET_RX_SUCCESS;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
#ifdef CONFIG_RPS
|
||||
if (static_key_false(&rps_needed)) {
|
||||
struct rps_dev_flow voidflow, *rflow = &voidflow;
|
||||
int cpu, ret;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
cpu = get_rps_cpu(skb->dev, skb, &rflow);
|
||||
int cpu = get_rps_cpu(skb->dev, skb, &rflow);
|
||||
|
||||
if (cpu >= 0) {
|
||||
ret = enqueue_to_backlog(skb, cpu, &rflow->last_qtail);
|
||||
rcu_read_unlock();
|
||||
return ret;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
#endif
|
||||
return __netif_receive_skb(skb);
|
||||
ret = __netif_receive_skb(skb);
|
||||
rcu_read_unlock();
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(netif_receive_skb);
|
||||
|
||||
@@ -4059,8 +4056,10 @@ static int process_backlog(struct napi_struct *napi, int quota)
|
||||
unsigned int qlen;
|
||||
|
||||
while ((skb = __skb_dequeue(&sd->process_queue))) {
|
||||
rcu_read_lock();
|
||||
local_irq_enable();
|
||||
__netif_receive_skb(skb);
|
||||
rcu_read_unlock();
|
||||
local_irq_disable();
|
||||
input_queue_head_incr(sd);
|
||||
if (++work >= quota) {
|
||||
|
||||
@@ -645,15 +645,17 @@ static int dump_rules(struct sk_buff *skb, struct netlink_callback *cb,
|
||||
{
|
||||
int idx = 0;
|
||||
struct fib_rule *rule;
|
||||
int err = 0;
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(rule, &ops->rules_list, list) {
|
||||
if (idx < cb->args[1])
|
||||
goto skip;
|
||||
|
||||
if (fib_nl_fill_rule(skb, rule, NETLINK_CB(cb->skb).portid,
|
||||
cb->nlh->nlmsg_seq, RTM_NEWRULE,
|
||||
NLM_F_MULTI, ops) < 0)
|
||||
err = fib_nl_fill_rule(skb, rule, NETLINK_CB(cb->skb).portid,
|
||||
cb->nlh->nlmsg_seq, RTM_NEWRULE,
|
||||
NLM_F_MULTI, ops);
|
||||
if (err)
|
||||
break;
|
||||
skip:
|
||||
idx++;
|
||||
@@ -662,7 +664,7 @@ skip:
|
||||
cb->args[1] = idx;
|
||||
rules_ops_put(ops);
|
||||
|
||||
return skb->len;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int fib_nl_dumprule(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
@@ -678,7 +680,9 @@ static int fib_nl_dumprule(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
if (ops == NULL)
|
||||
return -EAFNOSUPPORT;
|
||||
|
||||
return dump_rules(skb, cb, ops);
|
||||
dump_rules(skb, cb, ops);
|
||||
|
||||
return skb->len;
|
||||
}
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
+3
-1
@@ -3377,8 +3377,10 @@ static int pktgen_thread_worker(void *arg)
|
||||
pktgen_rem_thread(t);
|
||||
|
||||
/* Wait for kthread_stop */
|
||||
while (!kthread_should_stop()) {
|
||||
for (;;) {
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
if (kthread_should_stop())
|
||||
break;
|
||||
schedule();
|
||||
}
|
||||
__set_current_state(TASK_RUNNING);
|
||||
|
||||
+12
-4
@@ -20,7 +20,7 @@
|
||||
#include <net/route.h>
|
||||
#include <net/tcp_states.h>
|
||||
|
||||
int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
|
||||
int __ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
|
||||
{
|
||||
struct inet_sock *inet = inet_sk(sk);
|
||||
struct sockaddr_in *usin = (struct sockaddr_in *) uaddr;
|
||||
@@ -39,8 +39,6 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
|
||||
|
||||
sk_dst_reset(sk);
|
||||
|
||||
lock_sock(sk);
|
||||
|
||||
oif = sk->sk_bound_dev_if;
|
||||
saddr = inet->inet_saddr;
|
||||
if (ipv4_is_multicast(usin->sin_addr.s_addr)) {
|
||||
@@ -81,9 +79,19 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
|
||||
sk_dst_set(sk, &rt->dst);
|
||||
err = 0;
|
||||
out:
|
||||
release_sock(sk);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(__ip4_datagram_connect);
|
||||
|
||||
int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
|
||||
{
|
||||
int res;
|
||||
|
||||
lock_sock(sk);
|
||||
res = __ip4_datagram_connect(sk, uaddr, addr_len);
|
||||
release_sock(sk);
|
||||
return res;
|
||||
}
|
||||
EXPORT_SYMBOL(ip4_datagram_connect);
|
||||
|
||||
/* Because UDP xmit path can manipulate sk_dst_cache without holding
|
||||
|
||||
@@ -356,7 +356,7 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
|
||||
ihl = ip_hdrlen(skb);
|
||||
|
||||
/* Determine the position of this fragment. */
|
||||
end = offset + skb->len - ihl;
|
||||
end = offset + skb->len - skb_network_offset(skb) - ihl;
|
||||
err = -EINVAL;
|
||||
|
||||
/* Is this the final fragment? */
|
||||
@@ -386,7 +386,7 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
|
||||
goto err;
|
||||
|
||||
err = -ENOMEM;
|
||||
if (pskb_pull(skb, ihl) == NULL)
|
||||
if (!pskb_pull(skb, skb_network_offset(skb) + ihl))
|
||||
goto err;
|
||||
|
||||
err = pskb_trim_rcsum(skb, end - offset);
|
||||
@@ -627,6 +627,9 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
|
||||
iph->frag_off = qp->q.max_size ? htons(IP_DF) : 0;
|
||||
iph->tot_len = htons(len);
|
||||
iph->tos |= ecn;
|
||||
|
||||
ip_send_check(iph);
|
||||
|
||||
IP_INC_STATS_BH(net, IPSTATS_MIB_REASMOKS);
|
||||
qp->q.fragments = NULL;
|
||||
qp->q.fragments_tail = NULL;
|
||||
|
||||
+15
-5
@@ -40,7 +40,7 @@ static bool ipv6_mapped_addr_any(const struct in6_addr *a)
|
||||
return ipv6_addr_v4mapped(a) && (a->s6_addr32[3] == 0);
|
||||
}
|
||||
|
||||
int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
|
||||
static int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
|
||||
{
|
||||
struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr;
|
||||
struct inet_sock *inet = inet_sk(sk);
|
||||
@@ -56,7 +56,7 @@ int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
|
||||
if (usin->sin6_family == AF_INET) {
|
||||
if (__ipv6_only_sock(sk))
|
||||
return -EAFNOSUPPORT;
|
||||
err = ip4_datagram_connect(sk, uaddr, addr_len);
|
||||
err = __ip4_datagram_connect(sk, uaddr, addr_len);
|
||||
goto ipv4_connected;
|
||||
}
|
||||
|
||||
@@ -99,9 +99,9 @@ int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
|
||||
sin.sin_addr.s_addr = daddr->s6_addr32[3];
|
||||
sin.sin_port = usin->sin6_port;
|
||||
|
||||
err = ip4_datagram_connect(sk,
|
||||
(struct sockaddr *) &sin,
|
||||
sizeof(sin));
|
||||
err = __ip4_datagram_connect(sk,
|
||||
(struct sockaddr *) &sin,
|
||||
sizeof(sin));
|
||||
|
||||
ipv4_connected:
|
||||
if (err)
|
||||
@@ -205,6 +205,16 @@ out:
|
||||
fl6_sock_release(flowlabel);
|
||||
return err;
|
||||
}
|
||||
|
||||
int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
|
||||
{
|
||||
int res;
|
||||
|
||||
lock_sock(sk);
|
||||
res = __ip6_datagram_connect(sk, uaddr, addr_len);
|
||||
release_sock(sk);
|
||||
return res;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ip6_datagram_connect);
|
||||
|
||||
void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
|
||||
|
||||
@@ -36,6 +36,6 @@ out:
|
||||
return ret;
|
||||
|
||||
out_rt:
|
||||
inet_del_offload(&rthdr_offload, IPPROTO_ROUTING);
|
||||
inet6_del_offload(&rthdr_offload, IPPROTO_ROUTING);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -359,6 +359,7 @@ static void ip6gre_tunnel_uninit(struct net_device *dev)
|
||||
struct ip6gre_net *ign = net_generic(net, ip6gre_net_id);
|
||||
|
||||
ip6gre_tunnel_unlink(ign, netdev_priv(dev));
|
||||
ip6_tnl_dst_reset(netdev_priv(dev));
|
||||
dev_put(dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -325,10 +325,10 @@ int ip6_mc_input(struct sk_buff *skb)
|
||||
if (offset < 0)
|
||||
goto out;
|
||||
|
||||
if (!ipv6_is_mld(skb, nexthdr, offset))
|
||||
goto out;
|
||||
if (ipv6_is_mld(skb, nexthdr, offset))
|
||||
deliver = true;
|
||||
|
||||
deliver = true;
|
||||
goto out;
|
||||
}
|
||||
/* unknown RA - process it normally */
|
||||
}
|
||||
|
||||
+1
-1
@@ -552,7 +552,7 @@ static void ipmr_mfc_seq_stop(struct seq_file *seq, void *v)
|
||||
|
||||
if (it->cache == &mrt->mfc6_unres_queue)
|
||||
spin_unlock_bh(&mfc_unres_lock);
|
||||
else if (it->cache == mrt->mfc6_cache_array)
|
||||
else if (it->cache == &mrt->mfc6_cache_array[it->ct])
|
||||
read_unlock(&mrt_lock);
|
||||
}
|
||||
|
||||
|
||||
@@ -281,9 +281,6 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
|
||||
if (tx->sdata->vif.type == NL80211_IFTYPE_WDS)
|
||||
return TX_CONTINUE;
|
||||
|
||||
if (tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
|
||||
return TX_CONTINUE;
|
||||
|
||||
if (tx->flags & IEEE80211_TX_PS_BUFFERED)
|
||||
return TX_CONTINUE;
|
||||
|
||||
|
||||
+47
-32
@@ -214,25 +214,52 @@ err1:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
__netlink_set_ring(struct sock *sk, struct nl_mmap_req *req, bool tx_ring, void **pg_vec,
|
||||
unsigned int order)
|
||||
{
|
||||
struct netlink_sock *nlk = nlk_sk(sk);
|
||||
struct sk_buff_head *queue;
|
||||
struct netlink_ring *ring;
|
||||
|
||||
queue = tx_ring ? &sk->sk_write_queue : &sk->sk_receive_queue;
|
||||
ring = tx_ring ? &nlk->tx_ring : &nlk->rx_ring;
|
||||
|
||||
spin_lock_bh(&queue->lock);
|
||||
|
||||
ring->frame_max = req->nm_frame_nr - 1;
|
||||
ring->head = 0;
|
||||
ring->frame_size = req->nm_frame_size;
|
||||
ring->pg_vec_pages = req->nm_block_size / PAGE_SIZE;
|
||||
|
||||
swap(ring->pg_vec_len, req->nm_block_nr);
|
||||
swap(ring->pg_vec_order, order);
|
||||
swap(ring->pg_vec, pg_vec);
|
||||
|
||||
__skb_queue_purge(queue);
|
||||
spin_unlock_bh(&queue->lock);
|
||||
|
||||
WARN_ON(atomic_read(&nlk->mapped));
|
||||
|
||||
if (pg_vec)
|
||||
free_pg_vec(pg_vec, order, req->nm_block_nr);
|
||||
}
|
||||
|
||||
static int netlink_set_ring(struct sock *sk, struct nl_mmap_req *req,
|
||||
bool closing, bool tx_ring)
|
||||
bool tx_ring)
|
||||
{
|
||||
struct netlink_sock *nlk = nlk_sk(sk);
|
||||
struct netlink_ring *ring;
|
||||
struct sk_buff_head *queue;
|
||||
void **pg_vec = NULL;
|
||||
unsigned int order = 0;
|
||||
int err;
|
||||
|
||||
ring = tx_ring ? &nlk->tx_ring : &nlk->rx_ring;
|
||||
queue = tx_ring ? &sk->sk_write_queue : &sk->sk_receive_queue;
|
||||
|
||||
if (!closing) {
|
||||
if (atomic_read(&nlk->mapped))
|
||||
return -EBUSY;
|
||||
if (atomic_read(&ring->pending))
|
||||
return -EBUSY;
|
||||
}
|
||||
if (atomic_read(&nlk->mapped))
|
||||
return -EBUSY;
|
||||
if (atomic_read(&ring->pending))
|
||||
return -EBUSY;
|
||||
|
||||
if (req->nm_block_nr) {
|
||||
if (ring->pg_vec != NULL)
|
||||
@@ -264,31 +291,19 @@ static int netlink_set_ring(struct sock *sk, struct nl_mmap_req *req,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = -EBUSY;
|
||||
mutex_lock(&nlk->pg_vec_lock);
|
||||
if (closing || atomic_read(&nlk->mapped) == 0) {
|
||||
err = 0;
|
||||
spin_lock_bh(&queue->lock);
|
||||
|
||||
ring->frame_max = req->nm_frame_nr - 1;
|
||||
ring->head = 0;
|
||||
ring->frame_size = req->nm_frame_size;
|
||||
ring->pg_vec_pages = req->nm_block_size / PAGE_SIZE;
|
||||
|
||||
swap(ring->pg_vec_len, req->nm_block_nr);
|
||||
swap(ring->pg_vec_order, order);
|
||||
swap(ring->pg_vec, pg_vec);
|
||||
|
||||
__skb_queue_purge(queue);
|
||||
spin_unlock_bh(&queue->lock);
|
||||
|
||||
WARN_ON(atomic_read(&nlk->mapped));
|
||||
if (atomic_read(&nlk->mapped) == 0) {
|
||||
__netlink_set_ring(sk, req, tx_ring, pg_vec, order);
|
||||
mutex_unlock(&nlk->pg_vec_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
mutex_unlock(&nlk->pg_vec_lock);
|
||||
|
||||
if (pg_vec)
|
||||
free_pg_vec(pg_vec, order, req->nm_block_nr);
|
||||
return err;
|
||||
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
static void netlink_mm_open(struct vm_area_struct *vma)
|
||||
@@ -762,10 +777,10 @@ static void netlink_sock_destruct(struct sock *sk)
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
if (nlk->rx_ring.pg_vec)
|
||||
netlink_set_ring(sk, &req, true, false);
|
||||
__netlink_set_ring(sk, &req, false, NULL, 0);
|
||||
memset(&req, 0, sizeof(req));
|
||||
if (nlk->tx_ring.pg_vec)
|
||||
netlink_set_ring(sk, &req, true, true);
|
||||
__netlink_set_ring(sk, &req, true, NULL, 0);
|
||||
}
|
||||
#endif /* CONFIG_NETLINK_MMAP */
|
||||
|
||||
@@ -2017,7 +2032,7 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname,
|
||||
return -EINVAL;
|
||||
if (copy_from_user(&req, optval, sizeof(req)))
|
||||
return -EFAULT;
|
||||
err = netlink_set_ring(sk, &req, false,
|
||||
err = netlink_set_ring(sk, &req,
|
||||
optname == NETLINK_TX_RING);
|
||||
break;
|
||||
}
|
||||
|
||||
+1
-1
@@ -176,7 +176,7 @@ int rds_info_getsockopt(struct socket *sock, int optname, char __user *optval,
|
||||
|
||||
/* check for all kinds of wrapping and the like */
|
||||
start = (unsigned long)optval;
|
||||
if (len < 0 || len + PAGE_SIZE - 1 < len || start + len < start) {
|
||||
if (len < 0 || len > INT_MAX - PAGE_SIZE + 1 || start + len < start) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
+41
-23
@@ -1170,7 +1170,7 @@ static void sctp_v4_del_protocol(void)
|
||||
unregister_inetaddr_notifier(&sctp_inetaddr_notifier);
|
||||
}
|
||||
|
||||
static int __net_init sctp_net_init(struct net *net)
|
||||
static int __net_init sctp_defaults_init(struct net *net)
|
||||
{
|
||||
int status;
|
||||
|
||||
@@ -1263,12 +1263,6 @@ static int __net_init sctp_net_init(struct net *net)
|
||||
|
||||
sctp_dbg_objcnt_init(net);
|
||||
|
||||
/* Initialize the control inode/socket for handling OOTB packets. */
|
||||
if ((status = sctp_ctl_sock_init(net))) {
|
||||
pr_err("Failed to initialize the SCTP control sock\n");
|
||||
goto err_ctl_sock_init;
|
||||
}
|
||||
|
||||
/* Initialize the local address list. */
|
||||
INIT_LIST_HEAD(&net->sctp.local_addr_list);
|
||||
spin_lock_init(&net->sctp.local_addr_lock);
|
||||
@@ -1284,9 +1278,6 @@ static int __net_init sctp_net_init(struct net *net)
|
||||
|
||||
return 0;
|
||||
|
||||
err_ctl_sock_init:
|
||||
sctp_dbg_objcnt_exit(net);
|
||||
sctp_proc_exit(net);
|
||||
err_init_proc:
|
||||
cleanup_sctp_mibs(net);
|
||||
err_init_mibs:
|
||||
@@ -1295,15 +1286,12 @@ err_sysctl_register:
|
||||
return status;
|
||||
}
|
||||
|
||||
static void __net_exit sctp_net_exit(struct net *net)
|
||||
static void __net_exit sctp_defaults_exit(struct net *net)
|
||||
{
|
||||
/* Free the local address list */
|
||||
sctp_free_addr_wq(net);
|
||||
sctp_free_local_addr_list(net);
|
||||
|
||||
/* Free the control endpoint. */
|
||||
inet_ctl_sock_destroy(net->sctp.ctl_sock);
|
||||
|
||||
sctp_dbg_objcnt_exit(net);
|
||||
|
||||
sctp_proc_exit(net);
|
||||
@@ -1311,9 +1299,32 @@ static void __net_exit sctp_net_exit(struct net *net)
|
||||
sctp_sysctl_net_unregister(net);
|
||||
}
|
||||
|
||||
static struct pernet_operations sctp_net_ops = {
|
||||
.init = sctp_net_init,
|
||||
.exit = sctp_net_exit,
|
||||
static struct pernet_operations sctp_defaults_ops = {
|
||||
.init = sctp_defaults_init,
|
||||
.exit = sctp_defaults_exit,
|
||||
};
|
||||
|
||||
static int __net_init sctp_ctrlsock_init(struct net *net)
|
||||
{
|
||||
int status;
|
||||
|
||||
/* Initialize the control inode/socket for handling OOTB packets. */
|
||||
status = sctp_ctl_sock_init(net);
|
||||
if (status)
|
||||
pr_err("Failed to initialize the SCTP control sock\n");
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void __net_init sctp_ctrlsock_exit(struct net *net)
|
||||
{
|
||||
/* Free the control endpoint. */
|
||||
inet_ctl_sock_destroy(net->sctp.ctl_sock);
|
||||
}
|
||||
|
||||
static struct pernet_operations sctp_ctrlsock_ops = {
|
||||
.init = sctp_ctrlsock_init,
|
||||
.exit = sctp_ctrlsock_exit,
|
||||
};
|
||||
|
||||
/* Initialize the universe into something sensible. */
|
||||
@@ -1448,8 +1459,11 @@ SCTP_STATIC __init int sctp_init(void)
|
||||
sctp_v4_pf_init();
|
||||
sctp_v6_pf_init();
|
||||
|
||||
status = sctp_v4_protosw_init();
|
||||
status = register_pernet_subsys(&sctp_defaults_ops);
|
||||
if (status)
|
||||
goto err_register_defaults;
|
||||
|
||||
status = sctp_v4_protosw_init();
|
||||
if (status)
|
||||
goto err_protosw_init;
|
||||
|
||||
@@ -1457,9 +1471,9 @@ SCTP_STATIC __init int sctp_init(void)
|
||||
if (status)
|
||||
goto err_v6_protosw_init;
|
||||
|
||||
status = register_pernet_subsys(&sctp_net_ops);
|
||||
status = register_pernet_subsys(&sctp_ctrlsock_ops);
|
||||
if (status)
|
||||
goto err_register_pernet_subsys;
|
||||
goto err_register_ctrlsock;
|
||||
|
||||
status = sctp_v4_add_protocol();
|
||||
if (status)
|
||||
@@ -1476,12 +1490,14 @@ out:
|
||||
err_v6_add_protocol:
|
||||
sctp_v4_del_protocol();
|
||||
err_add_protocol:
|
||||
unregister_pernet_subsys(&sctp_net_ops);
|
||||
err_register_pernet_subsys:
|
||||
unregister_pernet_subsys(&sctp_ctrlsock_ops);
|
||||
err_register_ctrlsock:
|
||||
sctp_v6_protosw_exit();
|
||||
err_v6_protosw_init:
|
||||
sctp_v4_protosw_exit();
|
||||
err_protosw_init:
|
||||
unregister_pernet_subsys(&sctp_defaults_ops);
|
||||
err_register_defaults:
|
||||
sctp_v4_pf_exit();
|
||||
sctp_v6_pf_exit();
|
||||
sctp_sysctl_unregister();
|
||||
@@ -1514,12 +1530,14 @@ SCTP_STATIC __exit void sctp_exit(void)
|
||||
sctp_v6_del_protocol();
|
||||
sctp_v4_del_protocol();
|
||||
|
||||
unregister_pernet_subsys(&sctp_net_ops);
|
||||
unregister_pernet_subsys(&sctp_ctrlsock_ops);
|
||||
|
||||
/* Free protosw registrations */
|
||||
sctp_v6_protosw_exit();
|
||||
sctp_v4_protosw_exit();
|
||||
|
||||
unregister_pernet_subsys(&sctp_defaults_ops);
|
||||
|
||||
/* Unregister with socket layer. */
|
||||
sctp_v6_pf_exit();
|
||||
sctp_v4_pf_exit();
|
||||
|
||||
+32
-11
@@ -1548,8 +1548,10 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout)
|
||||
|
||||
/* Supposedly, no process has access to the socket, but
|
||||
* the net layers still may.
|
||||
* Also, sctp_destroy_sock() needs to be called with addr_wq_lock
|
||||
* held and that should be grabbed before socket lock.
|
||||
*/
|
||||
sctp_local_bh_disable();
|
||||
spin_lock_bh(&net->sctp.addr_wq_lock);
|
||||
sctp_bh_lock_sock(sk);
|
||||
|
||||
/* Hold the sock, since sk_common_release() will put sock_put()
|
||||
@@ -1559,7 +1561,7 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout)
|
||||
sk_common_release(sk);
|
||||
|
||||
sctp_bh_unlock_sock(sk);
|
||||
sctp_local_bh_enable();
|
||||
spin_unlock_bh(&net->sctp.addr_wq_lock);
|
||||
|
||||
sock_put(sk);
|
||||
|
||||
@@ -3508,6 +3510,7 @@ static int sctp_setsockopt_auto_asconf(struct sock *sk, char __user *optval,
|
||||
if ((val && sp->do_auto_asconf) || (!val && !sp->do_auto_asconf))
|
||||
return 0;
|
||||
|
||||
spin_lock_bh(&sock_net(sk)->sctp.addr_wq_lock);
|
||||
if (val == 0 && sp->do_auto_asconf) {
|
||||
list_del(&sp->auto_asconf_list);
|
||||
sp->do_auto_asconf = 0;
|
||||
@@ -3516,6 +3519,7 @@ static int sctp_setsockopt_auto_asconf(struct sock *sk, char __user *optval,
|
||||
&sock_net(sk)->sctp.auto_asconf_splist);
|
||||
sp->do_auto_asconf = 1;
|
||||
}
|
||||
spin_unlock_bh(&sock_net(sk)->sctp.addr_wq_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4007,18 +4011,28 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
|
||||
local_bh_disable();
|
||||
percpu_counter_inc(&sctp_sockets_allocated);
|
||||
sock_prot_inuse_add(net, sk->sk_prot, 1);
|
||||
|
||||
/* Nothing can fail after this block, otherwise
|
||||
* sctp_destroy_sock() will be called without addr_wq_lock held
|
||||
*/
|
||||
if (net->sctp.default_auto_asconf) {
|
||||
spin_lock(&sock_net(sk)->sctp.addr_wq_lock);
|
||||
list_add_tail(&sp->auto_asconf_list,
|
||||
&net->sctp.auto_asconf_splist);
|
||||
sp->do_auto_asconf = 1;
|
||||
} else
|
||||
spin_unlock(&sock_net(sk)->sctp.addr_wq_lock);
|
||||
} else {
|
||||
sp->do_auto_asconf = 0;
|
||||
}
|
||||
|
||||
local_bh_enable();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Cleanup any SCTP per socket resources. */
|
||||
/* Cleanup any SCTP per socket resources. Must be called with
|
||||
* sock_net(sk)->sctp.addr_wq_lock held if sp->do_auto_asconf is true
|
||||
*/
|
||||
SCTP_STATIC void sctp_destroy_sock(struct sock *sk)
|
||||
{
|
||||
struct sctp_sock *sp;
|
||||
@@ -6957,6 +6971,19 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk,
|
||||
newinet->mc_list = NULL;
|
||||
}
|
||||
|
||||
static inline void sctp_copy_descendant(struct sock *sk_to,
|
||||
const struct sock *sk_from)
|
||||
{
|
||||
int ancestor_size = sizeof(struct inet_sock) +
|
||||
sizeof(struct sctp_sock) -
|
||||
offsetof(struct sctp_sock, auto_asconf_list);
|
||||
|
||||
if (sk_from->sk_family == PF_INET6)
|
||||
ancestor_size += sizeof(struct ipv6_pinfo);
|
||||
|
||||
__inet_sk_copy_descendant(sk_to, sk_from, ancestor_size);
|
||||
}
|
||||
|
||||
/* Populate the fields of the newsk from the oldsk and migrate the assoc
|
||||
* and its messages to the newsk.
|
||||
*/
|
||||
@@ -6971,7 +6998,6 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
|
||||
struct sk_buff *skb, *tmp;
|
||||
struct sctp_ulpevent *event;
|
||||
struct sctp_bind_hashbucket *head;
|
||||
struct list_head tmplist;
|
||||
|
||||
/* Migrate socket buffer sizes and all the socket level options to the
|
||||
* new socket.
|
||||
@@ -6979,12 +7005,7 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
|
||||
newsk->sk_sndbuf = oldsk->sk_sndbuf;
|
||||
newsk->sk_rcvbuf = oldsk->sk_rcvbuf;
|
||||
/* Brute force copy old sctp opt. */
|
||||
if (oldsp->do_auto_asconf) {
|
||||
memcpy(&tmplist, &newsp->auto_asconf_list, sizeof(tmplist));
|
||||
inet_sk_copy_descendant(newsk, oldsk);
|
||||
memcpy(&newsp->auto_asconf_list, &tmplist, sizeof(tmplist));
|
||||
} else
|
||||
inet_sk_copy_descendant(newsk, oldsk);
|
||||
sctp_copy_descendant(newsk, oldsk);
|
||||
|
||||
/* Restore the ep value that was overwritten with the above structure
|
||||
* copy.
|
||||
|
||||
@@ -1528,6 +1528,7 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags)
|
||||
res = tipc_create(sock_net(sock->sk), new_sock, 0, 0);
|
||||
if (res)
|
||||
goto exit;
|
||||
security_sk_clone(sock->sk, new_sock->sk);
|
||||
|
||||
new_sk = new_sock->sk;
|
||||
new_tsock = tipc_sk(new_sk);
|
||||
|
||||
@@ -1137,7 +1137,7 @@ static const struct hda_fixup alc880_fixups[] = {
|
||||
/* override all pins as BIOS on old Amilo is broken */
|
||||
.type = HDA_FIXUP_PINS,
|
||||
.v.pins = (const struct hda_pintbl[]) {
|
||||
{ 0x14, 0x0121411f }, /* HP */
|
||||
{ 0x14, 0x0121401f }, /* HP */
|
||||
{ 0x15, 0x99030120 }, /* speaker */
|
||||
{ 0x16, 0x99030130 }, /* bass speaker */
|
||||
{ 0x17, 0x411111f0 }, /* N/A */
|
||||
@@ -1157,7 +1157,7 @@ static const struct hda_fixup alc880_fixups[] = {
|
||||
/* almost compatible with FUJITSU, but no bass and SPDIF */
|
||||
.type = HDA_FIXUP_PINS,
|
||||
.v.pins = (const struct hda_pintbl[]) {
|
||||
{ 0x14, 0x0121411f }, /* HP */
|
||||
{ 0x14, 0x0121401f }, /* HP */
|
||||
{ 0x15, 0x99030120 }, /* speaker */
|
||||
{ 0x16, 0x411111f0 }, /* N/A */
|
||||
{ 0x17, 0x411111f0 }, /* N/A */
|
||||
@@ -1365,7 +1365,7 @@ static const struct snd_pci_quirk alc880_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810),
|
||||
SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM),
|
||||
SND_PCI_QUIRK(0x1631, 0xe011, "PB 13201056", ALC880_FIXUP_6ST_AUTOMUTE),
|
||||
SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_FIXUP_F1734),
|
||||
SND_PCI_QUIRK(0x1734, 0x107c, "FSC Amilo M1437", ALC880_FIXUP_FUJITSU),
|
||||
SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU),
|
||||
SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734),
|
||||
SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU),
|
||||
|
||||
Reference in New Issue
Block a user