Merge 4.19.323 into android-4.19-stable

Changes in 4.19.323
	staging: iio: frequency: ad9833: Get frequency value statically
	staging: iio: frequency: ad9833: Load clock using clock framework
	staging: iio: frequency: ad9834: Validate frequency parameter value
	usbnet: ipheth: fix carrier detection in modes 1 and 4
	net: ethernet: use ip_hdrlen() instead of bit shift
	net: phy: vitesse: repair vsc73xx autonegotiation
	scripts: kconfig: merge_config: config files: add a trailing newline
	arm64: dts: rockchip: override BIOS_DISABLE signal via GPIO hog on RK3399 Puma
	net/mlx5: Update the list of the PCI supported devices
	net: ftgmac100: Enable TX interrupt to avoid TX timeout
	net: dpaa: Pad packets to ETH_ZLEN
	soundwire: stream: Revert "soundwire: stream: fix programming slave ports for non-continous port maps"
	selftests/vm: remove call to ksft_set_plan()
	selftests/kcmp: remove call to ksft_set_plan()
	ASoC: allow module autoloading for table db1200_pids
	pinctrl: at91: make it work with current gpiolib
	microblaze: don't treat zero reserved memory regions as error
	net: ftgmac100: Ensure tx descriptor updates are visible
	wifi: iwlwifi: mvm: fix iwl_mvm_max_scan_ie_fw_cmd_room()
	wifi: iwlwifi: mvm: don't wait for tx queues if firmware is dead
	ASoC: tda7419: fix module autoloading
	spi: bcm63xx: Enable module autoloading
	x86/hyperv: Set X86_FEATURE_TSC_KNOWN_FREQ when Hyper-V provides frequency
	ocfs2: add bounds checking to ocfs2_xattr_find_entry()
	ocfs2: strict bound check before memcmp in ocfs2_xattr_find_entry()
	gpio: prevent potential speculation leaks in gpio_device_get_desc()
	USB: serial: pl2303: add device id for Macrosilicon MS3020
	ACPI: PMIC: Remove unneeded check in tps68470_pmic_opregion_probe()
	wifi: ath9k: fix parameter check in ath9k_init_debug()
	wifi: ath9k: Remove error checks when creating debugfs entries
	netfilter: nf_tables: elements with timeout below CONFIG_HZ never expire
	wifi: cfg80211: fix UBSAN noise in cfg80211_wext_siwscan()
	wifi: cfg80211: fix two more possible UBSAN-detected off-by-one errors
	wifi: mac80211: use two-phase skb reclamation in ieee80211_do_stop()
	can: bcm: Clear bo->bcm_proc_read after remove_proc_entry().
	Bluetooth: btusb: Fix not handling ZPL/short-transfer
	block, bfq: fix possible UAF for bfqq->bic with merge chain
	block, bfq: choose the last bfqq from merge chain in bfq_setup_cooperator()
	block, bfq: don't break merge chain in bfq_split_bfqq()
	spi: ppc4xx: handle irq_of_parse_and_map() errors
	spi: ppc4xx: Avoid returning 0 when failed to parse and map IRQ
	ARM: versatile: fix OF node leak in CPUs prepare
	reset: berlin: fix OF node leak in probe() error path
	clocksource/drivers/qcom: Add missing iounmap() on errors in msm_dt_timer_init()
	hwmon: (max16065) Fix overflows seen when writing limits
	mtd: slram: insert break after errors in parsing the map
	hwmon: (ntc_thermistor) fix module autoloading
	power: supply: max17042_battery: Fix SOC threshold calc w/ no current sense
	fbdev: hpfb: Fix an error handling path in hpfb_dio_probe()
	drm/stm: Fix an error handling path in stm_drm_platform_probe()
	drm/amd: fix typo
	drm/amdgpu: Replace one-element array with flexible-array member
	drm/amdgpu: properly handle vbios fake edid sizing
	drm/radeon: Replace one-element array with flexible-array member
	drm/radeon: properly handle vbios fake edid sizing
	drm/rockchip: vop: Allow 4096px width scaling
	drm/radeon/evergreen_cs: fix int overflow errors in cs track offsets
	jfs: fix out-of-bounds in dbNextAG() and diAlloc()
	drm/msm/a5xx: properly clear preemption records on resume
	drm/msm/a5xx: fix races in preemption evaluation stage
	ipmi: docs: don't advertise deprecated sysfs entries
	drm/msm: fix %s null argument error
	xen: use correct end address of kernel for conflict checking
	xen/swiotlb: simplify range_straddles_page_boundary()
	xen/swiotlb: add alignment check for dma buffers
	selftests/bpf: Fix error compiling test_lru_map.c
	xz: cleanup CRC32 edits from 2018
	kthread: add kthread_work tracepoints
	kthread: fix task state in kthread worker if being frozen
	jbd2: introduce/export functions jbd2_journal_submit|finish_inode_data_buffers()
	ext4: clear EXT4_GROUP_INFO_WAS_TRIMMED_BIT even mount with discard
	smackfs: Use rcu_assign_pointer() to ensure safe assignment in smk_set_cipso
	ext4: avoid negative min_clusters in find_group_orlov()
	ext4: return error on ext4_find_inline_entry
	ext4: avoid OOB when system.data xattr changes underneath the filesystem
	nilfs2: fix potential null-ptr-deref in nilfs_btree_insert()
	nilfs2: determine empty node blocks as corrupted
	nilfs2: fix potential oob read in nilfs_btree_check_delete()
	perf sched timehist: Fix missing free of session in perf_sched__timehist()
	perf sched timehist: Fixed timestamp error when unable to confirm event sched_in time
	perf time-utils: Fix 32-bit nsec parsing
	clk: rockchip: Set parent rate for DCLK_VOP clock on RK3228
	drivers: media: dvb-frontends/rtl2832: fix an out-of-bounds write error
	drivers: media: dvb-frontends/rtl2830: fix an out-of-bounds write error
	PCI: xilinx-nwl: Fix register misspelling
	RDMA/iwcm: Fix WARNING:at_kernel/workqueue.c:#check_flush_dependency
	pinctrl: single: fix missing error code in pcs_probe()
	clk: ti: dra7-atl: Fix leak of of_nodes
	pinctrl: mvebu: Fix devinit_dove_pinctrl_probe function
	RDMA/cxgb4: Added NULL check for lookup_atid
	ntb: intel: Fix the NULL vs IS_ERR() bug for debugfs_create_dir()
	nfsd: call cache_put if xdr_reserve_space returns NULL
	f2fs: enhance to update i_mode and acl atomically in f2fs_setattr()
	f2fs: fix typo
	f2fs: fix to update i_ctime in __f2fs_setxattr()
	f2fs: remove unneeded check condition in __f2fs_setxattr()
	f2fs: reduce expensive checkpoint trigger frequency
	coresight: tmc: sg: Do not leak sg_table
	netfilter: nf_reject_ipv6: fix nf_reject_ip6_tcphdr_put()
	net: seeq: Fix use after free vulnerability in ether3 Driver Due to Race Condition
	tcp: introduce tcp_skb_timestamp_us() helper
	tcp: check skb is non-NULL in tcp_rto_delta_us()
	net: qrtr: Update packets cloning when broadcasting
	netfilter: ctnetlink: compile ctnetlink_label_size with CONFIG_NF_CONNTRACK_EVENTS
	crypto: aead,cipher - zeroize key buffer after use
	Remove *.orig pattern from .gitignore
	soc: versatile: integrator: fix OF node leak in probe() error path
	USB: appledisplay: close race between probe and completion handler
	USB: misc: cypress_cy7c63: check for short transfer
	firmware_loader: Block path traversal
	tty: rp2: Fix reset with non forgiving PCIe host bridges
	drbd: Fix atomicity violation in drbd_uuid_set_bm()
	drbd: Add NULL check for net_conf to prevent dereference in state validation
	ACPI: sysfs: validate return type of _STR method
	f2fs: prevent possible int overflow in dir_block_index()
	f2fs: avoid potential int overflow in sanity_check_area_boundary()
	vfs: fix race between evice_inodes() and find_inode()&iput()
	fs: Fix file_set_fowner LSM hook inconsistencies
	nfs: fix memory leak in error path of nfs4_do_reclaim
	PCI: xilinx-nwl: Use irq_data_get_irq_chip_data()
	PCI: xilinx-nwl: Fix off-by-one in INTx IRQ handler
	soc: versatile: realview: fix memory leak during device remove
	soc: versatile: realview: fix soc_dev leak during device remove
	usb: yurex: Replace snprintf() with the safer scnprintf() variant
	USB: misc: yurex: fix race between read and write
	pps: remove usage of the deprecated ida_simple_xx() API
	pps: add an error check in parport_attach
	i2c: aspeed: Update the stop sw state when the bus recovery occurs
	i2c: isch: Add missed 'else'
	usb: yurex: Fix inconsistent locking bug in yurex_read()
	mailbox: rockchip: fix a typo in module autoloading
	mailbox: bcm2835: Fix timeout during suspend mode
	ceph: remove the incorrect Fw reference check when dirtying pages
	netfilter: uapi: NFTA_FLOWTABLE_HOOK is NLA_NESTED
	netfilter: nf_tables: prevent nf_skb_duplicated corruption
	r8152: Factor out OOB link list waits
	net: ethernet: lantiq_etop: fix memory disclosure
	net: avoid potential underflow in qdisc_pkt_len_init() with UFO
	net: add more sanity checks to qdisc_pkt_len_init()
	ipv4: ip_gre: Fix drops of small packets in ipgre_xmit
	sctp: set sk_state back to CLOSED if autobind fails in sctp_listen_start
	ALSA: hda/generic: Unconditionally prefer preferred_dacs pairs
	ALSA: hda/conexant: Fix conflicting quirk for System76 Pangolin
	f2fs: Require FMODE_WRITE for atomic write ioctls
	wifi: ath9k: fix possible integer overflow in ath9k_get_et_stats()
	wifi: ath9k_htc: Use __skb_set_length() for resetting urb before resubmit
	net: hisilicon: hip04: fix OF node leak in probe()
	net: hisilicon: hns_dsaf_mac: fix OF node leak in hns_mac_get_info()
	net: hisilicon: hns_mdio: fix OF node leak in probe()
	ACPICA: Fix memory leak if acpi_ps_get_next_namepath() fails
	ACPICA: Fix memory leak if acpi_ps_get_next_field() fails
	ACPI: EC: Do not release locks during operation region accesses
	ACPICA: check null return of ACPI_ALLOCATE_ZEROED() in acpi_db_convert_to_package()
	tipc: guard against string buffer overrun
	net: mvpp2: Increase size of queue_name buffer
	ipv4: Check !in_dev earlier for ioctl(SIOCSIFADDR).
	ipv4: Mask upper DSCP bits and ECN bits in NETLINK_FIB_LOOKUP family
	tcp: avoid reusing FIN_WAIT2 when trying to find port in connect() process
	ACPICA: iasl: handle empty connection_node
	wifi: mwifiex: Fix memcpy() field-spanning write warning in mwifiex_cmd_802_11_scan_ext()
	signal: Replace BUG_ON()s
	ALSA: asihpi: Fix potential OOB array access
	ALSA: hdsp: Break infinite MIDI input flush loop
	fbdev: pxafb: Fix possible use after free in pxafb_task()
	power: reset: brcmstb: Do not go into infinite loop if reset fails
	ata: sata_sil: Rename sil_blacklist to sil_quirks
	jfs: UBSAN: shift-out-of-bounds in dbFindBits
	jfs: Fix uaf in dbFreeBits
	jfs: check if leafidx greater than num leaves per dmap tree
	jfs: Fix uninit-value access of new_ea in ea_buffer
	drm/amd/display: Check stream before comparing them
	drm/amd/display: Fix index out of bounds in degamma hardware format translation
	drm/printer: Allow NULL data in devcoredump printer
	scsi: aacraid: Rearrange order of struct aac_srb_unit
	drm/radeon/r100: Handle unknown family in r100_cp_init_microcode()
	of/irq: Refer to actual buffer size in of_irq_parse_one()
	ext4: ext4_search_dir should return a proper error
	ext4: fix i_data_sem unlock order in ext4_ind_migrate()
	spi: s3c64xx: fix timeout counters in flush_fifo
	selftests: breakpoints: use remaining time to check if suspend succeed
	selftests: vDSO: fix vDSO symbols lookup for powerpc64
	i2c: xiic: Wait for TX empty to avoid missed TX NAKs
	spi: bcm63xx: Fix module autoloading
	perf/core: Fix small negative period being ignored
	parisc: Fix itlb miss handler for 64-bit programs
	ALSA: core: add isascii() check to card ID generator
	ext4: no need to continue when the number of entries is 1
	ext4: propagate errors from ext4_find_extent() in ext4_insert_range()
	ext4: fix incorrect tid assumption in __jbd2_log_wait_for_space()
	ext4: aovid use-after-free in ext4_ext_insert_extent()
	ext4: fix double brelse() the buffer of the extents path
	ext4: fix incorrect tid assumption in ext4_wait_for_tail_page_commit()
	parisc: Fix 64-bit userspace syscall path
	of/irq: Support #msi-cells=<0> in of_msi_get_domain
	jbd2: stop waiting for space when jbd2_cleanup_journal_tail() returns error
	ocfs2: fix the la space leak when unmounting an ocfs2 volume
	ocfs2: fix uninit-value in ocfs2_get_block()
	ocfs2: reserve space for inline xattr before attaching reflink tree
	ocfs2: cancel dqi_sync_work before freeing oinfo
	ocfs2: remove unreasonable unlock in ocfs2_read_blocks
	ocfs2: fix null-ptr-deref when journal load failed.
	ocfs2: fix possible null-ptr-deref in ocfs2_set_buffer_uptodate
	riscv: define ILLEGAL_POINTER_VALUE for 64bit
	aoe: fix the potential use-after-free problem in more places
	clk: rockchip: fix error for unknown clocks
	media: uapi/linux/cec.h: cec_msg_set_reply_to: zero flags
	media: venus: fix use after free bug in venus_remove due to race condition
	iio: magnetometer: ak8975: Fix reading for ak099xx sensors
	tomoyo: fallback to realpath if symlink's pathname does not exist
	Input: adp5589-keys - fix adp5589_gpio_get_value()
	btrfs: wait for fixup workers before stopping cleaner kthread during umount
	gpio: davinci: fix lazy disable
	ext4: avoid ext4_error()'s caused by ENOMEM in the truncate path
	ext4: fix slab-use-after-free in ext4_split_extent_at()
	ext4: update orig_path in ext4_find_extent()
	arm64: Add Cortex-715 CPU part definition
	arm64: cputype: Add Neoverse-N3 definitions
	arm64: errata: Expand speculative SSBS workaround once more
	uprobes: fix kernel info leak via "[uprobes]" vma
	nfsd: use ktime_get_seconds() for timestamps
	nfsd: fix delegation_blocked() to block correctly for at least 30 seconds
	rtc: at91sam9: drop platform_data support
	rtc: at91sam9: fix OF node leak in probe() error path
	ACPI: battery: Simplify battery hook locking
	ACPI: battery: Fix possible crash when unregistering a battery hook
	ext4: fix inode tree inconsistency caused by ENOMEM
	net: ethernet: cortina: Drop TSO support
	tracing: Remove precision vsnprintf() check from print event
	drm: Move drm_mode_setcrtc() local re-init to failure path
	drm/crtc: fix uninitialized variable use even harder
	virtio_console: fix misc probe bugs
	Input: synaptics-rmi4 - fix UAF of IRQ domain on driver removal
	bpf: Check percpu map value size first
	s390/facility: Disable compile time optimization for decompressor code
	s390/mm: Add cond_resched() to cmm_alloc/free_pages()
	ext4: nested locking for xattr inode
	s390/cpum_sf: Remove WARN_ON_ONCE statements
	ktest.pl: Avoid false positives with grub2 skip regex
	clk: bcm: bcm53573: fix OF node leak in init
	i2c: i801: Use a different adapter-name for IDF adapters
	PCI: Mark Creative Labs EMU20k2 INTx masking as broken
	media: videobuf2-core: clear memory related fields in __vb2_plane_dmabuf_put()
	usb: chipidea: udc: enable suspend interrupt after usb reset
	tools/iio: Add memory allocation failure check for trigger_name
	driver core: bus: Return -EIO instead of 0 when show/store invalid bus attribute
	fbdev: sisfb: Fix strbuf array overflow
	NFS: Remove print_overflow_msg()
	SUNRPC: Fix integer overflow in decode_rc_list()
	tcp: fix tcp_enter_recovery() to zero retrans_stamp when it's safe
	netfilter: br_netfilter: fix panic with metadata_dst skb
	Bluetooth: RFCOMM: FIX possible deadlock in rfcomm_sk_state_change
	gpio: aspeed: Add the flush write to ensure the write complete.
	clk: Add (devm_)clk_get_optional() functions
	clk: generalize devm_clk_get() a bit
	clk: Provide new devm_clk helpers for prepared and enabled clocks
	gpio: aspeed: Use devm_clk api to manage clock source
	igb: Do not bring the device up after non-fatal error
	net: ibm: emac: mal: fix wrong goto
	ppp: fix ppp_async_encode() illegal access
	net: ipv6: ensure we call ipv6_mc_down() at most once
	CDC-NCM: avoid overflow in sanity checking
	HID: plantronics: Workaround for an unexcepted opposite volume key
	Revert "usb: yurex: Replace snprintf() with the safer scnprintf() variant"
	usb: xhci: Fix problem with xhci resume from suspend
	usb: storage: ignore bogus device raised by JieLi BR21 USB sound chip
	net: Fix an unsafe loop on the list
	posix-clock: Fix missing timespec64 check in pc_clock_settime()
	arm64: probes: Remove broken LDR (literal) uprobe support
	arm64: probes: Fix simulate_ldr*_literal()
	PCI: Add function 0 DMA alias quirk for Glenfly Arise chip
	fat: fix uninitialized variable
	KVM: Fix a data race on last_boosted_vcpu in kvm_vcpu_on_spin()
	net: dsa: mv88e6xxx: Fix out-of-bound access
	s390/sclp_vt220: Convert newlines to CRLF instead of LFCR
	KVM: s390: Change virtual to physical address access in diag 0x258 handler
	x86/cpufeatures: Define X86_FEATURE_AMD_IBPB_RET
	drm/vmwgfx: Handle surface check failure correctly
	iio: dac: stm32-dac-core: add missing select REGMAP_MMIO in Kconfig
	iio: adc: ti-ads8688: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig
	iio: hid-sensors: Fix an error handling path in _hid_sensor_set_report_latency()
	iio: light: opt3001: add missing full-scale range value
	Bluetooth: Remove debugfs directory on module init failure
	Bluetooth: btusb: Fix regression with fake CSR controllers 0a12:0001
	xhci: Fix incorrect stream context type macro
	USB: serial: option: add support for Quectel EG916Q-GL
	USB: serial: option: add Telit FN920C04 MBIM compositions
	parport: Proper fix for array out-of-bounds access
	x86/apic: Always explicitly disarm TSC-deadline timer
	nilfs2: propagate directory read errors from nilfs_find_entry()
	clk: Fix pointer casting to prevent oops in devm_clk_release()
	clk: Fix slab-out-of-bounds error in devm_clk_release()
	RDMA/bnxt_re: Fix incorrect AVID type in WQE structure
	RDMA/cxgb4: Fix RDMA_CM_EVENT_UNREACHABLE error for iWARP
	RDMA/bnxt_re: Return more meaningful error
	drm/msm/dsi: fix 32-bit signed integer extension in pclk_rate calculation
	macsec: don't increment counters for an unrelated SA
	net: ethernet: aeroflex: fix potential memory leak in greth_start_xmit_gbit()
	net: systemport: fix potential memory leak in bcm_sysport_xmit()
	usb: typec: altmode should keep reference to parent
	Bluetooth: bnep: fix wild-memory-access in proto_unregister
	arm64:uprobe fix the uprobe SWBP_INSN in big-endian
	arm64: probes: Fix uprobes for big-endian kernels
	KVM: s390: gaccess: Refactor gpa and length calculation
	KVM: s390: gaccess: Refactor access address range check
	KVM: s390: gaccess: Cleanup access to guest pages
	KVM: s390: gaccess: Check if guest address is in memslot
	udf: fix uninit-value use in udf_get_fileshortad
	jfs: Fix sanity check in dbMount
	net/sun3_82586: fix potential memory leak in sun3_82586_send_packet()
	be2net: fix potential memory leak in be_xmit()
	net: usb: usbnet: fix name regression
	posix-clock: posix-clock: Fix unbalanced locking in pc_clock_settime()
	ALSA: hda/realtek: Update default depop procedure
	drm/amd: Guard against bad data for ATIF ACPI method
	ACPI: button: Add DMI quirk for Samsung Galaxy Book2 to fix initial lid detection issue
	nilfs2: fix kernel bug due to missing clearing of buffer delay flag
	hv_netvsc: Fix VF namespace also in synthetic NIC NETDEV_REGISTER event
	selinux: improve error checking in sel_write_load()
	arm64/uprobes: change the uprobe_opcode_t typedef to fix the sparse warning
	xfrm: validate new SA's prefixlen using SA family when sel.family is unset
	usb: dwc3: remove generic PHY calibrate() calls
	usb: dwc3: Add splitdisable quirk for Hisilicon Kirin Soc
	usb: dwc3: core: Stop processing of pending events if controller is halted
	cgroup: Fix potential overflow issue when checking max_depth
	wifi: mac80211: skip non-uploaded keys in ieee80211_iter_keys
	gtp: simplify error handling code in 'gtp_encap_enable()'
	gtp: allow -1 to be specified as file description from userspace
	net/sched: stop qdisc_tree_reduce_backlog on TC_H_ROOT
	bpf: Fix out-of-bounds write in trie_get_next_key()
	net: support ip generic csum processing in skb_csum_hwoffload_help
	net: skip offload for NETIF_F_IPV6_CSUM if ipv6 header contains extension
	netfilter: nft_payload: sanitize offset and length before calling skb_checksum()
	firmware: arm_sdei: Fix the input parameter of cpuhp_remove_state()
	net: amd: mvme147: Fix probe banner message
	misc: sgi-gru: Don't disable preemption in GRU driver
	usbip: tools: Fix detach_port() invalid port error path
	usb: phy: Fix API devm_usb_put_phy() can not release the phy
	xhci: Fix Link TRB DMA in command ring stopped completion event
	Revert "driver core: Fix uevent_show() vs driver detach race"
	wifi: mac80211: do not pass a stopped vif to the driver in .get_txpower
	wifi: ath10k: Fix memory leak in management tx
	wifi: iwlegacy: Clear stale interrupts before resuming device
	nilfs2: fix potential deadlock with newly created symlinks
	ocfs2: pass u64 to ocfs2_truncate_inline maybe overflow
	nilfs2: fix kernel bug due to missing clearing of checked flag
	mm: shmem: fix data-race in shmem_getattr()
	vt: prevent kernel-infoleak in con_font_get()
	Linux 4.19.323

Change-Id: I2348f834187153067ab46b3b48b8fe7da9cee1f1
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman
2024-11-09 11:24:17 +00:00
325 changed files with 2619 additions and 1787 deletions

1
.gitignore vendored
View File

@@ -114,7 +114,6 @@ GTAGS
# id-utils files # id-utils files
ID ID
*.orig
*~ *~
\#*# \#*#

View File

@@ -518,7 +518,7 @@ at module load time (for a module) with::
[dbg_probe=1] [dbg_probe=1]
The addresses are normal I2C addresses. The adapter is the string The addresses are normal I2C addresses. The adapter is the string
name of the adapter, as shown in /sys/class/i2c-adapter/i2c-<n>/name. name of the adapter, as shown in /sys/bus/i2c/devices/i2c-<n>/name.
It is *NOT* i2c-<n> itself. Also, the comparison is done ignoring It is *NOT* i2c-<n> itself. Also, the comparison is done ignoring
spaces, so if the name is "This is an I2C chip" you can say spaces, so if the name is "This is an I2C chip" you can say
adapter_name=ThisisanI2cchip. This is because it's hard to pass in adapter_name=ThisisanI2cchip. This is because it's hard to pass in

View File

@@ -66,6 +66,7 @@ stable kernels.
| ARM | Cortex-A78 | #3324344 | ARM64_ERRATUM_3194386 | | ARM | Cortex-A78 | #3324344 | ARM64_ERRATUM_3194386 |
| ARM | Cortex-A78C | #3324346,3324347| ARM64_ERRATUM_3194386 | | ARM | Cortex-A78C | #3324346,3324347| ARM64_ERRATUM_3194386 |
| ARM | Cortex-A710 | #3324338 | ARM64_ERRATUM_3194386 | | ARM | Cortex-A710 | #3324338 | ARM64_ERRATUM_3194386 |
| ARM | Cortex-A715 | #3456084 | ARM64_ERRATUM_3194386 |
| ARM | Cortex-A720 | #3456091 | ARM64_ERRATUM_3194386 | | ARM | Cortex-A720 | #3456091 | ARM64_ERRATUM_3194386 |
| ARM | Cortex-A725 | #3456106 | ARM64_ERRATUM_3194386 | | ARM | Cortex-A725 | #3456106 | ARM64_ERRATUM_3194386 |
| ARM | Cortex-X1 | #3324344 | ARM64_ERRATUM_3194386 | | ARM | Cortex-X1 | #3324344 | ARM64_ERRATUM_3194386 |
@@ -77,6 +78,7 @@ stable kernels.
| ARM | Neoverse-N1 | #1542419 | ARM64_ERRATUM_1542419 | | ARM | Neoverse-N1 | #1542419 | ARM64_ERRATUM_1542419 |
| ARM | Neoverse-N1 | #3324349 | ARM64_ERRATUM_3194386 | | ARM | Neoverse-N1 | #3324349 | ARM64_ERRATUM_3194386 |
| ARM | Neoverse-N2 | #3324339 | ARM64_ERRATUM_3194386 | | ARM | Neoverse-N2 | #3324339 | ARM64_ERRATUM_3194386 |
| ARM | Neoverse-N3 | #3456111 | ARM64_ERRATUM_3194386 |
| ARM | Neoverse-V1 | #3324341 | ARM64_ERRATUM_3194386 | | ARM | Neoverse-V1 | #3324341 | ARM64_ERRATUM_3194386 |
| ARM | Neoverse-V2 | #3324336 | ARM64_ERRATUM_3194386 | | ARM | Neoverse-V2 | #3324336 | ARM64_ERRATUM_3194386 |
| ARM | Neoverse-V3 | #3312417 | ARM64_ERRATUM_3194386 | | ARM | Neoverse-V3 | #3312417 | ARM64_ERRATUM_3194386 |

View File

@@ -235,6 +235,7 @@ certainly invest a bit more effort into libata core layer).
CLOCK CLOCK
devm_clk_get() devm_clk_get()
devm_clk_get_optional()
devm_clk_put() devm_clk_put()
devm_clk_hw_register() devm_clk_hw_register()
devm_of_clk_add_hw_provider() devm_of_clk_add_hw_provider()

View File

@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
VERSION = 4 VERSION = 4
PATCHLEVEL = 19 PATCHLEVEL = 19
SUBLEVEL = 322 SUBLEVEL = 323
EXTRAVERSION = EXTRAVERSION =
NAME = "People's Front" NAME = "People's Front"

View File

@@ -70,6 +70,7 @@ static void __init realview_smp_prepare_cpus(unsigned int max_cpus)
return; return;
} }
map = syscon_node_to_regmap(np); map = syscon_node_to_regmap(np);
of_node_put(np);
if (IS_ERR(map)) { if (IS_ERR(map)) {
pr_err("PLATSMP: No syscon regmap\n"); pr_err("PLATSMP: No syscon regmap\n");
return; return;

View File

@@ -551,6 +551,7 @@ config ARM64_ERRATUM_3194386
* ARM Cortex-A78C erratum 3324346 * ARM Cortex-A78C erratum 3324346
* ARM Cortex-A78C erratum 3324347 * ARM Cortex-A78C erratum 3324347
* ARM Cortex-A710 erratam 3324338 * ARM Cortex-A710 erratam 3324338
* ARM Cortex-A715 errartum 3456084
* ARM Cortex-A720 erratum 3456091 * ARM Cortex-A720 erratum 3456091
* ARM Cortex-A725 erratum 3456106 * ARM Cortex-A725 erratum 3456106
* ARM Cortex-X1 erratum 3324344 * ARM Cortex-X1 erratum 3324344
@@ -561,6 +562,7 @@ config ARM64_ERRATUM_3194386
* ARM Cortex-X925 erratum 3324334 * ARM Cortex-X925 erratum 3324334
* ARM Neoverse-N1 erratum 3324349 * ARM Neoverse-N1 erratum 3324349
* ARM Neoverse N2 erratum 3324339 * ARM Neoverse N2 erratum 3324339
* ARM Neoverse-N3 erratum 3456111
* ARM Neoverse-V1 erratum 3324341 * ARM Neoverse-V1 erratum 3324341
* ARM Neoverse V2 erratum 3324336 * ARM Neoverse V2 erratum 3324336
* ARM Neoverse-V3 erratum 3312417 * ARM Neoverse-V3 erratum 3312417

View File

@@ -147,6 +147,22 @@
status = "okay"; status = "okay";
}; };
&gpio3 {
/*
* The Qseven BIOS_DISABLE signal on the RK3399-Q7 keeps the on-module
* eMMC and SPI flash powered-down initially (in fact it keeps the
* reset signal asserted). BIOS_DISABLE_OVERRIDE pin allows to override
* that signal so that eMMC and SPI can be used regardless of the state
* of the signal.
*/
bios-disable-override-hog {
gpios = <RK_PD5 GPIO_ACTIVE_LOW>;
gpio-hog;
line-name = "bios_disable_override";
output-high;
};
};
&gmac { &gmac {
assigned-clocks = <&cru SCLK_RMII_SRC>; assigned-clocks = <&cru SCLK_RMII_SRC>;
assigned-clock-parents = <&clkin_gmac>; assigned-clock-parents = <&clkin_gmac>;
@@ -433,9 +449,14 @@
&pinctrl { &pinctrl {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&q7_thermal_pin>; pinctrl-0 = <&q7_thermal_pin &bios_disable_override_hog_pin>;
gpios { gpios {
bios_disable_override_hog_pin: bios-disable-override-hog-pin {
rockchip,pins =
<3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_down>;
};
q7_thermal_pin: q7-thermal-pin { q7_thermal_pin: q7-thermal-pin {
rockchip,pins = rockchip,pins =
<0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;

View File

@@ -86,6 +86,7 @@
#define ARM_CPU_PART_CORTEX_A78 0xD41 #define ARM_CPU_PART_CORTEX_A78 0xD41
#define ARM_CPU_PART_CORTEX_X1 0xD44 #define ARM_CPU_PART_CORTEX_X1 0xD44
#define ARM_CPU_PART_CORTEX_A710 0xD47 #define ARM_CPU_PART_CORTEX_A710 0xD47
#define ARM_CPU_PART_CORTEX_A715 0xD4D
#define ARM_CPU_PART_CORTEX_X2 0xD48 #define ARM_CPU_PART_CORTEX_X2 0xD48
#define ARM_CPU_PART_NEOVERSE_N2 0xD49 #define ARM_CPU_PART_NEOVERSE_N2 0xD49
#define ARM_CPU_PART_CORTEX_A78C 0xD4B #define ARM_CPU_PART_CORTEX_A78C 0xD4B
@@ -97,6 +98,7 @@
#define ARM_CPU_PART_NEOVERSE_V3 0xD84 #define ARM_CPU_PART_NEOVERSE_V3 0xD84
#define ARM_CPU_PART_CORTEX_X925 0xD85 #define ARM_CPU_PART_CORTEX_X925 0xD85
#define ARM_CPU_PART_CORTEX_A725 0xD87 #define ARM_CPU_PART_CORTEX_A725 0xD87
#define ARM_CPU_PART_NEOVERSE_N3 0xD8E
#define APM_CPU_PART_POTENZA 0x000 #define APM_CPU_PART_POTENZA 0x000
@@ -130,6 +132,7 @@
#define MIDR_CORTEX_A78 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78) #define MIDR_CORTEX_A78 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78)
#define MIDR_CORTEX_X1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1) #define MIDR_CORTEX_X1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1)
#define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710) #define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710)
#define MIDR_CORTEX_A715 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A715)
#define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2) #define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2)
#define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2) #define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)
#define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C) #define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C)
@@ -141,6 +144,7 @@
#define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3) #define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3)
#define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925) #define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925)
#define MIDR_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725) #define MIDR_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725)
#define MIDR_NEOVERSE_N3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N3)
#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) #define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX) #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
#define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX) #define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)

View File

@@ -13,21 +13,19 @@
#include <asm/insn.h> #include <asm/insn.h>
#include <asm/probes.h> #include <asm/probes.h>
#define MAX_UINSN_BYTES AARCH64_INSN_SIZE #define UPROBE_SWBP_INSN cpu_to_le32(BRK64_OPCODE_UPROBES)
#define UPROBE_SWBP_INSN BRK64_OPCODE_UPROBES
#define UPROBE_SWBP_INSN_SIZE AARCH64_INSN_SIZE #define UPROBE_SWBP_INSN_SIZE AARCH64_INSN_SIZE
#define UPROBE_XOL_SLOT_BYTES MAX_UINSN_BYTES #define UPROBE_XOL_SLOT_BYTES AARCH64_INSN_SIZE
typedef u32 uprobe_opcode_t; typedef __le32 uprobe_opcode_t;
struct arch_uprobe_task { struct arch_uprobe_task {
}; };
struct arch_uprobe { struct arch_uprobe {
union { union {
u8 insn[MAX_UINSN_BYTES]; __le32 insn;
u8 ixol[MAX_UINSN_BYTES]; __le32 ixol;
}; };
struct arch_probe_insn api; struct arch_probe_insn api;
bool simulate; bool simulate;

View File

@@ -714,6 +714,7 @@ static const struct midr_range erratum_spec_ssbs_list[] = {
MIDR_ALL_VERSIONS(MIDR_CORTEX_A78), MIDR_ALL_VERSIONS(MIDR_CORTEX_A78),
MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C), MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
MIDR_ALL_VERSIONS(MIDR_CORTEX_A710), MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
MIDR_ALL_VERSIONS(MIDR_CORTEX_A715),
MIDR_ALL_VERSIONS(MIDR_CORTEX_A720), MIDR_ALL_VERSIONS(MIDR_CORTEX_A720),
MIDR_ALL_VERSIONS(MIDR_CORTEX_A725), MIDR_ALL_VERSIONS(MIDR_CORTEX_A725),
MIDR_ALL_VERSIONS(MIDR_CORTEX_X1), MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
@@ -724,6 +725,7 @@ static const struct midr_range erratum_spec_ssbs_list[] = {
MIDR_ALL_VERSIONS(MIDR_CORTEX_X925), MIDR_ALL_VERSIONS(MIDR_CORTEX_X925),
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1), MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2), MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N3),
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1), MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2), MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2),
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3), MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3),

View File

@@ -104,10 +104,6 @@ arm_probe_decode_insn(probe_opcode_t insn, struct arch_probe_insn *api)
aarch64_insn_is_blr(insn) || aarch64_insn_is_blr(insn) ||
aarch64_insn_is_ret(insn)) { aarch64_insn_is_ret(insn)) {
api->handler = simulate_br_blr_ret; api->handler = simulate_br_blr_ret;
} else if (aarch64_insn_is_ldr_lit(insn)) {
api->handler = simulate_ldr_literal;
} else if (aarch64_insn_is_ldrsw_lit(insn)) {
api->handler = simulate_ldrsw_literal;
} else { } else {
/* /*
* Instruction cannot be stepped out-of-line and we don't * Instruction cannot be stepped out-of-line and we don't
@@ -145,6 +141,17 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct arch_specific_insn *asi)
probe_opcode_t insn = le32_to_cpu(*addr); probe_opcode_t insn = le32_to_cpu(*addr);
probe_opcode_t *scan_end = NULL; probe_opcode_t *scan_end = NULL;
unsigned long size = 0, offset = 0; unsigned long size = 0, offset = 0;
struct arch_probe_insn *api = &asi->api;
if (aarch64_insn_is_ldr_lit(insn)) {
api->handler = simulate_ldr_literal;
decoded = INSN_GOOD_NO_SLOT;
} else if (aarch64_insn_is_ldrsw_lit(insn)) {
api->handler = simulate_ldrsw_literal;
decoded = INSN_GOOD_NO_SLOT;
} else {
decoded = arm_probe_decode_insn(insn, &asi->api);
}
/* /*
* If there's a symbol defined in front of and near enough to * If there's a symbol defined in front of and near enough to
@@ -162,7 +169,6 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct arch_specific_insn *asi)
else else
scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE; scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
} }
decoded = arm_probe_decode_insn(insn, &asi->api);
if (decoded != INSN_REJECTED && scan_end) if (decoded != INSN_REJECTED && scan_end)
if (is_probed_address_atomic(addr - 1, scan_end)) if (is_probed_address_atomic(addr - 1, scan_end))

View File

@@ -178,17 +178,15 @@ simulate_tbz_tbnz(u32 opcode, long addr, struct pt_regs *regs)
void __kprobes void __kprobes
simulate_ldr_literal(u32 opcode, long addr, struct pt_regs *regs) simulate_ldr_literal(u32 opcode, long addr, struct pt_regs *regs)
{ {
u64 *load_addr; unsigned long load_addr;
int xn = opcode & 0x1f; int xn = opcode & 0x1f;
int disp;
disp = ldr_displacement(opcode); load_addr = addr + ldr_displacement(opcode);
load_addr = (u64 *) (addr + disp);
if (opcode & (1 << 30)) /* x0-x30 */ if (opcode & (1 << 30)) /* x0-x30 */
set_x_reg(regs, xn, *load_addr); set_x_reg(regs, xn, READ_ONCE(*(u64 *)load_addr));
else /* w0-w30 */ else /* w0-w30 */
set_w_reg(regs, xn, *load_addr); set_w_reg(regs, xn, READ_ONCE(*(u32 *)load_addr));
instruction_pointer_set(regs, instruction_pointer(regs) + 4); instruction_pointer_set(regs, instruction_pointer(regs) + 4);
} }
@@ -196,14 +194,12 @@ simulate_ldr_literal(u32 opcode, long addr, struct pt_regs *regs)
void __kprobes void __kprobes
simulate_ldrsw_literal(u32 opcode, long addr, struct pt_regs *regs) simulate_ldrsw_literal(u32 opcode, long addr, struct pt_regs *regs)
{ {
s32 *load_addr; unsigned long load_addr;
int xn = opcode & 0x1f; int xn = opcode & 0x1f;
int disp;
disp = ldr_displacement(opcode); load_addr = addr + ldr_displacement(opcode);
load_addr = (s32 *) (addr + disp);
set_x_reg(regs, xn, *load_addr); set_x_reg(regs, xn, READ_ONCE(*(s32 *)load_addr));
instruction_pointer_set(regs, instruction_pointer(regs) + 4); instruction_pointer_set(regs, instruction_pointer(regs) + 4);
} }

View File

@@ -45,7 +45,7 @@ int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm,
else if (!IS_ALIGNED(addr, AARCH64_INSN_SIZE)) else if (!IS_ALIGNED(addr, AARCH64_INSN_SIZE))
return -EINVAL; return -EINVAL;
insn = *(probe_opcode_t *)(&auprobe->insn[0]); insn = le32_to_cpu(auprobe->insn);
switch (arm_probe_decode_insn(insn, &auprobe->api)) { switch (arm_probe_decode_insn(insn, &auprobe->api)) {
case INSN_REJECTED: case INSN_REJECTED:
@@ -111,7 +111,7 @@ bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
if (!auprobe->simulate) if (!auprobe->simulate)
return false; return false;
insn = *(probe_opcode_t *)(&auprobe->insn[0]); insn = le32_to_cpu(auprobe->insn);
addr = instruction_pointer(regs); addr = instruction_pointer(regs);
if (auprobe->api.handler) if (auprobe->api.handler)

View File

@@ -289,11 +289,6 @@ asmlinkage void __init mmu_init(void)
{ {
unsigned int kstart, ksize; unsigned int kstart, ksize;
if (!memblock.reserved.cnt) {
pr_emerg("Error memory count\n");
machine_restart(NULL);
}
if ((u32) memblock.memory.regions[0].size < 0x400000) { if ((u32) memblock.memory.regions[0].size < 0x400000) {
pr_emerg("Memory must be greater than 4MB\n"); pr_emerg("Memory must be greater than 4MB\n");
machine_restart(NULL); machine_restart(NULL);

View File

@@ -1089,8 +1089,7 @@ ENTRY_CFI(intr_save) /* for os_hpmc */
STREG %r16, PT_ISR(%r29) STREG %r16, PT_ISR(%r29)
STREG %r17, PT_IOR(%r29) STREG %r17, PT_IOR(%r29)
#if 0 && defined(CONFIG_64BIT) #if defined(CONFIG_64BIT)
/* Revisit when we have 64-bit code above 4Gb */
b,n intr_save2 b,n intr_save2
skip_save_ior: skip_save_ior:
@@ -1098,8 +1097,7 @@ skip_save_ior:
* need to adjust iasq/iaoq here in the same way we adjusted isr/ior * need to adjust iasq/iaoq here in the same way we adjusted isr/ior
* above. * above.
*/ */
extrd,u,* %r8,PSW_W_BIT,1,%r1 bb,COND(>=),n %r8,PSW_W_BIT,intr_save2
cmpib,COND(=),n 1,%r1,intr_save2
LDREG PT_IASQ0(%r29), %r16 LDREG PT_IASQ0(%r29), %r16
LDREG PT_IAOQ0(%r29), %r17 LDREG PT_IAOQ0(%r29), %r17
/* adjust iasq/iaoq */ /* adjust iasq/iaoq */

View File

@@ -217,10 +217,10 @@ linux_gateway_entry:
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
ldil L%sys_call_table, %r1 ldil L%sys_call_table, %r1
or,= %r2,%r2,%r2 or,ev %r2,%r2,%r2
addil L%(sys_call_table64-sys_call_table), %r1 ldil L%sys_call_table64, %r1
ldo R%sys_call_table(%r1), %r19 ldo R%sys_call_table(%r1), %r19
or,= %r2,%r2,%r2 or,ev %r2,%r2,%r2
ldo R%sys_call_table64(%r1), %r19 ldo R%sys_call_table64(%r1), %r19
#else #else
load32 sys_call_table, %r19 load32 sys_call_table, %r19
@@ -355,10 +355,10 @@ tracesys_next:
extrd,u %r19,63,1,%r2 /* W hidden in bottom bit */ extrd,u %r19,63,1,%r2 /* W hidden in bottom bit */
ldil L%sys_call_table, %r1 ldil L%sys_call_table, %r1
or,= %r2,%r2,%r2 or,ev %r2,%r2,%r2
addil L%(sys_call_table64-sys_call_table), %r1 ldil L%sys_call_table64, %r1
ldo R%sys_call_table(%r1), %r19 ldo R%sys_call_table(%r1), %r19
or,= %r2,%r2,%r2 or,ev %r2,%r2,%r2
ldo R%sys_call_table64(%r1), %r19 ldo R%sys_call_table64(%r1), %r19
#else #else
load32 sys_call_table, %r19 load32 sys_call_table, %r19
@@ -930,6 +930,8 @@ ENTRY(sys_call_table)
END(sys_call_table) END(sys_call_table)
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
#undef __SYSCALL_WITH_COMPAT
#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native)
.align 8 .align 8
ENTRY(sys_call_table64) ENTRY(sys_call_table64)
#define SYSCALL_TABLE_64BIT #define SYSCALL_TABLE_64BIT

View File

@@ -84,6 +84,11 @@ config GENERIC_CSUM
config GENERIC_HWEIGHT config GENERIC_HWEIGHT
def_bool y def_bool y
config ILLEGAL_POINTER_VALUE
hex
default 0 if 32BIT
default 0xdead000000000000 if 64BIT
config PGTABLE_LEVELS config PGTABLE_LEVELS
int int
default 3 if 64BIT default 3 if 64BIT

View File

@@ -53,8 +53,10 @@ static inline int test_facility(unsigned long nr)
unsigned long facilities_als[] = { FACILITIES_ALS }; unsigned long facilities_als[] = { FACILITIES_ALS };
if (__builtin_constant_p(nr) && nr < sizeof(facilities_als) * 8) { if (__builtin_constant_p(nr) && nr < sizeof(facilities_als) * 8) {
if (__test_facility(nr, &facilities_als)) if (__test_facility(nr, &facilities_als)) {
return 1; if (!__is_defined(__DECOMPRESSOR))
return 1;
}
} }
return __test_facility(nr, &S390_lowcore.stfle_fac_list); return __test_facility(nr, &S390_lowcore.stfle_fac_list);
} }

View File

@@ -1360,7 +1360,7 @@ static int aux_output_begin(struct perf_output_handle *handle,
unsigned long head, base, offset; unsigned long head, base, offset;
struct hws_trailer_entry *te; struct hws_trailer_entry *te;
if (WARN_ON_ONCE(handle->head & ~PAGE_MASK)) if (handle->head & ~PAGE_MASK)
return -EINVAL; return -EINVAL;
aux->head = handle->head >> PAGE_SHIFT; aux->head = handle->head >> PAGE_SHIFT;
@@ -1528,7 +1528,7 @@ static void hw_collect_aux(struct cpu_hw_sf *cpuhw)
unsigned long num_sdb; unsigned long num_sdb;
aux = perf_get_aux(handle); aux = perf_get_aux(handle);
if (WARN_ON_ONCE(!aux)) if (!aux)
return; return;
/* Inform user space new data arrived */ /* Inform user space new data arrived */
@@ -1547,7 +1547,7 @@ static void hw_collect_aux(struct cpu_hw_sf *cpuhw)
debug_sprintf_event(sfdbg, 1, "AUX buffer used up\n"); debug_sprintf_event(sfdbg, 1, "AUX buffer used up\n");
break; break;
} }
if (WARN_ON_ONCE(!aux)) if (!aux)
return; return;
/* Update head and alert_mark to new position */ /* Update head and alert_mark to new position */
@@ -1746,12 +1746,8 @@ static void cpumsf_pmu_start(struct perf_event *event, int flags)
{ {
struct cpu_hw_sf *cpuhw = this_cpu_ptr(&cpu_hw_sf); struct cpu_hw_sf *cpuhw = this_cpu_ptr(&cpu_hw_sf);
if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED))) if (!(event->hw.state & PERF_HES_STOPPED))
return; return;
if (flags & PERF_EF_RELOAD)
WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE));
perf_pmu_disable(event->pmu); perf_pmu_disable(event->pmu);
event->hw.state = 0; event->hw.state = 0;
cpuhw->lsctl.cs = 1; cpuhw->lsctl.cs = 1;

View File

@@ -78,7 +78,7 @@ static int __diag_page_ref_service(struct kvm_vcpu *vcpu)
vcpu->stat.diagnose_258++; vcpu->stat.diagnose_258++;
if (vcpu->run->s.regs.gprs[rx] & 7) if (vcpu->run->s.regs.gprs[rx] & 7)
return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
rc = read_guest(vcpu, vcpu->run->s.regs.gprs[rx], rx, &parm, sizeof(parm)); rc = read_guest_real(vcpu, vcpu->run->s.regs.gprs[rx], &parm, sizeof(parm));
if (rc) if (rc)
return kvm_s390_inject_prog_cond(vcpu, rc); return kvm_s390_inject_prog_cond(vcpu, rc);
if (parm.parm_version != 2 || parm.parm_len < 5 || parm.code != 0x258) if (parm.parm_version != 2 || parm.parm_len < 5 || parm.code != 0x258)

View File

@@ -794,46 +794,102 @@ static int low_address_protection_enabled(struct kvm_vcpu *vcpu,
return 1; return 1;
} }
static int guest_page_range(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, /**
unsigned long *pages, unsigned long nr_pages, * guest_range_to_gpas() - Calculate guest physical addresses of page fragments
const union asce asce, enum gacc_mode mode) * covering a logical range
* @vcpu: virtual cpu
* @ga: guest address, start of range
* @ar: access register
* @gpas: output argument, may be NULL
* @len: length of range in bytes
* @asce: address-space-control element to use for translation
* @mode: access mode
*
* Translate a logical range to a series of guest absolute addresses,
* such that the concatenation of page fragments starting at each gpa make up
* the whole range.
* The translation is performed as if done by the cpu for the given @asce, @ar,
* @mode and state of the @vcpu.
* If the translation causes an exception, its program interruption code is
* returned and the &struct kvm_s390_pgm_info pgm member of @vcpu is modified
* such that a subsequent call to kvm_s390_inject_prog_vcpu() will inject
* a correct exception into the guest.
* The resulting gpas are stored into @gpas, unless it is NULL.
*
* Note: All fragments except the first one start at the beginning of a page.
* When deriving the boundaries of a fragment from a gpa, all but the last
* fragment end at the end of the page.
*
* Return:
* * 0 - success
* * <0 - translation could not be performed, for example if guest
* memory could not be accessed
* * >0 - an access exception occurred. In this case the returned value
* is the program interruption code and the contents of pgm may
* be used to inject an exception into the guest.
*/
static int guest_range_to_gpas(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar,
unsigned long *gpas, unsigned long len,
const union asce asce, enum gacc_mode mode)
{ {
psw_t *psw = &vcpu->arch.sie_block->gpsw; psw_t *psw = &vcpu->arch.sie_block->gpsw;
unsigned int offset = offset_in_page(ga);
unsigned int fragment_len;
int lap_enabled, rc = 0; int lap_enabled, rc = 0;
enum prot_type prot; enum prot_type prot;
unsigned long gpa;
lap_enabled = low_address_protection_enabled(vcpu, asce); lap_enabled = low_address_protection_enabled(vcpu, asce);
while (nr_pages) { while (min(PAGE_SIZE - offset, len) > 0) {
fragment_len = min(PAGE_SIZE - offset, len);
ga = kvm_s390_logical_to_effective(vcpu, ga); ga = kvm_s390_logical_to_effective(vcpu, ga);
if (mode == GACC_STORE && lap_enabled && is_low_address(ga)) if (mode == GACC_STORE && lap_enabled && is_low_address(ga))
return trans_exc(vcpu, PGM_PROTECTION, ga, ar, mode, return trans_exc(vcpu, PGM_PROTECTION, ga, ar, mode,
PROT_TYPE_LA); PROT_TYPE_LA);
ga &= PAGE_MASK;
if (psw_bits(*psw).dat) { if (psw_bits(*psw).dat) {
rc = guest_translate(vcpu, ga, pages, asce, mode, &prot); rc = guest_translate(vcpu, ga, &gpa, asce, mode, &prot);
if (rc < 0) if (rc < 0)
return rc; return rc;
} else { } else {
*pages = kvm_s390_real_to_abs(vcpu, ga); gpa = kvm_s390_real_to_abs(vcpu, ga);
if (kvm_is_error_gpa(vcpu->kvm, *pages)) if (kvm_is_error_gpa(vcpu->kvm, gpa))
rc = PGM_ADDRESSING; rc = PGM_ADDRESSING;
} }
if (rc) if (rc)
return trans_exc(vcpu, rc, ga, ar, mode, prot); return trans_exc(vcpu, rc, ga, ar, mode, prot);
ga += PAGE_SIZE; if (gpas)
pages++; *gpas++ = gpa;
nr_pages--; offset = 0;
ga += fragment_len;
len -= fragment_len;
} }
return 0; return 0;
} }
static int access_guest_page(struct kvm *kvm, enum gacc_mode mode, gpa_t gpa,
void *data, unsigned int len)
{
const unsigned int offset = offset_in_page(gpa);
const gfn_t gfn = gpa_to_gfn(gpa);
int rc;
if (!gfn_to_memslot(kvm, gfn))
return PGM_ADDRESSING;
if (mode == GACC_STORE)
rc = kvm_write_guest_page(kvm, gfn, data, offset, len);
else
rc = kvm_read_guest_page(kvm, gfn, data, offset, len);
return rc;
}
int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, void *data, int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, void *data,
unsigned long len, enum gacc_mode mode) unsigned long len, enum gacc_mode mode)
{ {
psw_t *psw = &vcpu->arch.sie_block->gpsw; psw_t *psw = &vcpu->arch.sie_block->gpsw;
unsigned long _len, nr_pages, gpa, idx; unsigned long nr_pages, idx;
unsigned long pages_array[2]; unsigned long gpa_array[2];
unsigned long *pages; unsigned int fragment_len;
unsigned long *gpas;
int need_ipte_lock; int need_ipte_lock;
union asce asce; union asce asce;
int rc; int rc;
@@ -845,50 +901,45 @@ int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, void *data,
if (rc) if (rc)
return rc; return rc;
nr_pages = (((ga & ~PAGE_MASK) + len - 1) >> PAGE_SHIFT) + 1; nr_pages = (((ga & ~PAGE_MASK) + len - 1) >> PAGE_SHIFT) + 1;
pages = pages_array; gpas = gpa_array;
if (nr_pages > ARRAY_SIZE(pages_array)) if (nr_pages > ARRAY_SIZE(gpa_array))
pages = vmalloc(array_size(nr_pages, sizeof(unsigned long))); gpas = vmalloc(array_size(nr_pages, sizeof(unsigned long)));
if (!pages) if (!gpas)
return -ENOMEM; return -ENOMEM;
need_ipte_lock = psw_bits(*psw).dat && !asce.r; need_ipte_lock = psw_bits(*psw).dat && !asce.r;
if (need_ipte_lock) if (need_ipte_lock)
ipte_lock(vcpu); ipte_lock(vcpu);
rc = guest_page_range(vcpu, ga, ar, pages, nr_pages, asce, mode); rc = guest_range_to_gpas(vcpu, ga, ar, gpas, len, asce, mode);
for (idx = 0; idx < nr_pages && !rc; idx++) { for (idx = 0; idx < nr_pages && !rc; idx++) {
gpa = *(pages + idx) + (ga & ~PAGE_MASK); fragment_len = min(PAGE_SIZE - offset_in_page(gpas[idx]), len);
_len = min(PAGE_SIZE - (gpa & ~PAGE_MASK), len); rc = access_guest_page(vcpu->kvm, mode, gpas[idx], data, fragment_len);
if (mode == GACC_STORE) len -= fragment_len;
rc = kvm_write_guest(vcpu->kvm, gpa, data, _len); data += fragment_len;
else
rc = kvm_read_guest(vcpu->kvm, gpa, data, _len);
len -= _len;
ga += _len;
data += _len;
} }
if (need_ipte_lock) if (need_ipte_lock)
ipte_unlock(vcpu); ipte_unlock(vcpu);
if (nr_pages > ARRAY_SIZE(pages_array)) if (nr_pages > ARRAY_SIZE(gpa_array))
vfree(pages); vfree(gpas);
return rc; return rc;
} }
int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra,
void *data, unsigned long len, enum gacc_mode mode) void *data, unsigned long len, enum gacc_mode mode)
{ {
unsigned long _len, gpa; unsigned int fragment_len;
unsigned long gpa;
int rc = 0; int rc = 0;
while (len && !rc) { while (len && !rc) {
gpa = kvm_s390_real_to_abs(vcpu, gra); gpa = kvm_s390_real_to_abs(vcpu, gra);
_len = min(PAGE_SIZE - (gpa & ~PAGE_MASK), len); fragment_len = min(PAGE_SIZE - offset_in_page(gpa), len);
if (mode) rc = access_guest_page(vcpu->kvm, mode, gpa, data, fragment_len);
rc = write_guest_abs(vcpu, gpa, data, _len); len -= fragment_len;
else gra += fragment_len;
rc = read_guest_abs(vcpu, gpa, data, _len); data += fragment_len;
len -= _len;
gra += _len;
data += _len;
} }
if (rc > 0)
vcpu->arch.pgm.code = rc;
return rc; return rc;
} }
@@ -904,8 +955,6 @@ int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra,
int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar, int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar,
unsigned long *gpa, enum gacc_mode mode) unsigned long *gpa, enum gacc_mode mode)
{ {
psw_t *psw = &vcpu->arch.sie_block->gpsw;
enum prot_type prot;
union asce asce; union asce asce;
int rc; int rc;
@@ -913,23 +962,7 @@ int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar,
rc = get_vcpu_asce(vcpu, &asce, gva, ar, mode); rc = get_vcpu_asce(vcpu, &asce, gva, ar, mode);
if (rc) if (rc)
return rc; return rc;
if (is_low_address(gva) && low_address_protection_enabled(vcpu, asce)) { return guest_range_to_gpas(vcpu, gva, ar, gpa, 1, asce, mode);
if (mode == GACC_STORE)
return trans_exc(vcpu, PGM_PROTECTION, gva, 0,
mode, PROT_TYPE_LA);
}
if (psw_bits(*psw).dat && !asce.r) { /* Use DAT? */
rc = guest_translate(vcpu, gva, gpa, asce, mode, &prot);
if (rc > 0)
return trans_exc(vcpu, rc, gva, 0, mode, prot);
} else {
*gpa = kvm_s390_real_to_abs(vcpu, gva);
if (kvm_is_error_gpa(vcpu->kvm, *gpa))
return trans_exc(vcpu, rc, gva, PGM_ADDRESSING, mode, 0);
}
return rc;
} }
/** /**
@@ -938,17 +971,14 @@ int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar,
int check_gva_range(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar, int check_gva_range(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar,
unsigned long length, enum gacc_mode mode) unsigned long length, enum gacc_mode mode)
{ {
unsigned long gpa; union asce asce;
unsigned long currlen;
int rc = 0; int rc = 0;
rc = get_vcpu_asce(vcpu, &asce, gva, ar, mode);
if (rc)
return rc;
ipte_lock(vcpu); ipte_lock(vcpu);
while (length > 0 && !rc) { rc = guest_range_to_gpas(vcpu, gva, ar, NULL, length, asce, mode);
currlen = min(length, PAGE_SIZE - (gva % PAGE_SIZE));
rc = guest_translate_address(vcpu, gva, ar, &gpa, mode);
gva += currlen;
length -= currlen;
}
ipte_unlock(vcpu); ipte_unlock(vcpu);
return rc; return rc;

View File

@@ -344,11 +344,12 @@ int read_guest_abs(struct kvm_vcpu *vcpu, unsigned long gpa, void *data,
* @len: number of bytes to copy * @len: number of bytes to copy
* *
* Copy @len bytes from @data (kernel space) to @gra (guest real address). * Copy @len bytes from @data (kernel space) to @gra (guest real address).
* It is up to the caller to ensure that the entire guest memory range is
* valid memory before calling this function.
* Guest low address and key protection are not checked. * Guest low address and key protection are not checked.
* *
* Returns zero on success or -EFAULT on error. * Returns zero on success, -EFAULT when copying from @data failed, or
* PGM_ADRESSING in case @gra is outside a memslot. In this case, pgm check info
* is also stored to allow injecting into the guest (if applicable) using
* kvm_s390_inject_prog_cond().
* *
* If an error occurs data may have been copied partially to guest memory. * If an error occurs data may have been copied partially to guest memory.
*/ */
@@ -367,11 +368,12 @@ int write_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, void *data,
* @len: number of bytes to copy * @len: number of bytes to copy
* *
* Copy @len bytes from @gra (guest real address) to @data (kernel space). * Copy @len bytes from @gra (guest real address) to @data (kernel space).
* It is up to the caller to ensure that the entire guest memory range is
* valid memory before calling this function.
* Guest key protection is not checked. * Guest key protection is not checked.
* *
* Returns zero on success or -EFAULT on error. * Returns zero on success, -EFAULT when copying to @data failed, or
* PGM_ADRESSING in case @gra is outside a memslot. In this case, pgm check info
* is also stored to allow injecting into the guest (if applicable) using
* kvm_s390_inject_prog_cond().
* *
* If an error occurs data may have been copied partially to kernel space. * If an error occurs data may have been copied partially to kernel space.
*/ */

View File

@@ -98,11 +98,12 @@ static long cmm_alloc_pages(long nr, long *counter,
(*counter)++; (*counter)++;
spin_unlock(&cmm_lock); spin_unlock(&cmm_lock);
nr--; nr--;
cond_resched();
} }
return nr; return nr;
} }
static long cmm_free_pages(long nr, long *counter, struct cmm_page_array **list) static long __cmm_free_pages(long nr, long *counter, struct cmm_page_array **list)
{ {
struct cmm_page_array *pa; struct cmm_page_array *pa;
unsigned long addr; unsigned long addr;
@@ -126,6 +127,21 @@ static long cmm_free_pages(long nr, long *counter, struct cmm_page_array **list)
return nr; return nr;
} }
static long cmm_free_pages(long nr, long *counter, struct cmm_page_array **list)
{
long inc = 0;
while (nr) {
inc = min(256L, nr);
nr -= inc;
inc = __cmm_free_pages(inc, counter, list);
if (inc)
break;
cond_resched();
}
return nr + inc;
}
static int cmm_oom_notify(struct notifier_block *self, static int cmm_oom_notify(struct notifier_block *self,
unsigned long dummy, void *parm) unsigned long dummy, void *parm)
{ {

View File

@@ -216,7 +216,7 @@
#define X86_FEATURE_SPEC_STORE_BYPASS_DISABLE ( 7*32+23) /* "" Disable Speculative Store Bypass. */ #define X86_FEATURE_SPEC_STORE_BYPASS_DISABLE ( 7*32+23) /* "" Disable Speculative Store Bypass. */
#define X86_FEATURE_LS_CFG_SSBD ( 7*32+24) /* "" AMD SSBD implementation via LS_CFG MSR */ #define X86_FEATURE_LS_CFG_SSBD ( 7*32+24) /* "" AMD SSBD implementation via LS_CFG MSR */
#define X86_FEATURE_IBRS ( 7*32+25) /* Indirect Branch Restricted Speculation */ #define X86_FEATURE_IBRS ( 7*32+25) /* Indirect Branch Restricted Speculation */
#define X86_FEATURE_IBPB ( 7*32+26) /* Indirect Branch Prediction Barrier */ #define X86_FEATURE_IBPB ( 7*32+26) /* "ibpb" Indirect Branch Prediction Barrier without a guaranteed RSB flush */
#define X86_FEATURE_STIBP ( 7*32+27) /* Single Thread Indirect Branch Predictors */ #define X86_FEATURE_STIBP ( 7*32+27) /* Single Thread Indirect Branch Predictors */
#define X86_FEATURE_ZEN ( 7*32+28) /* "" CPU is AMD family 0x17 (Zen) */ #define X86_FEATURE_ZEN ( 7*32+28) /* "" CPU is AMD family 0x17 (Zen) */
#define X86_FEATURE_L1TF_PTEINV ( 7*32+29) /* "" L1TF workaround PTE inversion */ #define X86_FEATURE_L1TF_PTEINV ( 7*32+29) /* "" L1TF workaround PTE inversion */
@@ -306,6 +306,7 @@
#define X86_FEATURE_VIRT_SSBD (13*32+25) /* Virtualized Speculative Store Bypass Disable */ #define X86_FEATURE_VIRT_SSBD (13*32+25) /* Virtualized Speculative Store Bypass Disable */
#define X86_FEATURE_AMD_SSB_NO (13*32+26) /* "" Speculative Store Bypass is fixed in hardware. */ #define X86_FEATURE_AMD_SSB_NO (13*32+26) /* "" Speculative Store Bypass is fixed in hardware. */
#define X86_FEATURE_BTC_NO (13*32+29) /* "" Not vulnerable to Branch Type Confusion */ #define X86_FEATURE_BTC_NO (13*32+29) /* "" Not vulnerable to Branch Type Confusion */
#define X86_FEATURE_AMD_IBPB_RET (13*32+30) /* "" IBPB clears return address predictor */
/* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 14 */ /* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 14 */
#define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */ #define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */

View File

@@ -484,7 +484,19 @@ static int lapic_timer_shutdown(struct clock_event_device *evt)
v = apic_read(APIC_LVTT); v = apic_read(APIC_LVTT);
v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
apic_write(APIC_LVTT, v); apic_write(APIC_LVTT, v);
apic_write(APIC_TMICT, 0);
/*
* Setting APIC_LVT_MASKED (above) should be enough to tell
* the hardware that this timer will never fire. But AMD
* erratum 411 and some Intel CPU behavior circa 2024 say
* otherwise. Time for belt and suspenders programming: mask
* the timer _and_ zero the counter registers:
*/
if (v & APIC_LVT_TIMER_TSCDEADLINE)
wrmsrl(MSR_IA32_TSC_DEADLINE, 0);
else
apic_write(APIC_TMICT, 0);
return 0; return 0;
} }

View File

@@ -243,6 +243,7 @@ static void __init ms_hyperv_init_platform(void)
ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) { ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) {
x86_platform.calibrate_tsc = hv_get_tsc_khz; x86_platform.calibrate_tsc = hv_get_tsc_khz;
x86_platform.calibrate_cpu = hv_get_tsc_khz; x86_platform.calibrate_cpu = hv_get_tsc_khz;
setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
} }
if (ms_hyperv.hints & HV_X64_ENLIGHTENED_VMCS_RECOMMENDED) { if (ms_hyperv.hints & HV_X64_ENLIGHTENED_VMCS_RECOMMENDED) {

View File

@@ -862,7 +862,7 @@ char * __init xen_memory_setup(void)
* to relocating (and even reusing) pages with kernel text or data. * to relocating (and even reusing) pages with kernel text or data.
*/ */
if (xen_is_e820_reserved(__pa_symbol(_text), if (xen_is_e820_reserved(__pa_symbol(_text),
__pa_symbol(__bss_stop) - __pa_symbol(_text))) { __pa_symbol(_end) - __pa_symbol(_text))) {
xen_raw_console_write("Xen hypervisor allocated kernel memory conflicts with E820 map\n"); xen_raw_console_write("Xen hypervisor allocated kernel memory conflicts with E820 map\n");
BUG(); BUG();
} }

View File

@@ -2226,8 +2226,12 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,
struct bfq_queue *in_service_bfqq, *new_bfqq; struct bfq_queue *in_service_bfqq, *new_bfqq;
/* if a merge has already been setup, then proceed with that first */ /* if a merge has already been setup, then proceed with that first */
if (bfqq->new_bfqq) new_bfqq = bfqq->new_bfqq;
return bfqq->new_bfqq; if (new_bfqq) {
while (new_bfqq->new_bfqq)
new_bfqq = new_bfqq->new_bfqq;
return new_bfqq;
}
/* /*
* Prevent bfqq from being merged if it has been created too * Prevent bfqq from being merged if it has been created too
@@ -5033,7 +5037,7 @@ bfq_split_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq)
{ {
bfq_log_bfqq(bfqq->bfqd, bfqq, "splitting queue"); bfq_log_bfqq(bfqq->bfqd, bfqq, "splitting queue");
if (bfqq_process_refs(bfqq) == 1) { if (bfqq_process_refs(bfqq) == 1 && !bfqq->new_bfqq) {
bfqq->pid = current->pid; bfqq->pid = current->pid;
bfq_clear_bfqq_coop(bfqq); bfq_clear_bfqq_coop(bfqq);
bfq_clear_bfqq_split_coop(bfqq); bfq_clear_bfqq_split_coop(bfqq);
@@ -5218,7 +5222,8 @@ static struct bfq_queue *bfq_init_rq(struct request *rq)
* addition, if the queue has also just been split, we have to * addition, if the queue has also just been split, we have to
* resume its state. * resume its state.
*/ */
if (likely(bfqq != &bfqd->oom_bfqq) && bfqq_process_refs(bfqq) == 1) { if (likely(bfqq != &bfqd->oom_bfqq) && !bfqq->new_bfqq &&
bfqq_process_refs(bfqq) == 1) {
bfqq->bic = bic; bfqq->bic = bic;
if (split) { if (split) {
/* /*

View File

@@ -45,8 +45,7 @@ static int setkey_unaligned(struct crypto_aead *tfm, const u8 *key,
alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
memcpy(alignbuffer, key, keylen); memcpy(alignbuffer, key, keylen);
ret = crypto_aead_alg(tfm)->setkey(tfm, alignbuffer, keylen); ret = crypto_aead_alg(tfm)->setkey(tfm, alignbuffer, keylen);
memset(alignbuffer, 0, keylen); kzfree(buffer);
kfree(buffer);
return ret; return ret;
} }

View File

@@ -38,8 +38,7 @@ static int setkey_unaligned(struct crypto_tfm *tfm, const u8 *key,
alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
memcpy(alignbuffer, key, keylen); memcpy(alignbuffer, key, keylen);
ret = cia->cia_setkey(tfm, alignbuffer, keylen); ret = cia->cia_setkey(tfm, alignbuffer, keylen);
memset(alignbuffer, 0, keylen); kzfree(buffer);
kfree(buffer);
return ret; return ret;
} }

View File

@@ -170,6 +170,8 @@ acpi_status acpi_db_convert_to_package(char *string, union acpi_object *object)
elements = elements =
ACPI_ALLOCATE_ZEROED(DB_DEFAULT_PKG_ELEMENTS * ACPI_ALLOCATE_ZEROED(DB_DEFAULT_PKG_ELEMENTS *
sizeof(union acpi_object)); sizeof(union acpi_object));
if (!elements)
return (AE_NO_MEMORY);
this = string; this = string;
for (i = 0; i < (DB_DEFAULT_PKG_ELEMENTS - 1); i++) { for (i = 0; i < (DB_DEFAULT_PKG_ELEMENTS - 1); i++) {

View File

@@ -437,6 +437,9 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
if (info->connection_node) { if (info->connection_node) {
second_desc = info->connection_node->object; second_desc = info->connection_node->object;
if (second_desc == NULL) {
break;
}
if (!(second_desc->common.flags & AOPOBJ_DATA_VALID)) { if (!(second_desc->common.flags & AOPOBJ_DATA_VALID)) {
status = status =
acpi_ds_get_buffer_arguments(second_desc); acpi_ds_get_buffer_arguments(second_desc);

View File

@@ -25,6 +25,8 @@ acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state);
static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
*parser_state); *parser_state);
static void acpi_ps_free_field_list(union acpi_parse_object *start);
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_ps_get_next_package_length * FUNCTION: acpi_ps_get_next_package_length
@@ -683,6 +685,39 @@ static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
return_PTR(field); return_PTR(field);
} }
/*******************************************************************************
*
* FUNCTION: acpi_ps_free_field_list
*
* PARAMETERS: start - First Op in field list
*
* RETURN: None.
*
* DESCRIPTION: Free all Op objects inside a field list.
*
******************************************************************************/
static void acpi_ps_free_field_list(union acpi_parse_object *start)
{
union acpi_parse_object *cur = start;
union acpi_parse_object *next;
union acpi_parse_object *arg;
while (cur) {
next = cur->common.next;
/* AML_INT_CONNECTION_OP can have a single argument */
arg = acpi_ps_get_arg(cur, 0);
if (arg) {
acpi_ps_free_op(arg);
}
acpi_ps_free_op(cur);
cur = next;
}
}
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_ps_get_next_arg * FUNCTION: acpi_ps_get_next_arg
@@ -751,6 +786,10 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
while (parser_state->aml < parser_state->pkg_end) { while (parser_state->aml < parser_state->pkg_end) {
field = acpi_ps_get_next_field(parser_state); field = acpi_ps_get_next_field(parser_state);
if (!field) { if (!field) {
if (arg) {
acpi_ps_free_field_list(arg);
}
return_ACPI_STATUS(AE_NO_MEMORY); return_ACPI_STATUS(AE_NO_MEMORY);
} }
@@ -820,6 +859,10 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
acpi_ps_get_next_namepath(walk_state, parser_state, acpi_ps_get_next_namepath(walk_state, parser_state,
arg, arg,
ACPI_NOT_METHOD_CALL); ACPI_NOT_METHOD_CALL);
if (ACPI_FAILURE(status)) {
acpi_ps_free_op(arg);
return_ACPI_STATUS(status);
}
} else { } else {
/* Single complex argument, nothing returned */ /* Single complex argument, nothing returned */
@@ -854,6 +897,10 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
acpi_ps_get_next_namepath(walk_state, parser_state, acpi_ps_get_next_namepath(walk_state, parser_state,
arg, arg,
ACPI_POSSIBLE_METHOD_CALL); ACPI_POSSIBLE_METHOD_CALL);
if (ACPI_FAILURE(status)) {
acpi_ps_free_op(arg);
return_ACPI_STATUS(status);
}
if (arg->common.aml_opcode == AML_INT_METHODCALL_OP) { if (arg->common.aml_opcode == AML_INT_METHODCALL_OP) {

View File

@@ -713,27 +713,34 @@ static LIST_HEAD(acpi_battery_list);
static LIST_HEAD(battery_hook_list); static LIST_HEAD(battery_hook_list);
static DEFINE_MUTEX(hook_mutex); static DEFINE_MUTEX(hook_mutex);
static void __battery_hook_unregister(struct acpi_battery_hook *hook, int lock) static void battery_hook_unregister_unlocked(struct acpi_battery_hook *hook)
{ {
struct acpi_battery *battery; struct acpi_battery *battery;
/* /*
* In order to remove a hook, we first need to * In order to remove a hook, we first need to
* de-register all the batteries that are registered. * de-register all the batteries that are registered.
*/ */
if (lock)
mutex_lock(&hook_mutex);
list_for_each_entry(battery, &acpi_battery_list, list) { list_for_each_entry(battery, &acpi_battery_list, list) {
hook->remove_battery(battery->bat); hook->remove_battery(battery->bat);
} }
list_del(&hook->list); list_del_init(&hook->list);
if (lock)
mutex_unlock(&hook_mutex);
pr_info("extension unregistered: %s\n", hook->name); pr_info("extension unregistered: %s\n", hook->name);
} }
void battery_hook_unregister(struct acpi_battery_hook *hook) void battery_hook_unregister(struct acpi_battery_hook *hook)
{ {
__battery_hook_unregister(hook, 1); mutex_lock(&hook_mutex);
/*
* Ignore already unregistered battery hooks. This might happen
* if a battery hook was previously unloaded due to an error when
* adding a new battery.
*/
if (!list_empty(&hook->list))
battery_hook_unregister_unlocked(hook);
mutex_unlock(&hook_mutex);
} }
EXPORT_SYMBOL_GPL(battery_hook_unregister); EXPORT_SYMBOL_GPL(battery_hook_unregister);
@@ -742,7 +749,6 @@ void battery_hook_register(struct acpi_battery_hook *hook)
struct acpi_battery *battery; struct acpi_battery *battery;
mutex_lock(&hook_mutex); mutex_lock(&hook_mutex);
INIT_LIST_HEAD(&hook->list);
list_add(&hook->list, &battery_hook_list); list_add(&hook->list, &battery_hook_list);
/* /*
* Now that the driver is registered, we need * Now that the driver is registered, we need
@@ -759,7 +765,7 @@ void battery_hook_register(struct acpi_battery_hook *hook)
* hooks. * hooks.
*/ */
pr_err("extension failed to load: %s", hook->name); pr_err("extension failed to load: %s", hook->name);
__battery_hook_unregister(hook, 0); battery_hook_unregister_unlocked(hook);
goto end; goto end;
} }
} }
@@ -796,7 +802,7 @@ static void battery_hook_add_battery(struct acpi_battery *battery)
*/ */
pr_err("error in extension, unloading: %s", pr_err("error in extension, unloading: %s",
hook_node->name); hook_node->name);
__battery_hook_unregister(hook_node, 0); battery_hook_unregister_unlocked(hook_node);
} }
} }
mutex_unlock(&hook_mutex); mutex_unlock(&hook_mutex);
@@ -829,7 +835,7 @@ static void __exit battery_hook_exit(void)
* need to remove the hooks. * need to remove the hooks.
*/ */
list_for_each_entry_safe(hook, ptr, &battery_hook_list, list) { list_for_each_entry_safe(hook, ptr, &battery_hook_list, list) {
__battery_hook_unregister(hook, 1); battery_hook_unregister(hook);
} }
mutex_destroy(&hook_mutex); mutex_destroy(&hook_mutex);
} }

View File

@@ -124,6 +124,17 @@ static const struct dmi_system_id lid_blacklst[] = {
}, },
.driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN, .driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN,
}, },
{
/*
* Samsung galaxybook2 ,initial _LID device notification returns
* lid closed.
*/
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
DMI_MATCH(DMI_PRODUCT_NAME, "750XED"),
},
.driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN,
},
{} {}
}; };

View File

@@ -539,8 +539,9 @@ int acpi_device_setup_files(struct acpi_device *dev)
* If device has _STR, 'description' file is created * If device has _STR, 'description' file is created
*/ */
if (acpi_has_method(dev->handle, "_STR")) { if (acpi_has_method(dev->handle, "_STR")) {
status = acpi_evaluate_object(dev->handle, "_STR", status = acpi_evaluate_object_typed(dev->handle, "_STR",
NULL, &buffer); NULL, &buffer,
ACPI_TYPE_BUFFER);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
buffer.pointer = NULL; buffer.pointer = NULL;
dev->pnp.str_obj = buffer.pointer; dev->pnp.str_obj = buffer.pointer;

View File

@@ -807,6 +807,9 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
unsigned long tmp; unsigned long tmp;
int ret = 0; int ret = 0;
if (t->rdata)
memset(t->rdata, 0, t->rlen);
/* start transaction */ /* start transaction */
spin_lock_irqsave(&ec->lock, tmp); spin_lock_irqsave(&ec->lock, tmp);
/* Enable GPE for command processing (IBF=0/OBF=1) */ /* Enable GPE for command processing (IBF=0/OBF=1) */
@@ -843,8 +846,6 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
if (!ec || (!t) || (t->wlen && !t->wdata) || (t->rlen && !t->rdata)) if (!ec || (!t) || (t->wlen && !t->wdata) || (t->rlen && !t->rdata))
return -EINVAL; return -EINVAL;
if (t->rdata)
memset(t->rdata, 0, t->rlen);
mutex_lock(&ec->mutex); mutex_lock(&ec->mutex);
if (ec->global_lock) { if (ec->global_lock) {
@@ -871,7 +872,7 @@ static int acpi_ec_burst_enable(struct acpi_ec *ec)
.wdata = NULL, .rdata = &d, .wdata = NULL, .rdata = &d,
.wlen = 0, .rlen = 1}; .wlen = 0, .rlen = 1};
return acpi_ec_transaction(ec, &t); return acpi_ec_transaction_unlocked(ec, &t);
} }
static int acpi_ec_burst_disable(struct acpi_ec *ec) static int acpi_ec_burst_disable(struct acpi_ec *ec)
@@ -881,7 +882,7 @@ static int acpi_ec_burst_disable(struct acpi_ec *ec)
.wlen = 0, .rlen = 0}; .wlen = 0, .rlen = 0};
return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ? return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ?
acpi_ec_transaction(ec, &t) : 0; acpi_ec_transaction_unlocked(ec, &t) : 0;
} }
static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data) static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data)
@@ -897,6 +898,19 @@ static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data)
return result; return result;
} }
static int acpi_ec_read_unlocked(struct acpi_ec *ec, u8 address, u8 *data)
{
int result;
u8 d;
struct transaction t = {.command = ACPI_EC_COMMAND_READ,
.wdata = &address, .rdata = &d,
.wlen = 1, .rlen = 1};
result = acpi_ec_transaction_unlocked(ec, &t);
*data = d;
return result;
}
static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data) static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
{ {
u8 wdata[2] = { address, data }; u8 wdata[2] = { address, data };
@@ -907,6 +921,16 @@ static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
return acpi_ec_transaction(ec, &t); return acpi_ec_transaction(ec, &t);
} }
static int acpi_ec_write_unlocked(struct acpi_ec *ec, u8 address, u8 data)
{
u8 wdata[2] = { address, data };
struct transaction t = {.command = ACPI_EC_COMMAND_WRITE,
.wdata = wdata, .rdata = NULL,
.wlen = 2, .rlen = 0};
return acpi_ec_transaction_unlocked(ec, &t);
}
int ec_read(u8 addr, u8 *val) int ec_read(u8 addr, u8 *val)
{ {
int err; int err;
@@ -1320,6 +1344,7 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
struct acpi_ec *ec = handler_context; struct acpi_ec *ec = handler_context;
int result = 0, i, bytes = bits / 8; int result = 0, i, bytes = bits / 8;
u8 *value = (u8 *)value64; u8 *value = (u8 *)value64;
u32 glk;
if ((address > 0xFF) || !value || !handler_context) if ((address > 0xFF) || !value || !handler_context)
return AE_BAD_PARAMETER; return AE_BAD_PARAMETER;
@@ -1327,13 +1352,25 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
if (function != ACPI_READ && function != ACPI_WRITE) if (function != ACPI_READ && function != ACPI_WRITE)
return AE_BAD_PARAMETER; return AE_BAD_PARAMETER;
mutex_lock(&ec->mutex);
if (ec->global_lock) {
acpi_status status;
status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
if (ACPI_FAILURE(status)) {
result = -ENODEV;
goto unlock;
}
}
if (ec->busy_polling || bits > 8) if (ec->busy_polling || bits > 8)
acpi_ec_burst_enable(ec); acpi_ec_burst_enable(ec);
for (i = 0; i < bytes; ++i, ++address, ++value) { for (i = 0; i < bytes; ++i, ++address, ++value) {
result = (function == ACPI_READ) ? result = (function == ACPI_READ) ?
acpi_ec_read(ec, address, value) : acpi_ec_read_unlocked(ec, address, value) :
acpi_ec_write(ec, address, *value); acpi_ec_write_unlocked(ec, address, *value);
if (result < 0) if (result < 0)
break; break;
} }
@@ -1341,6 +1378,12 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
if (ec->busy_polling || bits > 8) if (ec->busy_polling || bits > 8)
acpi_ec_burst_disable(ec); acpi_ec_burst_disable(ec);
if (ec->global_lock)
acpi_release_global_lock(glk);
unlock:
mutex_unlock(&ec->mutex);
switch (result) { switch (result) {
case -EINVAL: case -EINVAL:
return AE_BAD_PARAMETER; return AE_BAD_PARAMETER;

View File

@@ -376,10 +376,8 @@ static int tps68470_pmic_opregion_probe(struct platform_device *pdev)
struct tps68470_pmic_opregion *opregion; struct tps68470_pmic_opregion *opregion;
acpi_status status; acpi_status status;
if (!dev || !tps68470_regmap) { if (!tps68470_regmap)
dev_warn(dev, "dev or regmap is NULL\n"); return dev_err_probe(dev, -EINVAL, "regmap is missing\n");
return -EINVAL;
}
if (!handle) { if (!handle) {
dev_warn(dev, "acpi handle is NULL\n"); dev_warn(dev, "acpi handle is NULL\n");

View File

@@ -144,7 +144,7 @@ static const struct pci_device_id sil_pci_tbl[] = {
static const struct sil_drivelist { static const struct sil_drivelist {
const char *product; const char *product;
unsigned int quirk; unsigned int quirk;
} sil_blacklist [] = { } sil_quirks[] = {
{ "ST320012AS", SIL_QUIRK_MOD15WRITE }, { "ST320012AS", SIL_QUIRK_MOD15WRITE },
{ "ST330013AS", SIL_QUIRK_MOD15WRITE }, { "ST330013AS", SIL_QUIRK_MOD15WRITE },
{ "ST340017AS", SIL_QUIRK_MOD15WRITE }, { "ST340017AS", SIL_QUIRK_MOD15WRITE },
@@ -617,8 +617,8 @@ static void sil_thaw(struct ata_port *ap)
* list, and apply the fixups to only the specific * list, and apply the fixups to only the specific
* devices/hosts/firmwares that need it. * devices/hosts/firmwares that need it.
* *
* 20040111 - Seagate drives affected by the Mod15Write bug are blacklisted * 20040111 - Seagate drives affected by the Mod15Write bug are quirked
* The Maxtor quirk is in the blacklist, but I'm keeping the original * The Maxtor quirk is in sil_quirks, but I'm keeping the original
* pessimistic fix for the following reasons... * pessimistic fix for the following reasons...
* - There seems to be less info on it, only one device gleaned off the * - There seems to be less info on it, only one device gleaned off the
* Windows driver, maybe only one is affected. More info would be greatly * Windows driver, maybe only one is affected. More info would be greatly
@@ -637,9 +637,9 @@ static void sil_dev_config(struct ata_device *dev)
ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num)); ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
for (n = 0; sil_blacklist[n].product; n++) for (n = 0; sil_quirks[n].product; n++)
if (!strcmp(sil_blacklist[n].product, model_num)) { if (!strcmp(sil_quirks[n].product, model_num)) {
quirks = sil_blacklist[n].quirk; quirks = sil_quirks[n].quirk;
break; break;
} }

View File

@@ -103,7 +103,8 @@ static ssize_t bus_attr_show(struct kobject *kobj, struct attribute *attr,
{ {
struct bus_attribute *bus_attr = to_bus_attr(attr); struct bus_attribute *bus_attr = to_bus_attr(attr);
struct subsys_private *subsys_priv = to_subsys_private(kobj); struct subsys_private *subsys_priv = to_subsys_private(kobj);
ssize_t ret = 0; /* return -EIO for reading a bus attribute without show() */
ssize_t ret = -EIO;
if (bus_attr->show) if (bus_attr->show)
ret = bus_attr->show(subsys_priv->bus, buf); ret = bus_attr->show(subsys_priv->bus, buf);
@@ -115,7 +116,8 @@ static ssize_t bus_attr_store(struct kobject *kobj, struct attribute *attr,
{ {
struct bus_attribute *bus_attr = to_bus_attr(attr); struct bus_attribute *bus_attr = to_bus_attr(attr);
struct subsys_private *subsys_priv = to_subsys_private(kobj); struct subsys_private *subsys_priv = to_subsys_private(kobj);
ssize_t ret = 0; /* return -EIO for writing a bus attribute without store() */
ssize_t ret = -EIO;
if (bus_attr->store) if (bus_attr->store)
ret = bus_attr->store(subsys_priv->bus, buf, count); ret = bus_attr->store(subsys_priv->bus, buf, count);

View File

@@ -24,7 +24,6 @@
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/rcupdate.h>
#include <linux/sched/signal.h> #include <linux/sched/signal.h>
#include <linux/sysfs.h> #include <linux/sysfs.h>
@@ -1560,7 +1559,6 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj,
struct kobj_uevent_env *env) struct kobj_uevent_env *env)
{ {
struct device *dev = kobj_to_dev(kobj); struct device *dev = kobj_to_dev(kobj);
struct device_driver *driver;
int retval = 0; int retval = 0;
/* add device node properties if present */ /* add device node properties if present */
@@ -1589,12 +1587,8 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj,
if (dev->type && dev->type->name) if (dev->type && dev->type->name)
add_uevent_var(env, "DEVTYPE=%s", dev->type->name); add_uevent_var(env, "DEVTYPE=%s", dev->type->name);
/* Synchronize with module_remove_driver() */ if (dev->driver)
rcu_read_lock(); add_uevent_var(env, "DRIVER=%s", dev->driver->name);
driver = READ_ONCE(dev->driver);
if (driver)
add_uevent_var(env, "DRIVER=%s", driver->name);
rcu_read_unlock();
/* Add common DT information about the device */ /* Add common DT information about the device */
of_device_uevent(dev, env); of_device_uevent(dev, env);
@@ -1664,8 +1658,11 @@ static ssize_t uevent_show(struct device *dev, struct device_attribute *attr,
if (!env) if (!env)
return -ENOMEM; return -ENOMEM;
/* Synchronize with really_probe() */
device_lock(dev);
/* let the kset specific function add its keys */ /* let the kset specific function add its keys */
retval = kset->uevent_ops->uevent(kset, &dev->kobj, env); retval = kset->uevent_ops->uevent(kset, &dev->kobj, env);
device_unlock(dev);
if (retval) if (retval)
goto out; goto out;

View File

@@ -565,6 +565,26 @@ static void fw_abort_batch_reqs(struct firmware *fw)
mutex_unlock(&fw_lock); mutex_unlock(&fw_lock);
} }
/*
* Reject firmware file names with ".." path components.
* There are drivers that construct firmware file names from device-supplied
* strings, and we don't want some device to be able to tell us "I would like to
* be sent my firmware from ../../../etc/shadow, please".
*
* Search for ".." surrounded by either '/' or start/end of string.
*
* This intentionally only looks at the firmware name, not at the firmware base
* directory or at symlink contents.
*/
static bool name_contains_dotdot(const char *name)
{
size_t name_len = strlen(name);
return strcmp(name, "..") == 0 || strncmp(name, "../", 3) == 0 ||
strstr(name, "/../") != NULL ||
(name_len >= 3 && strcmp(name+name_len-3, "/..") == 0);
}
/* called from request_firmware() and request_firmware_work_func() */ /* called from request_firmware() and request_firmware_work_func() */
static int static int
_request_firmware(const struct firmware **firmware_p, const char *name, _request_firmware(const struct firmware **firmware_p, const char *name,
@@ -582,6 +602,14 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
goto out; goto out;
} }
if (name_contains_dotdot(name)) {
dev_warn(device,
"Firmware load for '%s' refused, path contains '..' component\n",
name);
ret = -EINVAL;
goto out;
}
ret = _request_firmware_prepare(&fw, name, device, buf, size, ret = _request_firmware_prepare(&fw, name, device, buf, size,
opt_flags); opt_flags);
if (ret <= 0) /* error or already assigned */ if (ret <= 0) /* error or already assigned */
@@ -622,6 +650,8 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
* @name will be used as $FIRMWARE in the uevent environment and * @name will be used as $FIRMWARE in the uevent environment and
* should be distinctive enough not to be confused with any other * should be distinctive enough not to be confused with any other
* firmware image for this or any other device. * firmware image for this or any other device.
* It must not contain any ".." path components - "foo/bar..bin" is
* allowed, but "foo/../bar.bin" is not.
* *
* Caller must hold the reference count of @device. * Caller must hold the reference count of @device.
* *

View File

@@ -7,7 +7,6 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/rcupdate.h>
#include "base.h" #include "base.h"
static char *make_driver_name(struct device_driver *drv) static char *make_driver_name(struct device_driver *drv)
@@ -78,9 +77,6 @@ void module_remove_driver(struct device_driver *drv)
if (!drv) if (!drv)
return; return;
/* Synchronize with dev_uevent() */
synchronize_rcu();
sysfs_remove_link(&drv->p->kobj, "module"); sysfs_remove_link(&drv->p->kobj, "module");
if (drv->owner) if (drv->owner)

View File

@@ -362,6 +362,7 @@ ata_rw_frameinit(struct frame *f)
} }
ah->cmdstat = ATA_CMD_PIO_READ | writebit | extbit; ah->cmdstat = ATA_CMD_PIO_READ | writebit | extbit;
dev_hold(t->ifp->nd);
skb->dev = t->ifp->nd; skb->dev = t->ifp->nd;
} }
@@ -402,6 +403,8 @@ aoecmd_ata_rw(struct aoedev *d)
__skb_queue_head_init(&queue); __skb_queue_head_init(&queue);
__skb_queue_tail(&queue, skb); __skb_queue_tail(&queue, skb);
aoenet_xmit(&queue); aoenet_xmit(&queue);
} else {
dev_put(f->t->ifp->nd);
} }
return 1; return 1;
} }
@@ -484,10 +487,13 @@ resend(struct aoedev *d, struct frame *f)
memcpy(h->dst, t->addr, sizeof h->dst); memcpy(h->dst, t->addr, sizeof h->dst);
memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src); memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src);
dev_hold(t->ifp->nd);
skb->dev = t->ifp->nd; skb->dev = t->ifp->nd;
skb = skb_clone(skb, GFP_ATOMIC); skb = skb_clone(skb, GFP_ATOMIC);
if (skb == NULL) if (skb == NULL) {
dev_put(t->ifp->nd);
return; return;
}
f->sent = ktime_get(); f->sent = ktime_get();
__skb_queue_head_init(&queue); __skb_queue_head_init(&queue);
__skb_queue_tail(&queue, skb); __skb_queue_tail(&queue, skb);
@@ -618,6 +624,8 @@ probe(struct aoetgt *t)
__skb_queue_head_init(&queue); __skb_queue_head_init(&queue);
__skb_queue_tail(&queue, skb); __skb_queue_tail(&queue, skb);
aoenet_xmit(&queue); aoenet_xmit(&queue);
} else {
dev_put(f->t->ifp->nd);
} }
} }
@@ -1407,6 +1415,7 @@ aoecmd_ata_id(struct aoedev *d)
ah->cmdstat = ATA_CMD_ID_ATA; ah->cmdstat = ATA_CMD_ID_ATA;
ah->lba3 = 0xa0; ah->lba3 = 0xa0;
dev_hold(t->ifp->nd);
skb->dev = t->ifp->nd; skb->dev = t->ifp->nd;
d->rttavg = RTTAVG_INIT; d->rttavg = RTTAVG_INIT;
@@ -1416,6 +1425,8 @@ aoecmd_ata_id(struct aoedev *d)
skb = skb_clone(skb, GFP_ATOMIC); skb = skb_clone(skb, GFP_ATOMIC);
if (skb) if (skb)
f->sent = ktime_get(); f->sent = ktime_get();
else
dev_put(t->ifp->nd);
return skb; return skb;
} }

View File

@@ -3499,10 +3499,12 @@ void drbd_uuid_new_current(struct drbd_device *device) __must_hold(local)
void drbd_uuid_set_bm(struct drbd_device *device, u64 val) __must_hold(local) void drbd_uuid_set_bm(struct drbd_device *device, u64 val) __must_hold(local)
{ {
unsigned long flags; unsigned long flags;
if (device->ldev->md.uuid[UI_BITMAP] == 0 && val == 0)
return;
spin_lock_irqsave(&device->ldev->md.uuid_lock, flags); spin_lock_irqsave(&device->ldev->md.uuid_lock, flags);
if (device->ldev->md.uuid[UI_BITMAP] == 0 && val == 0) {
spin_unlock_irqrestore(&device->ldev->md.uuid_lock, flags);
return;
}
if (val == 0) { if (val == 0) {
drbd_uuid_move_history(device); drbd_uuid_move_history(device);
device->ldev->md.uuid[UI_HISTORY_START] = device->ldev->md.uuid[UI_BITMAP]; device->ldev->md.uuid[UI_HISTORY_START] = device->ldev->md.uuid[UI_BITMAP];

View File

@@ -888,7 +888,7 @@ is_valid_state(struct drbd_device *device, union drbd_state ns)
ns.disk == D_OUTDATED) ns.disk == D_OUTDATED)
rv = SS_CONNECTED_OUTDATES; rv = SS_CONNECTED_OUTDATES;
else if ((ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) && else if (nc && (ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) &&
(nc->verify_alg[0] == 0)) (nc->verify_alg[0] == 0))
rv = SS_NO_VERIFY_ALG; rv = SS_NO_VERIFY_ALG;

View File

@@ -743,7 +743,15 @@ static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags)
if (!urb) if (!urb)
return -ENOMEM; return -ENOMEM;
size = le16_to_cpu(data->intr_ep->wMaxPacketSize); if (le16_to_cpu(data->udev->descriptor.idVendor) == 0x0a12 &&
le16_to_cpu(data->udev->descriptor.idProduct) == 0x0001)
/* Fake CSR devices don't seem to support sort-transter */
size = le16_to_cpu(data->intr_ep->wMaxPacketSize);
else
/* Use maximum HCI Event size so the USB stack handles
* ZPL/short-transfer automatically.
*/
size = HCI_MAX_EVENT_SIZE;
buf = kmalloc(size, mem_flags); buf = kmalloc(size, mem_flags);
if (!buf) { if (!buf) {

View File

@@ -2075,25 +2075,27 @@ static int virtcons_probe(struct virtio_device *vdev)
multiport = true; multiport = true;
} }
err = init_vqs(portdev);
if (err < 0) {
dev_err(&vdev->dev, "Error %d initializing vqs\n", err);
goto free_chrdev;
}
spin_lock_init(&portdev->ports_lock); spin_lock_init(&portdev->ports_lock);
INIT_LIST_HEAD(&portdev->ports); INIT_LIST_HEAD(&portdev->ports);
INIT_LIST_HEAD(&portdev->list); INIT_LIST_HEAD(&portdev->list);
virtio_device_ready(portdev->vdev);
INIT_WORK(&portdev->config_work, &config_work_handler); INIT_WORK(&portdev->config_work, &config_work_handler);
INIT_WORK(&portdev->control_work, &control_work_handler); INIT_WORK(&portdev->control_work, &control_work_handler);
if (multiport) { if (multiport) {
spin_lock_init(&portdev->c_ivq_lock); spin_lock_init(&portdev->c_ivq_lock);
spin_lock_init(&portdev->c_ovq_lock); spin_lock_init(&portdev->c_ovq_lock);
}
err = init_vqs(portdev);
if (err < 0) {
dev_err(&vdev->dev, "Error %d initializing vqs\n", err);
goto free_chrdev;
}
virtio_device_ready(portdev->vdev);
if (multiport) {
err = fill_queue(portdev->c_ivq, &portdev->c_ivq_lock); err = fill_queue(portdev->c_ivq, &portdev->c_ivq_lock);
if (err < 0) { if (err < 0) {
dev_err(&vdev->dev, dev_err(&vdev->dev,

View File

@@ -115,7 +115,7 @@ static void bcm53573_ilp_init(struct device_node *np)
goto err_free_ilp; goto err_free_ilp;
} }
ilp->regmap = syscon_node_to_regmap(of_get_parent(np)); ilp->regmap = syscon_node_to_regmap(np->parent);
if (IS_ERR(ilp->regmap)) { if (IS_ERR(ilp->regmap)) {
err = PTR_ERR(ilp->regmap); err = PTR_ERR(ilp->regmap);
goto err_free_ilp; goto err_free_ilp;

View File

@@ -9,31 +9,101 @@
#include <linux/export.h> #include <linux/export.h>
#include <linux/gfp.h> #include <linux/gfp.h>
struct devm_clk_state {
struct clk *clk;
void (*exit)(struct clk *clk);
};
static void devm_clk_release(struct device *dev, void *res) static void devm_clk_release(struct device *dev, void *res)
{ {
clk_put(*(struct clk **)res); struct devm_clk_state *state = res;
if (state->exit)
state->exit(state->clk);
clk_put(state->clk);
}
static struct clk *__devm_clk_get(struct device *dev, const char *id,
struct clk *(*get)(struct device *dev, const char *id),
int (*init)(struct clk *clk),
void (*exit)(struct clk *clk))
{
struct devm_clk_state *state;
struct clk *clk;
int ret;
state = devres_alloc(devm_clk_release, sizeof(*state), GFP_KERNEL);
if (!state)
return ERR_PTR(-ENOMEM);
clk = get(dev, id);
if (IS_ERR(clk)) {
ret = PTR_ERR(clk);
goto err_clk_get;
}
if (init) {
ret = init(clk);
if (ret)
goto err_clk_init;
}
state->clk = clk;
state->exit = exit;
devres_add(dev, state);
return clk;
err_clk_init:
clk_put(clk);
err_clk_get:
devres_free(state);
return ERR_PTR(ret);
} }
struct clk *devm_clk_get(struct device *dev, const char *id) struct clk *devm_clk_get(struct device *dev, const char *id)
{ {
struct clk **ptr, *clk; return __devm_clk_get(dev, id, clk_get, NULL, NULL);
ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL);
if (!ptr)
return ERR_PTR(-ENOMEM);
clk = clk_get(dev, id);
if (!IS_ERR(clk)) {
*ptr = clk;
devres_add(dev, ptr);
} else {
devres_free(ptr);
}
return clk;
} }
EXPORT_SYMBOL(devm_clk_get); EXPORT_SYMBOL(devm_clk_get);
struct clk *devm_clk_get_prepared(struct device *dev, const char *id)
{
return __devm_clk_get(dev, id, clk_get, clk_prepare, clk_unprepare);
}
EXPORT_SYMBOL_GPL(devm_clk_get_prepared);
struct clk *devm_clk_get_enabled(struct device *dev, const char *id)
{
return __devm_clk_get(dev, id, clk_get,
clk_prepare_enable, clk_disable_unprepare);
}
EXPORT_SYMBOL_GPL(devm_clk_get_enabled);
struct clk *devm_clk_get_optional(struct device *dev, const char *id)
{
return __devm_clk_get(dev, id, clk_get_optional, NULL, NULL);
}
EXPORT_SYMBOL(devm_clk_get_optional);
struct clk *devm_clk_get_optional_prepared(struct device *dev, const char *id)
{
return __devm_clk_get(dev, id, clk_get_optional,
clk_prepare, clk_unprepare);
}
EXPORT_SYMBOL_GPL(devm_clk_get_optional_prepared);
struct clk *devm_clk_get_optional_enabled(struct device *dev, const char *id)
{
return __devm_clk_get(dev, id, clk_get_optional,
clk_prepare_enable, clk_disable_unprepare);
}
EXPORT_SYMBOL_GPL(devm_clk_get_optional_enabled);
struct clk_bulk_devres { struct clk_bulk_devres {
struct clk_bulk_data *clks; struct clk_bulk_data *clks;
int num_clks; int num_clks;
@@ -93,18 +163,19 @@ EXPORT_SYMBOL(devm_clk_put);
struct clk *devm_get_clk_from_child(struct device *dev, struct clk *devm_get_clk_from_child(struct device *dev,
struct device_node *np, const char *con_id) struct device_node *np, const char *con_id)
{ {
struct clk **ptr, *clk; struct devm_clk_state *state;
struct clk *clk;
ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL); state = devres_alloc(devm_clk_release, sizeof(*state), GFP_KERNEL);
if (!ptr) if (!state)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
clk = of_clk_get_by_name(np, con_id); clk = of_clk_get_by_name(np, con_id);
if (!IS_ERR(clk)) { if (!IS_ERR(clk)) {
*ptr = clk; state->clk = clk;
devres_add(dev, ptr); devres_add(dev, state);
} else { } else {
devres_free(ptr); devres_free(state);
} }
return clk; return clk;

View File

@@ -415,7 +415,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
RK2928_CLKSEL_CON(29), 0, 3, DFLAGS), RK2928_CLKSEL_CON(29), 0, 3, DFLAGS),
DIV(0, "sclk_vop_pre", "sclk_vop_src", 0, DIV(0, "sclk_vop_pre", "sclk_vop_src", 0,
RK2928_CLKSEL_CON(27), 8, 8, DFLAGS), RK2928_CLKSEL_CON(27), 8, 8, DFLAGS),
MUX(DCLK_VOP, "dclk_vop", mux_dclk_vop_p, 0, MUX(DCLK_VOP, "dclk_vop", mux_dclk_vop_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
RK2928_CLKSEL_CON(27), 1, 1, MFLAGS), RK2928_CLKSEL_CON(27), 1, 1, MFLAGS),
FACTOR(0, "xin12m", "xin24m", 0, 1, 2), FACTOR(0, "xin12m", "xin24m", 0, 1, 2),

View File

@@ -444,12 +444,13 @@ void __init rockchip_clk_register_branches(
struct rockchip_clk_branch *list, struct rockchip_clk_branch *list,
unsigned int nr_clk) unsigned int nr_clk)
{ {
struct clk *clk = NULL; struct clk *clk;
unsigned int idx; unsigned int idx;
unsigned long flags; unsigned long flags;
for (idx = 0; idx < nr_clk; idx++, list++) { for (idx = 0; idx < nr_clk; idx++, list++) {
flags = list->flags; flags = list->flags;
clk = NULL;
/* catch simple muxes */ /* catch simple muxes */
switch (list->branch_type) { switch (list->branch_type) {

View File

@@ -257,6 +257,7 @@ static int of_dra7_atl_clk_probe(struct platform_device *pdev)
} }
clk = of_clk_get_from_provider(&clkspec); clk = of_clk_get_from_provider(&clkspec);
of_node_put(clkspec.np);
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
pr_err("%s: failed to get atl clock %d from provider\n", pr_err("%s: failed to get atl clock %d from provider\n",
__func__, i); __func__, i);

View File

@@ -242,6 +242,7 @@ static int __init msm_dt_timer_init(struct device_node *np)
} }
if (of_property_read_u32(np, "clock-frequency", &freq)) { if (of_property_read_u32(np, "clock-frequency", &freq)) {
iounmap(cpu0_base);
pr_err("Unknown frequency\n"); pr_err("Unknown frequency\n");
return -EINVAL; return -EINVAL;
} }
@@ -252,7 +253,11 @@ static int __init msm_dt_timer_init(struct device_node *np)
freq /= 4; freq /= 4;
writel_relaxed(DGT_CLK_CTL_DIV_4, source_base + DGT_CLK_CTL); writel_relaxed(DGT_CLK_CTL_DIV_4, source_base + DGT_CLK_CTL);
return msm_timer_init(freq, 32, irq, !!percpu_offset); ret = msm_timer_init(freq, 32, irq, !!percpu_offset);
if (ret)
iounmap(cpu0_base);
return ret;
} }
TIMER_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init); TIMER_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init);
TIMER_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init); TIMER_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init);

View File

@@ -800,7 +800,7 @@ static int sdei_device_freeze(struct device *dev)
int err; int err;
/* unregister private events */ /* unregister private events */
cpuhp_remove_state(sdei_entry_point); cpuhp_remove_state(sdei_hp_state);
err = sdei_unregister_shared(); err = sdei_unregister_shared();
if (err) if (err)

View File

@@ -407,6 +407,8 @@ static void __aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset,
gpio->dcache[GPIO_BANK(offset)] = reg; gpio->dcache[GPIO_BANK(offset)] = reg;
iowrite32(reg, addr); iowrite32(reg, addr);
/* Flush write */
ioread32(addr);
} }
static void aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset, static void aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset,
@@ -1174,7 +1176,7 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev)
if (!gpio_id) if (!gpio_id)
return -EINVAL; return -EINVAL;
gpio->clk = of_clk_get(pdev->dev.of_node, 0); gpio->clk = devm_clk_get_enabled(&pdev->dev, NULL);
if (IS_ERR(gpio->clk)) { if (IS_ERR(gpio->clk)) {
dev_warn(&pdev->dev, dev_warn(&pdev->dev,
"Failed to get clock from devicetree, debouncing disabled\n"); "Failed to get clock from devicetree, debouncing disabled\n");

View File

@@ -294,7 +294,7 @@ static int davinci_gpio_probe(struct platform_device *pdev)
* serve as EDMA event triggers. * serve as EDMA event triggers.
*/ */
static void gpio_irq_disable(struct irq_data *d) static void gpio_irq_mask(struct irq_data *d)
{ {
struct davinci_gpio_regs __iomem *g = irq2regs(d); struct davinci_gpio_regs __iomem *g = irq2regs(d);
u32 mask = (u32) irq_data_get_irq_handler_data(d); u32 mask = (u32) irq_data_get_irq_handler_data(d);
@@ -303,7 +303,7 @@ static void gpio_irq_disable(struct irq_data *d)
writel_relaxed(mask, &g->clr_rising); writel_relaxed(mask, &g->clr_rising);
} }
static void gpio_irq_enable(struct irq_data *d) static void gpio_irq_unmask(struct irq_data *d)
{ {
struct davinci_gpio_regs __iomem *g = irq2regs(d); struct davinci_gpio_regs __iomem *g = irq2regs(d);
u32 mask = (u32) irq_data_get_irq_handler_data(d); u32 mask = (u32) irq_data_get_irq_handler_data(d);
@@ -329,8 +329,8 @@ static int gpio_irq_type(struct irq_data *d, unsigned trigger)
static struct irq_chip gpio_irqchip = { static struct irq_chip gpio_irqchip = {
.name = "GPIO", .name = "GPIO",
.irq_enable = gpio_irq_enable, .irq_unmask = gpio_irq_unmask,
.irq_disable = gpio_irq_disable, .irq_mask = gpio_irq_mask,
.irq_set_type = gpio_irq_type, .irq_set_type = gpio_irq_type,
.flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_SKIP_SET_WAKE, .flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_SKIP_SET_WAKE,
}; };

View File

@@ -3,6 +3,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/nospec.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/device.h> #include <linux/device.h>
@@ -144,7 +145,7 @@ struct gpio_desc *gpiochip_get_desc(struct gpio_chip *chip,
if (hwnum >= gdev->ngpio) if (hwnum >= gdev->ngpio)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
return &gdev->descs[hwnum]; return &gdev->descs[array_index_nospec(hwnum, gdev->ngpio)];
} }
/** /**

View File

@@ -90,6 +90,7 @@ static union acpi_object *amdgpu_atif_call(struct amdgpu_atif *atif,
struct acpi_buffer *params) struct acpi_buffer *params)
{ {
acpi_status status; acpi_status status;
union acpi_object *obj;
union acpi_object atif_arg_elements[2]; union acpi_object atif_arg_elements[2];
struct acpi_object_list atif_arg; struct acpi_object_list atif_arg;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
@@ -112,16 +113,24 @@ static union acpi_object *amdgpu_atif_call(struct amdgpu_atif *atif,
status = acpi_evaluate_object(atif->handle, NULL, &atif_arg, status = acpi_evaluate_object(atif->handle, NULL, &atif_arg,
&buffer); &buffer);
obj = (union acpi_object *)buffer.pointer;
/* Fail only if calling the method fails and ATIF is supported */ /* Fail if calling the method fails and ATIF is supported */
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n", DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n",
acpi_format_exception(status)); acpi_format_exception(status));
kfree(buffer.pointer); kfree(obj);
return NULL; return NULL;
} }
return buffer.pointer; if (obj->type != ACPI_TYPE_BUFFER) {
DRM_DEBUG_DRIVER("bad object returned from ATIF: %d\n",
obj->type);
kfree(obj);
return NULL;
}
return obj;
} }
/** /**

View File

@@ -2095,23 +2095,29 @@ amdgpu_atombios_encoder_get_lcd_info(struct amdgpu_encoder *encoder)
fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record; fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record;
if (fake_edid_record->ucFakeEDIDLength) { if (fake_edid_record->ucFakeEDIDLength) {
struct edid *edid; struct edid *edid;
int edid_size = int edid_size;
max((int)EDID_LENGTH, (int)fake_edid_record->ucFakeEDIDLength);
edid = kmalloc(edid_size, GFP_KERNEL);
if (edid) {
memcpy((u8 *)edid, (u8 *)&fake_edid_record->ucFakeEDIDString[0],
fake_edid_record->ucFakeEDIDLength);
if (fake_edid_record->ucFakeEDIDLength == 128)
edid_size = fake_edid_record->ucFakeEDIDLength;
else
edid_size = fake_edid_record->ucFakeEDIDLength * 128;
edid = kmemdup(&fake_edid_record->ucFakeEDIDString[0],
edid_size, GFP_KERNEL);
if (edid) {
if (drm_edid_is_valid(edid)) { if (drm_edid_is_valid(edid)) {
adev->mode_info.bios_hardcoded_edid = edid; adev->mode_info.bios_hardcoded_edid = edid;
adev->mode_info.bios_hardcoded_edid_size = edid_size; adev->mode_info.bios_hardcoded_edid_size = edid_size;
} else } else {
kfree(edid); kfree(edid);
}
} }
record += struct_size(fake_edid_record,
ucFakeEDIDString,
edid_size);
} else {
/* empty fake edid record must be 3 bytes long */
record += sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + 1;
} }
record += fake_edid_record->ucFakeEDIDLength ?
fake_edid_record->ucFakeEDIDLength + 2 :
sizeof(ATOM_FAKE_EDID_PATCH_RECORD);
break; break;
case LCD_PANEL_RESOLUTION_RECORD_TYPE: case LCD_PANEL_RESOLUTION_RECORD_TYPE:
panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record; panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record;

View File

@@ -1569,6 +1569,8 @@ static bool are_stream_backends_same(
bool dc_is_stream_unchanged( bool dc_is_stream_unchanged(
struct dc_stream_state *old_stream, struct dc_stream_state *stream) struct dc_stream_state *old_stream, struct dc_stream_state *stream)
{ {
if (!old_stream || !stream)
return false;
if (!are_stream_backends_same(old_stream, stream)) if (!are_stream_backends_same(old_stream, stream))
return false; return false;

View File

@@ -482,6 +482,8 @@ bool cm_helper_translate_curve_to_degamma_hw_format(
i += increment) { i += increment) {
if (j == hw_points - 1) if (j == hw_points - 1)
break; break;
if (i >= TRANSFER_FUNC_POINTS)
return false;
rgb_resulted[j].red = output_tf->tf_pts.red[i]; rgb_resulted[j].red = output_tf->tf_pts.red[i];
rgb_resulted[j].green = output_tf->tf_pts.green[i]; rgb_resulted[j].green = output_tf->tf_pts.green[i];
rgb_resulted[j].blue = output_tf->tf_pts.blue[i]; rgb_resulted[j].blue = output_tf->tf_pts.blue[i];

View File

@@ -4106,8 +4106,8 @@ typedef struct _ATOM_LCD_MODE_CONTROL_CAP
typedef struct _ATOM_FAKE_EDID_PATCH_RECORD typedef struct _ATOM_FAKE_EDID_PATCH_RECORD
{ {
UCHAR ucRecordType; UCHAR ucRecordType;
UCHAR ucFakeEDIDLength; // = 128 means EDID lenght is 128 bytes, otherwise the EDID length = ucFakeEDIDLength*128 UCHAR ucFakeEDIDLength; // = 128 means EDID length is 128 bytes, otherwise the EDID length = ucFakeEDIDLength*128
UCHAR ucFakeEDIDString[1]; // This actually has ucFakeEdidLength elements. UCHAR ucFakeEDIDString[]; // This actually has ucFakeEdidLength elements.
} ATOM_FAKE_EDID_PATCH_RECORD; } ATOM_FAKE_EDID_PATCH_RECORD;
typedef struct _ATOM_PANEL_RESOLUTION_PATCH_RECORD typedef struct _ATOM_PANEL_RESOLUTION_PATCH_RECORD

View File

@@ -567,9 +567,9 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
struct drm_mode_crtc *crtc_req = data; struct drm_mode_crtc *crtc_req = data;
struct drm_crtc *crtc; struct drm_crtc *crtc;
struct drm_plane *plane; struct drm_plane *plane;
struct drm_connector **connector_set, *connector; struct drm_connector **connector_set = NULL, *connector;
struct drm_framebuffer *fb; struct drm_framebuffer *fb = NULL;
struct drm_display_mode *mode; struct drm_display_mode *mode = NULL;
struct drm_mode_set set; struct drm_mode_set set;
uint32_t __user *set_connectors_ptr; uint32_t __user *set_connectors_ptr;
struct drm_modeset_acquire_ctx ctx; struct drm_modeset_acquire_ctx ctx;
@@ -601,10 +601,6 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
mutex_lock(&crtc->dev->mode_config.mutex); mutex_lock(&crtc->dev->mode_config.mutex);
drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE); drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
retry: retry:
connector_set = NULL;
fb = NULL;
mode = NULL;
ret = drm_modeset_lock_all_ctx(crtc->dev, &ctx); ret = drm_modeset_lock_all_ctx(crtc->dev, &ctx);
if (ret) if (ret)
goto out; goto out;
@@ -767,6 +763,13 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
} }
kfree(connector_set); kfree(connector_set);
drm_mode_destroy(dev, mode); drm_mode_destroy(dev, mode);
/* In case we need to retry... */
connector_set = NULL;
fb = NULL;
mode = NULL;
num_connectors = 0;
if (ret == -EDEADLK) { if (ret == -EDEADLK) {
ret = drm_modeset_backoff(&ctx); ret = drm_modeset_backoff(&ctx);
if (!ret) if (!ret)

View File

@@ -54,8 +54,9 @@ void __drm_puts_coredump(struct drm_printer *p, const char *str)
copy = iterator->remain; copy = iterator->remain;
/* Copy out the bit of the string that we need */ /* Copy out the bit of the string that we need */
memcpy(iterator->data, if (iterator->data)
str + (iterator->start - iterator->offset), copy); memcpy(iterator->data,
str + (iterator->start - iterator->offset), copy);
iterator->offset = iterator->start + copy; iterator->offset = iterator->start + copy;
iterator->remain -= copy; iterator->remain -= copy;
@@ -64,7 +65,8 @@ void __drm_puts_coredump(struct drm_printer *p, const char *str)
len = min_t(ssize_t, strlen(str), iterator->remain); len = min_t(ssize_t, strlen(str), iterator->remain);
memcpy(iterator->data + pos, str, len); if (iterator->data)
memcpy(iterator->data + pos, str, len);
iterator->offset += len; iterator->offset += len;
iterator->remain -= len; iterator->remain -= len;
@@ -94,8 +96,9 @@ void __drm_printfn_coredump(struct drm_printer *p, struct va_format *vaf)
if ((iterator->offset >= iterator->start) && (len < iterator->remain)) { if ((iterator->offset >= iterator->start) && (len < iterator->remain)) {
ssize_t pos = iterator->offset - iterator->start; ssize_t pos = iterator->offset - iterator->start;
snprintf(((char *) iterator->data) + pos, if (iterator->data)
iterator->remain, "%pV", vaf); snprintf(((char *) iterator->data) + pos,
iterator->remain, "%pV", vaf);
iterator->offset += len; iterator->offset += len;
iterator->remain -= len; iterator->remain -= len;

View File

@@ -44,6 +44,7 @@ struct a5xx_gpu {
uint64_t preempt_iova[MSM_GPU_MAX_RINGS]; uint64_t preempt_iova[MSM_GPU_MAX_RINGS];
atomic_t preempt_state; atomic_t preempt_state;
spinlock_t preempt_start_lock;
struct timer_list preempt_timer; struct timer_list preempt_timer;
}; };

View File

@@ -107,12 +107,19 @@ void a5xx_preempt_trigger(struct msm_gpu *gpu)
if (gpu->nr_rings == 1) if (gpu->nr_rings == 1)
return; return;
/*
* Serialize preemption start to ensure that we always make
* decision on latest state. Otherwise we can get stuck in
* lower priority or empty ring.
*/
spin_lock_irqsave(&a5xx_gpu->preempt_start_lock, flags);
/* /*
* Try to start preemption by moving from NONE to START. If * Try to start preemption by moving from NONE to START. If
* unsuccessful, a preemption is already in flight * unsuccessful, a preemption is already in flight
*/ */
if (!try_preempt_state(a5xx_gpu, PREEMPT_NONE, PREEMPT_START)) if (!try_preempt_state(a5xx_gpu, PREEMPT_NONE, PREEMPT_START))
return; goto out;
/* Get the next ring to preempt to */ /* Get the next ring to preempt to */
ring = get_next_ring(gpu); ring = get_next_ring(gpu);
@@ -137,9 +144,11 @@ void a5xx_preempt_trigger(struct msm_gpu *gpu)
set_preempt_state(a5xx_gpu, PREEMPT_ABORT); set_preempt_state(a5xx_gpu, PREEMPT_ABORT);
update_wptr(gpu, a5xx_gpu->cur_ring); update_wptr(gpu, a5xx_gpu->cur_ring);
set_preempt_state(a5xx_gpu, PREEMPT_NONE); set_preempt_state(a5xx_gpu, PREEMPT_NONE);
return; goto out;
} }
spin_unlock_irqrestore(&a5xx_gpu->preempt_start_lock, flags);
/* Make sure the wptr doesn't update while we're in motion */ /* Make sure the wptr doesn't update while we're in motion */
spin_lock_irqsave(&ring->lock, flags); spin_lock_irqsave(&ring->lock, flags);
a5xx_gpu->preempt[ring->id]->wptr = get_wptr(ring); a5xx_gpu->preempt[ring->id]->wptr = get_wptr(ring);
@@ -163,6 +172,10 @@ void a5xx_preempt_trigger(struct msm_gpu *gpu)
/* And actually start the preemption */ /* And actually start the preemption */
gpu_write(gpu, REG_A5XX_CP_CONTEXT_SWITCH_CNTL, 1); gpu_write(gpu, REG_A5XX_CP_CONTEXT_SWITCH_CNTL, 1);
return;
out:
spin_unlock_irqrestore(&a5xx_gpu->preempt_start_lock, flags);
} }
void a5xx_preempt_irq(struct msm_gpu *gpu) void a5xx_preempt_irq(struct msm_gpu *gpu)
@@ -200,6 +213,12 @@ void a5xx_preempt_irq(struct msm_gpu *gpu)
update_wptr(gpu, a5xx_gpu->cur_ring); update_wptr(gpu, a5xx_gpu->cur_ring);
set_preempt_state(a5xx_gpu, PREEMPT_NONE); set_preempt_state(a5xx_gpu, PREEMPT_NONE);
/*
* Try to trigger preemption again in case there was a submit or
* retire during ring switch
*/
a5xx_preempt_trigger(gpu);
} }
void a5xx_preempt_hw_init(struct msm_gpu *gpu) void a5xx_preempt_hw_init(struct msm_gpu *gpu)
@@ -209,6 +228,8 @@ void a5xx_preempt_hw_init(struct msm_gpu *gpu)
int i; int i;
for (i = 0; i < gpu->nr_rings; i++) { for (i = 0; i < gpu->nr_rings; i++) {
a5xx_gpu->preempt[i]->data = 0;
a5xx_gpu->preempt[i]->info = 0;
a5xx_gpu->preempt[i]->wptr = 0; a5xx_gpu->preempt[i]->wptr = 0;
a5xx_gpu->preempt[i]->rptr = 0; a5xx_gpu->preempt[i]->rptr = 0;
a5xx_gpu->preempt[i]->rbase = gpu->rb[i]->iova; a5xx_gpu->preempt[i]->rbase = gpu->rb[i]->iova;
@@ -300,5 +321,6 @@ void a5xx_preempt_init(struct msm_gpu *gpu)
} }
} }
spin_lock_init(&a5xx_gpu->preempt_start_lock);
timer_setup(&a5xx_gpu->preempt_timer, a5xx_preempt_timer, 0); timer_setup(&a5xx_gpu->preempt_timer, a5xx_preempt_timer, 0);
} }

View File

@@ -366,7 +366,7 @@ void mdp5_smp_dump(struct mdp5_smp *smp, struct drm_printer *p)
drm_printf(p, "%s:%d\t%d\t%s\n", drm_printf(p, "%s:%d\t%d\t%s\n",
pipe2name(pipe), j, inuse, pipe2name(pipe), j, inuse,
plane ? plane->name : NULL); plane ? plane->name : "(null)");
total += inuse; total += inuse;
} }

View File

@@ -671,7 +671,7 @@ static u32 dsi_get_pclk_rate(struct msm_dsi_host *msm_host, bool is_dual_dsi)
struct drm_display_mode *mode = msm_host->mode; struct drm_display_mode *mode = msm_host->mode;
u32 pclk_rate; u32 pclk_rate;
pclk_rate = mode->clock * 1000; pclk_rate = mode->clock * 1000u;
/* /*
* For dual DSI mode, the current DRM mode has the complete width of the * For dual DSI mode, the current DRM mode has the complete width of the

View File

@@ -3615,7 +3615,7 @@ typedef struct _ATOM_FAKE_EDID_PATCH_RECORD
{ {
UCHAR ucRecordType; UCHAR ucRecordType;
UCHAR ucFakeEDIDLength; UCHAR ucFakeEDIDLength;
UCHAR ucFakeEDIDString[1]; // This actually has ucFakeEdidLength elements. UCHAR ucFakeEDIDString[]; // This actually has ucFakeEdidLength elements.
} ATOM_FAKE_EDID_PATCH_RECORD; } ATOM_FAKE_EDID_PATCH_RECORD;
typedef struct _ATOM_PANEL_RESOLUTION_PATCH_RECORD typedef struct _ATOM_PANEL_RESOLUTION_PATCH_RECORD

View File

@@ -396,7 +396,7 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i
struct evergreen_cs_track *track = p->track; struct evergreen_cs_track *track = p->track;
struct eg_surface surf; struct eg_surface surf;
unsigned pitch, slice, mslice; unsigned pitch, slice, mslice;
unsigned long offset; u64 offset;
int r; int r;
mslice = G_028C6C_SLICE_MAX(track->cb_color_view[id]) + 1; mslice = G_028C6C_SLICE_MAX(track->cb_color_view[id]) + 1;
@@ -434,14 +434,14 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i
return r; return r;
} }
offset = track->cb_color_bo_offset[id] << 8; offset = (u64)track->cb_color_bo_offset[id] << 8;
if (offset & (surf.base_align - 1)) { if (offset & (surf.base_align - 1)) {
dev_warn(p->dev, "%s:%d cb[%d] bo base %ld not aligned with %ld\n", dev_warn(p->dev, "%s:%d cb[%d] bo base %llu not aligned with %ld\n",
__func__, __LINE__, id, offset, surf.base_align); __func__, __LINE__, id, offset, surf.base_align);
return -EINVAL; return -EINVAL;
} }
offset += surf.layer_size * mslice; offset += (u64)surf.layer_size * mslice;
if (offset > radeon_bo_size(track->cb_color_bo[id])) { if (offset > radeon_bo_size(track->cb_color_bo[id])) {
/* old ddx are broken they allocate bo with w*h*bpp but /* old ddx are broken they allocate bo with w*h*bpp but
* program slice with ALIGN(h, 8), catch this and patch * program slice with ALIGN(h, 8), catch this and patch
@@ -449,14 +449,14 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i
*/ */
if (!surf.mode) { if (!surf.mode) {
uint32_t *ib = p->ib.ptr; uint32_t *ib = p->ib.ptr;
unsigned long tmp, nby, bsize, size, min = 0; u64 tmp, nby, bsize, size, min = 0;
/* find the height the ddx wants */ /* find the height the ddx wants */
if (surf.nby > 8) { if (surf.nby > 8) {
min = surf.nby - 8; min = surf.nby - 8;
} }
bsize = radeon_bo_size(track->cb_color_bo[id]); bsize = radeon_bo_size(track->cb_color_bo[id]);
tmp = track->cb_color_bo_offset[id] << 8; tmp = (u64)track->cb_color_bo_offset[id] << 8;
for (nby = surf.nby; nby > min; nby--) { for (nby = surf.nby; nby > min; nby--) {
size = nby * surf.nbx * surf.bpe * surf.nsamples; size = nby * surf.nbx * surf.bpe * surf.nsamples;
if ((tmp + size * mslice) <= bsize) { if ((tmp + size * mslice) <= bsize) {
@@ -468,7 +468,7 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i
slice = ((nby * surf.nbx) / 64) - 1; slice = ((nby * surf.nbx) / 64) - 1;
if (!evergreen_surface_check(p, &surf, "cb")) { if (!evergreen_surface_check(p, &surf, "cb")) {
/* check if this one works */ /* check if this one works */
tmp += surf.layer_size * mslice; tmp += (u64)surf.layer_size * mslice;
if (tmp <= bsize) { if (tmp <= bsize) {
ib[track->cb_color_slice_idx[id]] = slice; ib[track->cb_color_slice_idx[id]] = slice;
goto old_ddx_ok; goto old_ddx_ok;
@@ -477,9 +477,9 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i
} }
} }
dev_warn(p->dev, "%s:%d cb[%d] bo too small (layer size %d, " dev_warn(p->dev, "%s:%d cb[%d] bo too small (layer size %d, "
"offset %d, max layer %d, bo size %ld, slice %d)\n", "offset %llu, max layer %d, bo size %ld, slice %d)\n",
__func__, __LINE__, id, surf.layer_size, __func__, __LINE__, id, surf.layer_size,
track->cb_color_bo_offset[id] << 8, mslice, (u64)track->cb_color_bo_offset[id] << 8, mslice,
radeon_bo_size(track->cb_color_bo[id]), slice); radeon_bo_size(track->cb_color_bo[id]), slice);
dev_warn(p->dev, "%s:%d problematic surf: (%d %d) (%d %d %d %d %d %d %d)\n", dev_warn(p->dev, "%s:%d problematic surf: (%d %d) (%d %d %d %d %d %d %d)\n",
__func__, __LINE__, surf.nbx, surf.nby, __func__, __LINE__, surf.nbx, surf.nby,
@@ -563,7 +563,7 @@ static int evergreen_cs_track_validate_stencil(struct radeon_cs_parser *p)
struct evergreen_cs_track *track = p->track; struct evergreen_cs_track *track = p->track;
struct eg_surface surf; struct eg_surface surf;
unsigned pitch, slice, mslice; unsigned pitch, slice, mslice;
unsigned long offset; u64 offset;
int r; int r;
mslice = G_028008_SLICE_MAX(track->db_depth_view) + 1; mslice = G_028008_SLICE_MAX(track->db_depth_view) + 1;
@@ -609,18 +609,18 @@ static int evergreen_cs_track_validate_stencil(struct radeon_cs_parser *p)
return r; return r;
} }
offset = track->db_s_read_offset << 8; offset = (u64)track->db_s_read_offset << 8;
if (offset & (surf.base_align - 1)) { if (offset & (surf.base_align - 1)) {
dev_warn(p->dev, "%s:%d stencil read bo base %ld not aligned with %ld\n", dev_warn(p->dev, "%s:%d stencil read bo base %llu not aligned with %ld\n",
__func__, __LINE__, offset, surf.base_align); __func__, __LINE__, offset, surf.base_align);
return -EINVAL; return -EINVAL;
} }
offset += surf.layer_size * mslice; offset += (u64)surf.layer_size * mslice;
if (offset > radeon_bo_size(track->db_s_read_bo)) { if (offset > radeon_bo_size(track->db_s_read_bo)) {
dev_warn(p->dev, "%s:%d stencil read bo too small (layer size %d, " dev_warn(p->dev, "%s:%d stencil read bo too small (layer size %d, "
"offset %ld, max layer %d, bo size %ld)\n", "offset %llu, max layer %d, bo size %ld)\n",
__func__, __LINE__, surf.layer_size, __func__, __LINE__, surf.layer_size,
(unsigned long)track->db_s_read_offset << 8, mslice, (u64)track->db_s_read_offset << 8, mslice,
radeon_bo_size(track->db_s_read_bo)); radeon_bo_size(track->db_s_read_bo));
dev_warn(p->dev, "%s:%d stencil invalid (0x%08x 0x%08x 0x%08x 0x%08x)\n", dev_warn(p->dev, "%s:%d stencil invalid (0x%08x 0x%08x 0x%08x 0x%08x)\n",
__func__, __LINE__, track->db_depth_size, __func__, __LINE__, track->db_depth_size,
@@ -628,18 +628,18 @@ static int evergreen_cs_track_validate_stencil(struct radeon_cs_parser *p)
return -EINVAL; return -EINVAL;
} }
offset = track->db_s_write_offset << 8; offset = (u64)track->db_s_write_offset << 8;
if (offset & (surf.base_align - 1)) { if (offset & (surf.base_align - 1)) {
dev_warn(p->dev, "%s:%d stencil write bo base %ld not aligned with %ld\n", dev_warn(p->dev, "%s:%d stencil write bo base %llu not aligned with %ld\n",
__func__, __LINE__, offset, surf.base_align); __func__, __LINE__, offset, surf.base_align);
return -EINVAL; return -EINVAL;
} }
offset += surf.layer_size * mslice; offset += (u64)surf.layer_size * mslice;
if (offset > radeon_bo_size(track->db_s_write_bo)) { if (offset > radeon_bo_size(track->db_s_write_bo)) {
dev_warn(p->dev, "%s:%d stencil write bo too small (layer size %d, " dev_warn(p->dev, "%s:%d stencil write bo too small (layer size %d, "
"offset %ld, max layer %d, bo size %ld)\n", "offset %llu, max layer %d, bo size %ld)\n",
__func__, __LINE__, surf.layer_size, __func__, __LINE__, surf.layer_size,
(unsigned long)track->db_s_write_offset << 8, mslice, (u64)track->db_s_write_offset << 8, mslice,
radeon_bo_size(track->db_s_write_bo)); radeon_bo_size(track->db_s_write_bo));
return -EINVAL; return -EINVAL;
} }
@@ -660,7 +660,7 @@ static int evergreen_cs_track_validate_depth(struct radeon_cs_parser *p)
struct evergreen_cs_track *track = p->track; struct evergreen_cs_track *track = p->track;
struct eg_surface surf; struct eg_surface surf;
unsigned pitch, slice, mslice; unsigned pitch, slice, mslice;
unsigned long offset; u64 offset;
int r; int r;
mslice = G_028008_SLICE_MAX(track->db_depth_view) + 1; mslice = G_028008_SLICE_MAX(track->db_depth_view) + 1;
@@ -707,34 +707,34 @@ static int evergreen_cs_track_validate_depth(struct radeon_cs_parser *p)
return r; return r;
} }
offset = track->db_z_read_offset << 8; offset = (u64)track->db_z_read_offset << 8;
if (offset & (surf.base_align - 1)) { if (offset & (surf.base_align - 1)) {
dev_warn(p->dev, "%s:%d stencil read bo base %ld not aligned with %ld\n", dev_warn(p->dev, "%s:%d stencil read bo base %llu not aligned with %ld\n",
__func__, __LINE__, offset, surf.base_align); __func__, __LINE__, offset, surf.base_align);
return -EINVAL; return -EINVAL;
} }
offset += surf.layer_size * mslice; offset += (u64)surf.layer_size * mslice;
if (offset > radeon_bo_size(track->db_z_read_bo)) { if (offset > radeon_bo_size(track->db_z_read_bo)) {
dev_warn(p->dev, "%s:%d depth read bo too small (layer size %d, " dev_warn(p->dev, "%s:%d depth read bo too small (layer size %d, "
"offset %ld, max layer %d, bo size %ld)\n", "offset %llu, max layer %d, bo size %ld)\n",
__func__, __LINE__, surf.layer_size, __func__, __LINE__, surf.layer_size,
(unsigned long)track->db_z_read_offset << 8, mslice, (u64)track->db_z_read_offset << 8, mslice,
radeon_bo_size(track->db_z_read_bo)); radeon_bo_size(track->db_z_read_bo));
return -EINVAL; return -EINVAL;
} }
offset = track->db_z_write_offset << 8; offset = (u64)track->db_z_write_offset << 8;
if (offset & (surf.base_align - 1)) { if (offset & (surf.base_align - 1)) {
dev_warn(p->dev, "%s:%d stencil write bo base %ld not aligned with %ld\n", dev_warn(p->dev, "%s:%d stencil write bo base %llu not aligned with %ld\n",
__func__, __LINE__, offset, surf.base_align); __func__, __LINE__, offset, surf.base_align);
return -EINVAL; return -EINVAL;
} }
offset += surf.layer_size * mslice; offset += (u64)surf.layer_size * mslice;
if (offset > radeon_bo_size(track->db_z_write_bo)) { if (offset > radeon_bo_size(track->db_z_write_bo)) {
dev_warn(p->dev, "%s:%d depth write bo too small (layer size %d, " dev_warn(p->dev, "%s:%d depth write bo too small (layer size %d, "
"offset %ld, max layer %d, bo size %ld)\n", "offset %llu, max layer %d, bo size %ld)\n",
__func__, __LINE__, surf.layer_size, __func__, __LINE__, surf.layer_size,
(unsigned long)track->db_z_write_offset << 8, mslice, (u64)track->db_z_write_offset << 8, mslice,
radeon_bo_size(track->db_z_write_bo)); radeon_bo_size(track->db_z_write_bo));
return -EINVAL; return -EINVAL;
} }

View File

@@ -999,45 +999,65 @@ static int r100_cp_init_microcode(struct radeon_device *rdev)
DRM_DEBUG_KMS("\n"); DRM_DEBUG_KMS("\n");
if ((rdev->family == CHIP_R100) || (rdev->family == CHIP_RV100) || switch (rdev->family) {
(rdev->family == CHIP_RV200) || (rdev->family == CHIP_RS100) || case CHIP_R100:
(rdev->family == CHIP_RS200)) { case CHIP_RV100:
case CHIP_RV200:
case CHIP_RS100:
case CHIP_RS200:
DRM_INFO("Loading R100 Microcode\n"); DRM_INFO("Loading R100 Microcode\n");
fw_name = FIRMWARE_R100; fw_name = FIRMWARE_R100;
} else if ((rdev->family == CHIP_R200) || break;
(rdev->family == CHIP_RV250) ||
(rdev->family == CHIP_RV280) || case CHIP_R200:
(rdev->family == CHIP_RS300)) { case CHIP_RV250:
case CHIP_RV280:
case CHIP_RS300:
DRM_INFO("Loading R200 Microcode\n"); DRM_INFO("Loading R200 Microcode\n");
fw_name = FIRMWARE_R200; fw_name = FIRMWARE_R200;
} else if ((rdev->family == CHIP_R300) || break;
(rdev->family == CHIP_R350) ||
(rdev->family == CHIP_RV350) || case CHIP_R300:
(rdev->family == CHIP_RV380) || case CHIP_R350:
(rdev->family == CHIP_RS400) || case CHIP_RV350:
(rdev->family == CHIP_RS480)) { case CHIP_RV380:
case CHIP_RS400:
case CHIP_RS480:
DRM_INFO("Loading R300 Microcode\n"); DRM_INFO("Loading R300 Microcode\n");
fw_name = FIRMWARE_R300; fw_name = FIRMWARE_R300;
} else if ((rdev->family == CHIP_R420) || break;
(rdev->family == CHIP_R423) ||
(rdev->family == CHIP_RV410)) { case CHIP_R420:
case CHIP_R423:
case CHIP_RV410:
DRM_INFO("Loading R400 Microcode\n"); DRM_INFO("Loading R400 Microcode\n");
fw_name = FIRMWARE_R420; fw_name = FIRMWARE_R420;
} else if ((rdev->family == CHIP_RS690) || break;
(rdev->family == CHIP_RS740)) {
case CHIP_RS690:
case CHIP_RS740:
DRM_INFO("Loading RS690/RS740 Microcode\n"); DRM_INFO("Loading RS690/RS740 Microcode\n");
fw_name = FIRMWARE_RS690; fw_name = FIRMWARE_RS690;
} else if (rdev->family == CHIP_RS600) { break;
case CHIP_RS600:
DRM_INFO("Loading RS600 Microcode\n"); DRM_INFO("Loading RS600 Microcode\n");
fw_name = FIRMWARE_RS600; fw_name = FIRMWARE_RS600;
} else if ((rdev->family == CHIP_RV515) || break;
(rdev->family == CHIP_R520) ||
(rdev->family == CHIP_RV530) || case CHIP_RV515:
(rdev->family == CHIP_R580) || case CHIP_R520:
(rdev->family == CHIP_RV560) || case CHIP_RV530:
(rdev->family == CHIP_RV570)) { case CHIP_R580:
case CHIP_RV560:
case CHIP_RV570:
DRM_INFO("Loading R500 Microcode\n"); DRM_INFO("Loading R500 Microcode\n");
fw_name = FIRMWARE_R520; fw_name = FIRMWARE_R520;
break;
default:
DRM_ERROR("Unsupported Radeon family %u\n", rdev->family);
return -EINVAL;
} }
err = request_firmware(&rdev->me_fw, fw_name, rdev->dev); err = request_firmware(&rdev->me_fw, fw_name, rdev->dev);

View File

@@ -1727,23 +1727,29 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct
fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record; fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record;
if (fake_edid_record->ucFakeEDIDLength) { if (fake_edid_record->ucFakeEDIDLength) {
struct edid *edid; struct edid *edid;
int edid_size = int edid_size;
max((int)EDID_LENGTH, (int)fake_edid_record->ucFakeEDIDLength);
edid = kmalloc(edid_size, GFP_KERNEL);
if (edid) {
memcpy((u8 *)edid, (u8 *)&fake_edid_record->ucFakeEDIDString[0],
fake_edid_record->ucFakeEDIDLength);
if (fake_edid_record->ucFakeEDIDLength == 128)
edid_size = fake_edid_record->ucFakeEDIDLength;
else
edid_size = fake_edid_record->ucFakeEDIDLength * 128;
edid = kmemdup(&fake_edid_record->ucFakeEDIDString[0],
edid_size, GFP_KERNEL);
if (edid) {
if (drm_edid_is_valid(edid)) { if (drm_edid_is_valid(edid)) {
rdev->mode_info.bios_hardcoded_edid = edid; rdev->mode_info.bios_hardcoded_edid = edid;
rdev->mode_info.bios_hardcoded_edid_size = edid_size; rdev->mode_info.bios_hardcoded_edid_size = edid_size;
} else } else {
kfree(edid); kfree(edid);
}
} }
record += struct_size(fake_edid_record,
ucFakeEDIDString,
edid_size);
} else {
/* empty fake edid record must be 3 bytes long */
record += sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + 1;
} }
record += fake_edid_record->ucFakeEDIDLength ?
fake_edid_record->ucFakeEDIDLength + 2 :
sizeof(ATOM_FAKE_EDID_PATCH_RECORD);
break; break;
case LCD_PANEL_RESOLUTION_RECORD_TYPE: case LCD_PANEL_RESOLUTION_RECORD_TYPE:
panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record; panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record;

View File

@@ -308,8 +308,8 @@ static void scl_vop_cal_scl_fac(struct vop *vop, const struct vop_win_data *win,
if (info->is_yuv) if (info->is_yuv)
is_yuv = true; is_yuv = true;
if (dst_w > 3840) { if (dst_w > 4096) {
DRM_DEV_ERROR(vop->dev, "Maximum dst width (3840) exceeded\n"); DRM_DEV_ERROR(vop->dev, "Maximum dst width (4096) exceeded\n");
return; return;
} }

View File

@@ -152,10 +152,12 @@ static int stm_drm_platform_probe(struct platform_device *pdev)
ret = drm_dev_register(ddev, 0); ret = drm_dev_register(ddev, 0);
if (ret) if (ret)
goto err_put; goto err_unload;
return 0; return 0;
err_unload:
drv_unload(ddev);
err_put: err_put:
drm_dev_put(ddev); drm_dev_put(ddev);

View File

@@ -1468,6 +1468,7 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
DRM_ERROR("Surface size cannot exceed %dx%d", DRM_ERROR("Surface size cannot exceed %dx%d",
dev_priv->texture_max_width, dev_priv->texture_max_width,
dev_priv->texture_max_height); dev_priv->texture_max_height);
ret = -EINVAL;
goto err_out; goto err_out;
} }

View File

@@ -919,6 +919,8 @@
#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES 0xc056 #define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES 0xc056
#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES 0xc057 #define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES 0xc057
#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES 0xc058 #define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES 0xc058
#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3325_SERIES 0x430c
#define USB_DEVICE_ID_PLANTRONICS_ENCOREPRO_500_SERIES 0x431e
#define USB_VENDOR_ID_PANASONIC 0x04da #define USB_VENDOR_ID_PANASONIC 0x04da
#define USB_DEVICE_ID_PANABOARD_UBT780 0x1044 #define USB_DEVICE_ID_PANABOARD_UBT780 0x1044

View File

@@ -41,8 +41,10 @@
(usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER) (usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER)
#define PLT_QUIRK_DOUBLE_VOLUME_KEYS BIT(0) #define PLT_QUIRK_DOUBLE_VOLUME_KEYS BIT(0)
#define PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS BIT(1)
#define PLT_DOUBLE_KEY_TIMEOUT 5 /* ms */ #define PLT_DOUBLE_KEY_TIMEOUT 5 /* ms */
#define PLT_FOLLOWED_OPPOSITE_KEY_TIMEOUT 220 /* ms */
struct plt_drv_data { struct plt_drv_data {
unsigned long device_type; unsigned long device_type;
@@ -140,6 +142,21 @@ static int plantronics_event(struct hid_device *hdev, struct hid_field *field,
drv_data->last_volume_key_ts = cur_ts; drv_data->last_volume_key_ts = cur_ts;
} }
if (drv_data->quirks & PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS) {
unsigned long prev_ts, cur_ts;
/* Usages are filtered in plantronics_usages. */
if (!value) /* Handle key presses only. */
return 0;
prev_ts = drv_data->last_volume_key_ts;
cur_ts = jiffies;
if (jiffies_to_msecs(cur_ts - prev_ts) <= PLT_FOLLOWED_OPPOSITE_KEY_TIMEOUT)
return 1; /* Ignore the followed opposite volume key. */
drv_data->last_volume_key_ts = cur_ts;
}
return 0; return 0;
} }
@@ -213,6 +230,12 @@ static const struct hid_device_id plantronics_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES), USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES),
.driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS }, .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3325_SERIES),
.driver_data = PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS },
{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
USB_DEVICE_ID_PLANTRONICS_ENCOREPRO_500_SERIES),
.driver_data = PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS },
{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) }, { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) },
{ } { }
}; };

View File

@@ -117,9 +117,10 @@ static inline int LIMIT_TO_MV(int limit, int range)
return limit * range / 256; return limit * range / 256;
} }
static inline int MV_TO_LIMIT(int mv, int range) static inline int MV_TO_LIMIT(unsigned long mv, int range)
{ {
return clamp_val(DIV_ROUND_CLOSEST(mv * 256, range), 0, 255); mv = clamp_val(mv, 0, ULONG_MAX / 256);
return DIV_ROUND_CLOSEST(clamp_val(mv * 256, 0, range * 255), range);
} }
static inline int ADC_TO_CURR(int adc, int gain) static inline int ADC_TO_CURR(int adc, int gain)

View File

@@ -57,6 +57,7 @@ static const struct platform_device_id ntc_thermistor_id[] = {
{ "ncp15xh103", TYPE_NCPXXXH103 }, { "ncp15xh103", TYPE_NCPXXXH103 },
{ }, { },
}; };
MODULE_DEVICE_TABLE(platform, ntc_thermistor_id);
/* /*
* A compensation table should be sorted by the values of .ohm * A compensation table should be sorted by the values of .ohm

View File

@@ -255,6 +255,7 @@ void tmc_free_sg_table(struct tmc_sg_table *sg_table)
{ {
tmc_free_table_pages(sg_table); tmc_free_table_pages(sg_table);
tmc_free_data_pages(sg_table); tmc_free_data_pages(sg_table);
kfree(sg_table);
} }
/* /*
@@ -335,7 +336,6 @@ struct tmc_sg_table *tmc_alloc_sg_table(struct device *dev,
rc = tmc_alloc_table_pages(sg_table); rc = tmc_alloc_table_pages(sg_table);
if (rc) { if (rc) {
tmc_free_sg_table(sg_table); tmc_free_sg_table(sg_table);
kfree(sg_table);
return ERR_PTR(rc); return ERR_PTR(rc);
} }

View File

@@ -159,6 +159,13 @@ struct aspeed_i2c_bus {
static int aspeed_i2c_reset(struct aspeed_i2c_bus *bus); static int aspeed_i2c_reset(struct aspeed_i2c_bus *bus);
/* precondition: bus.lock has been acquired. */
static void aspeed_i2c_do_stop(struct aspeed_i2c_bus *bus)
{
bus->master_state = ASPEED_I2C_MASTER_STOP;
writel(ASPEED_I2CD_M_STOP_CMD, bus->base + ASPEED_I2C_CMD_REG);
}
static int aspeed_i2c_recover_bus(struct aspeed_i2c_bus *bus) static int aspeed_i2c_recover_bus(struct aspeed_i2c_bus *bus)
{ {
unsigned long time_left, flags; unsigned long time_left, flags;
@@ -176,7 +183,7 @@ static int aspeed_i2c_recover_bus(struct aspeed_i2c_bus *bus)
command); command);
reinit_completion(&bus->cmd_complete); reinit_completion(&bus->cmd_complete);
writel(ASPEED_I2CD_M_STOP_CMD, bus->base + ASPEED_I2C_CMD_REG); aspeed_i2c_do_stop(bus);
spin_unlock_irqrestore(&bus->lock, flags); spin_unlock_irqrestore(&bus->lock, flags);
time_left = wait_for_completion_timeout( time_left = wait_for_completion_timeout(
@@ -350,13 +357,6 @@ static void aspeed_i2c_do_start(struct aspeed_i2c_bus *bus)
writel(command, bus->base + ASPEED_I2C_CMD_REG); writel(command, bus->base + ASPEED_I2C_CMD_REG);
} }
/* precondition: bus.lock has been acquired. */
static void aspeed_i2c_do_stop(struct aspeed_i2c_bus *bus)
{
bus->master_state = ASPEED_I2C_MASTER_STOP;
writel(ASPEED_I2CD_M_STOP_CMD, bus->base + ASPEED_I2C_CMD_REG);
}
/* precondition: bus.lock has been acquired. */ /* precondition: bus.lock has been acquired. */
static void aspeed_i2c_next_msg_or_stop(struct aspeed_i2c_bus *bus) static void aspeed_i2c_next_msg_or_stop(struct aspeed_i2c_bus *bus)
{ {

View File

@@ -1674,8 +1674,15 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
i801_add_tco(priv); i801_add_tco(priv);
/*
* adapter.name is used by platform code to find the main I801 adapter
* to instantiante i2c_clients, do not change.
*/
snprintf(priv->adapter.name, sizeof(priv->adapter.name), snprintf(priv->adapter.name, sizeof(priv->adapter.name),
"SMBus I801 adapter at %04lx", priv->smba); "SMBus %s adapter at %04lx",
(priv->features & FEATURE_IDF) ? "I801 IDF" : "I801",
priv->smba);
err = i2c_add_adapter(&priv->adapter); err = i2c_add_adapter(&priv->adapter);
if (err) { if (err) {
platform_device_unregister(priv->tco_pdev); platform_device_unregister(priv->tco_pdev);

View File

@@ -107,8 +107,7 @@ static int sch_transaction(void)
if (retries > MAX_RETRIES) { if (retries > MAX_RETRIES) {
dev_err(&sch_adapter.dev, "SMBus Timeout!\n"); dev_err(&sch_adapter.dev, "SMBus Timeout!\n");
result = -ETIMEDOUT; result = -ETIMEDOUT;
} } else if (temp & 0x04) {
if (temp & 0x04) {
result = -EIO; result = -EIO;
dev_dbg(&sch_adapter.dev, "Bus collision! SMBus may be " dev_dbg(&sch_adapter.dev, "Bus collision! SMBus may be "
"locked until next hard reset. (sorry!)\n"); "locked until next hard reset. (sorry!)\n");

View File

@@ -478,14 +478,17 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
goto out; goto out;
} }
xiic_fill_tx_fifo(i2c); if (xiic_tx_space(i2c)) {
xiic_fill_tx_fifo(i2c);
/* current message sent and there is space in the fifo */ } else {
if (!xiic_tx_space(i2c) && xiic_tx_fifo_space(i2c) >= 2) { /* current message fully written */
dev_dbg(i2c->adap.dev.parent, dev_dbg(i2c->adap.dev.parent,
"%s end of message sent, nmsgs: %d\n", "%s end of message sent, nmsgs: %d\n",
__func__, i2c->nmsgs); __func__, i2c->nmsgs);
if (i2c->nmsgs > 1) { /* Don't move onto the next message until the TX FIFO empties,
* to ensure that a NAK is not missed.
*/
if (i2c->nmsgs > 1 && (pend & XIIC_INTR_TX_EMPTY_MASK)) {
i2c->nmsgs--; i2c->nmsgs--;
i2c->tx_msg++; i2c->tx_msg++;
xfer_more = 1; xfer_more = 1;
@@ -496,11 +499,7 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
"%s Got TX IRQ but no more to do...\n", "%s Got TX IRQ but no more to do...\n",
__func__); __func__);
} }
} else if (!xiic_tx_space(i2c) && (i2c->nmsgs == 1)) }
/* current frame is sent and is last,
* make sure to disable tx half
*/
xiic_irq_dis(i2c, XIIC_INTR_TX_HALF_MASK);
} }
out: out:
dev_dbg(i2c->adap.dev.parent, "%s clr: 0x%x\n", __func__, clr); dev_dbg(i2c->adap.dev.parent, "%s clr: 0x%x\n", __func__, clr);

View File

@@ -852,6 +852,8 @@ config TI_ADS7950
config TI_ADS8688 config TI_ADS8688
tristate "Texas Instruments ADS8688" tristate "Texas Instruments ADS8688"
depends on SPI && OF depends on SPI && OF
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help help
If you say yes here you get support for Texas Instruments ADS8684 and If you say yes here you get support for Texas Instruments ADS8684 and
and ADS8688 ADC chips and ADS8688 ADC chips

View File

@@ -46,7 +46,7 @@ static ssize_t _hid_sensor_set_report_latency(struct device *dev,
latency = integer * 1000 + fract / 1000; latency = integer * 1000 + fract / 1000;
ret = hid_sensor_set_report_latency(attrb, latency); ret = hid_sensor_set_report_latency(attrb, latency);
if (ret < 0) if (ret < 0)
return len; return ret;
attrb->latency_ms = hid_sensor_get_report_latency(attrb); attrb->latency_ms = hid_sensor_get_report_latency(attrb);

View File

@@ -335,6 +335,7 @@ config STM32_DAC
config STM32_DAC_CORE config STM32_DAC_CORE
tristate tristate
select REGMAP_MMIO
config TI_DAC082S085 config TI_DAC082S085
tristate "Texas Instruments 8/10/12-bit 2/4-channel DAC driver" tristate "Texas Instruments 8/10/12-bit 2/4-channel DAC driver"

View File

@@ -145,6 +145,10 @@ static const struct opt3001_scale opt3001_scales[] = {
.val = 20966, .val = 20966,
.val2 = 400000, .val2 = 400000,
}, },
{
.val = 41932,
.val2 = 800000,
},
{ {
.val = 83865, .val = 83865,
.val2 = 600000, .val2 = 600000,

View File

@@ -673,22 +673,8 @@ static int ak8975_start_read_axis(struct ak8975_data *data,
if (ret < 0) if (ret < 0)
return ret; return ret;
/* This will be executed only for non-interrupt based waiting case */ /* Return with zero if the data is ready. */
if (ret & data->def->ctrl_masks[ST1_DRDY]) { return !data->def->ctrl_regs[ST1_DRDY];
ret = i2c_smbus_read_byte_data(client,
data->def->ctrl_regs[ST2]);
if (ret < 0) {
dev_err(&client->dev, "Error in reading ST2\n");
return ret;
}
if (ret & (data->def->ctrl_masks[ST2_DERR] |
data->def->ctrl_masks[ST2_HOFL])) {
dev_err(&client->dev, "ST2 status error 0x%x\n", ret);
return -EINVAL;
}
}
return 0;
} }
/* Retrieve raw flux value for one of the x, y, or z axis. */ /* Retrieve raw flux value for one of the x, y, or z axis. */
@@ -715,6 +701,20 @@ static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val)
if (ret < 0) if (ret < 0)
goto exit; goto exit;
/* Read out ST2 for release lock on measurment data. */
ret = i2c_smbus_read_byte_data(client, data->def->ctrl_regs[ST2]);
if (ret < 0) {
dev_err(&client->dev, "Error in reading ST2\n");
goto exit;
}
if (ret & (data->def->ctrl_masks[ST2_DERR] |
data->def->ctrl_masks[ST2_HOFL])) {
dev_err(&client->dev, "ST2 status error 0x%x\n", ret);
ret = -EINVAL;
goto exit;
}
mutex_unlock(&data->lock); mutex_unlock(&data->lock);
pm_runtime_mark_last_busy(&data->client->dev); pm_runtime_mark_last_busy(&data->client->dev);

View File

@@ -1178,7 +1178,7 @@ static int __init iw_cm_init(void)
if (ret) if (ret)
return ret; return ret;
iwcm_wq = alloc_ordered_workqueue("iw_cm_wq", 0); iwcm_wq = alloc_ordered_workqueue("iw_cm_wq", WQ_MEM_RECLAIM);
if (!iwcm_wq) if (!iwcm_wq)
goto err_alloc; goto err_alloc;

View File

@@ -150,7 +150,7 @@ struct bnxt_qplib_swqe {
}; };
u32 q_key; u32 q_key;
u32 dst_qp; u32 dst_qp;
u16 avid; u32 avid;
} send; } send;
/* Send Raw Ethernet and QP1 */ /* Send Raw Ethernet and QP1 */

View File

@@ -234,7 +234,7 @@ int bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw,
/* failed with status */ /* failed with status */
dev_err(&rcfw->pdev->dev, "QPLIB: cmdq[%#x]=%#x status %#x", dev_err(&rcfw->pdev->dev, "QPLIB: cmdq[%#x]=%#x status %#x",
cookie, opcode, evnt->status); cookie, opcode, evnt->status);
rc = -EFAULT; rc = -EIO;
} }
return rc; return rc;

View File

@@ -1180,6 +1180,8 @@ static int act_establish(struct c4iw_dev *dev, struct sk_buff *skb)
int ret; int ret;
ep = lookup_atid(t, atid); ep = lookup_atid(t, atid);
if (!ep)
return -EINVAL;
pr_debug("ep %p tid %u snd_isn %u rcv_isn %u\n", ep, tid, pr_debug("ep %p tid %u snd_isn %u rcv_isn %u\n", ep, tid,
be32_to_cpu(req->snd_isn), be32_to_cpu(req->rcv_isn)); be32_to_cpu(req->snd_isn), be32_to_cpu(req->rcv_isn));
@@ -2041,7 +2043,7 @@ static int import_ep(struct c4iw_ep *ep, int iptype, __u8 *peer_ip,
err = -ENOMEM; err = -ENOMEM;
if (n->dev->flags & IFF_LOOPBACK) { if (n->dev->flags & IFF_LOOPBACK) {
if (iptype == 4) if (iptype == 4)
pdev = ip_dev_find(&init_net, *(__be32 *)peer_ip); pdev = __ip_dev_find(&init_net, *(__be32 *)peer_ip, false);
else if (IS_ENABLED(CONFIG_IPV6)) else if (IS_ENABLED(CONFIG_IPV6))
for_each_netdev(&init_net, pdev) { for_each_netdev(&init_net, pdev) {
if (ipv6_chk_addr(&init_net, if (ipv6_chk_addr(&init_net,
@@ -2056,12 +2058,12 @@ static int import_ep(struct c4iw_ep *ep, int iptype, __u8 *peer_ip,
err = -ENODEV; err = -ENODEV;
goto out; goto out;
} }
if (is_vlan_dev(pdev))
pdev = vlan_dev_real_dev(pdev);
ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t, ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t,
n, pdev, rt_tos2priority(tos)); n, pdev, rt_tos2priority(tos));
if (!ep->l2t) { if (!ep->l2t)
dev_put(pdev);
goto out; goto out;
}
ep->mtu = pdev->mtu; ep->mtu = pdev->mtu;
ep->tx_chan = cxgb4_port_chan(pdev); ep->tx_chan = cxgb4_port_chan(pdev);
ep->smac_idx = cxgb4_tp_smt_idx(adapter_type, ep->smac_idx = cxgb4_tp_smt_idx(adapter_type,
@@ -2075,7 +2077,6 @@ static int import_ep(struct c4iw_ep *ep, int iptype, __u8 *peer_ip,
ep->rss_qid = cdev->rdev.lldi.rxq_ids[ ep->rss_qid = cdev->rdev.lldi.rxq_ids[
cxgb4_port_idx(pdev) * step]; cxgb4_port_idx(pdev) * step];
set_tcp_window(ep, (struct port_info *)netdev_priv(pdev)); set_tcp_window(ep, (struct port_info *)netdev_priv(pdev));
dev_put(pdev);
} else { } else {
pdev = get_real_dev(n->dev); pdev = get_real_dev(n->dev);
ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t, ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t,
@@ -2235,6 +2236,9 @@ static int act_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
int ret = 0; int ret = 0;
ep = lookup_atid(t, atid); ep = lookup_atid(t, atid);
if (!ep)
return -EINVAL;
la = (struct sockaddr_in *)&ep->com.local_addr; la = (struct sockaddr_in *)&ep->com.local_addr;
ra = (struct sockaddr_in *)&ep->com.remote_addr; ra = (struct sockaddr_in *)&ep->com.remote_addr;
la6 = (struct sockaddr_in6 *)&ep->com.local_addr; la6 = (struct sockaddr_in6 *)&ep->com.local_addr;

View File

@@ -390,10 +390,17 @@ static int adp5589_gpio_get_value(struct gpio_chip *chip, unsigned off)
struct adp5589_kpad *kpad = gpiochip_get_data(chip); struct adp5589_kpad *kpad = gpiochip_get_data(chip);
unsigned int bank = kpad->var->bank(kpad->gpiomap[off]); unsigned int bank = kpad->var->bank(kpad->gpiomap[off]);
unsigned int bit = kpad->var->bit(kpad->gpiomap[off]); unsigned int bit = kpad->var->bit(kpad->gpiomap[off]);
int val;
return !!(adp5589_read(kpad->client, mutex_lock(&kpad->gpio_lock);
kpad->var->reg(ADP5589_GPI_STATUS_A) + bank) & if (kpad->dir[bank] & bit)
bit); val = kpad->dat_out[bank];
else
val = adp5589_read(kpad->client,
kpad->var->reg(ADP5589_GPI_STATUS_A) + bank);
mutex_unlock(&kpad->gpio_lock);
return !!(val & bit);
} }
static void adp5589_gpio_set_value(struct gpio_chip *chip, static void adp5589_gpio_set_value(struct gpio_chip *chip,

View File

@@ -981,12 +981,12 @@ static int rmi_driver_remove(struct device *dev)
rmi_disable_irq(rmi_dev, false); rmi_disable_irq(rmi_dev, false);
irq_domain_remove(data->irqdomain);
data->irqdomain = NULL;
rmi_f34_remove_sysfs(rmi_dev); rmi_f34_remove_sysfs(rmi_dev);
rmi_free_function_list(rmi_dev); rmi_free_function_list(rmi_dev);
irq_domain_remove(data->irqdomain);
data->irqdomain = NULL;
return 0; return 0;
} }

View File

@@ -152,7 +152,8 @@ static int bcm2835_mbox_probe(struct platform_device *pdev)
spin_lock_init(&mbox->lock); spin_lock_init(&mbox->lock);
ret = devm_request_irq(dev, irq_of_parse_and_map(dev->of_node, 0), ret = devm_request_irq(dev, irq_of_parse_and_map(dev->of_node, 0),
bcm2835_mbox_irq, 0, dev_name(dev), mbox); bcm2835_mbox_irq, IRQF_NO_SUSPEND, dev_name(dev),
mbox);
if (ret) { if (ret) {
dev_err(dev, "Failed to register a mailbox IRQ handler: %d\n", dev_err(dev, "Failed to register a mailbox IRQ handler: %d\n",
ret); ret);

View File

@@ -167,7 +167,7 @@ static const struct of_device_id rockchip_mbox_of_match[] = {
{ .compatible = "rockchip,rk3368-mailbox", .data = &rk3368_drv_data}, { .compatible = "rockchip,rk3368-mailbox", .data = &rk3368_drv_data},
{ }, { },
}; };
MODULE_DEVICE_TABLE(of, rockchp_mbox_of_match); MODULE_DEVICE_TABLE(of, rockchip_mbox_of_match);
static int rockchip_mbox_probe(struct platform_device *pdev) static int rockchip_mbox_probe(struct platform_device *pdev)
{ {

View File

@@ -281,6 +281,10 @@ static void __vb2_plane_dmabuf_put(struct vb2_buffer *vb, struct vb2_plane *p)
p->mem_priv = NULL; p->mem_priv = NULL;
p->dbuf = NULL; p->dbuf = NULL;
p->dbuf_mapped = 0; p->dbuf_mapped = 0;
p->bytesused = 0;
p->length = 0;
p->m.fd = 0;
p->data_offset = 0;
} }
/* /*
@@ -1169,10 +1173,6 @@ static int __prepare_dmabuf(struct vb2_buffer *vb, const void *pb)
/* Release previously acquired memory if present */ /* Release previously acquired memory if present */
__vb2_plane_dmabuf_put(vb, &vb->planes[plane]); __vb2_plane_dmabuf_put(vb, &vb->planes[plane]);
vb->planes[plane].bytesused = 0;
vb->planes[plane].length = 0;
vb->planes[plane].m.fd = 0;
vb->planes[plane].data_offset = 0;
/* Acquire each plane's memory */ /* Acquire each plane's memory */
mem_priv = call_ptr_memop(vb, attach_dmabuf, mem_priv = call_ptr_memop(vb, attach_dmabuf,

Some files were not shown because too many files have changed in this diff Show More