Merge 5.10.166 into android12-5.10-lts

Changes in 5.10.166
	clk: generalize devm_clk_get() a bit
	clk: Provide new devm_clk helpers for prepared and enabled clocks
	memory: atmel-sdramc: Fix missing clk_disable_unprepare in atmel_ramc_probe()
	memory: mvebu-devbus: Fix missing clk_disable_unprepare in mvebu_devbus_probe()
	ARM: dts: imx6ul-pico-dwarf: Use 'clock-frequency'
	ARM: dts: imx7d-pico: Use 'clock-frequency'
	ARM: dts: imx6qdl-gw560x: Remove incorrect 'uart-has-rtscts'
	arm64: dts: imx8mm-beacon: Fix ecspi2 pinmux
	ARM: imx: add missing of_node_put()
	HID: intel_ish-hid: Add check for ishtp_dma_tx_map
	EDAC/highbank: Fix memory leak in highbank_mc_probe()
	firmware: arm_scmi: Harden shared memory access in fetch_response
	firmware: arm_scmi: Harden shared memory access in fetch_notification
	tomoyo: fix broken dependency on *.conf.default
	RDMA/core: Fix ib block iterator counter overflow
	IB/hfi1: Reject a zero-length user expected buffer
	IB/hfi1: Reserve user expected TIDs
	IB/hfi1: Fix expected receive setup error exit issues
	IB/hfi1: Immediately remove invalid memory from hardware
	IB/hfi1: Remove user expected buffer invalidate race
	affs: initialize fsdata in affs_truncate()
	PM: AVS: qcom-cpr: Fix an error handling path in cpr_probe()
	phy: ti: fix Kconfig warning and operator precedence
	ARM: dts: at91: sam9x60: fix the ddr clock for sam9x60
	amd-xgbe: TX Flow Ctrl Registers are h/w ver dependent
	amd-xgbe: Delay AN timeout during KR training
	bpf: Fix pointer-leak due to insufficient speculative store bypass mitigation
	phy: rockchip-inno-usb2: Fix missing clk_disable_unprepare() in rockchip_usb2phy_power_on()
	net: nfc: Fix use-after-free in local_cleanup()
	net: wan: Add checks for NULL for utdm in undo_uhdlc_init and unmap_si_regs
	gpio: mxc: Always set GPIOs used as interrupt source to INPUT mode
	wifi: rndis_wlan: Prevent buffer overflow in rndis_query_oid
	net/sched: sch_taprio: fix possible use-after-free
	l2tp: Serialize access to sk_user_data with sk_callback_lock
	l2tp: Don't sleep and disable BH under writer-side sk_callback_lock
	l2tp: convert l2tp_tunnel_list to idr
	l2tp: close all race conditions in l2tp_tunnel_register()
	net: usb: sr9700: Handle negative len
	net: mdio: validate parameter addr in mdiobus_get_phy()
	HID: check empty report_list in hid_validate_values()
	HID: check empty report_list in bigben_probe()
	net: stmmac: fix invalid call to mdiobus_get_phy()
	HID: revert CHERRY_MOUSE_000C quirk
	usb: gadget: f_fs: Prevent race during ffs_ep0_queue_wait
	usb: gadget: f_fs: Ensure ep0req is dequeued before free_request
	net: mlx5: eliminate anonymous module_init & module_exit
	drm/panfrost: fix GENERIC_ATOMIC64 dependency
	dmaengine: Fix double increment of client_count in dma_chan_get()
	net: macb: fix PTP TX timestamp failure due to packet padding
	l2tp: prevent lockdep issue in l2tp_tunnel_register()
	HID: betop: check shape of output reports
	dmaengine: xilinx_dma: call of_node_put() when breaking out of for_each_child_of_node()
	nvme-pci: fix timeout request state check
	tcp: avoid the lookup process failing to get sk in ehash table
	w1: fix deadloop in __w1_remove_master_device()
	w1: fix WARNING after calling w1_process()
	driver core: Fix test_async_probe_init saves device in wrong array
	net: dsa: microchip: ksz9477: port map correction in ALU table entry register
	tcp: fix rate_app_limited to default to 1
	scsi: iscsi: Fix multiple iSCSI session unbind events sent to userspace
	cpufreq: Add Tegra234 to cpufreq-dt-platdev blocklist
	kcsan: test: don't put the expect array on the stack
	ASoC: fsl_micfil: Correct the number of steps on SX controls
	drm: Add orientation quirk for Lenovo ideapad D330-10IGL
	s390/debug: add _ASM_S390_ prefix to header guard
	cpufreq: armada-37xx: stop using 0 as NULL pointer
	ASoC: fsl_ssi: Rename AC'97 streams to avoid collisions with AC'97 CODEC
	ASoC: fsl-asoc-card: Fix naming of AC'97 CODEC widgets
	spi: spidev: remove debug messages that access spidev->spi without locking
	KVM: s390: interrupt: use READ_ONCE() before cmpxchg()
	scsi: hisi_sas: Set a port invalid only if there are no devices attached when refreshing port id
	platform/x86: touchscreen_dmi: Add info for the CSL Panther Tab HD
	platform/x86: asus-nb-wmi: Add alternate mapping for KEY_SCREENLOCK
	lockref: stop doing cpu_relax in the cmpxchg loop
	Revert "selftests/bpf: check null propagation only neither reg is PTR_TO_BTF_ID"
	netfilter: conntrack: do not renew entry stuck in tcp SYN_SENT state
	x86: ACPI: cstate: Optimize C3 entry on AMD CPUs
	fs: reiserfs: remove useless new_opts in reiserfs_remount
	sysctl: add a new register_sysctl_init() interface
	kernel/panic: move panic sysctls to its own file
	panic: unset panic_on_warn inside panic()
	ubsan: no need to unset panic_on_warn in ubsan_epilogue()
	kasan: no need to unset panic_on_warn in end_report()
	exit: Add and use make_task_dead.
	objtool: Add a missing comma to avoid string concatenation
	hexagon: Fix function name in die()
	h8300: Fix build errors from do_exit() to make_task_dead() transition
	csky: Fix function name in csky_alignment() and die()
	ia64: make IA64_MCA_RECOVERY bool instead of tristate
	panic: Separate sysctl logic from CONFIG_SMP
	exit: Put an upper limit on how often we can oops
	exit: Expose "oops_count" to sysfs
	exit: Allow oops_limit to be disabled
	panic: Consolidate open-coded panic_on_warn checks
	panic: Introduce warn_limit
	panic: Expose "warn_count" to sysfs
	docs: Fix path paste-o for /sys/kernel/warn_count
	exit: Use READ_ONCE() for all oops/warn limit reads
	Bluetooth: hci_sync: cancel cmd_timer if hci_open failed
	xhci: Set HCD flag to defer primary roothub registration
	scsi: hpsa: Fix allocation size for scsi_host_alloc()
	module: Don't wait for GOING modules
	tracing: Make sure trace_printk() can output as soon as it can be used
	trace_events_hist: add check for return value of 'create_hist_field'
	ftrace/scripts: Update the instructions for ftrace-bisect.sh
	cifs: Fix oops due to uncleared server->smbd_conn in reconnect
	KVM: x86/vmx: Do not skip segment attributes if unusable bit is set
	thermal: intel: int340x: Protect trip temperature from concurrent updates
	ARM: 9280/1: mm: fix warning on phys_addr_t to void pointer assignment
	EDAC/device: Respect any driver-supplied workqueue polling value
	EDAC/qcom: Do not pass llcc_driv_data as edac_device_ctl_info's pvt_info
	units: Add Watt units
	units: Add SI metric prefix definitions
	i2c: designware: Use DIV_ROUND_CLOSEST() macro
	i2c: designware: use casting of u64 in clock multiplication to avoid overflow
	netlink: prevent potential spectre v1 gadgets
	net: fix UaF in netns ops registration error path
	netfilter: nft_set_rbtree: Switch to node list walk for overlap detection
	netfilter: nft_set_rbtree: skip elements in transaction from garbage collection
	netlink: annotate data races around nlk->portid
	netlink: annotate data races around dst_portid and dst_group
	netlink: annotate data races around sk_state
	ipv4: prevent potential spectre v1 gadget in ip_metrics_convert()
	ipv4: prevent potential spectre v1 gadget in fib_metrics_match()
	netfilter: conntrack: fix vtag checks for ABORT/SHUTDOWN_COMPLETE
	netrom: Fix use-after-free of a listening socket.
	net/sched: sch_taprio: do not schedule in taprio_reset()
	sctp: fail if no bound addresses can be used for a given scope
	net: ravb: Fix possible hang if RIS2_QFF1 happen
	thermal: intel: int340x: Add locking to int340x_thermal_get_trip_type()
	net/tg3: resolve deadlock in tg3_reset_task() during EEH
	net: mdio-mux-meson-g12a: force internal PHY off on mux switch
	tools: gpio: fix -c option of gpio-event-mon
	Revert "Input: synaptics - switch touchpad on HP Laptop 15-da3001TU to RMI mode"
	nouveau: explicitly wait on the fence in nouveau_bo_move_m2mf
	nfsd: Ensure knfsd shuts down when the "nfsd" pseudofs is unmounted
	Revert "selftests/ftrace: Update synthetic event syntax errors"
	block: fix and cleanup bio_check_ro
	x86/i8259: Mark legacy PIC interrupts with IRQ_LEVEL
	netfilter: conntrack: unify established states for SCTP paths
	perf/x86/amd: fix potential integer overflow on shift of a int
	clk: Fix pointer casting to prevent oops in devm_clk_release()
	Linux 5.10.166

Change-Id: Ibf582f7504221c6ee1648da95c49b45e3678708c
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman
2023-02-16 14:07:30 +00:00
179 changed files with 1528 additions and 774 deletions

View File

@@ -0,0 +1,6 @@
What: /sys/kernel/oops_count
Date: November 2022
KernelVersion: 6.2.0
Contact: Linux Kernel Hardening List <linux-hardening@vger.kernel.org>
Description:
Shows how many times the system has Oopsed since last boot.

View File

@@ -0,0 +1,6 @@
What: /sys/kernel/warn_count
Date: November 2022
KernelVersion: 6.2.0
Contact: Linux Kernel Hardening List <linux-hardening@vger.kernel.org>
Description:
Shows how many times the system has Warned since last boot.

View File

@@ -663,6 +663,15 @@ This is the default behavior.
an oops event is detected. an oops event is detected.
oops_limit
==========
Number of kernel oopses after which the kernel should panic when
``panic_on_oops`` is not set. Setting this to 0 disables checking
the count. Setting this to 1 has the same effect as setting
``panic_on_oops=1``. The default value is 10000.
osrelease, ostype & version osrelease, ostype & version
=========================== ===========================
@@ -1469,6 +1478,16 @@ entry will default to 2 instead of 0.
2 Unprivileged calls to ``bpf()`` are disabled 2 Unprivileged calls to ``bpf()`` are disabled
= ============================================================= = =============================================================
warn_limit
==========
Number of kernel warnings after which the kernel should panic when
``panic_on_warn`` is not set. Setting this to 0 disables checking
the warning count. Setting this to 1 has the same effect as setting
``panic_on_warn=1``. The default value is 0.
watchdog watchdog
======== ========

View File

@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
VERSION = 5 VERSION = 5
PATCHLEVEL = 10 PATCHLEVEL = 10
SUBLEVEL = 165 SUBLEVEL = 166
EXTRAVERSION = EXTRAVERSION =
NAME = Dare mighty things NAME = Dare mighty things

View File

@@ -192,7 +192,7 @@ die_if_kernel(char * str, struct pt_regs *regs, long err, unsigned long *r9_15)
local_irq_enable(); local_irq_enable();
while (1); while (1);
} }
do_exit(SIGSEGV); make_task_dead(SIGSEGV);
} }
#ifndef CONFIG_MATHEMU #ifndef CONFIG_MATHEMU
@@ -577,7 +577,7 @@ do_entUna(void * va, unsigned long opcode, unsigned long reg,
printk("Bad unaligned kernel access at %016lx: %p %lx %lu\n", printk("Bad unaligned kernel access at %016lx: %p %lx %lu\n",
pc, va, opcode, reg); pc, va, opcode, reg);
do_exit(SIGSEGV); make_task_dead(SIGSEGV);
got_exception: got_exception:
/* Ok, we caught the exception, but we don't want it. Is there /* Ok, we caught the exception, but we don't want it. Is there
@@ -632,7 +632,7 @@ got_exception:
local_irq_enable(); local_irq_enable();
while (1); while (1);
} }
do_exit(SIGSEGV); make_task_dead(SIGSEGV);
} }
/* /*

View File

@@ -204,7 +204,7 @@ retry:
printk(KERN_ALERT "Unable to handle kernel paging request at " printk(KERN_ALERT "Unable to handle kernel paging request at "
"virtual address %016lx\n", address); "virtual address %016lx\n", address);
die_if_kernel("Oops", regs, cause, (unsigned long*)regs - 16); die_if_kernel("Oops", regs, cause, (unsigned long*)regs - 16);
do_exit(SIGKILL); make_task_dead(SIGKILL);
/* We ran out of memory, or some other thing happened to us that /* We ran out of memory, or some other thing happened to us that
made us unable to handle the page fault gracefully. */ made us unable to handle the page fault gracefully. */

View File

@@ -634,7 +634,6 @@
&uart1 { &uart1 {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart1>; pinctrl-0 = <&pinctrl_uart1>;
uart-has-rtscts;
rts-gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>; rts-gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>;
status = "okay"; status = "okay";
}; };

View File

@@ -32,7 +32,7 @@
}; };
&i2c2 { &i2c2 {
clock_frequency = <100000>; clock-frequency = <100000>;
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c2>; pinctrl-0 = <&pinctrl_i2c2>;
status = "okay"; status = "okay";

View File

@@ -32,7 +32,7 @@
}; };
&i2c1 { &i2c1 {
clock_frequency = <100000>; clock-frequency = <100000>;
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c1>; pinctrl-0 = <&pinctrl_i2c1>;
status = "okay"; status = "okay";
@@ -52,7 +52,7 @@
}; };
&i2c4 { &i2c4 {
clock_frequency = <100000>; clock-frequency = <100000>;
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c1>; pinctrl-0 = <&pinctrl_i2c1>;
status = "okay"; status = "okay";

View File

@@ -43,7 +43,7 @@
}; };
&i2c1 { &i2c1 {
clock_frequency = <100000>; clock-frequency = <100000>;
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c1>; pinctrl-0 = <&pinctrl_i2c1>;
status = "okay"; status = "okay";
@@ -64,7 +64,7 @@
}; };
&i2c2 { &i2c2 {
clock_frequency = <100000>; clock-frequency = <100000>;
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c2>; pinctrl-0 = <&pinctrl_i2c2>;
status = "okay"; status = "okay";

View File

@@ -567,7 +567,7 @@
mpddrc: mpddrc@ffffe800 { mpddrc: mpddrc@ffffe800 {
compatible = "microchip,sam9x60-ddramc", "atmel,sama5d3-ddramc"; compatible = "microchip,sam9x60-ddramc", "atmel,sama5d3-ddramc";
reg = <0xffffe800 0x200>; reg = <0xffffe800 0x200>;
clocks = <&pmc PMC_TYPE_SYSTEM 2>, <&pmc PMC_TYPE_CORE PMC_MCK>; clocks = <&pmc PMC_TYPE_SYSTEM 2>, <&pmc PMC_TYPE_PERIPHERAL 49>;
clock-names = "ddrck", "mpddr"; clock-names = "ddrck", "mpddr";
}; };

View File

@@ -348,7 +348,7 @@ static void oops_end(unsigned long flags, struct pt_regs *regs, int signr)
if (panic_on_oops) if (panic_on_oops)
panic("Fatal exception"); panic("Fatal exception");
if (signr) if (signr)
do_exit(signr); make_task_dead(signr);
} }
/* /*

View File

@@ -23,6 +23,7 @@ static int mx25_read_cpu_rev(void)
np = of_find_compatible_node(NULL, NULL, "fsl,imx25-iim"); np = of_find_compatible_node(NULL, NULL, "fsl,imx25-iim");
iim_base = of_iomap(np, 0); iim_base = of_iomap(np, 0);
of_node_put(np);
BUG_ON(!iim_base); BUG_ON(!iim_base);
rev = readl(iim_base + MXC_IIMSREV); rev = readl(iim_base + MXC_IIMSREV);
iounmap(iim_base); iounmap(iim_base);

View File

@@ -28,6 +28,7 @@ static int mx27_read_cpu_rev(void)
np = of_find_compatible_node(NULL, NULL, "fsl,imx27-ccm"); np = of_find_compatible_node(NULL, NULL, "fsl,imx27-ccm");
ccm_base = of_iomap(np, 0); ccm_base = of_iomap(np, 0);
of_node_put(np);
BUG_ON(!ccm_base); BUG_ON(!ccm_base);
/* /*
* now we have access to the IO registers. As we need * now we have access to the IO registers. As we need

View File

@@ -39,6 +39,7 @@ static int mx31_read_cpu_rev(void)
np = of_find_compatible_node(NULL, NULL, "fsl,imx31-iim"); np = of_find_compatible_node(NULL, NULL, "fsl,imx31-iim");
iim_base = of_iomap(np, 0); iim_base = of_iomap(np, 0);
of_node_put(np);
BUG_ON(!iim_base); BUG_ON(!iim_base);
/* read SREV register from IIM module */ /* read SREV register from IIM module */

View File

@@ -21,6 +21,7 @@ static int mx35_read_cpu_rev(void)
np = of_find_compatible_node(NULL, NULL, "fsl,imx35-iim"); np = of_find_compatible_node(NULL, NULL, "fsl,imx35-iim");
iim_base = of_iomap(np, 0); iim_base = of_iomap(np, 0);
of_node_put(np);
BUG_ON(!iim_base); BUG_ON(!iim_base);
rev = imx_readl(iim_base + MXC_IIMSREV); rev = imx_readl(iim_base + MXC_IIMSREV);

View File

@@ -28,6 +28,7 @@ static u32 imx5_read_srev_reg(const char *compat)
np = of_find_compatible_node(NULL, NULL, compat); np = of_find_compatible_node(NULL, NULL, compat);
iim_base = of_iomap(np, 0); iim_base = of_iomap(np, 0);
of_node_put(np);
WARN_ON(!iim_base); WARN_ON(!iim_base);
srev = readl(iim_base + IIM_SREV) & 0xff; srev = readl(iim_base + IIM_SREV) & 0xff;

View File

@@ -125,7 +125,7 @@ __do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
show_pte(KERN_ALERT, mm, addr); show_pte(KERN_ALERT, mm, addr);
die("Oops", regs, fsr); die("Oops", regs, fsr);
bust_spinlocks(0); bust_spinlocks(0);
do_exit(SIGKILL); make_task_dead(SIGKILL);
} }
/* /*

View File

@@ -161,7 +161,7 @@ void __init paging_init(const struct machine_desc *mdesc)
mpu_setup(); mpu_setup();
/* allocate the zero page. */ /* allocate the zero page. */
zero_page = memblock_alloc(PAGE_SIZE, PAGE_SIZE); zero_page = (void *)memblock_alloc(PAGE_SIZE, PAGE_SIZE);
if (!zero_page) if (!zero_page)
panic("%s: Failed to allocate %lu bytes align=0x%lx\n", panic("%s: Failed to allocate %lu bytes align=0x%lx\n",
__func__, PAGE_SIZE, PAGE_SIZE); __func__, PAGE_SIZE, PAGE_SIZE);

View File

@@ -70,7 +70,7 @@
&ecspi2 { &ecspi2 {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pinctrl_espi2>; pinctrl-0 = <&pinctrl_espi2>;
cs-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>; cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>;
status = "okay"; status = "okay";
eeprom@0 { eeprom@0 {
@@ -187,7 +187,7 @@
MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0x82 MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0x82
MX8MM_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI 0x82 MX8MM_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI 0x82
MX8MM_IOMUXC_ECSPI2_MISO_ECSPI2_MISO 0x82 MX8MM_IOMUXC_ECSPI2_MISO_ECSPI2_MISO 0x82
MX8MM_IOMUXC_ECSPI1_SS0_GPIO5_IO9 0x41 MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13 0x41
>; >;
}; };

View File

@@ -146,7 +146,7 @@ void die(const char *str, struct pt_regs *regs, int err)
raw_spin_unlock_irqrestore(&die_lock, flags); raw_spin_unlock_irqrestore(&die_lock, flags);
if (ret != NOTIFY_STOP) if (ret != NOTIFY_STOP)
do_exit(SIGSEGV); make_task_dead(SIGSEGV);
} }
static void arm64_show_signal(int signo, const char *str) static void arm64_show_signal(int signo, const char *str)

View File

@@ -299,7 +299,7 @@ static void die_kernel_fault(const char *msg, unsigned long addr,
show_pte(addr); show_pte(addr);
die("Oops", regs, esr); die("Oops", regs, esr);
bust_spinlocks(0); bust_spinlocks(0);
do_exit(SIGKILL); make_task_dead(SIGKILL);
} }
#ifdef CONFIG_KASAN_HW_TAGS #ifdef CONFIG_KASAN_HW_TAGS

View File

@@ -294,7 +294,7 @@ bad_area:
__func__, opcode, rz, rx, imm, addr); __func__, opcode, rz, rx, imm, addr);
show_regs(regs); show_regs(regs);
bust_spinlocks(0); bust_spinlocks(0);
do_exit(SIGKILL); make_task_dead(SIGKILL);
} }
force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)addr); force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)addr);

View File

@@ -111,7 +111,7 @@ void die(struct pt_regs *regs, const char *str)
if (panic_on_oops) if (panic_on_oops)
panic("Fatal exception"); panic("Fatal exception");
if (ret != NOTIFY_STOP) if (ret != NOTIFY_STOP)
do_exit(SIGSEGV); make_task_dead(SIGSEGV);
} }
void do_trap(struct pt_regs *regs, int signo, int code, unsigned long addr) void do_trap(struct pt_regs *regs, int signo, int code, unsigned long addr)

View File

@@ -17,6 +17,7 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/sched/debug.h> #include <linux/sched/debug.h>
#include <linux/sched/task.h>
#include <linux/mm_types.h> #include <linux/mm_types.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/errno.h> #include <linux/errno.h>
@@ -110,7 +111,7 @@ void die(const char *str, struct pt_regs *fp, unsigned long err)
dump(fp); dump(fp);
spin_unlock_irq(&die_lock); spin_unlock_irq(&die_lock);
do_exit(SIGSEGV); make_task_dead(SIGSEGV);
} }
static int kstack_depth_to_print = 24; static int kstack_depth_to_print = 24;

View File

@@ -51,7 +51,7 @@ asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
printk(" at virtual address %08lx\n", address); printk(" at virtual address %08lx\n", address);
if (!user_mode(regs)) if (!user_mode(regs))
die("Oops", regs, error_code); die("Oops", regs, error_code);
do_exit(SIGKILL); make_task_dead(SIGKILL);
return 1; return 1;
} }

View File

@@ -218,7 +218,7 @@ int die(const char *str, struct pt_regs *regs, long err)
panic("Fatal exception"); panic("Fatal exception");
oops_exit(); oops_exit();
do_exit(err); make_task_dead(err);
return 0; return 0;
} }

View File

@@ -361,7 +361,7 @@ config ARCH_PROC_KCORE_TEXT
depends on PROC_KCORE depends on PROC_KCORE
config IA64_MCA_RECOVERY config IA64_MCA_RECOVERY
tristate "MCA recovery from errors other than TLB." bool "MCA recovery from errors other than TLB."
config IA64_PALINFO config IA64_PALINFO
tristate "/proc/pal support" tristate "/proc/pal support"

View File

@@ -176,7 +176,7 @@ mca_handler_bh(unsigned long paddr, void *iip, unsigned long ipsr)
spin_unlock(&mca_bh_lock); spin_unlock(&mca_bh_lock);
/* This process is about to be killed itself */ /* This process is about to be killed itself */
do_exit(SIGKILL); make_task_dead(SIGKILL);
} }
/** /**

View File

@@ -85,7 +85,7 @@ die (const char *str, struct pt_regs *regs, long err)
if (panic_on_oops) if (panic_on_oops)
panic("Fatal exception"); panic("Fatal exception");
do_exit(SIGSEGV); make_task_dead(SIGSEGV);
return 0; return 0;
} }

View File

@@ -274,7 +274,7 @@ retry:
regs = NULL; regs = NULL;
bust_spinlocks(0); bust_spinlocks(0);
if (regs) if (regs)
do_exit(SIGKILL); make_task_dead(SIGKILL);
return; return;
out_of_memory: out_of_memory:

View File

@@ -1136,7 +1136,7 @@ void die_if_kernel (char *str, struct pt_regs *fp, int nr)
pr_crit("%s: %08x\n", str, nr); pr_crit("%s: %08x\n", str, nr);
show_registers(fp); show_registers(fp);
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
do_exit(SIGSEGV); make_task_dead(SIGSEGV);
} }
asmlinkage void set_esp0(unsigned long ssp) asmlinkage void set_esp0(unsigned long ssp)

View File

@@ -48,7 +48,7 @@ int send_fault_sig(struct pt_regs *regs)
pr_alert("Unable to handle kernel access"); pr_alert("Unable to handle kernel access");
pr_cont(" at virtual address %p\n", addr); pr_cont(" at virtual address %p\n", addr);
die_if_kernel("Oops", regs, 0 /*error_code*/); die_if_kernel("Oops", regs, 0 /*error_code*/);
do_exit(SIGKILL); make_task_dead(SIGKILL);
} }
return 1; return 1;

View File

@@ -44,10 +44,10 @@ void die(const char *str, struct pt_regs *fp, long err)
pr_warn("Oops: %s, sig: %ld\n", str, err); pr_warn("Oops: %s, sig: %ld\n", str, err);
show_regs(fp); show_regs(fp);
spin_unlock_irq(&die_lock); spin_unlock_irq(&die_lock);
/* do_exit() should take care of panic'ing from an interrupt /* make_task_dead() should take care of panic'ing from an interrupt
* context so we don't handle it here * context so we don't handle it here
*/ */
do_exit(err); make_task_dead(err);
} }
/* for user application debugging */ /* for user application debugging */

View File

@@ -413,7 +413,7 @@ void __noreturn die(const char *str, struct pt_regs *regs)
if (regs && kexec_should_crash(current)) if (regs && kexec_should_crash(current))
crash_kexec(regs); crash_kexec(regs);
do_exit(sig); make_task_dead(sig);
} }
extern struct exception_table_entry __start___dbe_table[]; extern struct exception_table_entry __start___dbe_table[];

View File

@@ -223,7 +223,7 @@ inline void handle_fpu_exception(struct pt_regs *regs)
} }
} else if (fpcsr & FPCSR_mskRIT) { } else if (fpcsr & FPCSR_mskRIT) {
if (!user_mode(regs)) if (!user_mode(regs))
do_exit(SIGILL); make_task_dead(SIGILL);
si_signo = SIGILL; si_signo = SIGILL;
} }

View File

@@ -185,7 +185,7 @@ void die(const char *str, struct pt_regs *regs, int err)
bust_spinlocks(0); bust_spinlocks(0);
spin_unlock_irq(&die_lock); spin_unlock_irq(&die_lock);
do_exit(SIGSEGV); make_task_dead(SIGSEGV);
} }
EXPORT_SYMBOL(die); EXPORT_SYMBOL(die);
@@ -289,7 +289,7 @@ void unhandled_interruption(struct pt_regs *regs)
pr_emerg("unhandled_interruption\n"); pr_emerg("unhandled_interruption\n");
show_regs(regs); show_regs(regs);
if (!user_mode(regs)) if (!user_mode(regs))
do_exit(SIGKILL); make_task_dead(SIGKILL);
force_sig(SIGKILL); force_sig(SIGKILL);
} }
@@ -300,7 +300,7 @@ void unhandled_exceptions(unsigned long entry, unsigned long addr,
addr, type); addr, type);
show_regs(regs); show_regs(regs);
if (!user_mode(regs)) if (!user_mode(regs))
do_exit(SIGKILL); make_task_dead(SIGKILL);
force_sig(SIGKILL); force_sig(SIGKILL);
} }
@@ -327,7 +327,7 @@ void do_revinsn(struct pt_regs *regs)
pr_emerg("Reserved Instruction\n"); pr_emerg("Reserved Instruction\n");
show_regs(regs); show_regs(regs);
if (!user_mode(regs)) if (!user_mode(regs))
do_exit(SIGILL); make_task_dead(SIGILL);
force_sig(SIGILL); force_sig(SIGILL);
} }

View File

@@ -37,10 +37,10 @@ void die(const char *str, struct pt_regs *regs, long err)
show_regs(regs); show_regs(regs);
spin_unlock_irq(&die_lock); spin_unlock_irq(&die_lock);
/* /*
* do_exit() should take care of panic'ing from an interrupt * make_task_dead() should take care of panic'ing from an interrupt
* context so we don't handle it here * context so we don't handle it here
*/ */
do_exit(err); make_task_dead(err);
} }
void _exception(int signo, struct pt_regs *regs, int code, unsigned long addr) void _exception(int signo, struct pt_regs *regs, int code, unsigned long addr)

View File

@@ -212,7 +212,7 @@ void die(const char *str, struct pt_regs *regs, long err)
__asm__ __volatile__("l.nop 1"); __asm__ __volatile__("l.nop 1");
do {} while (1); do {} while (1);
#endif #endif
do_exit(SIGSEGV); make_task_dead(SIGSEGV);
} }
/* This is normally the 'Oops' routine */ /* This is normally the 'Oops' routine */

View File

@@ -268,7 +268,7 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err)
panic("Fatal exception"); panic("Fatal exception");
oops_exit(); oops_exit();
do_exit(SIGSEGV); make_task_dead(SIGSEGV);
} }
/* gdb uses break 4,8 */ /* gdb uses break 4,8 */

View File

@@ -245,7 +245,7 @@ static void oops_end(unsigned long flags, struct pt_regs *regs,
if (panic_on_oops) if (panic_on_oops)
panic("Fatal exception"); panic("Fatal exception");
do_exit(signr); make_task_dead(signr);
} }
NOKPROBE_SYMBOL(oops_end); NOKPROBE_SYMBOL(oops_end);

View File

@@ -57,7 +57,7 @@ void die(struct pt_regs *regs, const char *str)
if (panic_on_oops) if (panic_on_oops)
panic("Fatal exception"); panic("Fatal exception");
if (ret != NOTIFY_STOP) if (ret != NOTIFY_STOP)
do_exit(SIGSEGV); make_task_dead(SIGSEGV);
} }
void do_trap(struct pt_regs *regs, int signo, int code, unsigned long addr) void do_trap(struct pt_regs *regs, int signo, int code, unsigned long addr)

View File

@@ -34,7 +34,7 @@ static inline void no_context(struct pt_regs *regs, unsigned long addr)
(addr < PAGE_SIZE) ? "NULL pointer dereference" : (addr < PAGE_SIZE) ? "NULL pointer dereference" :
"paging request", addr); "paging request", addr);
die(regs, "Oops"); die(regs, "Oops");
do_exit(SIGKILL); make_task_dead(SIGKILL);
} }
static inline void mm_fault_error(struct pt_regs *regs, unsigned long addr, vm_fault_t fault) static inline void mm_fault_error(struct pt_regs *regs, unsigned long addr, vm_fault_t fault)

View File

@@ -4,8 +4,8 @@
* *
* Copyright IBM Corp. 1999, 2020 * Copyright IBM Corp. 1999, 2020
*/ */
#ifndef DEBUG_H #ifndef _ASM_S390_DEBUG_H
#define DEBUG_H #define _ASM_S390_DEBUG_H
#include <linux/string.h> #include <linux/string.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
@@ -425,4 +425,4 @@ int debug_unregister_view(debug_info_t *id, struct debug_view *view);
#define PRINT_FATAL(x...) printk(KERN_DEBUG PRINTK_HEADER x) #define PRINT_FATAL(x...) printk(KERN_DEBUG PRINTK_HEADER x)
#endif /* DASD_DEBUG */ #endif /* DASD_DEBUG */
#endif /* DEBUG_H */ #endif /* _ASM_S390_DEBUG_H */

View File

@@ -214,5 +214,5 @@ void die(struct pt_regs *regs, const char *str)
if (panic_on_oops) if (panic_on_oops)
panic("Fatal exception: panic_on_oops"); panic("Fatal exception: panic_on_oops");
oops_exit(); oops_exit();
do_exit(SIGSEGV); make_task_dead(SIGSEGV);
} }

View File

@@ -178,7 +178,7 @@ void s390_handle_mcck(void)
"malfunction (code 0x%016lx).\n", mcck.mcck_code); "malfunction (code 0x%016lx).\n", mcck.mcck_code);
printk(KERN_EMERG "mcck: task: %s, pid: %d.\n", printk(KERN_EMERG "mcck: task: %s, pid: %d.\n",
current->comm, current->pid); current->comm, current->pid);
do_exit(SIGSEGV); make_task_dead(SIGSEGV);
} }
} }
EXPORT_SYMBOL_GPL(s390_handle_mcck); EXPORT_SYMBOL_GPL(s390_handle_mcck);

View File

@@ -81,8 +81,9 @@ static int sca_inject_ext_call(struct kvm_vcpu *vcpu, int src_id)
struct esca_block *sca = vcpu->kvm->arch.sca; struct esca_block *sca = vcpu->kvm->arch.sca;
union esca_sigp_ctrl *sigp_ctrl = union esca_sigp_ctrl *sigp_ctrl =
&(sca->cpu[vcpu->vcpu_id].sigp_ctrl); &(sca->cpu[vcpu->vcpu_id].sigp_ctrl);
union esca_sigp_ctrl new_val = {0}, old_val = *sigp_ctrl; union esca_sigp_ctrl new_val = {0}, old_val;
old_val = READ_ONCE(*sigp_ctrl);
new_val.scn = src_id; new_val.scn = src_id;
new_val.c = 1; new_val.c = 1;
old_val.c = 0; old_val.c = 0;
@@ -93,8 +94,9 @@ static int sca_inject_ext_call(struct kvm_vcpu *vcpu, int src_id)
struct bsca_block *sca = vcpu->kvm->arch.sca; struct bsca_block *sca = vcpu->kvm->arch.sca;
union bsca_sigp_ctrl *sigp_ctrl = union bsca_sigp_ctrl *sigp_ctrl =
&(sca->cpu[vcpu->vcpu_id].sigp_ctrl); &(sca->cpu[vcpu->vcpu_id].sigp_ctrl);
union bsca_sigp_ctrl new_val = {0}, old_val = *sigp_ctrl; union bsca_sigp_ctrl new_val = {0}, old_val;
old_val = READ_ONCE(*sigp_ctrl);
new_val.scn = src_id; new_val.scn = src_id;
new_val.c = 1; new_val.c = 1;
old_val.c = 0; old_val.c = 0;
@@ -124,16 +126,18 @@ static void sca_clear_ext_call(struct kvm_vcpu *vcpu)
struct esca_block *sca = vcpu->kvm->arch.sca; struct esca_block *sca = vcpu->kvm->arch.sca;
union esca_sigp_ctrl *sigp_ctrl = union esca_sigp_ctrl *sigp_ctrl =
&(sca->cpu[vcpu->vcpu_id].sigp_ctrl); &(sca->cpu[vcpu->vcpu_id].sigp_ctrl);
union esca_sigp_ctrl old = *sigp_ctrl; union esca_sigp_ctrl old;
old = READ_ONCE(*sigp_ctrl);
expect = old.value; expect = old.value;
rc = cmpxchg(&sigp_ctrl->value, old.value, 0); rc = cmpxchg(&sigp_ctrl->value, old.value, 0);
} else { } else {
struct bsca_block *sca = vcpu->kvm->arch.sca; struct bsca_block *sca = vcpu->kvm->arch.sca;
union bsca_sigp_ctrl *sigp_ctrl = union bsca_sigp_ctrl *sigp_ctrl =
&(sca->cpu[vcpu->vcpu_id].sigp_ctrl); &(sca->cpu[vcpu->vcpu_id].sigp_ctrl);
union bsca_sigp_ctrl old = *sigp_ctrl; union bsca_sigp_ctrl old;
old = READ_ONCE(*sigp_ctrl);
expect = old.value; expect = old.value;
rc = cmpxchg(&sigp_ctrl->value, old.value, 0); rc = cmpxchg(&sigp_ctrl->value, old.value, 0);
} }

View File

@@ -57,7 +57,7 @@ void die(const char *str, struct pt_regs *regs, long err)
if (panic_on_oops) if (panic_on_oops)
panic("Fatal exception"); panic("Fatal exception");
do_exit(SIGSEGV); make_task_dead(SIGSEGV);
} }
void die_if_kernel(const char *str, struct pt_regs *regs, long err) void die_if_kernel(const char *str, struct pt_regs *regs, long err)

View File

@@ -86,9 +86,7 @@ void __noreturn die_if_kernel(char *str, struct pt_regs *regs)
} }
printk("Instruction DUMP:"); printk("Instruction DUMP:");
instruction_dump ((unsigned long *) regs->pc); instruction_dump ((unsigned long *) regs->pc);
if(regs->psr & PSR_PS) make_task_dead((regs->psr & PSR_PS) ? SIGKILL : SIGSEGV);
do_exit(SIGKILL);
do_exit(SIGSEGV);
} }
void do_hw_interrupt(struct pt_regs *regs, unsigned long type) void do_hw_interrupt(struct pt_regs *regs, unsigned long type)

View File

@@ -2564,9 +2564,7 @@ void __noreturn die_if_kernel(char *str, struct pt_regs *regs)
} }
if (panic_on_oops) if (panic_on_oops)
panic("Fatal exception"); panic("Fatal exception");
if (regs->tstate & TSTATE_PRIV) make_task_dead((regs->tstate & TSTATE_PRIV)? SIGKILL : SIGSEGV);
do_exit(SIGKILL);
do_exit(SIGSEGV);
} }
EXPORT_SYMBOL(die_if_kernel); EXPORT_SYMBOL(die_if_kernel);

View File

@@ -1333,14 +1333,14 @@ SYM_CODE_START(asm_exc_nmi)
SYM_CODE_END(asm_exc_nmi) SYM_CODE_END(asm_exc_nmi)
.pushsection .text, "ax" .pushsection .text, "ax"
SYM_CODE_START(rewind_stack_do_exit) SYM_CODE_START(rewind_stack_and_make_dead)
/* Prevent any naive code from trying to unwind to our caller. */ /* Prevent any naive code from trying to unwind to our caller. */
xorl %ebp, %ebp xorl %ebp, %ebp
movl PER_CPU_VAR(cpu_current_top_of_stack), %esi movl PER_CPU_VAR(cpu_current_top_of_stack), %esi
leal -TOP_OF_KERNEL_STACK_PADDING-PTREGS_SIZE(%esi), %esp leal -TOP_OF_KERNEL_STACK_PADDING-PTREGS_SIZE(%esi), %esp
call do_exit call make_task_dead
1: jmp 1b 1: jmp 1b
SYM_CODE_END(rewind_stack_do_exit) SYM_CODE_END(rewind_stack_and_make_dead)
.popsection .popsection

View File

@@ -1509,7 +1509,7 @@ SYM_CODE_END(ignore_sysret)
#endif #endif
.pushsection .text, "ax" .pushsection .text, "ax"
SYM_CODE_START(rewind_stack_do_exit) SYM_CODE_START(rewind_stack_and_make_dead)
UNWIND_HINT_FUNC UNWIND_HINT_FUNC
/* Prevent any naive code from trying to unwind to our caller. */ /* Prevent any naive code from trying to unwind to our caller. */
xorl %ebp, %ebp xorl %ebp, %ebp
@@ -1518,6 +1518,6 @@ SYM_CODE_START(rewind_stack_do_exit)
leaq -PTREGS_SIZE(%rax), %rsp leaq -PTREGS_SIZE(%rax), %rsp
UNWIND_HINT_REGS UNWIND_HINT_REGS
call do_exit call make_task_dead
SYM_CODE_END(rewind_stack_do_exit) SYM_CODE_END(rewind_stack_and_make_dead)
.popsection .popsection

View File

@@ -976,7 +976,7 @@ static int __init amd_core_pmu_init(void)
* numbered counter following it. * numbered counter following it.
*/ */
for (i = 0; i < x86_pmu.num_counters - 1; i += 2) for (i = 0; i < x86_pmu.num_counters - 1; i += 2)
even_ctr_mask |= 1 << i; even_ctr_mask |= BIT_ULL(i);
pair_constraint = (struct event_constraint) pair_constraint = (struct event_constraint)
__EVENT_CONSTRAINT(0, even_ctr_mask, 0, __EVENT_CONSTRAINT(0, even_ctr_mask, 0,

View File

@@ -79,6 +79,21 @@ void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags,
*/ */
flags->bm_control = 0; flags->bm_control = 0;
} }
if (c->x86_vendor == X86_VENDOR_AMD && c->x86 >= 0x17) {
/*
* For all AMD Zen or newer CPUs that support C3, caches
* should not be flushed by software while entering C3
* type state. Set bm->check to 1 so that kernel doesn't
* need to execute cache flush operation.
*/
flags->bm_check = 1;
/*
* In current AMD C state implementation ARB_DIS is no longer
* used. So set bm_control to zero to indicate ARB_DIS is not
* required while entering C3 type state.
*/
flags->bm_control = 0;
}
} }
EXPORT_SYMBOL(acpi_processor_power_init_bm_check); EXPORT_SYMBOL(acpi_processor_power_init_bm_check);

View File

@@ -351,7 +351,7 @@ unsigned long oops_begin(void)
} }
NOKPROBE_SYMBOL(oops_begin); NOKPROBE_SYMBOL(oops_begin);
void __noreturn rewind_stack_do_exit(int signr); void __noreturn rewind_stack_and_make_dead(int signr);
void oops_end(unsigned long flags, struct pt_regs *regs, int signr) void oops_end(unsigned long flags, struct pt_regs *regs, int signr)
{ {
@@ -386,7 +386,7 @@ void oops_end(unsigned long flags, struct pt_regs *regs, int signr)
* reuse the task stack and that existing poisons are invalid. * reuse the task stack and that existing poisons are invalid.
*/ */
kasan_unpoison_task_stack(current); kasan_unpoison_task_stack(current);
rewind_stack_do_exit(signr); rewind_stack_and_make_dead(signr);
} }
NOKPROBE_SYMBOL(oops_end); NOKPROBE_SYMBOL(oops_end);

View File

@@ -114,6 +114,7 @@ static void make_8259A_irq(unsigned int irq)
disable_irq_nosync(irq); disable_irq_nosync(irq);
io_apic_irqs &= ~(1<<irq); io_apic_irqs &= ~(1<<irq);
irq_set_chip_and_handler(irq, &i8259A_chip, handle_level_irq); irq_set_chip_and_handler(irq, &i8259A_chip, handle_level_irq);
irq_set_status_flags(irq, IRQ_LEVEL);
enable_irq(irq); enable_irq(irq);
lapic_assign_legacy_vector(irq, true); lapic_assign_legacy_vector(irq, true);
} }

View File

@@ -65,8 +65,10 @@ void __init init_ISA_irqs(void)
legacy_pic->init(0); legacy_pic->init(0);
for (i = 0; i < nr_legacy_irqs(); i++) for (i = 0; i < nr_legacy_irqs(); i++) {
irq_set_chip_and_handler(i, chip, handle_level_irq); irq_set_chip_and_handler(i, chip, handle_level_irq);
irq_set_status_flags(i, IRQ_LEVEL);
}
} }
void __init init_IRQ(void) void __init init_IRQ(void)

View File

@@ -3332,18 +3332,15 @@ static u32 vmx_segment_access_rights(struct kvm_segment *var)
{ {
u32 ar; u32 ar;
if (var->unusable || !var->present) ar = var->type & 15;
ar = 1 << 16; ar |= (var->s & 1) << 4;
else { ar |= (var->dpl & 3) << 5;
ar = var->type & 15; ar |= (var->present & 1) << 7;
ar |= (var->s & 1) << 4; ar |= (var->avl & 1) << 12;
ar |= (var->dpl & 3) << 5; ar |= (var->l & 1) << 13;
ar |= (var->present & 1) << 7; ar |= (var->db & 1) << 14;
ar |= (var->avl & 1) << 12; ar |= (var->g & 1) << 15;
ar |= (var->l & 1) << 13; ar |= (var->unusable || !var->present) << 16;
ar |= (var->db & 1) << 14;
ar |= (var->g & 1) << 15;
}
return ar; return ar;
} }

View File

@@ -545,5 +545,5 @@ void die(const char * str, struct pt_regs * regs, long err)
if (panic_on_oops) if (panic_on_oops)
panic("Fatal exception"); panic("Fatal exception");
do_exit(err); make_task_dead(err);
} }

View File

@@ -706,9 +706,7 @@ static inline bool bio_check_ro(struct bio *bio, struct hd_struct *part)
if (op_is_flush(bio->bi_opf) && !bio_sectors(bio)) if (op_is_flush(bio->bi_opf) && !bio_sectors(bio))
return false; return false;
pr_warn("Trying to write to read-only block-device %s (partno %d)\n",
WARN_ONCE(1,
"Trying to write to read-only block-device %s (partno %d)\n",
bio_devname(bio, b), part->partno); bio_devname(bio, b), part->partno);
/* Older lvm-tools actually trigger this */ /* Older lvm-tools actually trigger this */
return false; return false;

View File

@@ -146,7 +146,7 @@ static int __init test_async_probe_init(void)
calltime = ktime_get(); calltime = ktime_get();
for_each_online_cpu(cpu) { for_each_online_cpu(cpu) {
nid = cpu_to_node(cpu); nid = cpu_to_node(cpu);
pdev = &sync_dev[sync_id]; pdev = &async_dev[async_id];
*pdev = test_platform_device_register_node("test_async_driver", *pdev = test_platform_device_register_node("test_async_driver",
async_id, async_id,

View File

@@ -4,42 +4,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) struct clk *devm_clk_get_optional(struct device *dev, const char *id)
{ {
struct clk *clk = devm_clk_get(dev, id); return __devm_clk_get(dev, id, clk_get_optional, NULL, NULL);
if (clk == ERR_PTR(-ENOENT))
return NULL;
return clk;
} }
EXPORT_SYMBOL(devm_clk_get_optional); 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;

View File

@@ -443,7 +443,7 @@ static int __init armada37xx_cpufreq_driver_init(void)
return -ENODEV; return -ENODEV;
} }
clk = clk_get(cpu_dev, 0); clk = clk_get(cpu_dev, NULL);
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
dev_err(cpu_dev, "Cannot get clock for CPU0\n"); dev_err(cpu_dev, "Cannot get clock for CPU0\n");
return PTR_ERR(clk); return PTR_ERR(clk);

View File

@@ -130,6 +130,7 @@ static const struct of_device_id blacklist[] __initconst = {
{ .compatible = "nvidia,tegra30", }, { .compatible = "nvidia,tegra30", },
{ .compatible = "nvidia,tegra124", }, { .compatible = "nvidia,tegra124", },
{ .compatible = "nvidia,tegra210", }, { .compatible = "nvidia,tegra210", },
{ .compatible = "nvidia,tegra234", },
{ .compatible = "qcom,apq8096", }, { .compatible = "qcom,apq8096", },
{ .compatible = "qcom,msm8996", }, { .compatible = "qcom,msm8996", },

View File

@@ -451,7 +451,8 @@ static int dma_chan_get(struct dma_chan *chan)
/* The channel is already in use, update client count */ /* The channel is already in use, update client count */
if (chan->client_count) { if (chan->client_count) {
__module_get(owner); __module_get(owner);
goto out; chan->client_count++;
return 0;
} }
if (!try_module_get(owner)) if (!try_module_get(owner))
@@ -470,11 +471,11 @@ static int dma_chan_get(struct dma_chan *chan)
goto err_out; goto err_out;
} }
chan->client_count++;
if (!dma_has_cap(DMA_PRIVATE, chan->device->cap_mask)) if (!dma_has_cap(DMA_PRIVATE, chan->device->cap_mask))
balance_ref_count(chan); balance_ref_count(chan);
out:
chan->client_count++;
return 0; return 0;
err_out: err_out:

View File

@@ -3119,8 +3119,10 @@ static int xilinx_dma_probe(struct platform_device *pdev)
/* Initialize the channels */ /* Initialize the channels */
for_each_child_of_node(node, child) { for_each_child_of_node(node, child) {
err = xilinx_dma_child_probe(xdev, child); err = xilinx_dma_child_probe(xdev, child);
if (err < 0) if (err < 0) {
of_node_put(child);
goto error; goto error;
}
} }
if (xdev->dma_config->dmatype == XDMA_TYPE_VDMA) { if (xdev->dma_config->dmatype == XDMA_TYPE_VDMA) {

View File

@@ -34,6 +34,9 @@
static DEFINE_MUTEX(device_ctls_mutex); static DEFINE_MUTEX(device_ctls_mutex);
static LIST_HEAD(edac_device_list); static LIST_HEAD(edac_device_list);
/* Default workqueue processing interval on this instance, in msecs */
#define DEFAULT_POLL_INTERVAL 1000
#ifdef CONFIG_EDAC_DEBUG #ifdef CONFIG_EDAC_DEBUG
static void edac_device_dump_device(struct edac_device_ctl_info *edac_dev) static void edac_device_dump_device(struct edac_device_ctl_info *edac_dev)
{ {
@@ -366,7 +369,7 @@ static void edac_device_workq_function(struct work_struct *work_req)
* whole one second to save timers firing all over the period * whole one second to save timers firing all over the period
* between integral seconds * between integral seconds
*/ */
if (edac_dev->poll_msec == 1000) if (edac_dev->poll_msec == DEFAULT_POLL_INTERVAL)
edac_queue_work(&edac_dev->work, round_jiffies_relative(edac_dev->delay)); edac_queue_work(&edac_dev->work, round_jiffies_relative(edac_dev->delay));
else else
edac_queue_work(&edac_dev->work, edac_dev->delay); edac_queue_work(&edac_dev->work, edac_dev->delay);
@@ -396,7 +399,7 @@ static void edac_device_workq_setup(struct edac_device_ctl_info *edac_dev,
* timers firing on sub-second basis, while they are happy * timers firing on sub-second basis, while they are happy
* to fire together on the 1 second exactly * to fire together on the 1 second exactly
*/ */
if (edac_dev->poll_msec == 1000) if (edac_dev->poll_msec == DEFAULT_POLL_INTERVAL)
edac_queue_work(&edac_dev->work, round_jiffies_relative(edac_dev->delay)); edac_queue_work(&edac_dev->work, round_jiffies_relative(edac_dev->delay));
else else
edac_queue_work(&edac_dev->work, edac_dev->delay); edac_queue_work(&edac_dev->work, edac_dev->delay);
@@ -430,7 +433,7 @@ void edac_device_reset_delay_period(struct edac_device_ctl_info *edac_dev,
edac_dev->delay = msecs_to_jiffies(msec); edac_dev->delay = msecs_to_jiffies(msec);
/* See comment in edac_device_workq_setup() above */ /* See comment in edac_device_workq_setup() above */
if (edac_dev->poll_msec == 1000) if (edac_dev->poll_msec == DEFAULT_POLL_INTERVAL)
edac_mod_work(&edac_dev->work, round_jiffies_relative(edac_dev->delay)); edac_mod_work(&edac_dev->work, round_jiffies_relative(edac_dev->delay));
else else
edac_mod_work(&edac_dev->work, edac_dev->delay); edac_mod_work(&edac_dev->work, edac_dev->delay);
@@ -472,11 +475,7 @@ int edac_device_add_device(struct edac_device_ctl_info *edac_dev)
/* This instance is NOW RUNNING */ /* This instance is NOW RUNNING */
edac_dev->op_state = OP_RUNNING_POLL; edac_dev->op_state = OP_RUNNING_POLL;
/* edac_device_workq_setup(edac_dev, edac_dev->poll_msec ?: DEFAULT_POLL_INTERVAL);
* enable workq processing on this instance,
* default = 1000 msec
*/
edac_device_workq_setup(edac_dev, 1000);
} else { } else {
edac_dev->op_state = OP_RUNNING_INTERRUPT; edac_dev->op_state = OP_RUNNING_INTERRUPT;
} }

View File

@@ -174,8 +174,10 @@ static int highbank_mc_probe(struct platform_device *pdev)
drvdata = mci->pvt_info; drvdata = mci->pvt_info;
platform_set_drvdata(pdev, mci); platform_set_drvdata(pdev, mci);
if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL)) if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL)) {
return -ENOMEM; res = -ENOMEM;
goto free;
}
r = platform_get_resource(pdev, IORESOURCE_MEM, 0); r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r) { if (!r) {
@@ -243,6 +245,7 @@ err2:
edac_mc_del_mc(&pdev->dev); edac_mc_del_mc(&pdev->dev);
err: err:
devres_release_group(&pdev->dev, NULL); devres_release_group(&pdev->dev, NULL);
free:
edac_mc_free(mci); edac_mc_free(mci);
return res; return res;
} }

View File

@@ -252,7 +252,7 @@ clear:
static int static int
dump_syn_reg(struct edac_device_ctl_info *edev_ctl, int err_type, u32 bank) dump_syn_reg(struct edac_device_ctl_info *edev_ctl, int err_type, u32 bank)
{ {
struct llcc_drv_data *drv = edev_ctl->pvt_info; struct llcc_drv_data *drv = edev_ctl->dev->platform_data;
int ret; int ret;
ret = dump_syn_reg_values(drv, bank, err_type); ret = dump_syn_reg_values(drv, bank, err_type);
@@ -289,7 +289,7 @@ static irqreturn_t
llcc_ecc_irq_handler(int irq, void *edev_ctl) llcc_ecc_irq_handler(int irq, void *edev_ctl)
{ {
struct edac_device_ctl_info *edac_dev_ctl = edev_ctl; struct edac_device_ctl_info *edac_dev_ctl = edev_ctl;
struct llcc_drv_data *drv = edac_dev_ctl->pvt_info; struct llcc_drv_data *drv = edac_dev_ctl->dev->platform_data;
irqreturn_t irq_rc = IRQ_NONE; irqreturn_t irq_rc = IRQ_NONE;
u32 drp_error, trp_error, i; u32 drp_error, trp_error, i;
int ret; int ret;
@@ -358,7 +358,6 @@ static int qcom_llcc_edac_probe(struct platform_device *pdev)
edev_ctl->dev_name = dev_name(dev); edev_ctl->dev_name = dev_name(dev);
edev_ctl->ctl_name = "llcc"; edev_ctl->ctl_name = "llcc";
edev_ctl->panic_on_ue = LLCC_ERP_PANIC_ON_UE; edev_ctl->panic_on_ue = LLCC_ERP_PANIC_ON_UE;
edev_ctl->pvt_info = llcc_driv_data;
rc = edac_device_add_device(edev_ctl); rc = edac_device_add_device(edev_ctl);
if (rc) if (rc)

View File

@@ -58,10 +58,11 @@ u32 shmem_read_header(struct scmi_shared_mem __iomem *shmem)
void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem, void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem,
struct scmi_xfer *xfer) struct scmi_xfer *xfer)
{ {
size_t len = ioread32(&shmem->length);
xfer->hdr.status = ioread32(shmem->msg_payload); xfer->hdr.status = ioread32(shmem->msg_payload);
/* Skip the length of header and status in shmem area i.e 8 bytes */ /* Skip the length of header and status in shmem area i.e 8 bytes */
xfer->rx.len = min_t(size_t, xfer->rx.len, xfer->rx.len = min_t(size_t, xfer->rx.len, len > 8 ? len - 8 : 0);
ioread32(&shmem->length) - 8);
/* Take a copy to the rx buffer.. */ /* Take a copy to the rx buffer.. */
memcpy_fromio(xfer->rx.buf, shmem->msg_payload + 4, xfer->rx.len); memcpy_fromio(xfer->rx.buf, shmem->msg_payload + 4, xfer->rx.len);
@@ -70,8 +71,10 @@ void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem,
void shmem_fetch_notification(struct scmi_shared_mem __iomem *shmem, void shmem_fetch_notification(struct scmi_shared_mem __iomem *shmem,
size_t max_len, struct scmi_xfer *xfer) size_t max_len, struct scmi_xfer *xfer)
{ {
size_t len = ioread32(&shmem->length);
/* Skip only the length of header in shmem area i.e 4 bytes */ /* Skip only the length of header in shmem area i.e 4 bytes */
xfer->rx.len = min_t(size_t, max_len, ioread32(&shmem->length) - 4); xfer->rx.len = min_t(size_t, max_len, len > 4 ? len - 4 : 0);
/* Take a copy to the rx buffer.. */ /* Take a copy to the rx buffer.. */
memcpy_fromio(xfer->rx.buf, shmem->msg_payload, xfer->rx.len); memcpy_fromio(xfer->rx.buf, shmem->msg_payload, xfer->rx.len);

View File

@@ -231,7 +231,7 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type)
writel(1 << gpio_idx, port->base + GPIO_ISR); writel(1 << gpio_idx, port->base + GPIO_ISR);
return 0; return port->gc.direction_input(&port->gc, gpio_idx);
} }
static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio) static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio)

View File

@@ -272,6 +272,12 @@ static const struct dmi_system_id orientation_data[] = {
DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad D330-10IGM"), DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad D330-10IGM"),
}, },
.driver_data = (void *)&lcd1200x1920_rightside_up, .driver_data = (void *)&lcd1200x1920_rightside_up,
}, { /* Lenovo Ideapad D330-10IGL (HD) */
.matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad D330-10IGL"),
},
.driver_data = (void *)&lcd800x1280_rightside_up,
}, { /* Lenovo Yoga Book X90F / X91F / X91L */ }, { /* Lenovo Yoga Book X90F / X91F / X91L */
.matches = { .matches = {
/* Non exact match to match all versions */ /* Non exact match to match all versions */

View File

@@ -823,6 +823,15 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr,
if (ret == 0) { if (ret == 0) {
ret = nouveau_fence_new(chan, false, &fence); ret = nouveau_fence_new(chan, false, &fence);
if (ret == 0) { if (ret == 0) {
/* TODO: figure out a better solution here
*
* wait on the fence here explicitly as going through
* ttm_bo_move_accel_cleanup somehow doesn't seem to do it.
*
* Without this the operation can timeout and we'll fallback to a
* software copy, which might take several minutes to finish.
*/
nouveau_fence_wait(fence, false, false);
ret = ttm_bo_move_accel_cleanup(bo, ret = ttm_bo_move_accel_cleanup(bo,
&fence->base, &fence->base,
evict, false, evict, false,

View File

@@ -3,7 +3,8 @@
config DRM_PANFROST config DRM_PANFROST
tristate "Panfrost (DRM support for ARM Mali Midgard/Bifrost GPUs)" tristate "Panfrost (DRM support for ARM Mali Midgard/Bifrost GPUs)"
depends on DRM depends on DRM
depends on ARM || ARM64 || (COMPILE_TEST && !GENERIC_ATOMIC64) depends on ARM || ARM64 || COMPILE_TEST
depends on !GENERIC_ATOMIC64 # for IOMMU_IO_PGTABLE_LPAE
depends on MMU depends on MMU
select DRM_SCHED select DRM_SCHED
select IOMMU_SUPPORT select IOMMU_SUPPORT

View File

@@ -60,7 +60,6 @@ static int betopff_init(struct hid_device *hid)
struct list_head *report_list = struct list_head *report_list =
&hid->report_enum[HID_OUTPUT_REPORT].report_list; &hid->report_enum[HID_OUTPUT_REPORT].report_list;
struct input_dev *dev; struct input_dev *dev;
int field_count = 0;
int error; int error;
int i, j; int i, j;
@@ -86,19 +85,21 @@ static int betopff_init(struct hid_device *hid)
* ----------------------------------------- * -----------------------------------------
* Do init them with default value. * Do init them with default value.
*/ */
if (report->maxfield < 4) {
hid_err(hid, "not enough fields in the report: %d\n",
report->maxfield);
return -ENODEV;
}
for (i = 0; i < report->maxfield; i++) { for (i = 0; i < report->maxfield; i++) {
if (report->field[i]->report_count < 1) {
hid_err(hid, "no values in the field\n");
return -ENODEV;
}
for (j = 0; j < report->field[i]->report_count; j++) { for (j = 0; j < report->field[i]->report_count; j++) {
report->field[i]->value[j] = 0x00; report->field[i]->value[j] = 0x00;
field_count++;
} }
} }
if (field_count < 4) {
hid_err(hid, "not enough fields in the report: %d\n",
field_count);
return -ENODEV;
}
betopff = kzalloc(sizeof(*betopff), GFP_KERNEL); betopff = kzalloc(sizeof(*betopff), GFP_KERNEL);
if (!betopff) if (!betopff)
return -ENOMEM; return -ENOMEM;

View File

@@ -344,6 +344,11 @@ static int bigben_probe(struct hid_device *hid,
} }
report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
if (list_empty(report_list)) {
hid_err(hid, "no output report found\n");
error = -ENODEV;
goto error_hw_stop;
}
bigben->report = list_entry(report_list->next, bigben->report = list_entry(report_list->next,
struct hid_report, list); struct hid_report, list);

View File

@@ -988,8 +988,8 @@ struct hid_report *hid_validate_values(struct hid_device *hid,
* Validating on id 0 means we should examine the first * Validating on id 0 means we should examine the first
* report in the list. * report in the list.
*/ */
report = list_entry( report = list_first_entry_or_null(
hid->report_enum[type].report_list.next, &hid->report_enum[type].report_list,
struct hid_report, list); struct hid_report, list);
} else { } else {
report = hid->report_enum[type].report_id_hash[id]; report = hid->report_enum[type].report_id_hash[id];

View File

@@ -257,7 +257,6 @@
#define USB_DEVICE_ID_CH_AXIS_295 0x001c #define USB_DEVICE_ID_CH_AXIS_295 0x001c
#define USB_VENDOR_ID_CHERRY 0x046a #define USB_VENDOR_ID_CHERRY 0x046a
#define USB_DEVICE_ID_CHERRY_MOUSE_000C 0x000c
#define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023 #define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023
#define USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR 0x0027 #define USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR 0x0027

View File

@@ -54,7 +54,6 @@ static const struct hid_device_id hid_quirks[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE), HID_QUIRK_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE), HID_QUIRK_NOGET },
{ HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_PEDALS), HID_QUIRK_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_PEDALS), HID_QUIRK_NOGET },
{ HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_THROTTLE), HID_QUIRK_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_THROTTLE), HID_QUIRK_NOGET },
{ HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_MOUSE_000C), HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB), HID_QUIRK_NO_INIT_REPORTS }, { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB), HID_QUIRK_NO_INIT_REPORTS },
{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB_RAPIDFIRE), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB_RAPIDFIRE), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70RGB), HID_QUIRK_NO_INIT_REPORTS }, { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70RGB), HID_QUIRK_NO_INIT_REPORTS },

View File

@@ -104,6 +104,11 @@ void *ishtp_cl_get_dma_send_buf(struct ishtp_device *dev,
int required_slots = (size / DMA_SLOT_SIZE) int required_slots = (size / DMA_SLOT_SIZE)
+ 1 * (size % DMA_SLOT_SIZE != 0); + 1 * (size % DMA_SLOT_SIZE != 0);
if (!dev->ishtp_dma_tx_map) {
dev_err(dev->devc, "Fail to allocate Tx map\n");
return NULL;
}
spin_lock_irqsave(&dev->ishtp_dma_tx_lock, flags); spin_lock_irqsave(&dev->ishtp_dma_tx_lock, flags);
for (i = 0; i <= (dev->ishtp_dma_num_slots - required_slots); i++) { for (i = 0; i <= (dev->ishtp_dma_num_slots - required_slots); i++) {
free = 1; free = 1;
@@ -150,6 +155,11 @@ void ishtp_cl_release_dma_acked_mem(struct ishtp_device *dev,
return; return;
} }
if (!dev->ishtp_dma_tx_map) {
dev_err(dev->devc, "Fail to allocate Tx map\n");
return;
}
i = (msg_addr - dev->ishtp_host_dma_tx_buf) / DMA_SLOT_SIZE; i = (msg_addr - dev->ishtp_host_dma_tx_buf) / DMA_SLOT_SIZE;
spin_lock_irqsave(&dev->ishtp_dma_tx_lock, flags); spin_lock_irqsave(&dev->ishtp_dma_tx_lock, flags);
for (j = 0; j < acked_slots; j++) { for (j = 0; j < acked_slots; j++) {

View File

@@ -24,6 +24,7 @@
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/swab.h> #include <linux/swab.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/units.h>
#include "i2c-designware-core.h" #include "i2c-designware-core.h"
@@ -347,7 +348,8 @@ u32 i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset)
* *
* If your hardware is free from tHD;STA issue, try this one. * If your hardware is free from tHD;STA issue, try this one.
*/ */
return (ic_clk * tSYMBOL + 500000) / 1000000 - 8 + offset; return DIV_ROUND_CLOSEST_ULL((u64)ic_clk * tSYMBOL, MICRO) -
8 + offset;
else else
/* /*
* Conditional expression: * Conditional expression:
@@ -363,8 +365,8 @@ u32 i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset)
* The reason why we need to take into account "tf" here, * The reason why we need to take into account "tf" here,
* is the same as described in i2c_dw_scl_lcnt(). * is the same as described in i2c_dw_scl_lcnt().
*/ */
return (ic_clk * (tSYMBOL + tf) + 500000) / 1000000 return DIV_ROUND_CLOSEST_ULL((u64)ic_clk * (tSYMBOL + tf), MICRO) -
- 3 + offset; 3 + offset;
} }
u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset) u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset)
@@ -380,7 +382,8 @@ u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset)
* account the fall time of SCL signal (tf). Default tf value * account the fall time of SCL signal (tf). Default tf value
* should be 0.3 us, for safety. * should be 0.3 us, for safety.
*/ */
return ((ic_clk * (tLOW + tf) + 500000) / 1000000) - 1 + offset; return DIV_ROUND_CLOSEST_ULL((u64)ic_clk * (tLOW + tf), MICRO) -
1 + offset;
} }
int i2c_dw_set_sda_hold(struct dw_i2c_dev *dev) int i2c_dw_set_sda_hold(struct dw_i2c_dev *dev)

View File

@@ -32,12 +32,13 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/suspend.h> #include <linux/suspend.h>
#include <linux/units.h>
#include "i2c-designware-core.h" #include "i2c-designware-core.h"
static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev) static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev)
{ {
return clk_get_rate(dev->clk)/1000; return clk_get_rate(dev->clk) / KILO;
} }
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
@@ -284,7 +285,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
if (!dev->sda_hold_time && t->sda_hold_ns) if (!dev->sda_hold_time && t->sda_hold_ns)
dev->sda_hold_time = dev->sda_hold_time =
div_u64(clk_khz * t->sda_hold_ns + 500000, 1000000); DIV_S64_ROUND_CLOSEST(clk_khz * t->sda_hold_ns, MICRO);
} }
adap = &dev->adapter; adap = &dev->adapter;

View File

@@ -2911,15 +2911,18 @@ EXPORT_SYMBOL(__rdma_block_iter_start);
bool __rdma_block_iter_next(struct ib_block_iter *biter) bool __rdma_block_iter_next(struct ib_block_iter *biter)
{ {
unsigned int block_offset; unsigned int block_offset;
unsigned int sg_delta;
if (!biter->__sg_nents || !biter->__sg) if (!biter->__sg_nents || !biter->__sg)
return false; return false;
biter->__dma_addr = sg_dma_address(biter->__sg) + biter->__sg_advance; biter->__dma_addr = sg_dma_address(biter->__sg) + biter->__sg_advance;
block_offset = biter->__dma_addr & (BIT_ULL(biter->__pg_bit) - 1); block_offset = biter->__dma_addr & (BIT_ULL(biter->__pg_bit) - 1);
biter->__sg_advance += BIT_ULL(biter->__pg_bit) - block_offset; sg_delta = BIT_ULL(biter->__pg_bit) - block_offset;
if (biter->__sg_advance >= sg_dma_len(biter->__sg)) { if (sg_dma_len(biter->__sg) - biter->__sg_advance > sg_delta) {
biter->__sg_advance += sg_delta;
} else {
biter->__sg_advance = 0; biter->__sg_advance = 0;
biter->__sg = sg_next(biter->__sg); biter->__sg = sg_next(biter->__sg);
biter->__sg_nents--; biter->__sg_nents--;

View File

@@ -65,18 +65,25 @@ static void cacheless_tid_rb_remove(struct hfi1_filedata *fdata,
static bool tid_rb_invalidate(struct mmu_interval_notifier *mni, static bool tid_rb_invalidate(struct mmu_interval_notifier *mni,
const struct mmu_notifier_range *range, const struct mmu_notifier_range *range,
unsigned long cur_seq); unsigned long cur_seq);
static bool tid_cover_invalidate(struct mmu_interval_notifier *mni,
const struct mmu_notifier_range *range,
unsigned long cur_seq);
static int program_rcvarray(struct hfi1_filedata *fd, struct tid_user_buf *, static int program_rcvarray(struct hfi1_filedata *fd, struct tid_user_buf *,
struct tid_group *grp, struct tid_group *grp,
unsigned int start, u16 count, unsigned int start, u16 count,
u32 *tidlist, unsigned int *tididx, u32 *tidlist, unsigned int *tididx,
unsigned int *pmapped); unsigned int *pmapped);
static int unprogram_rcvarray(struct hfi1_filedata *fd, u32 tidinfo, static int unprogram_rcvarray(struct hfi1_filedata *fd, u32 tidinfo);
struct tid_group **grp); static void __clear_tid_node(struct hfi1_filedata *fd,
struct tid_rb_node *node);
static void clear_tid_node(struct hfi1_filedata *fd, struct tid_rb_node *node); static void clear_tid_node(struct hfi1_filedata *fd, struct tid_rb_node *node);
static const struct mmu_interval_notifier_ops tid_mn_ops = { static const struct mmu_interval_notifier_ops tid_mn_ops = {
.invalidate = tid_rb_invalidate, .invalidate = tid_rb_invalidate,
}; };
static const struct mmu_interval_notifier_ops tid_cover_ops = {
.invalidate = tid_cover_invalidate,
};
/* /*
* Initialize context and file private data needed for Expected * Initialize context and file private data needed for Expected
@@ -295,53 +302,65 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd,
tididx = 0, mapped, mapped_pages = 0; tididx = 0, mapped, mapped_pages = 0;
u32 *tidlist = NULL; u32 *tidlist = NULL;
struct tid_user_buf *tidbuf; struct tid_user_buf *tidbuf;
unsigned long mmu_seq = 0;
if (!PAGE_ALIGNED(tinfo->vaddr)) if (!PAGE_ALIGNED(tinfo->vaddr))
return -EINVAL; return -EINVAL;
if (tinfo->length == 0)
return -EINVAL;
tidbuf = kzalloc(sizeof(*tidbuf), GFP_KERNEL); tidbuf = kzalloc(sizeof(*tidbuf), GFP_KERNEL);
if (!tidbuf) if (!tidbuf)
return -ENOMEM; return -ENOMEM;
mutex_init(&tidbuf->cover_mutex);
tidbuf->vaddr = tinfo->vaddr; tidbuf->vaddr = tinfo->vaddr;
tidbuf->length = tinfo->length; tidbuf->length = tinfo->length;
tidbuf->psets = kcalloc(uctxt->expected_count, sizeof(*tidbuf->psets), tidbuf->psets = kcalloc(uctxt->expected_count, sizeof(*tidbuf->psets),
GFP_KERNEL); GFP_KERNEL);
if (!tidbuf->psets) { if (!tidbuf->psets) {
kfree(tidbuf); ret = -ENOMEM;
return -ENOMEM; goto fail_release_mem;
}
if (fd->use_mn) {
ret = mmu_interval_notifier_insert(
&tidbuf->notifier, current->mm,
tidbuf->vaddr, tidbuf->npages * PAGE_SIZE,
&tid_cover_ops);
if (ret)
goto fail_release_mem;
mmu_seq = mmu_interval_read_begin(&tidbuf->notifier);
} }
pinned = pin_rcv_pages(fd, tidbuf); pinned = pin_rcv_pages(fd, tidbuf);
if (pinned <= 0) { if (pinned <= 0) {
kfree(tidbuf->psets); ret = (pinned < 0) ? pinned : -ENOSPC;
kfree(tidbuf); goto fail_unpin;
return pinned;
} }
/* Find sets of physically contiguous pages */ /* Find sets of physically contiguous pages */
tidbuf->n_psets = find_phys_blocks(tidbuf, pinned); tidbuf->n_psets = find_phys_blocks(tidbuf, pinned);
/* /* Reserve the number of expected tids to be used. */
* We don't need to access this under a lock since tid_used is per
* process and the same process cannot be in hfi1_user_exp_rcv_clear()
* and hfi1_user_exp_rcv_setup() at the same time.
*/
spin_lock(&fd->tid_lock); spin_lock(&fd->tid_lock);
if (fd->tid_used + tidbuf->n_psets > fd->tid_limit) if (fd->tid_used + tidbuf->n_psets > fd->tid_limit)
pageset_count = fd->tid_limit - fd->tid_used; pageset_count = fd->tid_limit - fd->tid_used;
else else
pageset_count = tidbuf->n_psets; pageset_count = tidbuf->n_psets;
fd->tid_used += pageset_count;
spin_unlock(&fd->tid_lock); spin_unlock(&fd->tid_lock);
if (!pageset_count) if (!pageset_count) {
goto bail; ret = -ENOSPC;
goto fail_unreserve;
}
ngroups = pageset_count / dd->rcv_entries.group_size; ngroups = pageset_count / dd->rcv_entries.group_size;
tidlist = kcalloc(pageset_count, sizeof(*tidlist), GFP_KERNEL); tidlist = kcalloc(pageset_count, sizeof(*tidlist), GFP_KERNEL);
if (!tidlist) { if (!tidlist) {
ret = -ENOMEM; ret = -ENOMEM;
goto nomem; goto fail_unreserve;
} }
tididx = 0; tididx = 0;
@@ -437,43 +456,78 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd,
} }
unlock: unlock:
mutex_unlock(&uctxt->exp_mutex); mutex_unlock(&uctxt->exp_mutex);
nomem:
hfi1_cdbg(TID, "total mapped: tidpairs:%u pages:%u (%d)", tididx, hfi1_cdbg(TID, "total mapped: tidpairs:%u pages:%u (%d)", tididx,
mapped_pages, ret); mapped_pages, ret);
if (tididx) {
spin_lock(&fd->tid_lock);
fd->tid_used += tididx;
spin_unlock(&fd->tid_lock);
tinfo->tidcnt = tididx;
tinfo->length = mapped_pages * PAGE_SIZE;
if (copy_to_user(u64_to_user_ptr(tinfo->tidlist), /* fail if nothing was programmed, set error if none provided */
tidlist, sizeof(tidlist[0]) * tididx)) { if (tididx == 0) {
/* if (ret >= 0)
* On failure to copy to the user level, we need to undo ret = -ENOSPC;
* everything done so far so we don't leak resources. goto fail_unreserve;
*/ }
tinfo->tidlist = (unsigned long)&tidlist;
hfi1_user_exp_rcv_clear(fd, tinfo); /* adjust reserved tid_used to actual count */
tinfo->tidlist = 0; spin_lock(&fd->tid_lock);
ret = -EFAULT; fd->tid_used -= pageset_count - tididx;
goto bail; spin_unlock(&fd->tid_lock);
/* unpin all pages not covered by a TID */
unpin_rcv_pages(fd, tidbuf, NULL, mapped_pages, pinned - mapped_pages,
false);
if (fd->use_mn) {
/* check for an invalidate during setup */
bool fail = false;
mutex_lock(&tidbuf->cover_mutex);
fail = mmu_interval_read_retry(&tidbuf->notifier, mmu_seq);
mutex_unlock(&tidbuf->cover_mutex);
if (fail) {
ret = -EBUSY;
goto fail_unprogram;
} }
} }
/* tinfo->tidcnt = tididx;
* If not everything was mapped (due to insufficient RcvArray entries, tinfo->length = mapped_pages * PAGE_SIZE;
* for example), unpin all unmapped pages so we can pin them nex time.
*/ if (copy_to_user(u64_to_user_ptr(tinfo->tidlist),
if (mapped_pages != pinned) tidlist, sizeof(tidlist[0]) * tididx)) {
unpin_rcv_pages(fd, tidbuf, NULL, mapped_pages, ret = -EFAULT;
(pinned - mapped_pages), false); goto fail_unprogram;
bail: }
kfree(tidbuf->psets);
kfree(tidlist); if (fd->use_mn)
mmu_interval_notifier_remove(&tidbuf->notifier);
kfree(tidbuf->pages); kfree(tidbuf->pages);
kfree(tidbuf->psets);
kfree(tidbuf); kfree(tidbuf);
return ret > 0 ? 0 : ret; kfree(tidlist);
return 0;
fail_unprogram:
/* unprogram, unmap, and unpin all allocated TIDs */
tinfo->tidlist = (unsigned long)tidlist;
hfi1_user_exp_rcv_clear(fd, tinfo);
tinfo->tidlist = 0;
pinned = 0; /* nothing left to unpin */
pageset_count = 0; /* nothing left reserved */
fail_unreserve:
spin_lock(&fd->tid_lock);
fd->tid_used -= pageset_count;
spin_unlock(&fd->tid_lock);
fail_unpin:
if (fd->use_mn)
mmu_interval_notifier_remove(&tidbuf->notifier);
if (pinned > 0)
unpin_rcv_pages(fd, tidbuf, NULL, 0, pinned, false);
fail_release_mem:
kfree(tidbuf->pages);
kfree(tidbuf->psets);
kfree(tidbuf);
kfree(tidlist);
return ret;
} }
int hfi1_user_exp_rcv_clear(struct hfi1_filedata *fd, int hfi1_user_exp_rcv_clear(struct hfi1_filedata *fd,
@@ -494,7 +548,7 @@ int hfi1_user_exp_rcv_clear(struct hfi1_filedata *fd,
mutex_lock(&uctxt->exp_mutex); mutex_lock(&uctxt->exp_mutex);
for (tididx = 0; tididx < tinfo->tidcnt; tididx++) { for (tididx = 0; tididx < tinfo->tidcnt; tididx++) {
ret = unprogram_rcvarray(fd, tidinfo[tididx], NULL); ret = unprogram_rcvarray(fd, tidinfo[tididx]);
if (ret) { if (ret) {
hfi1_cdbg(TID, "Failed to unprogram rcv array %d", hfi1_cdbg(TID, "Failed to unprogram rcv array %d",
ret); ret);
@@ -750,6 +804,7 @@ static int set_rcvarray_entry(struct hfi1_filedata *fd,
} }
node->fdata = fd; node->fdata = fd;
mutex_init(&node->invalidate_mutex);
node->phys = page_to_phys(pages[0]); node->phys = page_to_phys(pages[0]);
node->npages = npages; node->npages = npages;
node->rcventry = rcventry; node->rcventry = rcventry;
@@ -765,11 +820,6 @@ static int set_rcvarray_entry(struct hfi1_filedata *fd,
&tid_mn_ops); &tid_mn_ops);
if (ret) if (ret)
goto out_unmap; goto out_unmap;
/*
* FIXME: This is in the wrong order, the notifier should be
* established before the pages are pinned by pin_rcv_pages.
*/
mmu_interval_read_begin(&node->notifier);
} }
fd->entry_to_rb[node->rcventry - uctxt->expected_base] = node; fd->entry_to_rb[node->rcventry - uctxt->expected_base] = node;
@@ -789,8 +839,7 @@ out_unmap:
return -EFAULT; return -EFAULT;
} }
static int unprogram_rcvarray(struct hfi1_filedata *fd, u32 tidinfo, static int unprogram_rcvarray(struct hfi1_filedata *fd, u32 tidinfo)
struct tid_group **grp)
{ {
struct hfi1_ctxtdata *uctxt = fd->uctxt; struct hfi1_ctxtdata *uctxt = fd->uctxt;
struct hfi1_devdata *dd = uctxt->dd; struct hfi1_devdata *dd = uctxt->dd;
@@ -813,9 +862,6 @@ static int unprogram_rcvarray(struct hfi1_filedata *fd, u32 tidinfo,
if (!node || node->rcventry != (uctxt->expected_base + rcventry)) if (!node || node->rcventry != (uctxt->expected_base + rcventry))
return -EBADF; return -EBADF;
if (grp)
*grp = node->grp;
if (fd->use_mn) if (fd->use_mn)
mmu_interval_notifier_remove(&node->notifier); mmu_interval_notifier_remove(&node->notifier);
cacheless_tid_rb_remove(fd, node); cacheless_tid_rb_remove(fd, node);
@@ -823,23 +869,34 @@ static int unprogram_rcvarray(struct hfi1_filedata *fd, u32 tidinfo,
return 0; return 0;
} }
static void clear_tid_node(struct hfi1_filedata *fd, struct tid_rb_node *node) static void __clear_tid_node(struct hfi1_filedata *fd, struct tid_rb_node *node)
{ {
struct hfi1_ctxtdata *uctxt = fd->uctxt; struct hfi1_ctxtdata *uctxt = fd->uctxt;
struct hfi1_devdata *dd = uctxt->dd; struct hfi1_devdata *dd = uctxt->dd;
mutex_lock(&node->invalidate_mutex);
if (node->freed)
goto done;
node->freed = true;
trace_hfi1_exp_tid_unreg(uctxt->ctxt, fd->subctxt, node->rcventry, trace_hfi1_exp_tid_unreg(uctxt->ctxt, fd->subctxt, node->rcventry,
node->npages, node->npages,
node->notifier.interval_tree.start, node->phys, node->notifier.interval_tree.start, node->phys,
node->dma_addr); node->dma_addr);
/* /* Make sure device has seen the write before pages are unpinned */
* Make sure device has seen the write before we unpin the
* pages.
*/
hfi1_put_tid(dd, node->rcventry, PT_INVALID_FLUSH, 0, 0); hfi1_put_tid(dd, node->rcventry, PT_INVALID_FLUSH, 0, 0);
unpin_rcv_pages(fd, NULL, node, 0, node->npages, true); unpin_rcv_pages(fd, NULL, node, 0, node->npages, true);
done:
mutex_unlock(&node->invalidate_mutex);
}
static void clear_tid_node(struct hfi1_filedata *fd, struct tid_rb_node *node)
{
struct hfi1_ctxtdata *uctxt = fd->uctxt;
__clear_tid_node(fd, node);
node->grp->used--; node->grp->used--;
node->grp->map &= ~(1 << (node->rcventry - node->grp->base)); node->grp->map &= ~(1 << (node->rcventry - node->grp->base));
@@ -898,10 +955,16 @@ static bool tid_rb_invalidate(struct mmu_interval_notifier *mni,
if (node->freed) if (node->freed)
return true; return true;
/* take action only if unmapping */
if (range->event != MMU_NOTIFY_UNMAP)
return true;
trace_hfi1_exp_tid_inval(uctxt->ctxt, fdata->subctxt, trace_hfi1_exp_tid_inval(uctxt->ctxt, fdata->subctxt,
node->notifier.interval_tree.start, node->notifier.interval_tree.start,
node->rcventry, node->npages, node->dma_addr); node->rcventry, node->npages, node->dma_addr);
node->freed = true;
/* clear the hardware rcvarray entry */
__clear_tid_node(fdata, node);
spin_lock(&fdata->invalid_lock); spin_lock(&fdata->invalid_lock);
if (fdata->invalid_tid_idx < uctxt->expected_count) { if (fdata->invalid_tid_idx < uctxt->expected_count) {
@@ -931,6 +994,23 @@ static bool tid_rb_invalidate(struct mmu_interval_notifier *mni,
return true; return true;
} }
static bool tid_cover_invalidate(struct mmu_interval_notifier *mni,
const struct mmu_notifier_range *range,
unsigned long cur_seq)
{
struct tid_user_buf *tidbuf =
container_of(mni, struct tid_user_buf, notifier);
/* take action only if unmapping */
if (range->event == MMU_NOTIFY_UNMAP) {
mutex_lock(&tidbuf->cover_mutex);
mmu_interval_set_seq(mni, cur_seq);
mutex_unlock(&tidbuf->cover_mutex);
}
return true;
}
static void cacheless_tid_rb_remove(struct hfi1_filedata *fdata, static void cacheless_tid_rb_remove(struct hfi1_filedata *fdata,
struct tid_rb_node *tnode) struct tid_rb_node *tnode)
{ {

View File

@@ -57,6 +57,8 @@ struct tid_pageset {
}; };
struct tid_user_buf { struct tid_user_buf {
struct mmu_interval_notifier notifier;
struct mutex cover_mutex;
unsigned long vaddr; unsigned long vaddr;
unsigned long length; unsigned long length;
unsigned int npages; unsigned int npages;
@@ -68,6 +70,7 @@ struct tid_user_buf {
struct tid_rb_node { struct tid_rb_node {
struct mmu_interval_notifier notifier; struct mmu_interval_notifier notifier;
struct hfi1_filedata *fdata; struct hfi1_filedata *fdata;
struct mutex invalidate_mutex; /* covers hw removal */
unsigned long phys; unsigned long phys;
struct tid_group *grp; struct tid_group *grp;
u32 rcventry; u32 rcventry;

View File

@@ -191,7 +191,6 @@ static const char * const smbus_pnp_ids[] = {
"SYN3221", /* HP 15-ay000 */ "SYN3221", /* HP 15-ay000 */
"SYN323d", /* HP Spectre X360 13-w013dx */ "SYN323d", /* HP Spectre X360 13-w013dx */
"SYN3257", /* HP Envy 13-ad105ng */ "SYN3257", /* HP Envy 13-ad105ng */
"SYN3286", /* HP Laptop 15-da3001TU */
NULL NULL
}; };

View File

@@ -47,19 +47,17 @@ static int atmel_ramc_probe(struct platform_device *pdev)
caps = of_device_get_match_data(&pdev->dev); caps = of_device_get_match_data(&pdev->dev);
if (caps->has_ddrck) { if (caps->has_ddrck) {
clk = devm_clk_get(&pdev->dev, "ddrck"); clk = devm_clk_get_enabled(&pdev->dev, "ddrck");
if (IS_ERR(clk)) if (IS_ERR(clk))
return PTR_ERR(clk); return PTR_ERR(clk);
clk_prepare_enable(clk);
} }
if (caps->has_mpddr_clk) { if (caps->has_mpddr_clk) {
clk = devm_clk_get(&pdev->dev, "mpddr"); clk = devm_clk_get_enabled(&pdev->dev, "mpddr");
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
pr_err("AT91 RAMC: couldn't get mpddr clock\n"); pr_err("AT91 RAMC: couldn't get mpddr clock\n");
return PTR_ERR(clk); return PTR_ERR(clk);
} }
clk_prepare_enable(clk);
} }
return 0; return 0;

View File

@@ -280,10 +280,9 @@ static int mvebu_devbus_probe(struct platform_device *pdev)
if (IS_ERR(devbus->base)) if (IS_ERR(devbus->base))
return PTR_ERR(devbus->base); return PTR_ERR(devbus->base);
clk = devm_clk_get(&pdev->dev, NULL); clk = devm_clk_get_enabled(&pdev->dev, NULL);
if (IS_ERR(clk)) if (IS_ERR(clk))
return PTR_ERR(clk); return PTR_ERR(clk);
clk_prepare_enable(clk);
/* /*
* Obtain clock period in picoseconds, * Obtain clock period in picoseconds,

View File

@@ -678,10 +678,10 @@ static int ksz9477_port_fdb_del(struct dsa_switch *ds, int port,
ksz_read32(dev, REG_SW_ALU_VAL_D, &alu_table[3]); ksz_read32(dev, REG_SW_ALU_VAL_D, &alu_table[3]);
/* clear forwarding port */ /* clear forwarding port */
alu_table[2] &= ~BIT(port); alu_table[1] &= ~BIT(port);
/* if there is no port to forward, clear table */ /* if there is no port to forward, clear table */
if ((alu_table[2] & ALU_V_PORT_MAP) == 0) { if ((alu_table[1] & ALU_V_PORT_MAP) == 0) {
alu_table[0] = 0; alu_table[0] = 0;
alu_table[1] = 0; alu_table[1] = 0;
alu_table[2] = 0; alu_table[2] = 0;

View File

@@ -524,19 +524,28 @@ static void xgbe_disable_vxlan(struct xgbe_prv_data *pdata)
netif_dbg(pdata, drv, pdata->netdev, "VXLAN acceleration disabled\n"); netif_dbg(pdata, drv, pdata->netdev, "VXLAN acceleration disabled\n");
} }
static unsigned int xgbe_get_fc_queue_count(struct xgbe_prv_data *pdata)
{
unsigned int max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES;
/* From MAC ver 30H the TFCR is per priority, instead of per queue */
if (XGMAC_GET_BITS(pdata->hw_feat.version, MAC_VR, SNPSVER) >= 0x30)
return max_q_count;
else
return min_t(unsigned int, pdata->tx_q_count, max_q_count);
}
static int xgbe_disable_tx_flow_control(struct xgbe_prv_data *pdata) static int xgbe_disable_tx_flow_control(struct xgbe_prv_data *pdata)
{ {
unsigned int max_q_count, q_count;
unsigned int reg, reg_val; unsigned int reg, reg_val;
unsigned int i; unsigned int i, q_count;
/* Clear MTL flow control */ /* Clear MTL flow control */
for (i = 0; i < pdata->rx_q_count; i++) for (i = 0; i < pdata->rx_q_count; i++)
XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, EHFC, 0); XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, EHFC, 0);
/* Clear MAC flow control */ /* Clear MAC flow control */
max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES; q_count = xgbe_get_fc_queue_count(pdata);
q_count = min_t(unsigned int, pdata->tx_q_count, max_q_count);
reg = MAC_Q0TFCR; reg = MAC_Q0TFCR;
for (i = 0; i < q_count; i++) { for (i = 0; i < q_count; i++) {
reg_val = XGMAC_IOREAD(pdata, reg); reg_val = XGMAC_IOREAD(pdata, reg);
@@ -553,9 +562,8 @@ static int xgbe_enable_tx_flow_control(struct xgbe_prv_data *pdata)
{ {
struct ieee_pfc *pfc = pdata->pfc; struct ieee_pfc *pfc = pdata->pfc;
struct ieee_ets *ets = pdata->ets; struct ieee_ets *ets = pdata->ets;
unsigned int max_q_count, q_count;
unsigned int reg, reg_val; unsigned int reg, reg_val;
unsigned int i; unsigned int i, q_count;
/* Set MTL flow control */ /* Set MTL flow control */
for (i = 0; i < pdata->rx_q_count; i++) { for (i = 0; i < pdata->rx_q_count; i++) {
@@ -579,8 +587,7 @@ static int xgbe_enable_tx_flow_control(struct xgbe_prv_data *pdata)
} }
/* Set MAC flow control */ /* Set MAC flow control */
max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES; q_count = xgbe_get_fc_queue_count(pdata);
q_count = min_t(unsigned int, pdata->tx_q_count, max_q_count);
reg = MAC_Q0TFCR; reg = MAC_Q0TFCR;
for (i = 0; i < q_count; i++) { for (i = 0; i < q_count; i++) {
reg_val = XGMAC_IOREAD(pdata, reg); reg_val = XGMAC_IOREAD(pdata, reg);

View File

@@ -496,6 +496,7 @@ static enum xgbe_an xgbe_an73_tx_training(struct xgbe_prv_data *pdata,
reg |= XGBE_KR_TRAINING_ENABLE; reg |= XGBE_KR_TRAINING_ENABLE;
reg |= XGBE_KR_TRAINING_START; reg |= XGBE_KR_TRAINING_START;
XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, reg); XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, reg);
pdata->kr_start_time = jiffies;
netif_dbg(pdata, link, pdata->netdev, netif_dbg(pdata, link, pdata->netdev,
"KR training initiated\n"); "KR training initiated\n");
@@ -632,6 +633,8 @@ static enum xgbe_an xgbe_an73_incompat_link(struct xgbe_prv_data *pdata)
xgbe_switch_mode(pdata); xgbe_switch_mode(pdata);
pdata->an_result = XGBE_AN_READY;
xgbe_an_restart(pdata); xgbe_an_restart(pdata);
return XGBE_AN_INCOMPAT_LINK; return XGBE_AN_INCOMPAT_LINK;
@@ -1275,9 +1278,30 @@ static bool xgbe_phy_aneg_done(struct xgbe_prv_data *pdata)
static void xgbe_check_link_timeout(struct xgbe_prv_data *pdata) static void xgbe_check_link_timeout(struct xgbe_prv_data *pdata)
{ {
unsigned long link_timeout; unsigned long link_timeout;
unsigned long kr_time;
int wait;
link_timeout = pdata->link_check + (XGBE_LINK_TIMEOUT * HZ); link_timeout = pdata->link_check + (XGBE_LINK_TIMEOUT * HZ);
if (time_after(jiffies, link_timeout)) { if (time_after(jiffies, link_timeout)) {
if ((xgbe_cur_mode(pdata) == XGBE_MODE_KR) &&
pdata->phy.autoneg == AUTONEG_ENABLE) {
/* AN restart should not happen while KR training is in progress.
* The while loop ensures no AN restart during KR training,
* waits up to 500ms and AN restart is triggered only if KR
* training is failed.
*/
wait = XGBE_KR_TRAINING_WAIT_ITER;
while (wait--) {
kr_time = pdata->kr_start_time +
msecs_to_jiffies(XGBE_AN_MS_TIMEOUT);
if (time_after(jiffies, kr_time))
break;
/* AN restart is not required, if AN result is COMPLETE */
if (pdata->an_result == XGBE_AN_COMPLETE)
return;
usleep_range(10000, 11000);
}
}
netif_dbg(pdata, link, pdata->netdev, "AN link timeout\n"); netif_dbg(pdata, link, pdata->netdev, "AN link timeout\n");
xgbe_phy_config_aneg(pdata); xgbe_phy_config_aneg(pdata);
} }

View File

@@ -289,6 +289,7 @@
/* Auto-negotiation */ /* Auto-negotiation */
#define XGBE_AN_MS_TIMEOUT 500 #define XGBE_AN_MS_TIMEOUT 500
#define XGBE_LINK_TIMEOUT 5 #define XGBE_LINK_TIMEOUT 5
#define XGBE_KR_TRAINING_WAIT_ITER 50
#define XGBE_SGMII_AN_LINK_STATUS BIT(1) #define XGBE_SGMII_AN_LINK_STATUS BIT(1)
#define XGBE_SGMII_AN_LINK_SPEED (BIT(2) | BIT(3)) #define XGBE_SGMII_AN_LINK_SPEED (BIT(2) | BIT(3))
@@ -1253,6 +1254,7 @@ struct xgbe_prv_data {
unsigned int parallel_detect; unsigned int parallel_detect;
unsigned int fec_ability; unsigned int fec_ability;
unsigned long an_start; unsigned long an_start;
unsigned long kr_start_time;
enum xgbe_an_mode an_mode; enum xgbe_an_mode an_mode;
/* I2C support */ /* I2C support */

View File

@@ -11185,7 +11185,7 @@ static void tg3_reset_task(struct work_struct *work)
rtnl_lock(); rtnl_lock();
tg3_full_lock(tp, 0); tg3_full_lock(tp, 0);
if (!netif_running(tp->dev)) { if (tp->pcierr_recovery || !netif_running(tp->dev)) {
tg3_flag_clear(tp, RESET_TASK_PENDING); tg3_flag_clear(tp, RESET_TASK_PENDING);
tg3_full_unlock(tp); tg3_full_unlock(tp);
rtnl_unlock(); rtnl_unlock();
@@ -18179,6 +18179,9 @@ static pci_ers_result_t tg3_io_error_detected(struct pci_dev *pdev,
netdev_info(netdev, "PCI I/O error detected\n"); netdev_info(netdev, "PCI I/O error detected\n");
/* Want to make sure that the reset task doesn't run */
tg3_reset_task_cancel(tp);
rtnl_lock(); rtnl_lock();
/* Could be second call or maybe we don't have netdev yet */ /* Could be second call or maybe we don't have netdev yet */
@@ -18195,9 +18198,6 @@ static pci_ers_result_t tg3_io_error_detected(struct pci_dev *pdev,
tg3_timer_stop(tp); tg3_timer_stop(tp);
/* Want to make sure that the reset task doesn't run */
tg3_reset_task_cancel(tp);
netif_device_detach(netdev); netif_device_detach(netdev);
/* Clean up software state, even if MMIO is blocked */ /* Clean up software state, even if MMIO is blocked */

View File

@@ -1963,7 +1963,6 @@ static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *ndev)
bool cloned = skb_cloned(*skb) || skb_header_cloned(*skb) || bool cloned = skb_cloned(*skb) || skb_header_cloned(*skb) ||
skb_is_nonlinear(*skb); skb_is_nonlinear(*skb);
int padlen = ETH_ZLEN - (*skb)->len; int padlen = ETH_ZLEN - (*skb)->len;
int headroom = skb_headroom(*skb);
int tailroom = skb_tailroom(*skb); int tailroom = skb_tailroom(*skb);
struct sk_buff *nskb; struct sk_buff *nskb;
u32 fcs; u32 fcs;
@@ -1977,9 +1976,6 @@ static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *ndev)
/* FCS could be appeded to tailroom. */ /* FCS could be appeded to tailroom. */
if (tailroom >= ETH_FCS_LEN) if (tailroom >= ETH_FCS_LEN)
goto add_fcs; goto add_fcs;
/* FCS could be appeded by moving data to headroom. */
else if (!cloned && headroom + tailroom >= ETH_FCS_LEN)
padlen = 0;
/* No room for FCS, need to reallocate skb. */ /* No room for FCS, need to reallocate skb. */
else else
padlen = ETH_FCS_LEN; padlen = ETH_FCS_LEN;
@@ -1988,10 +1984,7 @@ static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *ndev)
padlen += ETH_FCS_LEN; padlen += ETH_FCS_LEN;
} }
if (!cloned && headroom + tailroom >= padlen) { if (cloned || tailroom < padlen) {
(*skb)->data = memmove((*skb)->head, (*skb)->data, (*skb)->len);
skb_set_tail_pointer(*skb, (*skb)->len);
} else {
nskb = skb_copy_expand(*skb, 0, padlen, GFP_ATOMIC); nskb = skb_copy_expand(*skb, 0, padlen, GFP_ATOMIC);
if (!nskb) if (!nskb)
return -ENOMEM; return -ENOMEM;

View File

@@ -1642,7 +1642,7 @@ static void mlx5_core_verify_params(void)
} }
} }
static int __init init(void) static int __init mlx5_init(void)
{ {
int err; int err;
@@ -1667,7 +1667,7 @@ err_debug:
return err; return err;
} }
static void __exit cleanup(void) static void __exit mlx5_cleanup(void)
{ {
#ifdef CONFIG_MLX5_CORE_EN #ifdef CONFIG_MLX5_CORE_EN
mlx5e_cleanup(); mlx5e_cleanup();
@@ -1676,5 +1676,5 @@ static void __exit cleanup(void)
mlx5_unregister_debugfs(); mlx5_unregister_debugfs();
} }
module_init(init); module_init(mlx5_init);
module_exit(cleanup); module_exit(mlx5_cleanup);

View File

@@ -736,14 +736,14 @@ static void ravb_error_interrupt(struct net_device *ndev)
ravb_write(ndev, ~(EIS_QFS | EIS_RESERVED), EIS); ravb_write(ndev, ~(EIS_QFS | EIS_RESERVED), EIS);
if (eis & EIS_QFS) { if (eis & EIS_QFS) {
ris2 = ravb_read(ndev, RIS2); ris2 = ravb_read(ndev, RIS2);
ravb_write(ndev, ~(RIS2_QFF0 | RIS2_RFFF | RIS2_RESERVED), ravb_write(ndev, ~(RIS2_QFF0 | RIS2_QFF1 | RIS2_RFFF | RIS2_RESERVED),
RIS2); RIS2);
/* Receive Descriptor Empty int */ /* Receive Descriptor Empty int */
if (ris2 & RIS2_QFF0) if (ris2 & RIS2_QFF0)
priv->stats[RAVB_BE].rx_over_errors++; priv->stats[RAVB_BE].rx_over_errors++;
/* Receive Descriptor Empty int */ /* Receive Descriptor Empty int */
if (ris2 & RIS2_QFF1) if (ris2 & RIS2_QFF1)
priv->stats[RAVB_NC].rx_over_errors++; priv->stats[RAVB_NC].rx_over_errors++;

View File

@@ -1125,6 +1125,11 @@ static int stmmac_init_phy(struct net_device *dev)
int addr = priv->plat->phy_addr; int addr = priv->plat->phy_addr;
struct phy_device *phydev; struct phy_device *phydev;
if (addr < 0) {
netdev_err(priv->dev, "no phy found\n");
return -ENODEV;
}
phydev = mdiobus_get_phy(priv->mii, addr); phydev = mdiobus_get_phy(priv->mii, addr);
if (!phydev) { if (!phydev) {
netdev_err(priv->dev, "no phy at addr %d\n", addr); netdev_err(priv->dev, "no phy at addr %d\n", addr);

View File

@@ -4,6 +4,7 @@
*/ */
#include <linux/bitfield.h> #include <linux/bitfield.h>
#include <linux/delay.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/clk-provider.h> #include <linux/clk-provider.h>
#include <linux/device.h> #include <linux/device.h>
@@ -150,6 +151,7 @@ static const struct clk_ops g12a_ephy_pll_ops = {
static int g12a_enable_internal_mdio(struct g12a_mdio_mux *priv) static int g12a_enable_internal_mdio(struct g12a_mdio_mux *priv)
{ {
u32 value;
int ret; int ret;
/* Enable the phy clock */ /* Enable the phy clock */
@@ -163,18 +165,25 @@ static int g12a_enable_internal_mdio(struct g12a_mdio_mux *priv)
/* Initialize ephy control */ /* Initialize ephy control */
writel(EPHY_G12A_ID, priv->regs + ETH_PHY_CNTL0); writel(EPHY_G12A_ID, priv->regs + ETH_PHY_CNTL0);
writel(FIELD_PREP(PHY_CNTL1_ST_MODE, 3) |
FIELD_PREP(PHY_CNTL1_ST_PHYADD, EPHY_DFLT_ADD) | /* Make sure we get a 0 -> 1 transition on the enable bit */
FIELD_PREP(PHY_CNTL1_MII_MODE, EPHY_MODE_RMII) | value = FIELD_PREP(PHY_CNTL1_ST_MODE, 3) |
PHY_CNTL1_CLK_EN | FIELD_PREP(PHY_CNTL1_ST_PHYADD, EPHY_DFLT_ADD) |
PHY_CNTL1_CLKFREQ | FIELD_PREP(PHY_CNTL1_MII_MODE, EPHY_MODE_RMII) |
PHY_CNTL1_PHY_ENB, PHY_CNTL1_CLK_EN |
priv->regs + ETH_PHY_CNTL1); PHY_CNTL1_CLKFREQ;
writel(value, priv->regs + ETH_PHY_CNTL1);
writel(PHY_CNTL2_USE_INTERNAL | writel(PHY_CNTL2_USE_INTERNAL |
PHY_CNTL2_SMI_SRC_MAC | PHY_CNTL2_SMI_SRC_MAC |
PHY_CNTL2_RX_CLK_EPHY, PHY_CNTL2_RX_CLK_EPHY,
priv->regs + ETH_PHY_CNTL2); priv->regs + ETH_PHY_CNTL2);
value |= PHY_CNTL1_PHY_ENB;
writel(value, priv->regs + ETH_PHY_CNTL1);
/* The phy needs a bit of time to power up */
mdelay(10);
return 0; return 0;
} }

View File

@@ -108,7 +108,12 @@ EXPORT_SYMBOL(mdiobus_unregister_device);
struct phy_device *mdiobus_get_phy(struct mii_bus *bus, int addr) struct phy_device *mdiobus_get_phy(struct mii_bus *bus, int addr)
{ {
struct mdio_device *mdiodev = bus->mdio_map[addr]; struct mdio_device *mdiodev;
if (addr < 0 || addr >= ARRAY_SIZE(bus->mdio_map))
return NULL;
mdiodev = bus->mdio_map[addr];
if (!mdiodev) if (!mdiodev)
return NULL; return NULL;

View File

@@ -410,7 +410,7 @@ static int sr9700_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
/* ignore the CRC length */ /* ignore the CRC length */
len = (skb->data[1] | (skb->data[2] << 8)) - 4; len = (skb->data[1] | (skb->data[2] << 8)) - 4;
if (len > ETH_FRAME_LEN || len > skb->len) if (len > ETH_FRAME_LEN || len > skb->len || len < 0)
return 0; return 0;
/* the last packet of current skb */ /* the last packet of current skb */

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