Update to 3.16.7-ckt4
- Drop various patches that were applied upstream - Refresh "add sysctl to disallow unprivileged CLONE_NEWUSER by default" - Fix/ignore ABI changes as appropriate - Explicitly disable the new CONFIG_IWLWIFI_UAPSD symbol svn path=/dists/sid/linux/; revision=22261
This commit is contained in:
parent
e50021ff04
commit
167d9fdacc
|
@ -1,4 +1,4 @@
|
||||||
linux (3.16.7-ckt3-1) UNRELEASED; urgency=medium
|
linux (3.16.7-ckt4-1) UNRELEASED; urgency=medium
|
||||||
|
|
||||||
* New upstream stable update:
|
* New upstream stable update:
|
||||||
http://kernel.ubuntu.com/stable/ChangeLog-3.16.7-ckt3
|
http://kernel.ubuntu.com/stable/ChangeLog-3.16.7-ckt3
|
||||||
|
@ -83,6 +83,159 @@ linux (3.16.7-ckt3-1) UNRELEASED; urgency=medium
|
||||||
- bond: Check length of IFLA_BOND_ARP_IP_TARGET attributes
|
- bond: Check length of IFLA_BOND_ARP_IP_TARGET attributes
|
||||||
- gre: Set inner mac header in gro complete (regression in 3.16.7-ckt1)
|
- gre: Set inner mac header in gro complete (regression in 3.16.7-ckt1)
|
||||||
- [mips*] bpf: Fix broken BPF_MOD
|
- [mips*] bpf: Fix broken BPF_MOD
|
||||||
|
http://kernel.ubuntu.com/stable/ChangeLog-3.16.7-ckt4
|
||||||
|
- [x86] drm/i915: don't warn if backlight unexpectedly enabled
|
||||||
|
(Closes: #757805)
|
||||||
|
- [x86] drm/i915/dp: only use training pattern 3 on platforms that
|
||||||
|
support it (regression in 3.15)
|
||||||
|
- btrfs: don't go readonly on existing qgroup items
|
||||||
|
- writeback: fix a subtle race condition in I_DIRTY clearing
|
||||||
|
- [s390*] KVM: flush CPU on load control
|
||||||
|
- UBI: Fix double free after do_sync_erase()
|
||||||
|
- [x86] Drivers: hv: util: make struct hv_do_fcopy match Hyper-V host
|
||||||
|
messages (regression for amd64 in 3.16.7)
|
||||||
|
- Drivers: hv: vmbus: Fix a race condition when unregistering a device
|
||||||
|
- misc: genwqe: check for error from get_user_pages_fast()
|
||||||
|
- drbd: merge_bvec_fn: properly remap bvm->bi_bdev
|
||||||
|
- PCI: Restore detection of read-only BARs
|
||||||
|
- scsi: correct return values for .eh_abort_handler implementations
|
||||||
|
- genhd: check for int overflow in disk_expand_part_tbl()
|
||||||
|
- Btrfs: make sure we wait on logged extents when fsycning two subvols
|
||||||
|
- Btrfs: make sure logged extents complete in the current transaction V3
|
||||||
|
- Btrfs: do not move em to modified list when unpinning
|
||||||
|
- [armhf] mvebu: disable I/O coherency on non-SMP situations on
|
||||||
|
Armada 370/375/38x/XP
|
||||||
|
- nfs41: fix nfs4_proc_layoutget error handling
|
||||||
|
- USB: cdc-acm: check for valid interfaces
|
||||||
|
- HID: i2c-hid: fix race condition reading reports
|
||||||
|
- [armhf] mfd: twl4030-power: Fix regression with missing compatible flag
|
||||||
|
(regression in 3.16)
|
||||||
|
- [armhf] serial: samsung: wait for transfer completion before clock
|
||||||
|
disable
|
||||||
|
- n_tty: Fix read_buf race condition, increment read_head after pushing
|
||||||
|
data (regression in 3.12)
|
||||||
|
- dm cache: only use overwrite optimisation for promotion when in
|
||||||
|
writeback mode
|
||||||
|
- dm cache: dirty flag was mistakenly being cleared when promoting via
|
||||||
|
overwrite
|
||||||
|
- dm bufio: fix memleak when using a dm_buffer's inline bio
|
||||||
|
- iwlwifi: dvm: fix flush support for old firmware (regression in
|
||||||
|
3.16.7-ckt1)
|
||||||
|
- iwlwifi: mvm: update values for Smart Fifo (regression in 3.14)
|
||||||
|
- iommu/vt-d: Fix an off-by-one bug in __domain_mapping()
|
||||||
|
- dm crypt: use memzero_explicit for on-stack buffer
|
||||||
|
- mnt: Implicitly add MNT_NODEV on remount when it was implicitly added by
|
||||||
|
mount (regression in 3.16.3)
|
||||||
|
- umount: Disallow unprivileged mount force
|
||||||
|
- md/raid5: fetch_block must fetch all the blocks handle_stripe_dirtying
|
||||||
|
wants.
|
||||||
|
- [x86] drm/i915: Only warn the first time we attempt to mmio whilst
|
||||||
|
suspended (regression in 3.15)
|
||||||
|
- drm/vmwgfx: Fix error printout on signals pending
|
||||||
|
- drm/radeon: check the right ring in radeon_evict_flags()
|
||||||
|
- swiotlb-xen: pass dev_addr to xen_dma_unmap_page and
|
||||||
|
xen_dma_sync_single_for_cpu
|
||||||
|
- [armhf/armmp] swiotlb-xen: remove BUG_ON in xen_bus_to_phys
|
||||||
|
- swiotlb-xen: call xen_dma_sync_single_for_device when appropriate
|
||||||
|
- swiotlb-xen: pass dev_addr to swiotlb_tbl_unmap_single
|
||||||
|
- [powerpc] book3s: Fix partial invalidation of TLBs in MCE code.
|
||||||
|
- [armhf] clocksource: arch_timer: Fix code to use physical timers when
|
||||||
|
requested (regression in 3.11)
|
||||||
|
- userns: Prevent evasion of group negative permissions through a userns
|
||||||
|
(CVE-2014-8989):
|
||||||
|
+ Don't allow setgroups until a gid mapping has been setablished
|
||||||
|
+ Don't allow unprivileged creation of gid mappings
|
||||||
|
+ Add a knob to disable setgroups on a per user namespace basis
|
||||||
|
+ Allow setting gid_maps without privilege when setgroups is disabled
|
||||||
|
- KEYS: Fix stale key registration at error path
|
||||||
|
- blk-mq: Fix a use-after-free
|
||||||
|
- blk-mq: Fix a race between bt_clear_tag() and bt_get()
|
||||||
|
- nfsd4: fix xdr4 count of server in fs_location4 (regression in 3.16)
|
||||||
|
- [x86] drm/i915: Don't complain about stolen conflicts on gen3
|
||||||
|
(regression in 3.12)
|
||||||
|
- [x86] kvm: Clear paravirt_enabled on KVM guests for espfix32's benefit
|
||||||
|
(CVE-2014-8134)
|
||||||
|
- blk-mq: Fix uninitialized kobject at CPU hotplugging
|
||||||
|
- ncpfs: return proper error from NCP_IOC_SETROOT ioctl
|
||||||
|
- [armhf] rtc: omap: fix clock-source configuration (regression in 3.16)
|
||||||
|
- exit: pidns: alloc_pid() leaks pid_namespace if child_reaper is exiting
|
||||||
|
- [amd64] switch_to(): Load TLS descriptors before switching DS and ES
|
||||||
|
(CVE-2014-9419)
|
||||||
|
- [x86] KVM: nVMX: Disable unrestricted mode if ept=0 (regression in 3.13)
|
||||||
|
- [x86] KVM: em_ret_far overrides cpl (follow-up to CVE-2014-3647 fix)
|
||||||
|
- pstore-ram: Fix hangs by using write-combine mappings
|
||||||
|
- HID: i2c-hid: prevent buffer overflow in early IRQ
|
||||||
|
- mac80211: fix multicast LED blinking and counter (regression in
|
||||||
|
3.16.7-ckt2)
|
||||||
|
- cfg80211: avoid mem leak on driver hint set
|
||||||
|
- nl80211: check matches array length before acessing it
|
||||||
|
- cfg80211: don't WARN about two consecutive Country IE hint
|
||||||
|
(regression in 3.14)
|
||||||
|
- tracing/sched: Check preempt_count() for current when reading task->state
|
||||||
|
(regression in 3.13)
|
||||||
|
- [x86] tls: Validate TLS entries to protect espfix (CVE-2014-8133)
|
||||||
|
- [x86] tls: Disallow unusual TLS segments
|
||||||
|
- isofs: Fix infinite looping over CE entries (CVE-2014-9420)
|
||||||
|
- mac80211: free management frame keys when removing station
|
||||||
|
- ceph: do_sync is never initialized (regression in 3.12)
|
||||||
|
- mnt: Fix a memory stomp in umount (regression in 3.14)
|
||||||
|
- ocfs2: fix journal commit deadlock
|
||||||
|
- md/bitmap: always wait for writes on unplug.
|
||||||
|
- [armhf] mmc: omap_hsmmc: Fix UHS card with DDR50 support (regression in
|
||||||
|
3.16)
|
||||||
|
- [x86] mmc: sdhci-pci-o2micro: Fix Dell E5440 issue (regression in 3.14)
|
||||||
|
- dm space map metadata: fix sm_bootstrap_get_nr_blocks()
|
||||||
|
- dm thin: fix a race in thin_dtr
|
||||||
|
- eCryptfs: Force RO mount when encrypted view is enabled
|
||||||
|
- eCryptfs: Remove buggy and unnecessary write in file name decode routine
|
||||||
|
- tcm_loop: Fix wrong I_T nexus association
|
||||||
|
- Btrfs: fix fs corruption on transaction abort if device supports discard
|
||||||
|
- [x86] perf/intel/uncore: Make sure only uncore events are collected
|
||||||
|
- perf: Fix events installation during moving group
|
||||||
|
- iscsi,iser-target: Initiate termination only once (regression in 3.16.4)
|
||||||
|
- iser-target: Fix flush + disconnect completion handling
|
||||||
|
- iser-target: Parallelize CM connection establishment
|
||||||
|
- iser-target: Fix connected_handler + teardown flow race
|
||||||
|
- iser-target: Handle ADDR_CHANGE event for listener cm_id
|
||||||
|
- iser-target: Fix implicit termination of connections
|
||||||
|
- iser-target: Allocate PI contexts dynamically
|
||||||
|
- iser-target: Fix NULL dereference in SW mode DIF
|
||||||
|
- iscsi,iser-target: Expose supported protection ops according to t10_pi
|
||||||
|
- genirq: Prevent proc race against freeing of irq descriptors
|
||||||
|
- [powerpc] powernv: Switch off MMU before entering nap/sleep/rvwinkle mode
|
||||||
|
- [x86] storvsc: ring buffer failures may result in I/O freeze
|
||||||
|
- iscsi-target: Fail connection on short sendmsg writes
|
||||||
|
- [x86] drm/i915: Invalidate media caches on gen7
|
||||||
|
- [x86] drm/i915: Force the CS stall for invalidate flushes
|
||||||
|
- dm thin: fix inability to discard blocks when in out-of-data-space mode
|
||||||
|
- dm thin: fix missing out-of-data-space to write mode transition if blocks
|
||||||
|
are released
|
||||||
|
- dm: fix missed error code if .end_io isn't implemented by target_type
|
||||||
|
- [armhf] i2c: mv64xxx: rework offload support to fix several problems
|
||||||
|
(regression in 3.12)
|
||||||
|
- [x86] tls: Don't validate lm in set_thread_area() after all
|
||||||
|
- ALSA: usb-audio: extend KEF X300A FU 10 tweak to Arcam rPAC
|
||||||
|
- tick/powerclamp: Remove tick_nohz_idle abuse
|
||||||
|
- audit: don't attempt to lookup PIDs when changing PID filtering audit
|
||||||
|
rules (regression in 3.15)
|
||||||
|
- audit: use supplied gfp_mask from audit_buffer in
|
||||||
|
kauditd_send_multicast_skb (regression in 3.16)
|
||||||
|
- [arm64] kernel: fix __cpu_suspend mm switch on warm-boot
|
||||||
|
- audit: restore AUDIT_LOGINUID unset ABI (regression in 3.10)
|
||||||
|
- Btrfs: fix loop writing of async reclaim
|
||||||
|
- isofs: Fix unchecked printing of ER records (CVE-2014-9584)
|
||||||
|
- crypto: af_alg - fix backlog handling
|
||||||
|
- udf: Check path length when reading symlink
|
||||||
|
- udf: Verify i_size when loading inode
|
||||||
|
- udf: Verify symlink size before loading it
|
||||||
|
- udf: Check component length before reading it
|
||||||
|
- [x86] platform/chrome: chromeos_laptop - Add support for Acer C720
|
||||||
|
(Closes: #774209)
|
||||||
|
- batman-adv: Calculate extra tail size based on queued fragments
|
||||||
|
(Closes: #774155) (CVE-2014-9428)
|
||||||
|
- vfs: move d_rcu from overlapping d_child to overlapping d_alias
|
||||||
|
- vfs: deal with deadlock in d_walk() (CVE-2014-8559)
|
||||||
|
- KEYS: close race between key lookup and freeing (CVE-2014-9529)
|
||||||
|
|
||||||
[ Ben Hutchings ]
|
[ Ben Hutchings ]
|
||||||
* [sh4] Build with gcc-4.8 (Closes: #772602)
|
* [sh4] Build with gcc-4.8 (Closes: #772602)
|
||||||
|
@ -93,13 +246,11 @@ linux (3.16.7-ckt3-1) UNRELEASED; urgency=medium
|
||||||
* PCI: Fix ABI change in 3.16.7-ckt3
|
* PCI: Fix ABI change in 3.16.7-ckt3
|
||||||
* Ignore some ABI changes that don't appear to affect OOT modules:
|
* Ignore some ABI changes that don't appear to affect OOT modules:
|
||||||
- Removal of __add_pages(), __remove_pages(), of_device_is_stdout_path(),
|
- Removal of __add_pages(), __remove_pages(), of_device_is_stdout_path(),
|
||||||
clk_divider_ro_ops
|
clk_divider_ro_ops, tick_nohz_idle_enter, tick_nohz_idle_exit
|
||||||
- Changes to ASoC functions
|
- Changes to ASoC functions
|
||||||
* [arm64] Enable PSTORE as built-in and EFI_VARS_PSTORE as module;
|
* [arm64] Enable PSTORE as built-in and EFI_VARS_PSTORE as module;
|
||||||
ensure efivars and efi-pstore are loaded on EFI systems (Closes: #773309)
|
ensure efivars and efi-pstore are loaded on EFI systems (Closes: #773309)
|
||||||
* hwmon: Enable SENSORS_NCT6683 as module (Closes: #774372)
|
* hwmon: Enable SENSORS_NCT6683 as module (Closes: #774372)
|
||||||
* [x86] platform/chrome: chromeos_laptop - Add support for Acer C720
|
|
||||||
(Closes: #774209)
|
|
||||||
* udeb: Add i2c-designware-{core,platform} to i2c-modules and i2c-hid to
|
* udeb: Add i2c-designware-{core,platform} to i2c-modules and i2c-hid to
|
||||||
input-modules (Closes: #772578)
|
input-modules (Closes: #772578)
|
||||||
* [x86] ACPI / video: Run _BCL before deciding registering backlight
|
* [x86] ACPI / video: Run _BCL before deciding registering backlight
|
||||||
|
@ -107,24 +258,13 @@ linux (3.16.7-ckt3-1) UNRELEASED; urgency=medium
|
||||||
* [amd64] Enable EFI_MIXED to support Bay Trail systems
|
* [amd64] Enable EFI_MIXED to support Bay Trail systems
|
||||||
* efi: Expose underlying UEFI firmware platform size to userland, to
|
* efi: Expose underlying UEFI firmware platform size to userland, to
|
||||||
support installation on Bay Trail systems (Closes: #775191)
|
support installation on Bay Trail systems (Closes: #775191)
|
||||||
* [x86] tls: Validate TLS entries to protect espfix (CVE-2014-8133)
|
* vfs: Changes for compatibility with CVE-2014-8559 fix:
|
||||||
* [x86] kvm: Clear paravirt_enabled on KVM guests for espfix32's benefit
|
|
||||||
(CVE-2014-8134)
|
|
||||||
* [amd64] switch_to(): Load TLS descriptors before switching DS and ES
|
|
||||||
(CVE-2014-9419)
|
|
||||||
* isofs: Fix infinite looping over CE entries (CVE-2014-9420)
|
|
||||||
* batman-adv: Calculate extra tail size based on queued fragments
|
|
||||||
(Closes: #774155) (CVE-2014-9428)
|
|
||||||
* KEYS: close race between key lookup and freeing (CVE-2014-9529)
|
|
||||||
* isofs: Fix unchecked printing of ER records (CVE-2014-9584)
|
|
||||||
* vfs: Fix potential deadlock in dcache (CVE-2014-8559)
|
|
||||||
- move d_rcu from overlapping d_child to overlapping d_alias
|
|
||||||
- aufs: move d_rcu from overlapping d_child to overlapping d_alias
|
- aufs: move d_rcu from overlapping d_child to overlapping d_alias
|
||||||
- vfs: Avoid ABI change for dentry union changes
|
- vfs: Avoid ABI change for dentry union changes
|
||||||
- deal with deadlock in d_walk()
|
|
||||||
* [powerpc/powerpc{,-smp}] video/fb: Change FB_RADEON back to module
|
* [powerpc/powerpc{,-smp}] video/fb: Change FB_RADEON back to module
|
||||||
(Closes: #748398) (thanks to John Paul Adrian Glaubitz for thoroughly
|
(Closes: #748398) (thanks to John Paul Adrian Glaubitz for thoroughly
|
||||||
testing this change)
|
testing this change)
|
||||||
|
* userns: Fix ABI change in 3.16.7-ckt4
|
||||||
|
|
||||||
[ Ian Campbell ]
|
[ Ian Campbell ]
|
||||||
* [armhf] Enable support for support OMAP5432 uEVM by enabling:
|
* [armhf] Enable support for support OMAP5432 uEVM by enabling:
|
||||||
|
|
|
@ -3051,6 +3051,7 @@ CONFIG_IWLWIFI=m
|
||||||
CONFIG_IWLDVM=m
|
CONFIG_IWLDVM=m
|
||||||
CONFIG_IWLMVM=m
|
CONFIG_IWLMVM=m
|
||||||
# CONFIG_IWLWIFI_BCAST_FILTERING is not set
|
# CONFIG_IWLWIFI_BCAST_FILTERING is not set
|
||||||
|
# CONFIG_IWLWIFI_UAPSD is not set
|
||||||
# CONFIG_IWLWIFI_DEBUG is not set
|
# CONFIG_IWLWIFI_DEBUG is not set
|
||||||
# CONFIG_IWLWIFI_DEVICE_TRACING is not set
|
# CONFIG_IWLWIFI_DEVICE_TRACING is not set
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,8 @@ ignore-changes:
|
||||||
module:sound/soc/*
|
module:sound/soc/*
|
||||||
# Not needed by modules at all
|
# Not needed by modules at all
|
||||||
clk_divider_ro_ops
|
clk_divider_ro_ops
|
||||||
|
tick_nohz_idle_enter
|
||||||
|
tick_nohz_idle_exit
|
||||||
|
|
||||||
[base]
|
[base]
|
||||||
arches:
|
arches:
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
From: Sven Eckelmann <sven@narfation.org>
|
|
||||||
Date: Sat, 20 Dec 2014 13:48:55 +0100
|
|
||||||
Subject: batman-adv: Calculate extra tail size based on queued fragments
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
Origin: https://git.kernel.org/linus/5b6698b0e4a37053de35cc24ee695b98a7eb712b
|
|
||||||
|
|
||||||
The fragmentation code was replaced in 610bfc6bc99bc83680d190ebc69359a05fc7f605
|
|
||||||
("batman-adv: Receive fragmented packets and merge"). The new code provided a
|
|
||||||
mostly unused parameter skb for the merging function. It is used inside the
|
|
||||||
function to calculate the additionally needed skb tailroom. But instead of
|
|
||||||
increasing its own tailroom, it is only increasing the tailroom of the first
|
|
||||||
queued skb. This is not correct in some situations because the first queued
|
|
||||||
entry can be a different one than the parameter.
|
|
||||||
|
|
||||||
An observed problem was:
|
|
||||||
|
|
||||||
1. packet with size 104, total_size 1464, fragno 1 was received
|
|
||||||
- packet is queued
|
|
||||||
2. packet with size 1400, total_size 1464, fragno 0 was received
|
|
||||||
- packet is queued at the end of the list
|
|
||||||
3. enough data was received and can be given to the merge function
|
|
||||||
(1464 == (1400 - 20) + (104 - 20))
|
|
||||||
- merge functions gets 1400 byte large packet as skb argument
|
|
||||||
4. merge function gets first entry in queue (104 byte)
|
|
||||||
- stored as skb_out
|
|
||||||
5. merge function calculates the required extra tail as total_size - skb->len
|
|
||||||
- pskb_expand_head tail of skb_out with 64 bytes
|
|
||||||
6. merge function tries to squeeze the extra 1380 bytes from the second queued
|
|
||||||
skb (1400 byte aka skb parameter) in the 64 extra tail bytes of skb_out
|
|
||||||
|
|
||||||
Instead calculate the extra required tail bytes for skb_out also using skb_out
|
|
||||||
instead of using the parameter skb. The skb parameter is only used to get the
|
|
||||||
total_size from the last received packet. This is also the total_size used to
|
|
||||||
decide that all fragments were received.
|
|
||||||
|
|
||||||
Reported-by: Philipp Psurek <philipp.psurek@gmail.com>
|
|
||||||
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
|
||||||
Acked-by: Martin Hundebøll <martin@hundeboll.net>
|
|
||||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
||||||
---
|
|
||||||
net/batman-adv/fragmentation.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c
|
|
||||||
index fc1835c..8af3461 100644
|
|
||||||
--- a/net/batman-adv/fragmentation.c
|
|
||||||
+++ b/net/batman-adv/fragmentation.c
|
|
||||||
@@ -251,7 +251,7 @@ batadv_frag_merge_packets(struct hlist_head *chain, struct sk_buff *skb)
|
|
||||||
kfree(entry);
|
|
||||||
|
|
||||||
/* Make room for the rest of the fragments. */
|
|
||||||
- if (pskb_expand_head(skb_out, 0, size - skb->len, GFP_ATOMIC) < 0) {
|
|
||||||
+ if (pskb_expand_head(skb_out, 0, size - skb_out->len, GFP_ATOMIC) < 0) {
|
|
||||||
kfree_skb(skb_out);
|
|
||||||
skb_out = NULL;
|
|
||||||
goto free;
|
|
|
@ -1,82 +0,0 @@
|
||||||
From: Al Viro <viro@zeniv.linux.org.uk>
|
|
||||||
Date: Sun, 26 Oct 2014 19:31:10 -0400
|
|
||||||
Subject: deal with deadlock in d_walk()
|
|
||||||
Origin: https://git.kernel.org/linus/ca5358ef75fc69fee5322a38a340f5739d997c10
|
|
||||||
|
|
||||||
... by not hitting rename_retry for reasons other than rename having
|
|
||||||
happened. In other words, do _not_ restart when finding that
|
|
||||||
between unlocking the child and locking the parent the former got
|
|
||||||
into __dentry_kill(). Skip the killed siblings instead...
|
|
||||||
|
|
||||||
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
|
|
||||||
---
|
|
||||||
fs/dcache.c | 31 ++++++++++++++++---------------
|
|
||||||
1 file changed, 16 insertions(+), 15 deletions(-)
|
|
||||||
|
|
||||||
--- a/fs/dcache.c
|
|
||||||
+++ b/fs/dcache.c
|
|
||||||
@@ -484,7 +484,7 @@ static void __dentry_kill(struct dentry
|
|
||||||
}
|
|
||||||
/* if it was on the hash then remove it */
|
|
||||||
__d_drop(dentry);
|
|
||||||
- list_del(&dentry->d_child);
|
|
||||||
+ __list_del_entry(&dentry->d_child);
|
|
||||||
/*
|
|
||||||
* Inform d_walk() that we are no longer attached to the
|
|
||||||
* dentry tree
|
|
||||||
@@ -1138,33 +1138,31 @@ resume:
|
|
||||||
/*
|
|
||||||
* All done at this level ... ascend and resume the search.
|
|
||||||
*/
|
|
||||||
+ rcu_read_lock();
|
|
||||||
+ascend:
|
|
||||||
if (this_parent != parent) {
|
|
||||||
struct dentry *child = this_parent;
|
|
||||||
this_parent = child->d_parent;
|
|
||||||
|
|
||||||
- rcu_read_lock();
|
|
||||||
spin_unlock(&child->d_lock);
|
|
||||||
spin_lock(&this_parent->d_lock);
|
|
||||||
|
|
||||||
- /*
|
|
||||||
- * might go back up the wrong parent if we have had a rename
|
|
||||||
- * or deletion
|
|
||||||
- */
|
|
||||||
- if (this_parent != child->d_parent ||
|
|
||||||
- (child->d_flags & DCACHE_DENTRY_KILLED) ||
|
|
||||||
- need_seqretry(&rename_lock, seq)) {
|
|
||||||
- spin_unlock(&this_parent->d_lock);
|
|
||||||
- rcu_read_unlock();
|
|
||||||
+ /* might go back up the wrong parent if we have had a rename. */
|
|
||||||
+ if (need_seqretry(&rename_lock, seq))
|
|
||||||
goto rename_retry;
|
|
||||||
+ next = child->d_child.next;
|
|
||||||
+ while (unlikely(child->d_flags & DCACHE_DENTRY_KILLED)) {
|
|
||||||
+ if (next == &this_parent->d_subdirs)
|
|
||||||
+ goto ascend;
|
|
||||||
+ child = list_entry(next, struct dentry, d_child);
|
|
||||||
+ next = next->next;
|
|
||||||
}
|
|
||||||
rcu_read_unlock();
|
|
||||||
- next = child->d_child.next;
|
|
||||||
goto resume;
|
|
||||||
}
|
|
||||||
- if (need_seqretry(&rename_lock, seq)) {
|
|
||||||
- spin_unlock(&this_parent->d_lock);
|
|
||||||
+ if (need_seqretry(&rename_lock, seq))
|
|
||||||
goto rename_retry;
|
|
||||||
- }
|
|
||||||
+ rcu_read_unlock();
|
|
||||||
if (finish)
|
|
||||||
finish(data);
|
|
||||||
|
|
||||||
@@ -1174,6 +1172,9 @@ out_unlock:
|
|
||||||
return;
|
|
||||||
|
|
||||||
rename_retry:
|
|
||||||
+ spin_unlock(&this_parent->d_lock);
|
|
||||||
+ rcu_read_unlock();
|
|
||||||
+ BUG_ON(seq & 1);
|
|
||||||
if (!retry)
|
|
||||||
return;
|
|
||||||
seq = 1;
|
|
|
@ -1,52 +0,0 @@
|
||||||
From: Jan Kara <jack@suse.cz>
|
|
||||||
Date: Mon, 15 Dec 2014 14:22:46 +0100
|
|
||||||
Subject: isofs: Fix infinite looping over CE entries
|
|
||||||
Origin: https://git.kernel.org/linus/f54e18f1b831c92f6512d2eedb224cd63d607d3d
|
|
||||||
|
|
||||||
Rock Ridge extensions define so called Continuation Entries (CE) which
|
|
||||||
define where is further space with Rock Ridge data. Corrupted isofs
|
|
||||||
image can contain arbitrarily long chain of these, including a one
|
|
||||||
containing loop and thus causing kernel to end in an infinite loop when
|
|
||||||
traversing these entries.
|
|
||||||
|
|
||||||
Limit the traversal to 32 entries which should be more than enough space
|
|
||||||
to store all the Rock Ridge data.
|
|
||||||
|
|
||||||
Reported-by: P J P <ppandit@redhat.com>
|
|
||||||
CC: stable@vger.kernel.org
|
|
||||||
Signed-off-by: Jan Kara <jack@suse.cz>
|
|
||||||
---
|
|
||||||
fs/isofs/rock.c | 6 ++++++
|
|
||||||
1 file changed, 6 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c
|
|
||||||
index f488bba..bb63254 100644
|
|
||||||
--- a/fs/isofs/rock.c
|
|
||||||
+++ b/fs/isofs/rock.c
|
|
||||||
@@ -30,6 +30,7 @@ struct rock_state {
|
|
||||||
int cont_size;
|
|
||||||
int cont_extent;
|
|
||||||
int cont_offset;
|
|
||||||
+ int cont_loops;
|
|
||||||
struct inode *inode;
|
|
||||||
};
|
|
||||||
|
|
||||||
@@ -73,6 +74,9 @@ static void init_rock_state(struct rock_state *rs, struct inode *inode)
|
|
||||||
rs->inode = inode;
|
|
||||||
}
|
|
||||||
|
|
||||||
+/* Maximum number of Rock Ridge continuation entries */
|
|
||||||
+#define RR_MAX_CE_ENTRIES 32
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* Returns 0 if the caller should continue scanning, 1 if the scan must end
|
|
||||||
* and -ve on error.
|
|
||||||
@@ -105,6 +109,8 @@ static int rock_continue(struct rock_state *rs)
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
ret = -EIO;
|
|
||||||
+ if (++rs->cont_loops >= RR_MAX_CE_ENTRIES)
|
|
||||||
+ goto out;
|
|
||||||
bh = sb_bread(rs->inode->i_sb, rs->cont_extent);
|
|
||||||
if (bh) {
|
|
||||||
memcpy(rs->buffer, bh->b_data + rs->cont_offset,
|
|
|
@ -1,30 +0,0 @@
|
||||||
From: Jan Kara <jack@suse.cz>
|
|
||||||
Date: Thu, 18 Dec 2014 17:26:10 +0100
|
|
||||||
Subject: isofs: Fix unchecked printing of ER records
|
|
||||||
Origin: https://git.kernel.org/linus/4e2024624e678f0ebb916e6192bd23c1f9fdf696
|
|
||||||
|
|
||||||
We didn't check length of rock ridge ER records before printing them.
|
|
||||||
Thus corrupted isofs image can cause us to access and print some memory
|
|
||||||
behind the buffer with obvious consequences.
|
|
||||||
|
|
||||||
Reported-and-tested-by: Carl Henrik Lunde <chlunde@ping.uio.no>
|
|
||||||
CC: stable@vger.kernel.org
|
|
||||||
Signed-off-by: Jan Kara <jack@suse.cz>
|
|
||||||
---
|
|
||||||
fs/isofs/rock.c | 3 +++
|
|
||||||
1 file changed, 3 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c
|
|
||||||
index bb63254..735d752 100644
|
|
||||||
--- a/fs/isofs/rock.c
|
|
||||||
+++ b/fs/isofs/rock.c
|
|
||||||
@@ -362,6 +362,9 @@ repeat:
|
|
||||||
rs.cont_size = isonum_733(rr->u.CE.size);
|
|
||||||
break;
|
|
||||||
case SIG('E', 'R'):
|
|
||||||
+ /* Invalid length of ER tag id? */
|
|
||||||
+ if (rr->u.ER.len_id + offsetof(struct rock_ridge, u.ER.data) > rr->len)
|
|
||||||
+ goto out;
|
|
||||||
ISOFS_SB(inode->i_sb)->s_rock = 1;
|
|
||||||
printk(KERN_DEBUG "ISO 9660 Extensions: ");
|
|
||||||
{
|
|
|
@ -1,42 +0,0 @@
|
||||||
From: Sasha Levin <sasha.levin@oracle.com>
|
|
||||||
Date: Mon, 29 Dec 2014 09:39:01 -0500
|
|
||||||
Subject: KEYS: close race between key lookup and freeing
|
|
||||||
Origin: https://git.kernel.org/linus/a3a8784454692dd72e5d5d34dcdab17b4420e74c
|
|
||||||
|
|
||||||
When a key is being garbage collected, it's key->user would get put before
|
|
||||||
the ->destroy() callback is called, where the key is removed from it's
|
|
||||||
respective tracking structures.
|
|
||||||
|
|
||||||
This leaves a key hanging in a semi-invalid state which leaves a window open
|
|
||||||
for a different task to try an access key->user. An example is
|
|
||||||
find_keyring_by_name() which would dereference key->user for a key that is
|
|
||||||
in the process of being garbage collected (where key->user was freed but
|
|
||||||
->destroy() wasn't called yet - so it's still present in the linked list).
|
|
||||||
|
|
||||||
This would cause either a panic, or corrupt memory.
|
|
||||||
|
|
||||||
Fixes CVE-2014-9529.
|
|
||||||
|
|
||||||
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
|
|
||||||
Signed-off-by: David Howells <dhowells@redhat.com>
|
|
||||||
---
|
|
||||||
security/keys/gc.c | 4 ++--
|
|
||||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
--- a/security/keys/gc.c
|
|
||||||
+++ b/security/keys/gc.c
|
|
||||||
@@ -157,12 +157,12 @@ static noinline void key_gc_unused_keys(
|
|
||||||
if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
|
|
||||||
atomic_dec(&key->user->nikeys);
|
|
||||||
|
|
||||||
- key_user_put(key->user);
|
|
||||||
-
|
|
||||||
/* now throw away the key memory */
|
|
||||||
if (key->type->destroy)
|
|
||||||
key->type->destroy(key);
|
|
||||||
|
|
||||||
+ key_user_put(key->user);
|
|
||||||
+
|
|
||||||
kfree(key->description);
|
|
||||||
|
|
||||||
#ifdef KEY_DEBUGGING
|
|
|
@ -1,714 +0,0 @@
|
||||||
From: Al Viro <viro@zeniv.linux.org.uk>
|
|
||||||
Date: Sun, 26 Oct 2014 19:19:16 -0400
|
|
||||||
Subject: move d_rcu from overlapping d_child to overlapping d_alias
|
|
||||||
Origin: https://git.kernel.org/linus/946e51f2bf37f1656916eb75bd0742ba33983c28
|
|
||||||
|
|
||||||
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
|
|
||||||
[bwh: Backported to 3.16:
|
|
||||||
- Apply name changes in all the different places we use d_alias and d_child
|
|
||||||
- Adjust context]
|
|
||||||
---
|
|
||||||
arch/powerpc/platforms/cell/spufs/inode.c | 2 +-
|
|
||||||
drivers/staging/lustre/lustre/llite/dcache.c | 2 +-
|
|
||||||
drivers/staging/lustre/lustre/llite/llite_lib.c | 2 +-
|
|
||||||
drivers/staging/lustre/lustre/llite/namei.c | 8 ++--
|
|
||||||
fs/affs/amigaffs.c | 2 +-
|
|
||||||
fs/autofs4/expire.c | 12 +++---
|
|
||||||
fs/autofs4/root.c | 2 +-
|
|
||||||
fs/ceph/dir.c | 8 ++--
|
|
||||||
fs/ceph/inode.c | 2 +-
|
|
||||||
fs/cifs/inode.c | 2 +-
|
|
||||||
fs/coda/cache.c | 2 +-
|
|
||||||
fs/dcache.c | 53 ++++++++++++-------------
|
|
||||||
fs/debugfs/inode.c | 2 +-
|
|
||||||
fs/exportfs/expfs.c | 2 +-
|
|
||||||
fs/libfs.c | 12 +++---
|
|
||||||
fs/ncpfs/dir.c | 2 +-
|
|
||||||
fs/ncpfs/ncplib_kernel.h | 4 +-
|
|
||||||
fs/nfs/getroot.c | 2 +-
|
|
||||||
fs/notify/fsnotify.c | 4 +-
|
|
||||||
fs/ocfs2/dcache.c | 2 +-
|
|
||||||
include/linux/dcache.h | 8 ++--
|
|
||||||
kernel/trace/trace.c | 4 +-
|
|
||||||
kernel/trace/trace_events.c | 2 +-
|
|
||||||
security/selinux/selinuxfs.c | 6 +--
|
|
||||||
24 files changed, 73 insertions(+), 74 deletions(-)
|
|
||||||
|
|
||||||
--- a/arch/powerpc/platforms/cell/spufs/inode.c
|
|
||||||
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
|
|
||||||
@@ -164,7 +164,7 @@ static void spufs_prune_dir(struct dentr
|
|
||||||
struct dentry *dentry, *tmp;
|
|
||||||
|
|
||||||
mutex_lock(&dir->d_inode->i_mutex);
|
|
||||||
- list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_u.d_child) {
|
|
||||||
+ list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_child) {
|
|
||||||
spin_lock(&dentry->d_lock);
|
|
||||||
if (!(d_unhashed(dentry)) && dentry->d_inode) {
|
|
||||||
dget_dlock(dentry);
|
|
||||||
--- a/drivers/staging/lustre/lustre/llite/dcache.c
|
|
||||||
+++ b/drivers/staging/lustre/lustre/llite/dcache.c
|
|
||||||
@@ -258,7 +258,7 @@ void ll_invalidate_aliases(struct inode
|
|
||||||
inode->i_ino, inode->i_generation, inode);
|
|
||||||
|
|
||||||
ll_lock_dcache(inode);
|
|
||||||
- ll_d_hlist_for_each_entry(dentry, p, &inode->i_dentry, d_alias) {
|
|
||||||
+ ll_d_hlist_for_each_entry(dentry, p, &inode->i_dentry, d_u.d_alias) {
|
|
||||||
CDEBUG(D_DENTRY, "dentry in drop %.*s (%p) parent %p "
|
|
||||||
"inode %p flags %d\n", dentry->d_name.len,
|
|
||||||
dentry->d_name.name, dentry, dentry->d_parent,
|
|
||||||
--- a/drivers/staging/lustre/lustre/llite/llite_lib.c
|
|
||||||
+++ b/drivers/staging/lustre/lustre/llite/llite_lib.c
|
|
||||||
@@ -704,7 +704,7 @@ void lustre_dump_dentry(struct dentry *d
|
|
||||||
return;
|
|
||||||
|
|
||||||
list_for_each(tmp, &dentry->d_subdirs) {
|
|
||||||
- struct dentry *d = list_entry(tmp, struct dentry, d_u.d_child);
|
|
||||||
+ struct dentry *d = list_entry(tmp, struct dentry, d_child);
|
|
||||||
lustre_dump_dentry(d, recur - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
--- a/drivers/staging/lustre/lustre/llite/namei.c
|
|
||||||
+++ b/drivers/staging/lustre/lustre/llite/namei.c
|
|
||||||
@@ -167,14 +167,14 @@ static void ll_invalidate_negative_child
|
|
||||||
struct ll_d_hlist_node *p;
|
|
||||||
|
|
||||||
ll_lock_dcache(dir);
|
|
||||||
- ll_d_hlist_for_each_entry(dentry, p, &dir->i_dentry, d_alias) {
|
|
||||||
+ ll_d_hlist_for_each_entry(dentry, p, &dir->i_dentry, d_u.d_alias) {
|
|
||||||
spin_lock(&dentry->d_lock);
|
|
||||||
if (!list_empty(&dentry->d_subdirs)) {
|
|
||||||
struct dentry *child;
|
|
||||||
|
|
||||||
list_for_each_entry_safe(child, tmp_subdir,
|
|
||||||
&dentry->d_subdirs,
|
|
||||||
- d_u.d_child) {
|
|
||||||
+ d_child) {
|
|
||||||
if (child->d_inode == NULL)
|
|
||||||
d_lustre_invalidate(child, 1);
|
|
||||||
}
|
|
||||||
@@ -362,7 +362,7 @@ static struct dentry *ll_find_alias(stru
|
|
||||||
discon_alias = invalid_alias = NULL;
|
|
||||||
|
|
||||||
ll_lock_dcache(inode);
|
|
||||||
- ll_d_hlist_for_each_entry(alias, p, &inode->i_dentry, d_alias) {
|
|
||||||
+ ll_d_hlist_for_each_entry(alias, p, &inode->i_dentry, d_u.d_alias) {
|
|
||||||
LASSERT(alias != dentry);
|
|
||||||
|
|
||||||
spin_lock(&alias->d_lock);
|
|
||||||
@@ -943,7 +943,7 @@ static void ll_get_child_fid(struct inod
|
|
||||||
{
|
|
||||||
struct dentry *parent, *child;
|
|
||||||
|
|
||||||
- parent = ll_d_hlist_entry(dir->i_dentry, struct dentry, d_alias);
|
|
||||||
+ parent = ll_d_hlist_entry(dir->i_dentry, struct dentry, d_u.d_alias);
|
|
||||||
child = d_lookup(parent, name);
|
|
||||||
if (child) {
|
|
||||||
if (child->d_inode)
|
|
||||||
--- a/fs/affs/amigaffs.c
|
|
||||||
+++ b/fs/affs/amigaffs.c
|
|
||||||
@@ -127,7 +127,7 @@ affs_fix_dcache(struct inode *inode, u32
|
|
||||||
{
|
|
||||||
struct dentry *dentry;
|
|
||||||
spin_lock(&inode->i_lock);
|
|
||||||
- hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) {
|
|
||||||
+ hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) {
|
|
||||||
if (entry_ino == (u32)(long)dentry->d_fsdata) {
|
|
||||||
dentry->d_fsdata = (void *)inode->i_ino;
|
|
||||||
break;
|
|
||||||
--- a/fs/autofs4/expire.c
|
|
||||||
+++ b/fs/autofs4/expire.c
|
|
||||||
@@ -91,7 +91,7 @@ static struct dentry *get_next_positive_
|
|
||||||
spin_lock(&root->d_lock);
|
|
||||||
|
|
||||||
if (prev)
|
|
||||||
- next = prev->d_u.d_child.next;
|
|
||||||
+ next = prev->d_child.next;
|
|
||||||
else {
|
|
||||||
prev = dget_dlock(root);
|
|
||||||
next = prev->d_subdirs.next;
|
|
||||||
@@ -105,13 +105,13 @@ cont:
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
- q = list_entry(next, struct dentry, d_u.d_child);
|
|
||||||
+ q = list_entry(next, struct dentry, d_child);
|
|
||||||
|
|
||||||
spin_lock_nested(&q->d_lock, DENTRY_D_LOCK_NESTED);
|
|
||||||
/* Already gone or negative dentry (under construction) - try next */
|
|
||||||
if (!d_count(q) || !simple_positive(q)) {
|
|
||||||
spin_unlock(&q->d_lock);
|
|
||||||
- next = q->d_u.d_child.next;
|
|
||||||
+ next = q->d_child.next;
|
|
||||||
goto cont;
|
|
||||||
}
|
|
||||||
dget_dlock(q);
|
|
||||||
@@ -161,13 +161,13 @@ again:
|
|
||||||
goto relock;
|
|
||||||
}
|
|
||||||
spin_unlock(&p->d_lock);
|
|
||||||
- next = p->d_u.d_child.next;
|
|
||||||
+ next = p->d_child.next;
|
|
||||||
p = parent;
|
|
||||||
if (next != &parent->d_subdirs)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- ret = list_entry(next, struct dentry, d_u.d_child);
|
|
||||||
+ ret = list_entry(next, struct dentry, d_child);
|
|
||||||
|
|
||||||
spin_lock_nested(&ret->d_lock, DENTRY_D_LOCK_NESTED);
|
|
||||||
/* Negative dentry - try next */
|
|
||||||
@@ -461,7 +461,7 @@ found:
|
|
||||||
spin_lock(&sbi->lookup_lock);
|
|
||||||
spin_lock(&expired->d_parent->d_lock);
|
|
||||||
spin_lock_nested(&expired->d_lock, DENTRY_D_LOCK_NESTED);
|
|
||||||
- list_move(&expired->d_parent->d_subdirs, &expired->d_u.d_child);
|
|
||||||
+ list_move(&expired->d_parent->d_subdirs, &expired->d_child);
|
|
||||||
spin_unlock(&expired->d_lock);
|
|
||||||
spin_unlock(&expired->d_parent->d_lock);
|
|
||||||
spin_unlock(&sbi->lookup_lock);
|
|
||||||
--- a/fs/autofs4/root.c
|
|
||||||
+++ b/fs/autofs4/root.c
|
|
||||||
@@ -655,7 +655,7 @@ static void autofs_clear_leaf_automount_
|
|
||||||
/* only consider parents below dentrys in the root */
|
|
||||||
if (IS_ROOT(parent->d_parent))
|
|
||||||
return;
|
|
||||||
- d_child = &dentry->d_u.d_child;
|
|
||||||
+ d_child = &dentry->d_child;
|
|
||||||
/* Set parent managed if it's becoming empty */
|
|
||||||
if (d_child->next == &parent->d_subdirs &&
|
|
||||||
d_child->prev == &parent->d_subdirs)
|
|
||||||
--- a/fs/ceph/dir.c
|
|
||||||
+++ b/fs/ceph/dir.c
|
|
||||||
@@ -111,7 +111,7 @@ static int fpos_cmp(loff_t l, loff_t r)
|
|
||||||
/*
|
|
||||||
* When possible, we try to satisfy a readdir by peeking at the
|
|
||||||
* dcache. We make this work by carefully ordering dentries on
|
|
||||||
- * d_u.d_child when we initially get results back from the MDS, and
|
|
||||||
+ * d_child when we initially get results back from the MDS, and
|
|
||||||
* falling back to a "normal" sync readdir if any dentries in the dir
|
|
||||||
* are dropped.
|
|
||||||
*
|
|
||||||
@@ -147,11 +147,11 @@ static int __dcache_readdir(struct file
|
|
||||||
p = parent->d_subdirs.prev;
|
|
||||||
dout(" initial p %p/%p\n", p->prev, p->next);
|
|
||||||
} else {
|
|
||||||
- p = last->d_u.d_child.prev;
|
|
||||||
+ p = last->d_child.prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
more:
|
|
||||||
- dentry = list_entry(p, struct dentry, d_u.d_child);
|
|
||||||
+ dentry = list_entry(p, struct dentry, d_child);
|
|
||||||
di = ceph_dentry(dentry);
|
|
||||||
while (1) {
|
|
||||||
dout(" p %p/%p %s d_subdirs %p/%p\n", p->prev, p->next,
|
|
||||||
@@ -174,7 +174,7 @@ more:
|
|
||||||
!dentry->d_inode ? " null" : "");
|
|
||||||
spin_unlock(&dentry->d_lock);
|
|
||||||
p = p->prev;
|
|
||||||
- dentry = list_entry(p, struct dentry, d_u.d_child);
|
|
||||||
+ dentry = list_entry(p, struct dentry, d_child);
|
|
||||||
di = ceph_dentry(dentry);
|
|
||||||
}
|
|
||||||
|
|
||||||
--- a/fs/ceph/inode.c
|
|
||||||
+++ b/fs/ceph/inode.c
|
|
||||||
@@ -1399,7 +1399,7 @@ retry_lookup:
|
|
||||||
/* reorder parent's d_subdirs */
|
|
||||||
spin_lock(&parent->d_lock);
|
|
||||||
spin_lock_nested(&dn->d_lock, DENTRY_D_LOCK_NESTED);
|
|
||||||
- list_move(&dn->d_u.d_child, &parent->d_subdirs);
|
|
||||||
+ list_move(&dn->d_child, &parent->d_subdirs);
|
|
||||||
spin_unlock(&dn->d_lock);
|
|
||||||
spin_unlock(&parent->d_lock);
|
|
||||||
}
|
|
||||||
--- a/fs/cifs/inode.c
|
|
||||||
+++ b/fs/cifs/inode.c
|
|
||||||
@@ -887,7 +887,7 @@ inode_has_hashed_dentries(struct inode *
|
|
||||||
struct dentry *dentry;
|
|
||||||
|
|
||||||
spin_lock(&inode->i_lock);
|
|
||||||
- hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) {
|
|
||||||
+ hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) {
|
|
||||||
if (!d_unhashed(dentry) || IS_ROOT(dentry)) {
|
|
||||||
spin_unlock(&inode->i_lock);
|
|
||||||
return true;
|
|
||||||
--- a/fs/coda/cache.c
|
|
||||||
+++ b/fs/coda/cache.c
|
|
||||||
@@ -92,7 +92,7 @@ static void coda_flag_children(struct de
|
|
||||||
struct dentry *de;
|
|
||||||
|
|
||||||
spin_lock(&parent->d_lock);
|
|
||||||
- list_for_each_entry(de, &parent->d_subdirs, d_u.d_child) {
|
|
||||||
+ list_for_each_entry(de, &parent->d_subdirs, d_child) {
|
|
||||||
/* don't know what to do with negative dentries */
|
|
||||||
if (de->d_inode )
|
|
||||||
coda_flag_inode(de->d_inode, flag);
|
|
||||||
--- a/fs/dcache.c
|
|
||||||
+++ b/fs/dcache.c
|
|
||||||
@@ -44,7 +44,7 @@
|
|
||||||
/*
|
|
||||||
* Usage:
|
|
||||||
* dcache->d_inode->i_lock protects:
|
|
||||||
- * - i_dentry, d_alias, d_inode of aliases
|
|
||||||
+ * - i_dentry, d_u.d_alias, d_inode of aliases
|
|
||||||
* dcache_hash_bucket lock protects:
|
|
||||||
* - the dcache hash table
|
|
||||||
* s_anon bl list spinlock protects:
|
|
||||||
@@ -59,7 +59,7 @@
|
|
||||||
* - d_unhashed()
|
|
||||||
* - d_parent and d_subdirs
|
|
||||||
* - childrens' d_child and d_parent
|
|
||||||
- * - d_alias, d_inode
|
|
||||||
+ * - d_u.d_alias, d_inode
|
|
||||||
*
|
|
||||||
* Ordering:
|
|
||||||
* dentry->d_inode->i_lock
|
|
||||||
@@ -239,7 +239,6 @@ static void __d_free(struct rcu_head *he
|
|
||||||
{
|
|
||||||
struct dentry *dentry = container_of(head, struct dentry, d_u.d_rcu);
|
|
||||||
|
|
||||||
- WARN_ON(!hlist_unhashed(&dentry->d_alias));
|
|
||||||
if (dname_external(dentry))
|
|
||||||
kfree(dentry->d_name.name);
|
|
||||||
kmem_cache_free(dentry_cache, dentry);
|
|
||||||
@@ -247,6 +246,8 @@ static void __d_free(struct rcu_head *he
|
|
||||||
|
|
||||||
static void dentry_free(struct dentry *dentry)
|
|
||||||
{
|
|
||||||
+ WARN_ON(!hlist_unhashed(&dentry->d_u.d_alias));
|
|
||||||
+
|
|
||||||
/* if dentry was never visible to RCU, immediate free is OK */
|
|
||||||
if (!(dentry->d_flags & DCACHE_RCUACCESS))
|
|
||||||
__d_free(&dentry->d_u.d_rcu);
|
|
||||||
@@ -280,7 +281,7 @@ static void dentry_iput(struct dentry *
|
|
||||||
struct inode *inode = dentry->d_inode;
|
|
||||||
if (inode) {
|
|
||||||
dentry->d_inode = NULL;
|
|
||||||
- hlist_del_init(&dentry->d_alias);
|
|
||||||
+ hlist_del_init(&dentry->d_u.d_alias);
|
|
||||||
spin_unlock(&dentry->d_lock);
|
|
||||||
spin_unlock(&inode->i_lock);
|
|
||||||
if (!inode->i_nlink)
|
|
||||||
@@ -305,7 +306,7 @@ static void dentry_unlink_inode(struct d
|
|
||||||
struct inode *inode = dentry->d_inode;
|
|
||||||
__d_clear_type(dentry);
|
|
||||||
dentry->d_inode = NULL;
|
|
||||||
- hlist_del_init(&dentry->d_alias);
|
|
||||||
+ hlist_del_init(&dentry->d_u.d_alias);
|
|
||||||
dentry_rcuwalk_barrier(dentry);
|
|
||||||
spin_unlock(&dentry->d_lock);
|
|
||||||
spin_unlock(&inode->i_lock);
|
|
||||||
@@ -465,7 +466,7 @@ static void __dentry_kill(struct dentry
|
|
||||||
}
|
|
||||||
/* if it was on the hash then remove it */
|
|
||||||
__d_drop(dentry);
|
|
||||||
- list_del(&dentry->d_u.d_child);
|
|
||||||
+ list_del(&dentry->d_child);
|
|
||||||
/*
|
|
||||||
* Inform d_walk() that we are no longer attached to the
|
|
||||||
* dentry tree
|
|
||||||
@@ -749,7 +750,7 @@ static struct dentry *__d_find_alias(str
|
|
||||||
|
|
||||||
again:
|
|
||||||
discon_alias = NULL;
|
|
||||||
- hlist_for_each_entry(alias, &inode->i_dentry, d_alias) {
|
|
||||||
+ hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) {
|
|
||||||
spin_lock(&alias->d_lock);
|
|
||||||
if (S_ISDIR(inode->i_mode) || !d_unhashed(alias)) {
|
|
||||||
if (IS_ROOT(alias) &&
|
|
||||||
@@ -802,7 +803,7 @@ void d_prune_aliases(struct inode *inode
|
|
||||||
struct dentry *dentry;
|
|
||||||
restart:
|
|
||||||
spin_lock(&inode->i_lock);
|
|
||||||
- hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) {
|
|
||||||
+ hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) {
|
|
||||||
spin_lock(&dentry->d_lock);
|
|
||||||
if (!dentry->d_lockref.count) {
|
|
||||||
/*
|
|
||||||
@@ -1087,7 +1088,7 @@ repeat:
|
|
||||||
resume:
|
|
||||||
while (next != &this_parent->d_subdirs) {
|
|
||||||
struct list_head *tmp = next;
|
|
||||||
- struct dentry *dentry = list_entry(tmp, struct dentry, d_u.d_child);
|
|
||||||
+ struct dentry *dentry = list_entry(tmp, struct dentry, d_child);
|
|
||||||
next = tmp->next;
|
|
||||||
|
|
||||||
spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
|
|
||||||
@@ -1139,7 +1140,7 @@ resume:
|
|
||||||
goto rename_retry;
|
|
||||||
}
|
|
||||||
rcu_read_unlock();
|
|
||||||
- next = child->d_u.d_child.next;
|
|
||||||
+ next = child->d_child.next;
|
|
||||||
goto resume;
|
|
||||||
}
|
|
||||||
if (need_seqretry(&rename_lock, seq)) {
|
|
||||||
@@ -1474,8 +1475,8 @@ struct dentry *__d_alloc(struct super_bl
|
|
||||||
INIT_HLIST_BL_NODE(&dentry->d_hash);
|
|
||||||
INIT_LIST_HEAD(&dentry->d_lru);
|
|
||||||
INIT_LIST_HEAD(&dentry->d_subdirs);
|
|
||||||
- INIT_HLIST_NODE(&dentry->d_alias);
|
|
||||||
- INIT_LIST_HEAD(&dentry->d_u.d_child);
|
|
||||||
+ INIT_HLIST_NODE(&dentry->d_u.d_alias);
|
|
||||||
+ INIT_LIST_HEAD(&dentry->d_child);
|
|
||||||
d_set_d_op(dentry, dentry->d_sb->s_d_op);
|
|
||||||
|
|
||||||
this_cpu_inc(nr_dentry);
|
|
||||||
@@ -1505,7 +1506,7 @@ struct dentry *d_alloc(struct dentry * p
|
|
||||||
*/
|
|
||||||
__dget_dlock(parent);
|
|
||||||
dentry->d_parent = parent;
|
|
||||||
- list_add(&dentry->d_u.d_child, &parent->d_subdirs);
|
|
||||||
+ list_add(&dentry->d_child, &parent->d_subdirs);
|
|
||||||
spin_unlock(&parent->d_lock);
|
|
||||||
|
|
||||||
return dentry;
|
|
||||||
@@ -1598,7 +1599,7 @@ static void __d_instantiate(struct dentr
|
|
||||||
spin_lock(&dentry->d_lock);
|
|
||||||
__d_set_type(dentry, add_flags);
|
|
||||||
if (inode)
|
|
||||||
- hlist_add_head(&dentry->d_alias, &inode->i_dentry);
|
|
||||||
+ hlist_add_head(&dentry->d_u.d_alias, &inode->i_dentry);
|
|
||||||
dentry->d_inode = inode;
|
|
||||||
dentry_rcuwalk_barrier(dentry);
|
|
||||||
spin_unlock(&dentry->d_lock);
|
|
||||||
@@ -1622,7 +1623,7 @@ static void __d_instantiate(struct dentr
|
|
||||||
|
|
||||||
void d_instantiate(struct dentry *entry, struct inode * inode)
|
|
||||||
{
|
|
||||||
- BUG_ON(!hlist_unhashed(&entry->d_alias));
|
|
||||||
+ BUG_ON(!hlist_unhashed(&entry->d_u.d_alias));
|
|
||||||
if (inode)
|
|
||||||
spin_lock(&inode->i_lock);
|
|
||||||
__d_instantiate(entry, inode);
|
|
||||||
@@ -1661,7 +1662,7 @@ static struct dentry *__d_instantiate_un
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
- hlist_for_each_entry(alias, &inode->i_dentry, d_alias) {
|
|
||||||
+ hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) {
|
|
||||||
/*
|
|
||||||
* Don't need alias->d_lock here, because aliases with
|
|
||||||
* d_parent == entry->d_parent are not subject to name or
|
|
||||||
@@ -1687,7 +1688,7 @@ struct dentry *d_instantiate_unique(stru
|
|
||||||
{
|
|
||||||
struct dentry *result;
|
|
||||||
|
|
||||||
- BUG_ON(!hlist_unhashed(&entry->d_alias));
|
|
||||||
+ BUG_ON(!hlist_unhashed(&entry->d_u.d_alias));
|
|
||||||
|
|
||||||
if (inode)
|
|
||||||
spin_lock(&inode->i_lock);
|
|
||||||
@@ -1718,7 +1719,7 @@ EXPORT_SYMBOL(d_instantiate_unique);
|
|
||||||
*/
|
|
||||||
int d_instantiate_no_diralias(struct dentry *entry, struct inode *inode)
|
|
||||||
{
|
|
||||||
- BUG_ON(!hlist_unhashed(&entry->d_alias));
|
|
||||||
+ BUG_ON(!hlist_unhashed(&entry->d_u.d_alias));
|
|
||||||
|
|
||||||
spin_lock(&inode->i_lock);
|
|
||||||
if (S_ISDIR(inode->i_mode) && !hlist_empty(&inode->i_dentry)) {
|
|
||||||
@@ -1757,7 +1758,7 @@ static struct dentry * __d_find_any_alia
|
|
||||||
|
|
||||||
if (hlist_empty(&inode->i_dentry))
|
|
||||||
return NULL;
|
|
||||||
- alias = hlist_entry(inode->i_dentry.first, struct dentry, d_alias);
|
|
||||||
+ alias = hlist_entry(inode->i_dentry.first, struct dentry, d_u.d_alias);
|
|
||||||
__dget(alias);
|
|
||||||
return alias;
|
|
||||||
}
|
|
||||||
@@ -1834,7 +1835,7 @@ struct dentry *d_obtain_alias(struct ino
|
|
||||||
spin_lock(&tmp->d_lock);
|
|
||||||
tmp->d_inode = inode;
|
|
||||||
tmp->d_flags |= add_flags;
|
|
||||||
- hlist_add_head(&tmp->d_alias, &inode->i_dentry);
|
|
||||||
+ hlist_add_head(&tmp->d_u.d_alias, &inode->i_dentry);
|
|
||||||
hlist_bl_lock(&tmp->d_sb->s_anon);
|
|
||||||
hlist_bl_add_head(&tmp->d_hash, &tmp->d_sb->s_anon);
|
|
||||||
hlist_bl_unlock(&tmp->d_sb->s_anon);
|
|
||||||
@@ -2277,7 +2278,7 @@ int d_validate(struct dentry *dentry, st
|
|
||||||
struct dentry *child;
|
|
||||||
|
|
||||||
spin_lock(&dparent->d_lock);
|
|
||||||
- list_for_each_entry(child, &dparent->d_subdirs, d_u.d_child) {
|
|
||||||
+ list_for_each_entry(child, &dparent->d_subdirs, d_child) {
|
|
||||||
if (dentry == child) {
|
|
||||||
spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
|
|
||||||
__dget_dlock(dentry);
|
|
||||||
@@ -2545,8 +2546,8 @@ static void __d_move(struct dentry *dent
|
|
||||||
d_hash(dentry->d_parent, dentry->d_name.hash));
|
|
||||||
}
|
|
||||||
|
|
||||||
- list_del(&dentry->d_u.d_child);
|
|
||||||
- list_del(&target->d_u.d_child);
|
|
||||||
+ list_del(&dentry->d_child);
|
|
||||||
+ list_del(&target->d_child);
|
|
||||||
|
|
||||||
/* Switch the names.. */
|
|
||||||
switch_names(dentry, target, exchange);
|
|
||||||
@@ -2555,15 +2556,15 @@ static void __d_move(struct dentry *dent
|
|
||||||
if (IS_ROOT(dentry)) {
|
|
||||||
dentry->d_parent = target->d_parent;
|
|
||||||
target->d_parent = target;
|
|
||||||
- INIT_LIST_HEAD(&target->d_u.d_child);
|
|
||||||
+ INIT_LIST_HEAD(&target->d_child);
|
|
||||||
} else {
|
|
||||||
swap(dentry->d_parent, target->d_parent);
|
|
||||||
|
|
||||||
/* And add them back to the (new) parent lists */
|
|
||||||
- list_add(&target->d_u.d_child, &target->d_parent->d_subdirs);
|
|
||||||
+ list_add(&target->d_child, &target->d_parent->d_subdirs);
|
|
||||||
}
|
|
||||||
|
|
||||||
- list_add(&dentry->d_u.d_child, &dentry->d_parent->d_subdirs);
|
|
||||||
+ list_add(&dentry->d_child, &dentry->d_parent->d_subdirs);
|
|
||||||
|
|
||||||
write_seqcount_end(&target->d_seq);
|
|
||||||
write_seqcount_end(&dentry->d_seq);
|
|
||||||
@@ -2690,9 +2691,9 @@ static void __d_materialise_dentry(struc
|
|
||||||
switch_names(dentry, anon, false);
|
|
||||||
|
|
||||||
dentry->d_parent = dentry;
|
|
||||||
- list_del_init(&dentry->d_u.d_child);
|
|
||||||
+ list_del_init(&dentry->d_child);
|
|
||||||
anon->d_parent = dparent;
|
|
||||||
- list_move(&anon->d_u.d_child, &dparent->d_subdirs);
|
|
||||||
+ list_move(&anon->d_child, &dparent->d_subdirs);
|
|
||||||
|
|
||||||
write_seqcount_end(&dentry->d_seq);
|
|
||||||
write_seqcount_end(&anon->d_seq);
|
|
||||||
@@ -3324,7 +3325,7 @@ void d_tmpfile(struct dentry *dentry, st
|
|
||||||
{
|
|
||||||
inode_dec_link_count(inode);
|
|
||||||
BUG_ON(dentry->d_name.name != dentry->d_iname ||
|
|
||||||
- !hlist_unhashed(&dentry->d_alias) ||
|
|
||||||
+ !hlist_unhashed(&dentry->d_u.d_alias) ||
|
|
||||||
!d_unlinked(dentry));
|
|
||||||
spin_lock(&dentry->d_parent->d_lock);
|
|
||||||
spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
|
|
||||||
--- a/fs/debugfs/inode.c
|
|
||||||
+++ b/fs/debugfs/inode.c
|
|
||||||
@@ -553,7 +553,7 @@ void debugfs_remove_recursive(struct den
|
|
||||||
* use the d_u.d_child as the rcu head and corrupt this list.
|
|
||||||
*/
|
|
||||||
spin_lock(&parent->d_lock);
|
|
||||||
- list_for_each_entry(child, &parent->d_subdirs, d_u.d_child) {
|
|
||||||
+ list_for_each_entry(child, &parent->d_subdirs, d_child) {
|
|
||||||
if (!debugfs_positive(child))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
--- a/fs/exportfs/expfs.c
|
|
||||||
+++ b/fs/exportfs/expfs.c
|
|
||||||
@@ -50,7 +50,7 @@ find_acceptable_alias(struct dentry *res
|
|
||||||
|
|
||||||
inode = result->d_inode;
|
|
||||||
spin_lock(&inode->i_lock);
|
|
||||||
- hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) {
|
|
||||||
+ hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) {
|
|
||||||
dget(dentry);
|
|
||||||
spin_unlock(&inode->i_lock);
|
|
||||||
if (toput)
|
|
||||||
--- a/fs/libfs.c
|
|
||||||
+++ b/fs/libfs.c
|
|
||||||
@@ -114,18 +114,18 @@ loff_t dcache_dir_lseek(struct file *fil
|
|
||||||
|
|
||||||
spin_lock(&dentry->d_lock);
|
|
||||||
/* d_lock not required for cursor */
|
|
||||||
- list_del(&cursor->d_u.d_child);
|
|
||||||
+ list_del(&cursor->d_child);
|
|
||||||
p = dentry->d_subdirs.next;
|
|
||||||
while (n && p != &dentry->d_subdirs) {
|
|
||||||
struct dentry *next;
|
|
||||||
- next = list_entry(p, struct dentry, d_u.d_child);
|
|
||||||
+ next = list_entry(p, struct dentry, d_child);
|
|
||||||
spin_lock_nested(&next->d_lock, DENTRY_D_LOCK_NESTED);
|
|
||||||
if (simple_positive(next))
|
|
||||||
n--;
|
|
||||||
spin_unlock(&next->d_lock);
|
|
||||||
p = p->next;
|
|
||||||
}
|
|
||||||
- list_add_tail(&cursor->d_u.d_child, p);
|
|
||||||
+ list_add_tail(&cursor->d_child, p);
|
|
||||||
spin_unlock(&dentry->d_lock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -150,7 +150,7 @@ int dcache_readdir(struct file *file, st
|
|
||||||
{
|
|
||||||
struct dentry *dentry = file->f_path.dentry;
|
|
||||||
struct dentry *cursor = file->private_data;
|
|
||||||
- struct list_head *p, *q = &cursor->d_u.d_child;
|
|
||||||
+ struct list_head *p, *q = &cursor->d_child;
|
|
||||||
|
|
||||||
if (!dir_emit_dots(file, ctx))
|
|
||||||
return 0;
|
|
||||||
@@ -159,7 +159,7 @@ int dcache_readdir(struct file *file, st
|
|
||||||
list_move(q, &dentry->d_subdirs);
|
|
||||||
|
|
||||||
for (p = q->next; p != &dentry->d_subdirs; p = p->next) {
|
|
||||||
- struct dentry *next = list_entry(p, struct dentry, d_u.d_child);
|
|
||||||
+ struct dentry *next = list_entry(p, struct dentry, d_child);
|
|
||||||
spin_lock_nested(&next->d_lock, DENTRY_D_LOCK_NESTED);
|
|
||||||
if (!simple_positive(next)) {
|
|
||||||
spin_unlock(&next->d_lock);
|
|
||||||
@@ -287,7 +287,7 @@ int simple_empty(struct dentry *dentry)
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
spin_lock(&dentry->d_lock);
|
|
||||||
- list_for_each_entry(child, &dentry->d_subdirs, d_u.d_child) {
|
|
||||||
+ list_for_each_entry(child, &dentry->d_subdirs, d_child) {
|
|
||||||
spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED);
|
|
||||||
if (simple_positive(child)) {
|
|
||||||
spin_unlock(&child->d_lock);
|
|
||||||
--- a/fs/ncpfs/dir.c
|
|
||||||
+++ b/fs/ncpfs/dir.c
|
|
||||||
@@ -406,7 +406,7 @@ ncp_dget_fpos(struct dentry *dentry, str
|
|
||||||
spin_lock(&parent->d_lock);
|
|
||||||
next = parent->d_subdirs.next;
|
|
||||||
while (next != &parent->d_subdirs) {
|
|
||||||
- dent = list_entry(next, struct dentry, d_u.d_child);
|
|
||||||
+ dent = list_entry(next, struct dentry, d_child);
|
|
||||||
if ((unsigned long)dent->d_fsdata == fpos) {
|
|
||||||
if (dent->d_inode)
|
|
||||||
dget(dent);
|
|
||||||
--- a/fs/ncpfs/ncplib_kernel.h
|
|
||||||
+++ b/fs/ncpfs/ncplib_kernel.h
|
|
||||||
@@ -194,7 +194,7 @@ ncp_renew_dentries(struct dentry *parent
|
|
||||||
spin_lock(&parent->d_lock);
|
|
||||||
next = parent->d_subdirs.next;
|
|
||||||
while (next != &parent->d_subdirs) {
|
|
||||||
- dentry = list_entry(next, struct dentry, d_u.d_child);
|
|
||||||
+ dentry = list_entry(next, struct dentry, d_child);
|
|
||||||
|
|
||||||
if (dentry->d_fsdata == NULL)
|
|
||||||
ncp_age_dentry(server, dentry);
|
|
||||||
@@ -216,7 +216,7 @@ ncp_invalidate_dircache_entries(struct d
|
|
||||||
spin_lock(&parent->d_lock);
|
|
||||||
next = parent->d_subdirs.next;
|
|
||||||
while (next != &parent->d_subdirs) {
|
|
||||||
- dentry = list_entry(next, struct dentry, d_u.d_child);
|
|
||||||
+ dentry = list_entry(next, struct dentry, d_child);
|
|
||||||
dentry->d_fsdata = NULL;
|
|
||||||
ncp_age_dentry(server, dentry);
|
|
||||||
next = next->next;
|
|
||||||
--- a/fs/nfs/getroot.c
|
|
||||||
+++ b/fs/nfs/getroot.c
|
|
||||||
@@ -58,7 +58,7 @@ static int nfs_superblock_set_dummy_root
|
|
||||||
*/
|
|
||||||
spin_lock(&sb->s_root->d_inode->i_lock);
|
|
||||||
spin_lock(&sb->s_root->d_lock);
|
|
||||||
- hlist_del_init(&sb->s_root->d_alias);
|
|
||||||
+ hlist_del_init(&sb->s_root->d_u.d_alias);
|
|
||||||
spin_unlock(&sb->s_root->d_lock);
|
|
||||||
spin_unlock(&sb->s_root->d_inode->i_lock);
|
|
||||||
}
|
|
||||||
--- a/fs/notify/fsnotify.c
|
|
||||||
+++ b/fs/notify/fsnotify.c
|
|
||||||
@@ -63,14 +63,14 @@ void __fsnotify_update_child_dentry_flag
|
|
||||||
spin_lock(&inode->i_lock);
|
|
||||||
/* run all of the dentries associated with this inode. Since this is a
|
|
||||||
* directory, there damn well better only be one item on this list */
|
|
||||||
- hlist_for_each_entry(alias, &inode->i_dentry, d_alias) {
|
|
||||||
+ hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) {
|
|
||||||
struct dentry *child;
|
|
||||||
|
|
||||||
/* run all of the children of the original inode and fix their
|
|
||||||
* d_flags to indicate parental interest (their parent is the
|
|
||||||
* original inode) */
|
|
||||||
spin_lock(&alias->d_lock);
|
|
||||||
- list_for_each_entry(child, &alias->d_subdirs, d_u.d_child) {
|
|
||||||
+ list_for_each_entry(child, &alias->d_subdirs, d_child) {
|
|
||||||
if (!child->d_inode)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
--- a/fs/ocfs2/dcache.c
|
|
||||||
+++ b/fs/ocfs2/dcache.c
|
|
||||||
@@ -172,7 +172,7 @@ struct dentry *ocfs2_find_local_alias(st
|
|
||||||
struct dentry *dentry;
|
|
||||||
|
|
||||||
spin_lock(&inode->i_lock);
|
|
||||||
- hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) {
|
|
||||||
+ hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) {
|
|
||||||
spin_lock(&dentry->d_lock);
|
|
||||||
if (ocfs2_match_dentry(dentry, parent_blkno, skip_unhashed)) {
|
|
||||||
trace_ocfs2_find_local_alias(dentry->d_name.len,
|
|
||||||
--- a/include/linux/dcache.h
|
|
||||||
+++ b/include/linux/dcache.h
|
|
||||||
@@ -124,15 +124,15 @@ struct dentry {
|
|
||||||
void *d_fsdata; /* fs-specific data */
|
|
||||||
|
|
||||||
struct list_head d_lru; /* LRU list */
|
|
||||||
+ struct list_head d_child; /* child of parent list */
|
|
||||||
+ struct list_head d_subdirs; /* our children */
|
|
||||||
/*
|
|
||||||
- * d_child and d_rcu can share memory
|
|
||||||
+ * d_alias and d_rcu can share memory
|
|
||||||
*/
|
|
||||||
union {
|
|
||||||
- struct list_head d_child; /* child of parent list */
|
|
||||||
+ struct hlist_node d_alias; /* inode alias list */
|
|
||||||
struct rcu_head d_rcu;
|
|
||||||
} d_u;
|
|
||||||
- struct list_head d_subdirs; /* our children */
|
|
||||||
- struct hlist_node d_alias; /* inode alias list */
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
--- a/kernel/trace/trace.c
|
|
||||||
+++ b/kernel/trace/trace.c
|
|
||||||
@@ -6384,7 +6384,7 @@ static int instance_mkdir (struct inode
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* Paranoid: Make sure the parent is the "instances" directory */
|
|
||||||
- parent = hlist_entry(inode->i_dentry.first, struct dentry, d_alias);
|
|
||||||
+ parent = hlist_entry(inode->i_dentry.first, struct dentry, d_u.d_alias);
|
|
||||||
if (WARN_ON_ONCE(parent != trace_instance_dir))
|
|
||||||
return -ENOENT;
|
|
||||||
|
|
||||||
@@ -6411,7 +6411,7 @@ static int instance_rmdir(struct inode *
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* Paranoid: Make sure the parent is the "instances" directory */
|
|
||||||
- parent = hlist_entry(inode->i_dentry.first, struct dentry, d_alias);
|
|
||||||
+ parent = hlist_entry(inode->i_dentry.first, struct dentry, d_u.d_alias);
|
|
||||||
if (WARN_ON_ONCE(parent != trace_instance_dir))
|
|
||||||
return -ENOENT;
|
|
||||||
|
|
||||||
--- a/kernel/trace/trace_events.c
|
|
||||||
+++ b/kernel/trace/trace_events.c
|
|
||||||
@@ -459,7 +459,7 @@ static void remove_event_file_dir(struct
|
|
||||||
|
|
||||||
if (dir) {
|
|
||||||
spin_lock(&dir->d_lock); /* probably unneeded */
|
|
||||||
- list_for_each_entry(child, &dir->d_subdirs, d_u.d_child) {
|
|
||||||
+ list_for_each_entry(child, &dir->d_subdirs, d_child) {
|
|
||||||
if (child->d_inode) /* probably unneeded */
|
|
||||||
child->d_inode->i_private = NULL;
|
|
||||||
}
|
|
||||||
--- a/security/selinux/selinuxfs.c
|
|
||||||
+++ b/security/selinux/selinuxfs.c
|
|
||||||
@@ -1200,7 +1200,7 @@ static void sel_remove_entries(struct de
|
|
||||||
spin_lock(&de->d_lock);
|
|
||||||
node = de->d_subdirs.next;
|
|
||||||
while (node != &de->d_subdirs) {
|
|
||||||
- struct dentry *d = list_entry(node, struct dentry, d_u.d_child);
|
|
||||||
+ struct dentry *d = list_entry(node, struct dentry, d_child);
|
|
||||||
|
|
||||||
spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
|
|
||||||
list_del_init(node);
|
|
||||||
@@ -1674,12 +1674,12 @@ static void sel_remove_classes(void)
|
|
||||||
|
|
||||||
list_for_each(class_node, &class_dir->d_subdirs) {
|
|
||||||
struct dentry *class_subdir = list_entry(class_node,
|
|
||||||
- struct dentry, d_u.d_child);
|
|
||||||
+ struct dentry, d_child);
|
|
||||||
struct list_head *class_subdir_node;
|
|
||||||
|
|
||||||
list_for_each(class_subdir_node, &class_subdir->d_subdirs) {
|
|
||||||
struct dentry *d = list_entry(class_subdir_node,
|
|
||||||
- struct dentry, d_u.d_child);
|
|
||||||
+ struct dentry, d_child);
|
|
||||||
|
|
||||||
if (d->d_inode)
|
|
||||||
if (d->d_inode->i_mode & S_IFDIR)
|
|
|
@ -1,69 +0,0 @@
|
||||||
From: Martin Schwidefsky <schwidefsky@de.ibm.com>
|
|
||||||
Date: Tue, 15 Jul 2014 17:53:12 +0200
|
|
||||||
Subject: s390/3215: fix hanging console issue
|
|
||||||
Origin: https://git.kernel.org/cgit/linux/kernel/git/s390/linux.git/commit?id=26d766c60f4ea08cd14f0f3435a6db3d6cc2ae96
|
|
||||||
Bug-Debian: https://bugs.debian.org/747922
|
|
||||||
|
|
||||||
The ccw_device_start in raw3215_start_io can fail. raw3215_try_io
|
|
||||||
does not check if the request could be started and removes any
|
|
||||||
pending timer. This can leave the system in a hanging state.
|
|
||||||
Check for pending request after raw3215_start_io and start a
|
|
||||||
timer if necessary.
|
|
||||||
|
|
||||||
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
|
|
||||||
---
|
|
||||||
drivers/s390/char/con3215.c | 32 +++++++++++++++++---------------
|
|
||||||
1 file changed, 17 insertions(+), 15 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
|
|
||||||
index 5af7f0b..a6d47e5 100644
|
|
||||||
--- a/drivers/s390/char/con3215.c
|
|
||||||
+++ b/drivers/s390/char/con3215.c
|
|
||||||
@@ -288,12 +288,16 @@ static void raw3215_timeout(unsigned long __data)
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
|
|
||||||
- if (raw->flags & RAW3215_TIMER_RUNS) {
|
|
||||||
- del_timer(&raw->timer);
|
|
||||||
- raw->flags &= ~RAW3215_TIMER_RUNS;
|
|
||||||
- if (!(raw->port.flags & ASYNC_SUSPENDED)) {
|
|
||||||
- raw3215_mk_write_req(raw);
|
|
||||||
- raw3215_start_io(raw);
|
|
||||||
+ raw->flags &= ~RAW3215_TIMER_RUNS;
|
|
||||||
+ if (!(raw->port.flags & ASYNC_SUSPENDED)) {
|
|
||||||
+ raw3215_mk_write_req(raw);
|
|
||||||
+ raw3215_start_io(raw);
|
|
||||||
+ if ((raw->queued_read || raw->queued_write) &&
|
|
||||||
+ !(raw->flags & RAW3215_WORKING) &&
|
|
||||||
+ !(raw->flags & RAW3215_TIMER_RUNS)) {
|
|
||||||
+ raw->timer.expires = RAW3215_TIMEOUT + jiffies;
|
|
||||||
+ add_timer(&raw->timer);
|
|
||||||
+ raw->flags |= RAW3215_TIMER_RUNS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
|
|
||||||
@@ -317,17 +321,15 @@ static inline void raw3215_try_io(struct raw3215_info *raw)
|
|
||||||
(raw->flags & RAW3215_FLUSHING)) {
|
|
||||||
/* execute write requests bigger than minimum size */
|
|
||||||
raw3215_start_io(raw);
|
|
||||||
- if (raw->flags & RAW3215_TIMER_RUNS) {
|
|
||||||
- del_timer(&raw->timer);
|
|
||||||
- raw->flags &= ~RAW3215_TIMER_RUNS;
|
|
||||||
- }
|
|
||||||
- } else if (!(raw->flags & RAW3215_TIMER_RUNS)) {
|
|
||||||
- /* delay small writes */
|
|
||||||
- raw->timer.expires = RAW3215_TIMEOUT + jiffies;
|
|
||||||
- add_timer(&raw->timer);
|
|
||||||
- raw->flags |= RAW3215_TIMER_RUNS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+ if ((raw->queued_read || raw->queued_write) &&
|
|
||||||
+ !(raw->flags & RAW3215_WORKING) &&
|
|
||||||
+ !(raw->flags & RAW3215_TIMER_RUNS)) {
|
|
||||||
+ raw->timer.expires = RAW3215_TIMEOUT + jiffies;
|
|
||||||
+ add_timer(&raw->timer);
|
|
||||||
+ raw->flags |= RAW3215_TIMER_RUNS;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
|
@ -1,65 +0,0 @@
|
||||||
From: Martin Schwidefsky <schwidefsky@de.ibm.com>
|
|
||||||
Date: Wed, 13 Aug 2014 12:01:30 +0200
|
|
||||||
Subject: s390/3215: fix tty output containing tabs
|
|
||||||
Origin: https://git.kernel.org/linus/e512d56c799517f33b301d81e9a5e0ebf30c2d1e
|
|
||||||
|
|
||||||
git commit 37f81fa1f63ad38e16125526bb2769ae0ea8d332
|
|
||||||
"n_tty: do O_ONLCR translation as a single write"
|
|
||||||
surfaced a bug in the 3215 device driver. In combination this
|
|
||||||
broke tab expansion for tty ouput.
|
|
||||||
|
|
||||||
The cause is an asymmetry in the behaviour of tty3215_ops->write
|
|
||||||
vs tty3215_ops->put_char. The put_char function scans for '\t'
|
|
||||||
but the write function does not.
|
|
||||||
|
|
||||||
As the driver has logic for the '\t' expansion remove XTABS
|
|
||||||
from c_oflag of the initial termios as well.
|
|
||||||
|
|
||||||
Reported-by: Stephen Powell <zlinuxman@wowway.com>
|
|
||||||
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
|
|
||||||
---
|
|
||||||
drivers/s390/char/con3215.c | 20 +++++++++++++++++---
|
|
||||||
1 file changed, 17 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
|
|
||||||
index a6d47e5..c43aca6 100644
|
|
||||||
--- a/drivers/s390/char/con3215.c
|
|
||||||
+++ b/drivers/s390/char/con3215.c
|
|
||||||
@@ -1035,12 +1035,26 @@ static int tty3215_write(struct tty_struct * tty,
|
|
||||||
const unsigned char *buf, int count)
|
|
||||||
{
|
|
||||||
struct raw3215_info *raw;
|
|
||||||
+ int i, written;
|
|
||||||
|
|
||||||
if (!tty)
|
|
||||||
return 0;
|
|
||||||
raw = (struct raw3215_info *) tty->driver_data;
|
|
||||||
- raw3215_write(raw, buf, count);
|
|
||||||
- return count;
|
|
||||||
+ written = count;
|
|
||||||
+ while (count > 0) {
|
|
||||||
+ for (i = 0; i < count; i++)
|
|
||||||
+ if (buf[i] == '\t' || buf[i] == '\n')
|
|
||||||
+ break;
|
|
||||||
+ raw3215_write(raw, buf, i);
|
|
||||||
+ count -= i;
|
|
||||||
+ buf += i;
|
|
||||||
+ if (count > 0) {
|
|
||||||
+ raw3215_putchar(raw, *buf);
|
|
||||||
+ count--;
|
|
||||||
+ buf++;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ return written;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ -1188,7 +1202,7 @@ static int __init tty3215_init(void)
|
|
||||||
driver->subtype = SYSTEM_TYPE_TTY;
|
|
||||||
driver->init_termios = tty_std_termios;
|
|
||||||
driver->init_termios.c_iflag = IGNBRK | IGNPAR;
|
|
||||||
- driver->init_termios.c_oflag = ONLCR | XTABS;
|
|
||||||
+ driver->init_termios.c_oflag = ONLCR;
|
|
||||||
driver->init_termios.c_lflag = ISIG;
|
|
||||||
driver->flags = TTY_DRIVER_REAL_RAW;
|
|
||||||
tty_set_operations(driver, &tty3215_ops);
|
|
|
@ -1,63 +0,0 @@
|
||||||
From: Andy Lutomirski <luto@amacapital.net>
|
|
||||||
Date: Fri, 5 Dec 2014 19:03:28 -0800
|
|
||||||
Subject: x86, kvm: Clear paravirt_enabled on KVM guests for espfix32's benefit
|
|
||||||
Origin: https://git.kernel.org/linus/29fa6825463c97e5157284db80107d1bfac5d77b
|
|
||||||
|
|
||||||
paravirt_enabled has the following effects:
|
|
||||||
|
|
||||||
- Disables the F00F bug workaround warning. There is no F00F bug
|
|
||||||
workaround any more because Linux's standard IDT handling already
|
|
||||||
works around the F00F bug, but the warning still exists. This
|
|
||||||
is only cosmetic, and, in any event, there is no such thing as
|
|
||||||
KVM on a CPU with the F00F bug.
|
|
||||||
|
|
||||||
- Disables 32-bit APM BIOS detection. On a KVM paravirt system,
|
|
||||||
there should be no APM BIOS anyway.
|
|
||||||
|
|
||||||
- Disables tboot. I think that the tboot code should check the
|
|
||||||
CPUID hypervisor bit directly if it matters.
|
|
||||||
|
|
||||||
- paravirt_enabled disables espfix32. espfix32 should *not* be
|
|
||||||
disabled under KVM paravirt.
|
|
||||||
|
|
||||||
The last point is the purpose of this patch. It fixes a leak of the
|
|
||||||
high 16 bits of the kernel stack address on 32-bit KVM paravirt
|
|
||||||
guests. Fixes CVE-2014-8134.
|
|
||||||
|
|
||||||
Cc: stable@vger.kernel.org
|
|
||||||
Suggested-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
|
||||||
Signed-off-by: Andy Lutomirski <luto@amacapital.net>
|
|
||||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
||||||
---
|
|
||||||
arch/x86/kernel/kvm.c | 9 ++++++++-
|
|
||||||
arch/x86/kernel/kvmclock.c | 1 -
|
|
||||||
2 files changed, 8 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
--- a/arch/x86/kernel/kvm.c
|
|
||||||
+++ b/arch/x86/kernel/kvm.c
|
|
||||||
@@ -282,7 +282,14 @@ NOKPROBE_SYMBOL(do_async_page_fault);
|
|
||||||
static void __init paravirt_ops_setup(void)
|
|
||||||
{
|
|
||||||
pv_info.name = "KVM";
|
|
||||||
- pv_info.paravirt_enabled = 1;
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * KVM isn't paravirt in the sense of paravirt_enabled. A KVM
|
|
||||||
+ * guest kernel works like a bare metal kernel with additional
|
|
||||||
+ * features, and paravirt_enabled is about features that are
|
|
||||||
+ * missing.
|
|
||||||
+ */
|
|
||||||
+ pv_info.paravirt_enabled = 0;
|
|
||||||
|
|
||||||
if (kvm_para_has_feature(KVM_FEATURE_NOP_IO_DELAY))
|
|
||||||
pv_cpu_ops.io_delay = kvm_io_delay;
|
|
||||||
--- a/arch/x86/kernel/kvmclock.c
|
|
||||||
+++ b/arch/x86/kernel/kvmclock.c
|
|
||||||
@@ -263,7 +263,6 @@ void __init kvmclock_init(void)
|
|
||||||
#endif
|
|
||||||
kvm_get_preset_lpj();
|
|
||||||
clocksource_register_hz(&kvm_clock, NSEC_PER_SEC);
|
|
||||||
- pv_info.paravirt_enabled = 1;
|
|
||||||
pv_info.name = "KVM";
|
|
||||||
|
|
||||||
if (kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE_STABLE_BIT))
|
|
|
@ -1,75 +0,0 @@
|
||||||
From: Andy Lutomirski <luto@amacapital.net>
|
|
||||||
Date: Thu, 4 Dec 2014 16:48:16 -0800
|
|
||||||
Subject: x86/tls: Validate TLS entries to protect espfix
|
|
||||||
Origin: https://git.kernel.org/linus/41bdc78544b8a93a9c6814b8bbbfef966272abbe
|
|
||||||
|
|
||||||
Installing a 16-bit RW data segment into the GDT defeats espfix.
|
|
||||||
AFAICT this will not affect glibc, Wine, or dosemu at all.
|
|
||||||
|
|
||||||
Signed-off-by: Andy Lutomirski <luto@amacapital.net>
|
|
||||||
Acked-by: H. Peter Anvin <hpa@zytor.com>
|
|
||||||
Cc: stable@vger.kernel.org
|
|
||||||
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
|
||||||
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
|
||||||
Cc: security@kernel.org <security@kernel.org>
|
|
||||||
Cc: Willy Tarreau <w@1wt.eu>
|
|
||||||
Signed-off-by: Ingo Molnar <mingo@kernel.org>
|
|
||||||
---
|
|
||||||
arch/x86/kernel/tls.c | 23 +++++++++++++++++++++++
|
|
||||||
1 file changed, 23 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/arch/x86/kernel/tls.c b/arch/x86/kernel/tls.c
|
|
||||||
index f7fec09..e7650bd 100644
|
|
||||||
--- a/arch/x86/kernel/tls.c
|
|
||||||
+++ b/arch/x86/kernel/tls.c
|
|
||||||
@@ -27,6 +27,21 @@ static int get_free_idx(void)
|
|
||||||
return -ESRCH;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static bool tls_desc_okay(const struct user_desc *info)
|
|
||||||
+{
|
|
||||||
+ if (LDT_empty(info))
|
|
||||||
+ return true;
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * espfix is required for 16-bit data segments, but espfix
|
|
||||||
+ * only works for LDT segments.
|
|
||||||
+ */
|
|
||||||
+ if (!info->seg_32bit)
|
|
||||||
+ return false;
|
|
||||||
+
|
|
||||||
+ return true;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static void set_tls_desc(struct task_struct *p, int idx,
|
|
||||||
const struct user_desc *info, int n)
|
|
||||||
{
|
|
||||||
@@ -66,6 +81,9 @@ int do_set_thread_area(struct task_struct *p, int idx,
|
|
||||||
if (copy_from_user(&info, u_info, sizeof(info)))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
+ if (!tls_desc_okay(&info))
|
|
||||||
+ return -EINVAL;
|
|
||||||
+
|
|
||||||
if (idx == -1)
|
|
||||||
idx = info.entry_number;
|
|
||||||
|
|
||||||
@@ -192,6 +210,7 @@ int regset_tls_set(struct task_struct *target, const struct user_regset *regset,
|
|
||||||
{
|
|
||||||
struct user_desc infobuf[GDT_ENTRY_TLS_ENTRIES];
|
|
||||||
const struct user_desc *info;
|
|
||||||
+ int i;
|
|
||||||
|
|
||||||
if (pos >= GDT_ENTRY_TLS_ENTRIES * sizeof(struct user_desc) ||
|
|
||||||
(pos % sizeof(struct user_desc)) != 0 ||
|
|
||||||
@@ -205,6 +224,10 @@ int regset_tls_set(struct task_struct *target, const struct user_regset *regset,
|
|
||||||
else
|
|
||||||
info = infobuf;
|
|
||||||
|
|
||||||
+ for (i = 0; i < count / sizeof(struct user_desc); i++)
|
|
||||||
+ if (!tls_desc_okay(info + i))
|
|
||||||
+ return -EINVAL;
|
|
||||||
+
|
|
||||||
set_tls_desc(target,
|
|
||||||
GDT_ENTRY_TLS_MIN + (pos / sizeof(struct user_desc)),
|
|
||||||
info, count / sizeof(struct user_desc));
|
|
|
@ -1,304 +0,0 @@
|
||||||
From: Andy Lutomirski <luto@amacapital.net>
|
|
||||||
Date: Mon, 8 Dec 2014 13:55:20 -0800
|
|
||||||
Subject: x86_64, switch_to(): Load TLS descriptors before switching DS and ES
|
|
||||||
Origin: https://git.kernel.org/linus/f647d7c155f069c1a068030255c300663516420e
|
|
||||||
|
|
||||||
Otherwise, if buggy user code points DS or ES into the TLS
|
|
||||||
array, they would be corrupted after a context switch.
|
|
||||||
|
|
||||||
This also significantly improves the comments and documents some
|
|
||||||
gotchas in the code.
|
|
||||||
|
|
||||||
Before this patch, the both tests below failed. With this
|
|
||||||
patch, the es test passes, although the gsbase test still fails.
|
|
||||||
|
|
||||||
----- begin es test -----
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2014 Andy Lutomirski
|
|
||||||
* GPL v2
|
|
||||||
*/
|
|
||||||
|
|
||||||
static unsigned short GDT3(int idx)
|
|
||||||
{
|
|
||||||
return (idx << 3) | 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int create_tls(int idx, unsigned int base)
|
|
||||||
{
|
|
||||||
struct user_desc desc = {
|
|
||||||
.entry_number = idx,
|
|
||||||
.base_addr = base,
|
|
||||||
.limit = 0xfffff,
|
|
||||||
.seg_32bit = 1,
|
|
||||||
.contents = 0, /* Data, grow-up */
|
|
||||||
.read_exec_only = 0,
|
|
||||||
.limit_in_pages = 1,
|
|
||||||
.seg_not_present = 0,
|
|
||||||
.useable = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (syscall(SYS_set_thread_area, &desc) != 0)
|
|
||||||
err(1, "set_thread_area");
|
|
||||||
|
|
||||||
return desc.entry_number;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
int idx = create_tls(-1, 0);
|
|
||||||
printf("Allocated GDT index %d\n", idx);
|
|
||||||
|
|
||||||
unsigned short orig_es;
|
|
||||||
asm volatile ("mov %%es,%0" : "=rm" (orig_es));
|
|
||||||
|
|
||||||
int errors = 0;
|
|
||||||
int total = 1000;
|
|
||||||
for (int i = 0; i < total; i++) {
|
|
||||||
asm volatile ("mov %0,%%es" : : "rm" (GDT3(idx)));
|
|
||||||
usleep(100);
|
|
||||||
|
|
||||||
unsigned short es;
|
|
||||||
asm volatile ("mov %%es,%0" : "=rm" (es));
|
|
||||||
asm volatile ("mov %0,%%es" : : "rm" (orig_es));
|
|
||||||
if (es != GDT3(idx)) {
|
|
||||||
if (errors == 0)
|
|
||||||
printf("[FAIL]\tES changed from 0x%hx to 0x%hx\n",
|
|
||||||
GDT3(idx), es);
|
|
||||||
errors++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errors) {
|
|
||||||
printf("[FAIL]\tES was corrupted %d/%d times\n", errors, total);
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
printf("[OK]\tES was preserved\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
----- end es test -----
|
|
||||||
|
|
||||||
----- begin gsbase test -----
|
|
||||||
|
|
||||||
/*
|
|
||||||
* gsbase.c, a gsbase test
|
|
||||||
* Copyright (c) 2014 Andy Lutomirski
|
|
||||||
* GPL v2
|
|
||||||
*/
|
|
||||||
|
|
||||||
static unsigned char *testptr, *testptr2;
|
|
||||||
|
|
||||||
static unsigned char read_gs_testvals(void)
|
|
||||||
{
|
|
||||||
unsigned char ret;
|
|
||||||
asm volatile ("movb %%gs:%1, %0" : "=r" (ret) : "m" (*testptr));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
int errors = 0;
|
|
||||||
|
|
||||||
testptr = mmap((void *)0x200000000UL, 1, PROT_READ | PROT_WRITE,
|
|
||||||
MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
|
|
||||||
if (testptr == MAP_FAILED)
|
|
||||||
err(1, "mmap");
|
|
||||||
|
|
||||||
testptr2 = mmap((void *)0x300000000UL, 1, PROT_READ | PROT_WRITE,
|
|
||||||
MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
|
|
||||||
if (testptr2 == MAP_FAILED)
|
|
||||||
err(1, "mmap");
|
|
||||||
|
|
||||||
*testptr = 0;
|
|
||||||
*testptr2 = 1;
|
|
||||||
|
|
||||||
if (syscall(SYS_arch_prctl, ARCH_SET_GS,
|
|
||||||
(unsigned long)testptr2 - (unsigned long)testptr) != 0)
|
|
||||||
err(1, "ARCH_SET_GS");
|
|
||||||
|
|
||||||
usleep(100);
|
|
||||||
|
|
||||||
if (read_gs_testvals() == 1) {
|
|
||||||
printf("[OK]\tARCH_SET_GS worked\n");
|
|
||||||
} else {
|
|
||||||
printf("[FAIL]\tARCH_SET_GS failed\n");
|
|
||||||
errors++;
|
|
||||||
}
|
|
||||||
|
|
||||||
asm volatile ("mov %0,%%gs" : : "r" (0));
|
|
||||||
|
|
||||||
if (read_gs_testvals() == 0) {
|
|
||||||
printf("[OK]\tWriting 0 to gs worked\n");
|
|
||||||
} else {
|
|
||||||
printf("[FAIL]\tWriting 0 to gs failed\n");
|
|
||||||
errors++;
|
|
||||||
}
|
|
||||||
|
|
||||||
usleep(100);
|
|
||||||
|
|
||||||
if (read_gs_testvals() == 0) {
|
|
||||||
printf("[OK]\tgsbase is still zero\n");
|
|
||||||
} else {
|
|
||||||
printf("[FAIL]\tgsbase was corrupted\n");
|
|
||||||
errors++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return errors == 0 ? 0 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
----- end gsbase test -----
|
|
||||||
|
|
||||||
Signed-off-by: Andy Lutomirski <luto@amacapital.net>
|
|
||||||
Cc: <stable@vger.kernel.org>
|
|
||||||
Cc: Andi Kleen <andi@firstfloor.org>
|
|
||||||
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
|
||||||
Link: http://lkml.kernel.org/r/509d27c9fec78217691c3dad91cec87e1006b34a.1418075657.git.luto@amacapital.net
|
|
||||||
Signed-off-by: Ingo Molnar <mingo@kernel.org>
|
|
||||||
---
|
|
||||||
arch/x86/kernel/process_64.c | 101 +++++++++++++++++++++++++++++++------------
|
|
||||||
1 file changed, 73 insertions(+), 28 deletions(-)
|
|
||||||
|
|
||||||
--- a/arch/x86/kernel/process_64.c
|
|
||||||
+++ b/arch/x86/kernel/process_64.c
|
|
||||||
@@ -286,24 +286,9 @@ __switch_to(struct task_struct *prev_p,
|
|
||||||
|
|
||||||
fpu = switch_fpu_prepare(prev_p, next_p, cpu);
|
|
||||||
|
|
||||||
- /*
|
|
||||||
- * Reload esp0, LDT and the page table pointer:
|
|
||||||
- */
|
|
||||||
+ /* Reload esp0 and ss1. */
|
|
||||||
load_sp0(tss, next);
|
|
||||||
|
|
||||||
- /*
|
|
||||||
- * Switch DS and ES.
|
|
||||||
- * This won't pick up thread selector changes, but I guess that is ok.
|
|
||||||
- */
|
|
||||||
- savesegment(es, prev->es);
|
|
||||||
- if (unlikely(next->es | prev->es))
|
|
||||||
- loadsegment(es, next->es);
|
|
||||||
-
|
|
||||||
- savesegment(ds, prev->ds);
|
|
||||||
- if (unlikely(next->ds | prev->ds))
|
|
||||||
- loadsegment(ds, next->ds);
|
|
||||||
-
|
|
||||||
-
|
|
||||||
/* We must save %fs and %gs before load_TLS() because
|
|
||||||
* %fs and %gs may be cleared by load_TLS().
|
|
||||||
*
|
|
||||||
@@ -312,41 +297,101 @@ __switch_to(struct task_struct *prev_p,
|
|
||||||
savesegment(fs, fsindex);
|
|
||||||
savesegment(gs, gsindex);
|
|
||||||
|
|
||||||
+ /*
|
|
||||||
+ * Load TLS before restoring any segments so that segment loads
|
|
||||||
+ * reference the correct GDT entries.
|
|
||||||
+ */
|
|
||||||
load_TLS(next, cpu);
|
|
||||||
|
|
||||||
/*
|
|
||||||
- * Leave lazy mode, flushing any hypercalls made here.
|
|
||||||
- * This must be done before restoring TLS segments so
|
|
||||||
- * the GDT and LDT are properly updated, and must be
|
|
||||||
- * done before math_state_restore, so the TS bit is up
|
|
||||||
- * to date.
|
|
||||||
+ * Leave lazy mode, flushing any hypercalls made here. This
|
|
||||||
+ * must be done after loading TLS entries in the GDT but before
|
|
||||||
+ * loading segments that might reference them, and and it must
|
|
||||||
+ * be done before math_state_restore, so the TS bit is up to
|
|
||||||
+ * date.
|
|
||||||
*/
|
|
||||||
arch_end_context_switch(next_p);
|
|
||||||
|
|
||||||
+ /* Switch DS and ES.
|
|
||||||
+ *
|
|
||||||
+ * Reading them only returns the selectors, but writing them (if
|
|
||||||
+ * nonzero) loads the full descriptor from the GDT or LDT. The
|
|
||||||
+ * LDT for next is loaded in switch_mm, and the GDT is loaded
|
|
||||||
+ * above.
|
|
||||||
+ *
|
|
||||||
+ * We therefore need to write new values to the segment
|
|
||||||
+ * registers on every context switch unless both the new and old
|
|
||||||
+ * values are zero.
|
|
||||||
+ *
|
|
||||||
+ * Note that we don't need to do anything for CS and SS, as
|
|
||||||
+ * those are saved and restored as part of pt_regs.
|
|
||||||
+ */
|
|
||||||
+ savesegment(es, prev->es);
|
|
||||||
+ if (unlikely(next->es | prev->es))
|
|
||||||
+ loadsegment(es, next->es);
|
|
||||||
+
|
|
||||||
+ savesegment(ds, prev->ds);
|
|
||||||
+ if (unlikely(next->ds | prev->ds))
|
|
||||||
+ loadsegment(ds, next->ds);
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* Switch FS and GS.
|
|
||||||
*
|
|
||||||
- * Segment register != 0 always requires a reload. Also
|
|
||||||
- * reload when it has changed. When prev process used 64bit
|
|
||||||
- * base always reload to avoid an information leak.
|
|
||||||
+ * These are even more complicated than FS and GS: they have
|
|
||||||
+ * 64-bit bases are that controlled by arch_prctl. Those bases
|
|
||||||
+ * only differ from the values in the GDT or LDT if the selector
|
|
||||||
+ * is 0.
|
|
||||||
+ *
|
|
||||||
+ * Loading the segment register resets the hidden base part of
|
|
||||||
+ * the register to 0 or the value from the GDT / LDT. If the
|
|
||||||
+ * next base address zero, writing 0 to the segment register is
|
|
||||||
+ * much faster than using wrmsr to explicitly zero the base.
|
|
||||||
+ *
|
|
||||||
+ * The thread_struct.fs and thread_struct.gs values are 0
|
|
||||||
+ * if the fs and gs bases respectively are not overridden
|
|
||||||
+ * from the values implied by fsindex and gsindex. They
|
|
||||||
+ * are nonzero, and store the nonzero base addresses, if
|
|
||||||
+ * the bases are overridden.
|
|
||||||
+ *
|
|
||||||
+ * (fs != 0 && fsindex != 0) || (gs != 0 && gsindex != 0) should
|
|
||||||
+ * be impossible.
|
|
||||||
+ *
|
|
||||||
+ * Therefore we need to reload the segment registers if either
|
|
||||||
+ * the old or new selector is nonzero, and we need to override
|
|
||||||
+ * the base address if next thread expects it to be overridden.
|
|
||||||
+ *
|
|
||||||
+ * This code is unnecessarily slow in the case where the old and
|
|
||||||
+ * new indexes are zero and the new base is nonzero -- it will
|
|
||||||
+ * unnecessarily write 0 to the selector before writing the new
|
|
||||||
+ * base address.
|
|
||||||
+ *
|
|
||||||
+ * Note: This all depends on arch_prctl being the only way that
|
|
||||||
+ * user code can override the segment base. Once wrfsbase and
|
|
||||||
+ * wrgsbase are enabled, most of this code will need to change.
|
|
||||||
*/
|
|
||||||
if (unlikely(fsindex | next->fsindex | prev->fs)) {
|
|
||||||
loadsegment(fs, next->fsindex);
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
- * Check if the user used a selector != 0; if yes
|
|
||||||
- * clear 64bit base, since overloaded base is always
|
|
||||||
- * mapped to the Null selector
|
|
||||||
+ * If user code wrote a nonzero value to FS, then it also
|
|
||||||
+ * cleared the overridden base address.
|
|
||||||
+ *
|
|
||||||
+ * XXX: if user code wrote 0 to FS and cleared the base
|
|
||||||
+ * address itself, we won't notice and we'll incorrectly
|
|
||||||
+ * restore the prior base address next time we reschdule
|
|
||||||
+ * the process.
|
|
||||||
*/
|
|
||||||
if (fsindex)
|
|
||||||
prev->fs = 0;
|
|
||||||
}
|
|
||||||
- /* when next process has a 64bit base use it */
|
|
||||||
if (next->fs)
|
|
||||||
wrmsrl(MSR_FS_BASE, next->fs);
|
|
||||||
prev->fsindex = fsindex;
|
|
||||||
|
|
||||||
if (unlikely(gsindex | next->gsindex | prev->gs)) {
|
|
||||||
load_gs_index(next->gsindex);
|
|
||||||
+
|
|
||||||
+ /* This works (and fails) the same way as fsindex above. */
|
|
||||||
if (gsindex)
|
|
||||||
prev->gs = 0;
|
|
||||||
}
|
|
|
@ -15,7 +15,7 @@ Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
|
||||||
---
|
---
|
||||||
--- a/kernel/fork.c
|
--- a/kernel/fork.c
|
||||||
+++ b/kernel/fork.c
|
+++ b/kernel/fork.c
|
||||||
@@ -83,6 +83,11 @@
|
@@ -86,6 +86,11 @@
|
||||||
|
|
||||||
#define CREATE_TRACE_POINTS
|
#define CREATE_TRACE_POINTS
|
||||||
#include <trace/events/task.h>
|
#include <trace/events/task.h>
|
||||||
|
@ -27,7 +27,7 @@ Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Protected counters by write_lock_irq(&tasklist_lock)
|
* Protected counters by write_lock_irq(&tasklist_lock)
|
||||||
@@ -1144,6 +1149,10 @@ static struct task_struct *copy_process(
|
@@ -1149,6 +1154,10 @@ static struct task_struct *copy_process(
|
||||||
if ((clone_flags & (CLONE_NEWUSER|CLONE_FS)) == (CLONE_NEWUSER|CLONE_FS))
|
if ((clone_flags & (CLONE_NEWUSER|CLONE_FS)) == (CLONE_NEWUSER|CLONE_FS))
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
|
||||||
/*
|
/*
|
||||||
* Thread groups must share signals as well, and detached threads
|
* Thread groups must share signals as well, and detached threads
|
||||||
* can only be started up within the thread group.
|
* can only be started up within the thread group.
|
||||||
@@ -1831,6 +1840,12 @@ SYSCALL_DEFINE1(unshare, unsigned long,
|
@@ -1843,6 +1852,12 @@ SYSCALL_DEFINE1(unshare, unsigned long,
|
||||||
if (unshare_flags & CLONE_NEWNS)
|
if (unshare_flags & CLONE_NEWNS)
|
||||||
unshare_flags |= CLONE_FS;
|
unshare_flags |= CLONE_FS;
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
|
||||||
goto bad_unshare_out;
|
goto bad_unshare_out;
|
||||||
--- a/kernel/sysctl.c
|
--- a/kernel/sysctl.c
|
||||||
+++ b/kernel/sysctl.c
|
+++ b/kernel/sysctl.c
|
||||||
@@ -104,6 +104,9 @@ extern int core_uses_pid;
|
@@ -103,6 +103,9 @@ extern int core_uses_pid;
|
||||||
extern char core_pattern[];
|
extern char core_pattern[];
|
||||||
extern unsigned int core_pipe_limit;
|
extern unsigned int core_pipe_limit;
|
||||||
#endif
|
#endif
|
||||||
|
@ -63,7 +63,7 @@ Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
|
||||||
extern int pid_max;
|
extern int pid_max;
|
||||||
extern int pid_max_min, pid_max_max;
|
extern int pid_max_min, pid_max_max;
|
||||||
extern int percpu_pagelist_fraction;
|
extern int percpu_pagelist_fraction;
|
||||||
@@ -482,6 +485,15 @@ static struct ctl_table kern_table[] = {
|
@@ -489,6 +492,15 @@ static struct ctl_table kern_table[] = {
|
||||||
.mode = 0644,
|
.mode = 0644,
|
||||||
.proc_handler = proc_dointvec,
|
.proc_handler = proc_dointvec,
|
||||||
},
|
},
|
||||||
|
@ -89,5 +89,5 @@ Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
|
||||||
+int unprivileged_userns_clone;
|
+int unprivileged_userns_clone;
|
||||||
+
|
+
|
||||||
static struct kmem_cache *user_ns_cachep __read_mostly;
|
static struct kmem_cache *user_ns_cachep __read_mostly;
|
||||||
|
static DEFINE_MUTEX(userns_state_mutex);
|
||||||
|
|
||||||
static bool new_idmap_permitted(const struct file *file,
|
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
From: Ben Hutchings <ben@decadent.org.uk>
|
||||||
|
Date: Thu, 15 Jan 2015 23:16:35 +0000
|
||||||
|
Subject: userns: Fix ABI change in 3.16.7-ckt4
|
||||||
|
Forwarded: not-needed
|
||||||
|
|
||||||
|
The fix for CVE-2014-8989 added a new member to struct user_namespace.
|
||||||
|
This is always allocated, and the new member is always used, in
|
||||||
|
non-modular code. Move it to the end of the structure and hide it
|
||||||
|
from genksyms.
|
||||||
|
|
||||||
|
Also hide the new #include in kernel/groups.c.
|
||||||
|
|
||||||
|
---
|
||||||
|
--- a/include/linux/user_namespace.h
|
||||||
|
+++ b/include/linux/user_namespace.h
|
||||||
|
@@ -31,13 +31,16 @@ struct user_namespace {
|
||||||
|
kuid_t owner;
|
||||||
|
kgid_t group;
|
||||||
|
unsigned int proc_inum;
|
||||||
|
- unsigned long flags;
|
||||||
|
|
||||||
|
/* Register of per-UID persistent keyrings for this namespace */
|
||||||
|
#ifdef CONFIG_PERSISTENT_KEYRINGS
|
||||||
|
struct key *persistent_keyring_register;
|
||||||
|
struct rw_semaphore persistent_keyring_register_sem;
|
||||||
|
#endif
|
||||||
|
+
|
||||||
|
+#ifndef __GENKSYMS__
|
||||||
|
+ unsigned long flags;
|
||||||
|
+#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct user_namespace init_user_ns;
|
||||||
|
--- a/kernel/groups.c
|
||||||
|
+++ b/kernel/groups.c
|
||||||
|
@@ -6,7 +6,9 @@
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/security.h>
|
||||||
|
#include <linux/syscalls.h>
|
||||||
|
+#ifndef __GENKSYMS__
|
||||||
|
#include <linux/user_namespace.h>
|
||||||
|
+#endif
|
||||||
|
#include <asm/uaccess.h>
|
||||||
|
|
||||||
|
/* init to 2 - one for init_task, one to ensure it is never freed */
|
|
@ -1,124 +0,0 @@
|
||||||
From: Mika Westerberg <mika.westerberg@linux.intel.com>
|
|
||||||
Date: Tue, 17 Jun 2014 14:02:00 -0700
|
|
||||||
Subject: platform/chrome: chromeos_laptop - Add support for Acer C720
|
|
||||||
Origin: https://git.kernel.org/linus/da3b0ab75aadab63d1ffd5563100c9386e444dad
|
|
||||||
|
|
||||||
Acer C720 has touchpad and light sensor connected to a separate I2C buses.
|
|
||||||
Since the designware I2C host controller driver has two instances on this
|
|
||||||
particular machine we need a way to match the correct instance. Add support
|
|
||||||
for this and then register both C720 touchpad and light sensor.
|
|
||||||
|
|
||||||
This code is based on following patch from Benson Leung:
|
|
||||||
|
|
||||||
https://patchwork.kernel.org/patch/3074411/
|
|
||||||
|
|
||||||
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
|
|
||||||
Tested-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
|
|
||||||
Signed-off-by: Benson Leung <bleung@chromium.org>
|
|
||||||
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
|
|
||||||
Signed-off-by: Olof Johansson <olof@lixom.net>
|
|
||||||
---
|
|
||||||
drivers/platform/chrome/chromeos_laptop.c | 45 ++++++++++++++++++++++++++-----
|
|
||||||
1 file changed, 39 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/platform/chrome/chromeos_laptop.c b/drivers/platform/chrome/chromeos_laptop.c
|
|
||||||
index 7f1a2e2..a241e5f 100644
|
|
||||||
--- a/drivers/platform/chrome/chromeos_laptop.c
|
|
||||||
+++ b/drivers/platform/chrome/chromeos_laptop.c
|
|
||||||
@@ -45,6 +45,8 @@ static const char *i2c_adapter_names[] = {
|
|
||||||
"SMBus I801 adapter",
|
|
||||||
"i915 gmbus vga",
|
|
||||||
"i915 gmbus panel",
|
|
||||||
+ "i2c-designware-pci",
|
|
||||||
+ "i2c-designware-pci",
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Keep this enum consistent with i2c_adapter_names */
|
|
||||||
@@ -52,6 +54,8 @@ enum i2c_adapter_type {
|
|
||||||
I2C_ADAPTER_SMBUS = 0,
|
|
||||||
I2C_ADAPTER_VGADDC,
|
|
||||||
I2C_ADAPTER_PANEL,
|
|
||||||
+ I2C_ADAPTER_DESIGNWARE_0,
|
|
||||||
+ I2C_ADAPTER_DESIGNWARE_1,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct i2c_peripheral {
|
|
||||||
@@ -172,29 +176,42 @@ static struct i2c_client *__add_probed_i2c_device(
|
|
||||||
return client;
|
|
||||||
}
|
|
||||||
|
|
||||||
+struct i2c_lookup {
|
|
||||||
+ const char *name;
|
|
||||||
+ int instance;
|
|
||||||
+ int n;
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static int __find_i2c_adap(struct device *dev, void *data)
|
|
||||||
{
|
|
||||||
- const char *name = data;
|
|
||||||
+ struct i2c_lookup *lookup = data;
|
|
||||||
static const char *prefix = "i2c-";
|
|
||||||
struct i2c_adapter *adapter;
|
|
||||||
if (strncmp(dev_name(dev), prefix, strlen(prefix)) != 0)
|
|
||||||
return 0;
|
|
||||||
adapter = to_i2c_adapter(dev);
|
|
||||||
- return (strncmp(adapter->name, name, strlen(name)) == 0);
|
|
||||||
+ if (strncmp(adapter->name, lookup->name, strlen(lookup->name)) == 0 &&
|
|
||||||
+ lookup->n++ == lookup->instance)
|
|
||||||
+ return 1;
|
|
||||||
+ return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int find_i2c_adapter_num(enum i2c_adapter_type type)
|
|
||||||
{
|
|
||||||
struct device *dev = NULL;
|
|
||||||
struct i2c_adapter *adapter;
|
|
||||||
- const char *name = i2c_adapter_names[type];
|
|
||||||
+ struct i2c_lookup lookup;
|
|
||||||
+
|
|
||||||
+ memset(&lookup, 0, sizeof(lookup));
|
|
||||||
+ lookup.name = i2c_adapter_names[type];
|
|
||||||
+ lookup.instance = (type == I2C_ADAPTER_DESIGNWARE_1) ? 1 : 0;
|
|
||||||
+
|
|
||||||
/* find the adapter by name */
|
|
||||||
- dev = bus_find_device(&i2c_bus_type, NULL, (void *)name,
|
|
||||||
- __find_i2c_adap);
|
|
||||||
+ dev = bus_find_device(&i2c_bus_type, NULL, &lookup, __find_i2c_adap);
|
|
||||||
if (!dev) {
|
|
||||||
/* Adapters may appear later. Deferred probing will retry */
|
|
||||||
pr_notice("%s: i2c adapter %s not found on system.\n", __func__,
|
|
||||||
- name);
|
|
||||||
+ lookup.name);
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
adapter = to_i2c_adapter(dev);
|
|
||||||
@@ -377,6 +394,15 @@ static struct chromeos_laptop acer_ac700 = {
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
+static struct chromeos_laptop acer_c720 = {
|
|
||||||
+ .i2c_peripherals = {
|
|
||||||
+ /* Touchpad. */
|
|
||||||
+ { .add = setup_cyapa_tp, I2C_ADAPTER_DESIGNWARE_0 },
|
|
||||||
+ /* Light Sensor. */
|
|
||||||
+ { .add = setup_isl29018_als, I2C_ADAPTER_DESIGNWARE_1 },
|
|
||||||
+ },
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static struct chromeos_laptop hp_pavilion_14_chromebook = {
|
|
||||||
.i2c_peripherals = {
|
|
||||||
/* Touchpad. */
|
|
||||||
@@ -434,6 +460,13 @@ static struct dmi_system_id chromeos_laptop_dmi_table[] __initdata = {
|
|
||||||
_CBDD(acer_ac700),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
+ .ident = "Acer C720",
|
|
||||||
+ .matches = {
|
|
||||||
+ DMI_MATCH(DMI_PRODUCT_NAME, "Peppy"),
|
|
||||||
+ },
|
|
||||||
+ _CBDD(acer_c720),
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
.ident = "HP Pavilion 14 Chromebook",
|
|
||||||
.matches = {
|
|
||||||
DMI_MATCH(DMI_PRODUCT_NAME, "Butterfly"),
|
|
|
@ -51,17 +51,12 @@ bugfix/arm/omap-musb-choice.patch
|
||||||
bugfix/mips/disable-advansys.patch
|
bugfix/mips/disable-advansys.patch
|
||||||
bugfix/arm/ixp4xx_iobe.patch
|
bugfix/arm/ixp4xx_iobe.patch
|
||||||
bugfix/m68k/ethernat-kconfig.patch
|
bugfix/m68k/ethernat-kconfig.patch
|
||||||
bugfix/s390/s390-3215-fix-hanging-console-issue.patch
|
|
||||||
bugfix/s390/s390-3215-fix-tty-output-containing-tabs.patch
|
|
||||||
bugfix/x86/drm-i915-initialise-userptr-mmu_notifier-serial-to-1.patch
|
bugfix/x86/drm-i915-initialise-userptr-mmu_notifier-serial-to-1.patch
|
||||||
bugfix/x86/drm-i915-Add-some-L3-registers-to-the-parser-whiteli.patch
|
bugfix/x86/drm-i915-Add-some-L3-registers-to-the-parser-whiteli.patch
|
||||||
bugfix/parisc/parisc-reduce-sigrtmin-from-37-to-32-to-behave-like-.patch
|
bugfix/parisc/parisc-reduce-sigrtmin-from-37-to-32-to-behave-like-.patch
|
||||||
bugfix/arm64/arm64-add-missing-dts-entry-for-X-Gene-platform.patch
|
bugfix/arm64/arm64-add-missing-dts-entry-for-X-Gene-platform.patch
|
||||||
bugfix/arm64/arm64-removed-using-of-the-mask-attribute-in-the-dts.patch
|
bugfix/arm64/arm64-removed-using-of-the-mask-attribute-in-the-dts.patch
|
||||||
bugfix/x86/acpi-video-run-_bcl-before-deciding-registering-back.patch
|
bugfix/x86/acpi-video-run-_bcl-before-deciding-registering-back.patch
|
||||||
bugfix/x86/x86-tls-validate-tls-entries-to-protect-espfix.patch
|
|
||||||
bugfix/x86/x86-kvm-clear-paravirt_enabled-on-kvm-guests-for-esp.patch
|
|
||||||
bugfix/x86/x86_64-switch_to-load-tls-descriptors-before-switchi.patch
|
|
||||||
|
|
||||||
# Arch features
|
# Arch features
|
||||||
features/mips/MIPS-Support-hard-limit-of-cpu-count-nr_cpu_ids.patch
|
features/mips/MIPS-Support-hard-limit-of-cpu-count-nr_cpu_ids.patch
|
||||||
|
@ -128,7 +123,6 @@ features/arm64/drivers-net-xgene-fix-Use-separate-resources.patch
|
||||||
features/arm64/dtb-Add-10GbE-node-to-APM-X-Gene-SoC-device-tree.patch
|
features/arm64/dtb-Add-10GbE-node-to-APM-X-Gene-SoC-device-tree.patch
|
||||||
features/arm64/dtb-Add-SGMII-based-1GbE-node-to-APM-X-Gene-SoC-devi.patch
|
features/arm64/dtb-Add-SGMII-based-1GbE-node-to-APM-X-Gene-SoC-devi.patch
|
||||||
features/arm64/dtb-xgene-fix-Backward-compatibility-with-older-firm.patch
|
features/arm64/dtb-xgene-fix-Backward-compatibility-with-older-firm.patch
|
||||||
features/x86/platform-chrome-chromeos_laptop-add-support-for-acer.patch
|
|
||||||
|
|
||||||
# Miscellaneous bug fixes
|
# Miscellaneous bug fixes
|
||||||
bugfix/all/misc-bmp085-Enable-building-as-a-module.patch
|
bugfix/all/misc-bmp085-Enable-building-as-a-module.patch
|
||||||
|
@ -156,13 +150,7 @@ bugfix/all/xen-netback-Disable-NAPI-after-disabling-interrupts.patch
|
||||||
bugfix/all/xen-netback-do-not-report-success-if-backend_create_.patch
|
bugfix/all/xen-netback-do-not-report-success-if-backend_create_.patch
|
||||||
bugfix/all/netback-don-t-store-invalid-vif-pointer.patch
|
bugfix/all/netback-don-t-store-invalid-vif-pointer.patch
|
||||||
bugfix/all/xen-netback-support-frontends-without-feature-rx-not.patch
|
bugfix/all/xen-netback-support-frontends-without-feature-rx-not.patch
|
||||||
bugfix/all/isofs-fix-infinite-looping-over-ce-entries.patch
|
|
||||||
bugfix/all/batman-adv-calculate-extra-tail-size-based-on-queued.patch
|
|
||||||
bugfix/all/keys-close-race-between-key-lookup-and-freeing.patch
|
|
||||||
bugfix/all/isofs-fix-unchecked-printing-of-er-records.patch
|
|
||||||
bugfix/all/move-d_rcu-from-overlapping-d_child-to-overlapping-d.patch
|
|
||||||
bugfix/all/aufs-move-d_rcu-from-overlapping-d_child-to-overlapping-d.patch
|
bugfix/all/aufs-move-d_rcu-from-overlapping-d_child-to-overlapping-d.patch
|
||||||
bugfix/all/deal-with-deadlock-in-d_walk.patch
|
|
||||||
bugfix/all/net-mv643xx-disable-tso-by-default.patch
|
bugfix/all/net-mv643xx-disable-tso-by-default.patch
|
||||||
|
|
||||||
# memfd_create() & kdbus backport
|
# memfd_create() & kdbus backport
|
||||||
|
@ -497,3 +485,4 @@ debian/perf-fix-abi-change-in-3.16.7-ckt2.patch
|
||||||
debian/arm-thread_info-fix-abi-change-in-3.16.7-ckt3.patch
|
debian/arm-thread_info-fix-abi-change-in-3.16.7-ckt3.patch
|
||||||
debian/pci-fix-abi-change-in-3.16.7-ckt3.patch
|
debian/pci-fix-abi-change-in-3.16.7-ckt3.patch
|
||||||
debian/vfs-avoid-abi-change-for-dentry-union-changes.patch
|
debian/vfs-avoid-abi-change-for-dentry-union-changes.patch
|
||||||
|
debian/userns-fix-abi-change-in-3.16.7-ckt4.patch
|
||||||
|
|
Loading…
Reference in New Issue