https://source.android.com/docs/security/bulletin/2023-02-01 CVE-2022-39189 CVE-2022-39842 CVE-2022-41222 CVE-2023-20937 CVE-2023-20938 CVE-2022-0850 * tag 'ASB-2023-02-05_4.19-stable' of https://android.googlesource.com/kernel/common: Linux 4.19.272 usb: host: xhci-plat: add wakeup entry at sysfs ipv6: ensure sane device mtu in tunnels exit: Use READ_ONCE() for all oops/warn limit reads docs: Fix path paste-o for /sys/kernel/warn_count panic: Expose "warn_count" to sysfs panic: Introduce warn_limit panic: Consolidate open-coded panic_on_warn checks exit: Allow oops_limit to be disabled exit: Expose "oops_count" to sysfs exit: Put an upper limit on how often we can oops ia64: make IA64_MCA_RECOVERY bool instead of tristate h8300: Fix build errors from do_exit() to make_task_dead() transition hexagon: Fix function name in die() objtool: Add a missing comma to avoid string concatenation exit: Add and use make_task_dead. panic: unset panic_on_warn inside panic() sysctl: add a new register_sysctl_init() interface dmaengine: imx-sdma: Fix a possible memory leak in sdma_transfer_init ARM: dts: imx: Fix pca9547 i2c-mux node name x86/entry/64: Add instruction suffix to SYSRET x86/asm: Fix an assembler warning with current binutils drm/i915/display: fix compiler warning about array overrun x86/i8259: Mark legacy PIC interrupts with IRQ_LEVEL Revert "Input: synaptics - switch touchpad on HP Laptop 15-da3001TU to RMI mode" net/tg3: resolve deadlock in tg3_reset_task() during EEH net: ravb: Fix possible hang if RIS2_QFF1 happen sctp: fail if no bound addresses can be used for a given scope netrom: Fix use-after-free of a listening socket. netfilter: conntrack: fix vtag checks for ABORT/SHUTDOWN_COMPLETE ipv4: prevent potential spectre v1 gadget in ip_metrics_convert() netlink: annotate data races around sk_state netlink: annotate data races around dst_portid and dst_group netlink: annotate data races around nlk->portid netlink: remove hash::nelems check in netlink_insert netfilter: nft_set_rbtree: skip elements in transaction from garbage collection net: fix UaF in netns ops registration error path EDAC/device: Respect any driver-supplied workqueue polling value ARM: 9280/1: mm: fix warning on phys_addr_t to void pointer assignment cifs: Fix oops due to uncleared server->smbd_conn in reconnect smbd: Make upper layer decide when to destroy the transport trace_events_hist: add check for return value of 'create_hist_field' tracing: Make sure trace_printk() can output as soon as it can be used module: Don't wait for GOING modules scsi: hpsa: Fix allocation size for scsi_host_alloc() Bluetooth: hci_sync: cancel cmd_timer if hci_open failed fs: reiserfs: remove useless new_opts in reiserfs_remount perf env: Do not return pointers to local variables block: fix and cleanup bio_check_ro netfilter: conntrack: do not renew entry stuck in tcp SYN_SENT state w1: fix WARNING after calling w1_process() w1: fix deadloop in __w1_remove_master_device() tcp: avoid the lookup process failing to get sk in ehash table dmaengine: xilinx_dma: call of_node_put() when breaking out of for_each_child_of_node() dmaengine: xilinx_dma: Fix devm_platform_ioremap_resource error handling dmaengine: xilinx_dma: program hardware supported buffer length dmaengine: xilinx_dma: commonize DMA copy size calculation HID: betop: check shape of output reports net: macb: fix PTP TX timestamp failure due to packet padding dmaengine: Fix double increment of client_count in dma_chan_get() net: mlx5: eliminate anonymous module_init & module_exit usb: gadget: f_fs: Ensure ep0req is dequeued before free_request usb: gadget: f_fs: Prevent race during ffs_ep0_queue_wait HID: check empty report_list in hid_validate_values() net: mdio: validate parameter addr in mdiobus_get_phy() net: usb: sr9700: Handle negative len wifi: rndis_wlan: Prevent buffer overflow in rndis_query_oid net: nfc: Fix use-after-free in local_cleanup() phy: rockchip-inno-usb2: Fix missing clk_disable_unprepare() in rockchip_usb2phy_power_on() bpf: Fix pointer-leak due to insufficient speculative store bypass mitigation amd-xgbe: Delay AN timeout during KR training amd-xgbe: TX Flow Ctrl Registers are h/w ver dependent affs: initialize fsdata in affs_truncate() IB/hfi1: Fix expected receive setup error exit issues IB/hfi1: Reserve user expected TIDs IB/hfi1: Reject a zero-length user expected buffer tomoyo: fix broken dependency on *.conf.default EDAC/highbank: Fix memory leak in highbank_mc_probe() HID: intel_ish-hid: Add check for ishtp_dma_tx_map ARM: dts: imx6qdl-gw560x: Remove incorrect 'uart-has-rtscts' UPSTREAM: tcp: fix tcp_rmem documentation UPSTREAM: nvmem: core: skip child nodes not matching binding BACKPORT: nvmem: core: Fix a resource leak on error in nvmem_add_cells_from_of() UPSTREAM: sched/eas: Don't update misfit status if the task is pinned BACKPORT: arm64: link with -z norelro for LLD or aarch64-elf UPSTREAM: driver: core: Fix list corruption after device_del() UPSTREAM: coresight: tmc-etr: Fix barrier packet insertion for perf buffer UPSTREAM: f2fs: fix double free of unicode map BACKPORT: net: xfrm: fix memory leak in xfrm_user_policy() UPSTREAM: xfrm/compat: Don't allocate memory with __GFP_ZERO UPSTREAM: xfrm/compat: memset(0) 64-bit padding at right place UPSTREAM: xfrm/compat: Translate by copying XFRMA_UNSPEC attribute UPSTREAM: scsi: ufs: Fix missing brace warning for old compilers UPSTREAM: arm64: vdso32: make vdso32 install conditional UPSTREAM: loop: unset GENHD_FL_NO_PART_SCAN on LOOP_CONFIGURE BACKPORT: drm/virtio: fix missing dma_fence_put() in virtio_gpu_execbuffer_ioctl() BACKPORT: sched/uclamp: Protect uclamp fast path code with static key BACKPORT: sched/uclamp: Fix initialization of struct uclamp_rq UPSTREAM: coresight: etmv4: Fix CPU power management setup in probe() function UPSTREAM: arm64: vdso: Add --eh-frame-hdr to ldflags BACKPORT: arm64: vdso: Add '-Bsymbolic' to ldflags UPSTREAM: drm/virtio: fix a wait_event condition BACKPORT: sched/topology: Don't try to build empty sched domains BACKPORT: binder: prevent UAF read in print_binder_transaction_log_entry() BACKPORT: copy_process(): don't use ksys_close() on cleanups BACKPORT: arm64: vdso: Remove unnecessary asm-offsets.c definitions UPSTREAM: locking/lockdep, cpu/hotplug: Annotate AP thread Revert "xhci: Add a flag to disable USB3 lpm on a xhci root port level." BACKPORT: mac80211_hwsim: add concurrent channels scanning support over virtio BACKPORT: mac80211_hwsim: add frame transmission support over virtio This allows communication with external entities. BACKPORT: driver core: Skip unnecessary work when device doesn't have sync_state() Linux 4.19.271 x86/fpu: Use _Alignof to avoid undefined behavior in TYPE_ALIGN Revert "ext4: generalize extents status tree search functions" Revert "ext4: add new pending reservation mechanism" Revert "ext4: fix reserved cluster accounting at delayed write time" Revert "ext4: fix delayed allocation bug in ext4_clu_mapped for bigalloc + inline" gsmi: fix null-deref in gsmi_get_variable serial: atmel: fix incorrect baudrate setup serial: pch_uart: Pass correct sg to dma_unmap_sg() usb-storage: apply IGNORE_UAS only for HIKSEMI MD202 on RTL9210 usb: gadget: f_ncm: fix potential NULL ptr deref in ncm_bitrate() usb: gadget: g_webcam: Send color matching descriptor per frame usb: typec: altmodes/displayport: Fix pin assignment calculation usb: typec: altmodes/displayport: Add pin assignment helper usb: host: ehci-fsl: Fix module alias USB: serial: cp210x: add SCALANCE LPE-9000 device id cifs: do not include page data when checking signature mmc: sunxi-mmc: Fix clock refcount imbalance during unbind comedi: adv_pci1760: Fix PWM instruction handling usb: core: hub: disable autosuspend for TI TUSB8041 USB: misc: iowarrior: fix up header size for USB_DEVICE_ID_CODEMERCS_IOW100 USB: serial: option: add Quectel EM05CN modem USB: serial: option: add Quectel EM05CN (SG) modem USB: serial: option: add Quectel EC200U modem USB: serial: option: add Quectel EM05-G (RS) modem USB: serial: option: add Quectel EM05-G (CS) modem USB: serial: option: add Quectel EM05-G (GR) modem prlimit: do_prlimit needs to have a speculation check xhci: Add a flag to disable USB3 lpm on a xhci root port level. xhci: Fix null pointer dereference when host dies usb: xhci: Check endpoint is valid before dereferencing it xhci-pci: set the dma max_seg_size nilfs2: fix general protection fault in nilfs_btree_insert() Add exception protection processing for vd in axi_chan_handle_err function f2fs: let's avoid panic if extent_tree is not created RDMA/srp: Move large values to a new enum for gcc13 net/ethtool/ioctl: return -EOPNOTSUPP if we have no phy stats pNFS/filelayout: Fix coalescing test for single DS ANDROID: usb: f_accessory: Check buffer size when initialised via composite Linux 4.19.270 serial: tegra: Change lower tolerance baud rate limit for tegra20 and tegra30 serial: tegra: Only print FIFO error message when an error occurs tty: serial: tegra: Handle RX transfer in PIO mode if DMA wasn't started Revert "usb: ulpi: defer ulpi_register on ulpi_read_id timeout" efi: fix NULL-deref in init error path arm64: cmpxchg_double*: hazard against entire exchange variable drm/virtio: Fix GEM handle creation UAF x86/resctrl: Fix task CLOSID/RMID update race x86/resctrl: Use task_curr() instead of task_struct->on_cpu to prevent unnecessary IPI iommu/mediatek-v1: Fix an error handling path in mtk_iommu_v1_probe() iommu/mediatek-v1: Add error handle for mtk_iommu_probe net/mlx5: Fix ptp max frequency adjustment range net/mlx5: Rename ptp clock info nfc: pn533: Wait for out_urb's completion in pn533_usb_send_frame() hvc/xen: lock console list traversal regulator: da9211: Use irq handler when ready EDAC/device: Fix period calculation in edac_device_reset_delay_period() x86/boot: Avoid using Intel mnemonics in AT&T syntax asm netfilter: ipset: Fix overflow before widen in the bitmap_ip_create() function. ext4: fix delayed allocation bug in ext4_clu_mapped for bigalloc + inline ext4: fix reserved cluster accounting at delayed write time ext4: add new pending reservation mechanism ext4: generalize extents status tree search functions ext4: fix uninititialized value in 'ext4_evict_inode' ext4: fix use-after-free in ext4_orphan_cleanup ext4: lost matching-pair of trace in ext4_truncate ext4: fix bug_on in __es_tree_search caused by bad quota inode quota: Factor out setup of quota inode usb: ulpi: defer ulpi_register on ulpi_read_id timeout kest.pl: Fix grub2 menu handling for rebooting ktest.pl: Fix incorrect reboot for grub2bls ktest: introduce grub2bls REBOOT_TYPE option ktest: cleanup get_grub_index ktest: introduce _get_grub_index ktest: Add support for meta characters in GRUB_MENU ALSA: hda/hdmi: fix failures at PCM open on Intel ICL and later wifi: wilc1000: sdio: fix module autoloading ipv6: raw: Deduct extension header length in rawv6_push_pending_frames platform/x86: sony-laptop: Don't turn off 0x153 keyboard backlight during probe cifs: Fix uninitialized memory read for smb311 posix symlink create ALSA: pcm: Move rwsem lock inside snd_ctl_elem_read to prevent UAF net/ulp: prevent ULP without clone op from entering the LISTEN status s390/percpu: add READ_ONCE() to arch_this_cpu_to_op_simple() perf auxtrace: Fix address filter duplicate symbol selection docs: Fix the docs build with Sphinx 6.0 net: sched: disallow noqueue for qdisc classes driver core: Fix bus_type.match() error handling in __driver_attach() parisc: Align parisc MADV_XXX constants with all other architectures mbcache: Avoid nesting of cache->c_list_lock under bit locks hfs/hfsplus: avoid WARN_ON() for sanity check, use proper error handling hfs/hfsplus: use WARN_ON for sanity check ext4: don't allow journal inode to have encrypt flag riscv: uaccess: fix type of 0 variable on error in get_user() nfsd: fix handling of readdir in v4root vs. mount upcall timeout x86/bugs: Flush IBP in ib_prctl_set() ASoC: Intel: bytcr_rt5640: Add quirk for the Advantech MICA-071 tablet udf: Fix extension of the last extent in the file caif: fix memory leak in cfctrl_linkup_request() usb: rndis_host: Secure rndis_query check against int overflow net: sched: atm: dont intepret cls results when asked to drop RDMA/mlx5: Fix validation of max_rd_atomic caps for DC net: phy: xgmiitorgmii: Fix refcount leak in xgmiitorgmii_probe net: amd-xgbe: add missed tasklet_kill nfc: Fix potential resource leaks qlcnic: prevent ->dcb use-after-free on qlcnic_dcb_enable() failure bpf: pull before calling skb_postpull_rcsum() SUNRPC: ensure the matching upcall is in-flight upon downcall ext4: fix deadlock due to mbcache entry corruption mbcache: automatically delete entries from cache on freeing ext4: fix race when reusing xattr blocks ext4: unindent codeblock in ext4_xattr_block_set() ext4: remove EA inode entry from mbcache on inode eviction mbcache: add functions to delete entry if unused mbcache: don't reclaim used entries ext4: use kmemdup() to replace kmalloc + memcpy ext4: correct inconsistent error msg in nojournal mode ext4: goto right label 'failed_mount3a' driver core: Set deferred_probe_timeout to a longer default if CONFIG_MODULES is set ravb: Fix "failed to switch device to config mode" message during unbind perf probe: Fix to get the DW_AT_decl_file and DW_AT_call_file as unsinged data perf probe: Use dwarf_attr_integrate as generic DWARF attr accessor dm thin: resume even if in FAIL mode media: s5p-mfc: Fix in register read and write for H264 media: s5p-mfc: Clear workbit to handle error condition media: s5p-mfc: Fix to handle reference queue during finishing btrfs: replace strncpy() with strscpy() btrfs: send: avoid unnecessary backref lookups when finding clone source ext4: allocate extended attribute value in vmalloc area ext4: avoid unaccounted block allocation when expanding inode ext4: initialize quota before expanding inode in setproject ioctl ext4: fix inode leak in ext4_xattr_inode_create() on an error path ext4: avoid BUG_ON when creating xattrs ext4: fix error code return to user-space in ext4_get_branch() ext4: fix corruption when online resizing a 1K bigalloc fs ext4: init quota for 'old.inode' in 'ext4_rename' ext4: fix bug_on in __es_tree_search caused by bad boot loader inode ext4: add helper to check quota inums ext4: fix undefined behavior in bit shift for ext4_check_flag_values ext4: add inode table check in __ext4_get_inode_loc to aovid possible infinite loop drm/vmwgfx: Validate the box size for the snooped cursor drm/connector: send hotplug uevent on connector cleanup device_cgroup: Roll back to original exceptions after copy failure parisc: led: Fix potential null-ptr-deref in start_task() iommu/amd: Fix ivrs_acpihid cmdline parsing code crypto: n2 - add missing hash statesize PCI/sysfs: Fix double free in error path PCI: Fix pci_device_is_present() for VFs by checking PF ipmi: fix use after free in _ipmi_destroy_user() ima: Fix a potential NULL pointer access in ima_restore_measurement_list ipmi: fix long wait in unload when IPMI disconnect md/bitmap: Fix bitmap chunk size overflow issues cifs: fix confusing debug message media: dvb-core: Fix UAF due to refcount races at releasing media: dvb-core: Fix double free in dvb_register_device() ARM: 9256/1: NWFPE: avoid compiler-generated __aeabi_uldivmod tracing: Fix infinite loop in tracing_read_pipe on overflowed print_trace_line x86/microcode/intel: Do not retry microcode reloading on the APs dm cache: set needs_check flag after aborting metadata dm cache: Fix UAF in destroy() dm thin: Fix UAF in run_timer_softirq() dm thin: Use last transaction's pmd->root when commit failed dm cache: Fix ABBA deadlock between shrink_slab and dm_cache_metadata_abort binfmt: Fix error return code in load_elf_fdpic_binary() binfmt: Move install_exec_creds after setup_new_exec to match binfmt_elf selftests: Use optional USERCFLAGS and USERLDFLAGS ARM: ux500: do not directly dereference __iomem ktest.pl minconfig: Unset configs instead of just removing them soc: qcom: Select REMAP_MMIO for LLCC driver media: stv0288: use explicitly signed char SUNRPC: Don't leak netobj memory when gss_read_proxy_verf() fails tpm: tpm_tis: Add the missed acpi_put_table() to fix memory leak tpm: tpm_crb: Add the missed acpi_put_table() to fix memory leak mmc: vub300: fix warning - do not call blocking ops when !TASK_RUNNING md: fix a crash in mempool_free pnode: terminate at peers of source ALSA: line6: fix stack overflow in line6_midi_transmit ALSA: line6: correct midi status byte when receiving data from podxt ovl: Use ovl mounter's fsuid and fsgid in ovl_link() hfsplus: fix bug causing custom uid and gid being unable to be assigned with mount HID: plantronics: Additional PIDs for double volume key presses quirk powerpc/rtas: avoid scheduling in rtas_os_term() powerpc/rtas: avoid device tree lookups in rtas_os_term() ata: ahci: Fix PCS quirk application for suspend media: dvbdev: fix refcnt bug media: dvbdev: fix build warning due to comments gcov: add support for checksum field iio: adc: ad_sigma_delta: do not use internal iio_dev lock reiserfs: Add missing calls to reiserfs_security_free() HID: wacom: Ensure bootloader PID is usable in hidraw mode usb: dwc3: core: defer probe on ulpi_read_id timeout pstore: Make sure CONFIG_PSTORE_PMSG selects CONFIG_RT_MUTEXES pstore: Switch pmsg_lock to an rt_mutex to avoid priority inversion ASoC: rt5670: Remove unbalanced pm_runtime_put() ASoC: rockchip: spdif: Add missing clk_disable_unprepare() in rk_spdif_runtime_resume() ASoC: wm8994: Fix potential deadlock ASoC: rockchip: pdm: Add missing clk_disable_unprepare() in rockchip_pdm_runtime_resume() ASoC: mediatek: mt8173-rt5650-rt5514: fix refcount leak in mt8173_rt5650_rt5514_dev_probe() orangefs: Fix kmemleak in orangefs_prepare_debugfs_help_string() drm/sti: Fix return type of sti_{dvo,hda,hdmi}_connector_mode_valid() drm/fsl-dcu: Fix return type of fsl_dcu_drm_connector_mode_valid() clk: st: Fix memory leak in st_of_quadfs_setup() media: si470x: Fix use-after-free in si470x_int_in_callback() mmc: f-sdh30: Add quirks for broken timeout clock capability regulator: core: fix use_count leakage when handling boot-on blk-mq: fix possible memleak when register 'hctx' failed media: dvb-usb: fix memory leak in dvb_usb_adapter_init() media: dvbdev: adopts refcnt to avoid UAF media: dvb-frontends: fix leak of memory fw ppp: associate skb with a device at tx mrp: introduce active flags to prevent UAF when applicant uninit md/raid1: stop mdx_raid1 thread when raid1 array run failed drivers/md/md-bitmap: check the return value of md_bitmap_get_counter() drm/sti: Use drm_mode_copy() s390/lcs: Fix return type of lcs_start_xmit() s390/netiucv: Fix return type of netiucv_tx() s390/ctcm: Fix return type of ctc{mp,}m_tx() drm/amdgpu: Fix type of second parameter in trans_msg() callback igb: Do not free q_vector unless new one was allocated wifi: brcmfmac: Fix potential shift-out-of-bounds in brcmf_fw_alloc_request() hamradio: baycom_epp: Fix return type of baycom_send_packet() net: ethernet: ti: Fix return type of netcp_ndo_start_xmit() bpf: make sure skb->len != 0 when redirecting to a tunneling device ipmi: fix memleak when unload ipmi driver ASoC: codecs: rt298: Add quirk for KBL-R RVP platform wifi: ar5523: Fix use-after-free on ar5523_cmd() timed out wifi: ath9k: verify the expected usb_endpoints are present hfs: fix OOB Read in __hfs_brec_find acct: fix potential integer overflow in encode_comp_t() nilfs2: fix shift-out-of-bounds/overflow in nilfs_sb2_bad_offset() ACPICA: Fix error code path in acpi_ds_call_control_method() fs: jfs: fix shift-out-of-bounds in dbDiscardAG udf: Avoid double brelse() in udf_rename() fs: jfs: fix shift-out-of-bounds in dbAllocAG binfmt_misc: fix shift-out-of-bounds in check_special_flags net: stream: purge sk_error_queue in sk_stream_kill_queues() myri10ge: Fix an error handling path in myri10ge_probe() rxrpc: Fix missing unlock in rxrpc_do_sendmsg() net_sched: reject TCF_EM_SIMPLE case for complex ematch module skbuff: Account for tail adjustment during pull operations openvswitch: Fix flow lookup to use unmasked key rtc: mxc_v2: Add missing clk_disable_unprepare() r6040: Fix kmemleak in probe and remove nfc: pn533: Clear nfc_target before being used mISDN: hfcmulti: don't call dev_kfree_skb/kfree_skb() under spin_lock_irqsave() mISDN: hfcpci: don't call dev_kfree_skb/kfree_skb() under spin_lock_irqsave() mISDN: hfcsusb: don't call dev_kfree_skb/kfree_skb() under spin_lock_irqsave() nfsd: under NFSv4.1, fix double svc_xprt_put on rpc_create failure rtc: st-lpc: Add missing clk_disable_unprepare in st_rtc_probe() selftests/powerpc: Fix resource leaks powerpc/hv-gpci: Fix hv_gpci event list powerpc/83xx/mpc832x_rdb: call platform_device_put() in error case in of_fsl_spi_probe() powerpc/perf: callchain validate kernel stack pointer bounds powerpc/xive: add missing iounmap() in error path in xive_spapr_populate_irq_data() cxl: Fix refcount leak in cxl_calc_capp_routing powerpc/52xx: Fix a resource leak in an error handling path macintosh/macio-adb: check the return value of ioremap() macintosh: fix possible memory leak in macio_add_one_device() iommu/fsl_pamu: Fix resource leak in fsl_pamu_probe() iommu/amd: Fix pci device refcount leak in ppr_notifier() rtc: snvs: Allow a time difference on clock register read include/uapi/linux/swab: Fix potentially missing __always_inline HSI: omap_ssi_core: Fix error handling in ssi_init() perf symbol: correction while adjusting symbol power: supply: fix residue sysfs file in error handle route of __power_supply_register() HSI: omap_ssi_core: fix possible memory leak in ssi_probe() HSI: omap_ssi_core: fix unbalanced pm_runtime_disable() fbdev: uvesafb: Fixes an error handling path in uvesafb_probe() fbdev: vermilion: decrease reference count in error path fbdev: via: Fix error in via_core_init() fbdev: pm2fb: fix missing pci_disable_device() fbdev: ssd1307fb: Drop optional dependency samples: vfio-mdev: Fix missing pci_disable_device() in mdpy_fb_probe() tracing/hist: Fix issue of losting command info in error_log usb: storage: Add check for kcalloc i2c: ismt: Fix an out-of-bounds bug in ismt_access() vme: Fix error not catched in fake_init() staging: rtl8192e: Fix potential use-after-free in rtllib_rx_Monitor() staging: rtl8192u: Fix use after free in ieee80211_rx() i2c: pxa-pci: fix missing pci_disable_device() on error in ce4100_i2c_probe chardev: fix error handling in cdev_device_add() mcb: mcb-parse: fix error handing in chameleon_parse_gdd() drivers: mcb: fix resource leak in mcb_probe() usb: gadget: f_hid: fix refcount leak on error path usb: gadget: f_hid: fix f_hidg lifetime vs cdev usb: gadget: f_hid: optional SETUP/SET_REPORT mode cxl: fix possible null-ptr-deref in cxl_pci_init_afu|adapter() cxl: fix possible null-ptr-deref in cxl_guest_init_afu|adapter() misc: sgi-gru: fix use-after-free error in gru_set_context_option, gru_fault and gru_handle_user_call_os misc: tifm: fix possible memory leak in tifm_7xx1_switch_media() test_firmware: fix memory leak in test_firmware_init() serial: sunsab: Fix error handling in sunsab_init() serial: altera_uart: fix locking in polling mode tty: serial: altera_uart_{r,t}x_chars() need only uart_port tty: serial: clean up stop-tx part in altera_uart_tx_chars() serial: pch: Fix PCI device refcount leak in pch_request_dma() serial: pl011: Do not clear RX FIFO & RX interrupt in unthrottle. serial: amba-pl011: avoid SBSA UART accessing DMACR register usb: typec: Check for ops->exit instead of ops->enter in altmode_exit staging: vme_user: Fix possible UAF in tsi148_dma_list_add usb: fotg210-udc: Fix ages old endianness issues uio: uio_dmem_genirq: Fix deadlock between irq config and handling uio: uio_dmem_genirq: Fix missing unlock in irq configuration vfio: platform: Do not pass return buffer to ACPI _RST method class: fix possible memory leak in __class_register() serial: tegra: Read DMA status before terminating tty: serial: tegra: Activate RX DMA transfer by request serial: tegra: Add PIO mode support serial: tegra: report clk rate errors serial: tegra: add support to adjust baud rate serial: tegra: add support to use 8 bytes trigger serial: tegra: set maximum num of uart ports to 8 serial: tegra: check for FIFO mode enabled status serial: tegra: avoid reg access when clk disabled drivers: dio: fix possible memory leak in dio_init() IB/IPoIB: Fix queue count inconsistency for PKEY child interfaces hwrng: geode - Fix PCI device refcount leak hwrng: amd - Fix PCI device refcount leak crypto: img-hash - Fix variable dereferenced before check 'hdev->req' orangefs: Fix sysfs not cleanup when dev init failed RDMA/hfi1: Fix error return code in parse_platform_config() scsi: snic: Fix possible UAF in snic_tgt_create() scsi: fcoe: Fix transport not deattached when fcoe_if_init() fails scsi: ipr: Fix WARNING in ipr_init() scsi: fcoe: Fix possible name leak when device_register() fails scsi: hpsa: Fix possible memory leak in hpsa_add_sas_device() scsi: hpsa: Fix error handling in hpsa_add_sas_host() crypto: tcrypt - Fix multibuffer skcipher speed test mem leak scsi: hpsa: Fix possible memory leak in hpsa_init_one() scsi: hpsa: use local workqueues instead of system workqueues RDMA/rxe: Fix NULL-ptr-deref in rxe_qp_do_cleanup() when socket create failed crypto: ccree - Make cc_debugfs_global_fini() available for module init function RDMA/hfi: Decrease PCI device reference count in error path PCI: Check for alloc failure in pci_request_irq() scsi: scsi_debug: Fix a warning in resp_write_scat() RDMA/nldev: Return "-EAGAIN" if the cm_id isn't from expected port f2fs: fix normal discard process apparmor: Fix abi check to include v8 abi apparmor: fix lockdep warning when removing a namespace apparmor: fix a memleak in multi_transaction_new() stmmac: fix potential division by 0 Bluetooth: RFCOMM: don't call kfree_skb() under spin_lock_irqsave() Bluetooth: hci_core: don't call kfree_skb() under spin_lock_irqsave() Bluetooth: hci_bcsp: don't call kfree_skb() under spin_lock_irqsave() Bluetooth: hci_h5: don't call kfree_skb() under spin_lock_irqsave() Bluetooth: hci_qca: don't call kfree_skb() under spin_lock_irqsave() Bluetooth: btusb: don't call kfree_skb() under spin_lock_irqsave() ntb_netdev: Use dev_kfree_skb_any() in interrupt context net: lan9303: Fix read error execution path net: amd-xgbe: Check only the minimum speed for active/passive cables net: amd-xgbe: Fix logic around active and passive cables net: amd: lance: don't call dev_kfree_skb() under spin_lock_irqsave() hamradio: don't call dev_kfree_skb() under spin_lock_irqsave() net: ethernet: dnet: don't call dev_kfree_skb() under spin_lock_irqsave() net: emaclite: don't call dev_kfree_skb() under spin_lock_irqsave() net: apple: bmac: don't call dev_kfree_skb() under spin_lock_irqsave() net: apple: mace: don't call dev_kfree_skb() under spin_lock_irqsave() net/tunnel: wait until all sk_user_data reader finish before releasing the sock net: farsync: Fix kmemleak when rmmods farsync ethernet: s2io: don't call dev_kfree_skb() under spin_lock_irqsave() drivers: net: qlcnic: Fix potential memory leak in qlcnic_sriov_init() net: defxx: Fix missing err handling in dfx_init() net: vmw_vsock: vmci: Check memcpy_from_msg() clk: socfpga: use clk_hw_register for a5/c5 clk: socfpga: clk-pll: Remove unused variable 'rc' blktrace: Fix output non-blktrace event when blk_classic option enabled wifi: brcmfmac: Fix error return code in brcmf_sdio_download_firmware() rtl8xxxu: add enumeration for channel bandwidth wifi: rtl8xxxu: Add __packed to struct rtl8723bu_c2h clk: samsung: Fix memory leak in _samsung_clk_register_pll() media: coda: Add check for kmalloc media: coda: Add check for dcoda_iram_alloc media: c8sectpfe: Add of_node_put() when breaking out of loop mmc: mmci: fix return value check of mmc_add_host() mmc: wbsd: fix return value check of mmc_add_host() mmc: via-sdmmc: fix return value check of mmc_add_host() mmc: meson-gx: fix return value check of mmc_add_host() mmc: atmel-mci: fix return value check of mmc_add_host() mmc: wmt-sdmmc: fix return value check of mmc_add_host() mmc: vub300: fix return value check of mmc_add_host() mmc: toshsd: fix return value check of mmc_add_host() mmc: rtsx_usb_sdmmc: fix return value check of mmc_add_host() mmc: mxcmmc: fix return value check of mmc_add_host() mmc: moxart: fix return value check of mmc_add_host() NFSv4.x: Fail client initialisation if state manager thread can't run SUNRPC: Fix missing release socket in rpc_sockname() ALSA: mts64: fix possible null-ptr-defer in snd_mts64_interrupt media: saa7164: fix missing pci_disable_device() regulator: core: fix module refcount leak in set_supply() wifi: cfg80211: Fix not unregister reg_pdev when load_builtin_regdb_keys() fails bonding: uninitialized variable in bond_miimon_inspect() ASoC: pcm512x: Fix PM disable depth imbalance in pcm512x_probe drm/amdgpu: Fix PCI device refcount leak in amdgpu_atrm_get_bios() drm/radeon: Fix PCI device refcount leak in radeon_atrm_get_bios() ALSA: asihpi: fix missing pci_disable_device() NFSv4: Fix a deadlock between nfs4_open_recover_helper() and delegreturn NFSv4.2: Fix a memory stomp in decode_attr_security_label drm/tegra: Add missing clk_disable_unprepare() in tegra_dc_probe() media: s5p-mfc: Add variant data for MFC v7 hardware for Exynos 3250 SoC media: dvb-usb: az6027: fix null-ptr-deref in az6027_i2c_xfer() media: dvb-core: Fix ignored return value in dvb_register_frontend() pinctrl: pinconf-generic: add missing of_node_put() media: imon: fix a race condition in send_packet() drbd: remove call to memset before free device/resource/connection mtd: maps: pxa2xx-flash: fix memory leak in probe bonding: Export skip slave logic to function clk: rockchip: Fix memory leak in rockchip_clk_register_pll() ALSA: seq: fix undefined behavior in bit shift for SNDRV_SEQ_FILTER_USE_EVENT HID: hid-sensor-custom: set fixed size for custom attributes media: platform: exynos4-is: Fix error handling in fimc_md_init() media: solo6x10: fix possible memory leak in solo_sysfs_init() Input: elants_i2c - properly handle the reset GPIO when power is off mtd: lpddr2_nvm: Fix possible null-ptr-deref wifi: ath10k: Fix return value in ath10k_pci_init() ima: Fix misuse of dereference of pointer in template_desc_init_fields() regulator: core: fix unbalanced of node refcount in regulator_dev_lookup() ASoC: pxa: fix null-pointer dereference in filter() drm/radeon: Add the missed acpi_put_table() to fix memory leak net, proc: Provide PROC_FS=n fallback for proc_create_net_single_write() media: camss: Clean up received buffers on failed start of streaming wifi: rsi: Fix handling of 802.3 EAPOL frames sent via control port mtd: Fix device name leak when register device failed in add_mtd_device() media: vivid: fix compose size exceed boundary spi: Update reference to struct spi_controller can: kvaser_usb: Compare requested bittiming parameters with actual parameters in do_set_{,data}_bittiming can: kvaser_usb: Add struct kvaser_usb_busparams can: kvaser_usb_leaf: Fix bogus restart events can: kvaser_usb_leaf: Fix wrong CAN state after stopping can: kvaser_usb_leaf: Fix improved state not being reported can: kvaser_usb_leaf: Set Warning state even without bus errors can: kvaser_usb: kvaser_usb_leaf: Handle CMD_ERROR_EVENT can: kvaser_usb: kvaser_usb_leaf: Rename {leaf,usbcan}_cmd_error_event to {leaf,usbcan}_cmd_can_error_event can: kvaser_usb: kvaser_usb_leaf: Get capabilities from device can: kvaser_usb: do not increase tx statistics when sending error message frames media: i2c: ad5820: Fix error path pata_ipx4xx_cf: Fix unsigned comparison with less than zero wifi: rtl8xxxu: Fix reading the vendor of combo chips wifi: ath9k: hif_usb: Fix use-after-free in ath9k_hif_usb_reg_in_cb() wifi: ath9k: hif_usb: fix memory leak of urbs in ath9k_hif_usb_dealloc_tx_urbs() rapidio: devices: fix missing put_device in mport_cdev_open hfs: Fix OOB Write in hfs_asc2mac relay: fix type mismatch when allocating memory in relay_create_buf() eventfd: change int to __u64 in eventfd_signal() ifndef CONFIG_EVENTFD rapidio: fix possible UAF when kfifo_alloc() fails fs: sysv: Fix sysv_nblocks() returns wrong value MIPS: BCM63xx: Add check for NULL for clk in clk_enable platform/x86: mxm-wmi: fix memleak in mxm_wmi_call_mx[ds|mx]() PM: runtime: Do not call __rpm_callback() from rpm_idle() PM: runtime: Improve path in rpm_idle() when no callback xen/privcmd: Fix a possible warning in privcmd_ioctl_mmap_resource() x86/xen: Fix memory leak in xen_init_lock_cpu() x86/xen: Fix memory leak in xen_smp_intr_init{_pv}() xen/events: only register debug interrupt for 2-level events uprobes/x86: Allow to probe a NOP instruction with 0x66 prefix ACPICA: Fix use-after-free in acpi_ut_copy_ipackage_to_ipackage() clocksource/drivers/sh_cmt: Make sure channel clock supply is enabled rapidio: rio: fix possible name leak in rio_register_mport() rapidio: fix possible name leaks when rio_add_device() fails debugfs: fix error when writing negative value to atomic_t debugfs file lib/notifier-error-inject: fix error when writing -errno to debugfs file libfs: add DEFINE_SIMPLE_ATTRIBUTE_SIGNED for signed value cpufreq: amd_freq_sensitivity: Add missing pci_dev_put() irqchip: gic-pm: Use pm_runtime_resume_and_get() in gic_probe() perf/x86/intel/uncore: Fix reference count leak in hswep_has_limit_sbox() PNP: fix name memory leak in pnp_alloc_dev() MIPS: vpe-cmp: fix possible memory leak while module exiting MIPS: vpe-mt: fix possible memory leak while module exiting ocfs2: fix memory leak in ocfs2_stack_glue_init() proc: fixup uptime selftest timerqueue: Use rb_entry_safe() in timerqueue_getnext() perf: Fix possible memleak in pmu_dev_alloc() selftests/ftrace: event_triggers: wait longer for test_event_enable fs: don't audit the capability check in simple_xattr_list() alpha: fix syscall entry in !AUDUT_SYSCALL case cpuidle: dt: Return the correct numbers of parsed idle states tpm/tpm_crb: Fix error message in __crb_relinquish_locality() pstore: Avoid kcore oops by vmap()ing with VM_IOREMAP ARM: mmp: fix timer_read delay pstore/ram: Fix error return code in ramoops_probe() ARM: dts: turris-omnia: Add switch port 6 node ARM: dts: turris-omnia: Add ethernet aliases ARM: dts: armada-39x: Fix assigned-addresses for every PCIe Root Port ARM: dts: armada-38x: Fix assigned-addresses for every PCIe Root Port ARM: dts: armada-375: Fix assigned-addresses for every PCIe Root Port ARM: dts: armada-xp: Fix assigned-addresses for every PCIe Root Port ARM: dts: armada-370: Fix assigned-addresses for every PCIe Root Port ARM: dts: dove: Fix assigned-addresses for every PCIe Root Port arm64: dts: mediatek: mt6797: Fix 26M oscillator unit name arm64: dts: mt2712-evb: Fix vproc fixed regulators unit names arm64: dts: mt2712e: Fix unit address for pinctrl node arm64: dts: mt2712e: Fix unit_address_vs_reg warning for oscillators perf: arm_dsu: Fix hotplug callback leak in dsu_pmu_init() soc: ti: smartreflex: Fix PM disable depth imbalance in omap_sr_probe arm: dts: spear600: Fix clcd interrupt drivers: soc: ti: knav_qmss_queue: Mark knav_acc_firmwares as static ARM: dts: qcom: apq8064: fix coresight compatible usb: musb: remove extra check in musb_gadget_vbus_draw net: loopback: use NET_NAME_PREDICTABLE for name_assign_type Bluetooth: L2CAP: Fix u8 overflow igb: Initialize mailbox message for VF reset USB: serial: f81534: fix division by zero on line-speed change USB: serial: cp210x: add Kamstrup RF sniffer PIDs USB: serial: option: add Quectel EM05-G modem usb: gadget: uvc: Prevent buffer overflow in setup handler udf: Fix extending file within last block udf: Do not bother looking for prealloc extents if i_lenExtents matches i_size udf: Fix preallocation discarding at indirect extent boundary udf: Discard preallocation before extending file with a hole perf script python: Remove explicit shebang from tests/attr.c ASoC: ops: Correct bounds check for second channel on SX controls can: mcba_usb: Fix termination command argument can: sja1000: fix size of OCR_MODE_MASK define pinctrl: meditatek: Startup with the IRQs disabled ASoC: ops: Check bounds for second channel in snd_soc_put_volsw_sx() nfp: fix use-after-free in area_cache_get() block: unhash blkdev part inode when the part is deleted mm/khugepaged: invoke MMU notifiers in shmem/file collapse paths mm/khugepaged: fix GUP-fast interaction by sending IPI ANDROID: Add more hvc devices for virtio-console. Conflicts: drivers/base/core.c drivers/edac/edac_device.c drivers/hwtracing/coresight/coresight-etm4x.c drivers/net/wireless/mac80211_hwsim.c drivers/scsi/ufs/ufshcd-crypto.c drivers/usb/gadget/function/f_fs.c drivers/usb/gadget/function/f_hid.c Change-Id: Ied998db07e927ccb3376a78f044df36088d9e3b8
667 lines
19 KiB
C
667 lines
19 KiB
C
|
|
/*
|
|
* edac_device.c
|
|
* (C) 2007 www.douglaskthompson.com
|
|
*
|
|
* This file may be distributed under the terms of the
|
|
* GNU General Public License.
|
|
*
|
|
* Written by Doug Thompson <norsk5@xmission.com>
|
|
*
|
|
* edac_device API implementation
|
|
* 19 Jan 2007
|
|
*/
|
|
|
|
#include <asm/page.h>
|
|
#include <linux/uaccess.h>
|
|
#include <linux/ctype.h>
|
|
#include <linux/highmem.h>
|
|
#include <linux/init.h>
|
|
#include <linux/jiffies.h>
|
|
#include <linux/module.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/smp.h>
|
|
#include <linux/spinlock.h>
|
|
#include <linux/sysctl.h>
|
|
#include <linux/timer.h>
|
|
|
|
#include "edac_device.h"
|
|
#include "edac_module.h"
|
|
|
|
/* lock for the list: 'edac_device_list', manipulation of this list
|
|
* is protected by the 'device_ctls_mutex' lock
|
|
*/
|
|
static DEFINE_MUTEX(device_ctls_mutex);
|
|
static LIST_HEAD(edac_device_list);
|
|
|
|
/* Default workqueue processing interval on this instance, in msecs */
|
|
#define DEFAULT_POLL_INTERVAL 1000
|
|
|
|
#ifdef CONFIG_EDAC_DEBUG
|
|
static void edac_device_dump_device(struct edac_device_ctl_info *edac_dev)
|
|
{
|
|
edac_dbg(3, "\tedac_dev = %p dev_idx=%d\n",
|
|
edac_dev, edac_dev->dev_idx);
|
|
edac_dbg(4, "\tedac_dev->edac_check = %p\n", edac_dev->edac_check);
|
|
edac_dbg(3, "\tdev = %p\n", edac_dev->dev);
|
|
edac_dbg(3, "\tmod_name:ctl_name = %s:%s\n",
|
|
edac_dev->mod_name, edac_dev->ctl_name);
|
|
edac_dbg(3, "\tpvt_info = %p\n\n", edac_dev->pvt_info);
|
|
}
|
|
#endif /* CONFIG_EDAC_DEBUG */
|
|
|
|
struct edac_device_ctl_info *edac_device_alloc_ctl_info(
|
|
unsigned sz_private,
|
|
char *edac_device_name, unsigned nr_instances,
|
|
char *edac_block_name, unsigned nr_blocks,
|
|
unsigned offset_value, /* zero, 1, or other based offset */
|
|
struct edac_dev_sysfs_block_attribute *attrib_spec, unsigned nr_attrib,
|
|
int device_index)
|
|
{
|
|
struct edac_device_ctl_info *dev_ctl;
|
|
struct edac_device_instance *dev_inst, *inst;
|
|
struct edac_device_block *dev_blk, *blk_p, *blk;
|
|
struct edac_dev_sysfs_block_attribute *dev_attrib, *attrib_p, *attrib;
|
|
unsigned total_size;
|
|
unsigned count;
|
|
unsigned instance, block, attr;
|
|
void *pvt, *p;
|
|
int err;
|
|
|
|
edac_dbg(4, "instances=%d blocks=%d\n", nr_instances, nr_blocks);
|
|
|
|
/* Calculate the size of memory we need to allocate AND
|
|
* determine the offsets of the various item arrays
|
|
* (instance,block,attrib) from the start of an allocated structure.
|
|
* We want the alignment of each item (instance,block,attrib)
|
|
* to be at least as stringent as what the compiler would
|
|
* provide if we could simply hardcode everything into a single struct.
|
|
*/
|
|
p = NULL;
|
|
dev_ctl = edac_align_ptr(&p, sizeof(*dev_ctl), 1);
|
|
|
|
/* Calc the 'end' offset past end of ONE ctl_info structure
|
|
* which will become the start of the 'instance' array
|
|
*/
|
|
dev_inst = edac_align_ptr(&p, sizeof(*dev_inst), nr_instances);
|
|
|
|
/* Calc the 'end' offset past the instance array within the ctl_info
|
|
* which will become the start of the block array
|
|
*/
|
|
count = nr_instances * nr_blocks;
|
|
dev_blk = edac_align_ptr(&p, sizeof(*dev_blk), count);
|
|
|
|
/* Calc the 'end' offset past the dev_blk array
|
|
* which will become the start of the attrib array, if any.
|
|
*/
|
|
/* calc how many nr_attrib we need */
|
|
if (nr_attrib > 0)
|
|
count *= nr_attrib;
|
|
dev_attrib = edac_align_ptr(&p, sizeof(*dev_attrib), count);
|
|
|
|
/* Calc the 'end' offset past the attributes array */
|
|
pvt = edac_align_ptr(&p, sz_private, 1);
|
|
|
|
/* 'pvt' now points to where the private data area is.
|
|
* At this point 'pvt' (like dev_inst,dev_blk and dev_attrib)
|
|
* is baselined at ZERO
|
|
*/
|
|
total_size = ((unsigned long)pvt) + sz_private;
|
|
|
|
/* Allocate the amount of memory for the set of control structures */
|
|
dev_ctl = kzalloc(total_size, GFP_KERNEL);
|
|
if (dev_ctl == NULL)
|
|
return NULL;
|
|
|
|
/* Adjust pointers so they point within the actual memory we
|
|
* just allocated rather than an imaginary chunk of memory
|
|
* located at address 0.
|
|
* 'dev_ctl' points to REAL memory, while the others are
|
|
* ZERO based and thus need to be adjusted to point within
|
|
* the allocated memory.
|
|
*/
|
|
dev_inst = (struct edac_device_instance *)
|
|
(((char *)dev_ctl) + ((unsigned long)dev_inst));
|
|
dev_blk = (struct edac_device_block *)
|
|
(((char *)dev_ctl) + ((unsigned long)dev_blk));
|
|
dev_attrib = (struct edac_dev_sysfs_block_attribute *)
|
|
(((char *)dev_ctl) + ((unsigned long)dev_attrib));
|
|
pvt = sz_private ? (((char *)dev_ctl) + ((unsigned long)pvt)) : NULL;
|
|
|
|
/* Begin storing the information into the control info structure */
|
|
dev_ctl->dev_idx = device_index;
|
|
dev_ctl->nr_instances = nr_instances;
|
|
dev_ctl->instances = dev_inst;
|
|
dev_ctl->pvt_info = pvt;
|
|
|
|
/* Default logging of CEs and UEs */
|
|
dev_ctl->log_ce = 1;
|
|
dev_ctl->log_ue = 1;
|
|
|
|
/* Name of this edac device */
|
|
snprintf(dev_ctl->name,sizeof(dev_ctl->name),"%s",edac_device_name);
|
|
|
|
edac_dbg(4, "edac_dev=%p next after end=%p\n",
|
|
dev_ctl, pvt + sz_private);
|
|
|
|
/* Initialize every Instance */
|
|
for (instance = 0; instance < nr_instances; instance++) {
|
|
inst = &dev_inst[instance];
|
|
inst->ctl = dev_ctl;
|
|
inst->nr_blocks = nr_blocks;
|
|
blk_p = &dev_blk[instance * nr_blocks];
|
|
inst->blocks = blk_p;
|
|
|
|
/* name of this instance */
|
|
snprintf(inst->name, sizeof(inst->name),
|
|
"%s%u", edac_device_name, instance);
|
|
|
|
/* Initialize every block in each instance */
|
|
for (block = 0; block < nr_blocks; block++) {
|
|
blk = &blk_p[block];
|
|
blk->instance = inst;
|
|
snprintf(blk->name, sizeof(blk->name),
|
|
"%s%d", edac_block_name, block+offset_value);
|
|
|
|
edac_dbg(4, "instance=%d inst_p=%p block=#%d block_p=%p name='%s'\n",
|
|
instance, inst, block, blk, blk->name);
|
|
|
|
/* if there are NO attributes OR no attribute pointer
|
|
* then continue on to next block iteration
|
|
*/
|
|
if ((nr_attrib == 0) || (attrib_spec == NULL))
|
|
continue;
|
|
|
|
/* setup the attribute array for this block */
|
|
blk->nr_attribs = nr_attrib;
|
|
attrib_p = &dev_attrib[block*nr_instances*nr_attrib];
|
|
blk->block_attributes = attrib_p;
|
|
|
|
edac_dbg(4, "THIS BLOCK_ATTRIB=%p\n",
|
|
blk->block_attributes);
|
|
|
|
/* Initialize every user specified attribute in this
|
|
* block with the data the caller passed in
|
|
* Each block gets its own copy of pointers,
|
|
* and its unique 'value'
|
|
*/
|
|
for (attr = 0; attr < nr_attrib; attr++) {
|
|
attrib = &attrib_p[attr];
|
|
|
|
/* populate the unique per attrib
|
|
* with the code pointers and info
|
|
*/
|
|
attrib->attr = attrib_spec[attr].attr;
|
|
attrib->show = attrib_spec[attr].show;
|
|
attrib->store = attrib_spec[attr].store;
|
|
|
|
attrib->block = blk; /* up link */
|
|
|
|
edac_dbg(4, "alloc-attrib=%p attrib_name='%s' attrib-spec=%p spec-name=%s\n",
|
|
attrib, attrib->attr.name,
|
|
&attrib_spec[attr],
|
|
attrib_spec[attr].attr.name
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Mark this instance as merely ALLOCATED */
|
|
dev_ctl->op_state = OP_ALLOC;
|
|
|
|
/*
|
|
* Initialize the 'root' kobj for the edac_device controller
|
|
*/
|
|
err = edac_device_register_sysfs_main_kobj(dev_ctl);
|
|
if (err) {
|
|
kfree(dev_ctl);
|
|
return NULL;
|
|
}
|
|
|
|
/* at this point, the root kobj is valid, and in order to
|
|
* 'free' the object, then the function:
|
|
* edac_device_unregister_sysfs_main_kobj() must be called
|
|
* which will perform kobj unregistration and the actual free
|
|
* will occur during the kobject callback operation
|
|
*/
|
|
|
|
return dev_ctl;
|
|
}
|
|
EXPORT_SYMBOL_GPL(edac_device_alloc_ctl_info);
|
|
|
|
void edac_device_free_ctl_info(struct edac_device_ctl_info *ctl_info)
|
|
{
|
|
edac_device_unregister_sysfs_main_kobj(ctl_info);
|
|
}
|
|
EXPORT_SYMBOL_GPL(edac_device_free_ctl_info);
|
|
|
|
/*
|
|
* find_edac_device_by_dev
|
|
* scans the edac_device list for a specific 'struct device *'
|
|
*
|
|
* lock to be held prior to call: device_ctls_mutex
|
|
*
|
|
* Return:
|
|
* pointer to control structure managing 'dev'
|
|
* NULL if not found on list
|
|
*/
|
|
static struct edac_device_ctl_info *find_edac_device_by_dev(struct device *dev)
|
|
{
|
|
struct edac_device_ctl_info *edac_dev;
|
|
struct list_head *item;
|
|
|
|
edac_dbg(0, "\n");
|
|
|
|
list_for_each(item, &edac_device_list) {
|
|
edac_dev = list_entry(item, struct edac_device_ctl_info, link);
|
|
|
|
if (edac_dev->dev == dev)
|
|
return edac_dev;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
* add_edac_dev_to_global_list
|
|
* Before calling this function, caller must
|
|
* assign a unique value to edac_dev->dev_idx.
|
|
*
|
|
* lock to be held prior to call: device_ctls_mutex
|
|
*
|
|
* Return:
|
|
* 0 on success
|
|
* 1 on failure.
|
|
*/
|
|
static int add_edac_dev_to_global_list(struct edac_device_ctl_info *edac_dev)
|
|
{
|
|
struct list_head *item, *insert_before;
|
|
struct edac_device_ctl_info *rover;
|
|
|
|
insert_before = &edac_device_list;
|
|
|
|
/* Determine if already on the list */
|
|
rover = find_edac_device_by_dev(edac_dev->dev);
|
|
if (unlikely(rover != NULL))
|
|
goto fail0;
|
|
|
|
/* Insert in ascending order by 'dev_idx', so find position */
|
|
list_for_each(item, &edac_device_list) {
|
|
rover = list_entry(item, struct edac_device_ctl_info, link);
|
|
|
|
if (rover->dev_idx >= edac_dev->dev_idx) {
|
|
if (unlikely(rover->dev_idx == edac_dev->dev_idx))
|
|
goto fail1;
|
|
|
|
insert_before = item;
|
|
break;
|
|
}
|
|
}
|
|
|
|
list_add_tail_rcu(&edac_dev->link, insert_before);
|
|
return 0;
|
|
|
|
fail0:
|
|
edac_printk(KERN_WARNING, EDAC_MC,
|
|
"%s (%s) %s %s already assigned %d\n",
|
|
dev_name(rover->dev), edac_dev_name(rover),
|
|
rover->mod_name, rover->ctl_name, rover->dev_idx);
|
|
return 1;
|
|
|
|
fail1:
|
|
edac_printk(KERN_WARNING, EDAC_MC,
|
|
"bug in low-level driver: attempt to assign\n"
|
|
" duplicate dev_idx %d in %s()\n", rover->dev_idx,
|
|
__func__);
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
* del_edac_device_from_global_list
|
|
*/
|
|
static void del_edac_device_from_global_list(struct edac_device_ctl_info
|
|
*edac_device)
|
|
{
|
|
list_del_rcu(&edac_device->link);
|
|
|
|
/* these are for safe removal of devices from global list while
|
|
* NMI handlers may be traversing list
|
|
*/
|
|
synchronize_rcu();
|
|
INIT_LIST_HEAD(&edac_device->link);
|
|
}
|
|
|
|
/*
|
|
* edac_device_workq_function
|
|
* performs the operation scheduled by a workq request
|
|
*
|
|
* this workq is embedded within an edac_device_ctl_info
|
|
* structure, that needs to be polled for possible error events.
|
|
*
|
|
* This operation is to acquire the list mutex lock
|
|
* (thus preventing insertation or deletion)
|
|
* and then call the device's poll function IFF this device is
|
|
* running polled and there is a poll function defined.
|
|
*/
|
|
static void edac_device_workq_function(struct work_struct *work_req)
|
|
{
|
|
struct delayed_work *d_work = to_delayed_work(work_req);
|
|
struct edac_device_ctl_info *edac_dev = to_edac_device_ctl_work(d_work);
|
|
|
|
mutex_lock(&device_ctls_mutex);
|
|
|
|
/* If we are being removed, bail out immediately */
|
|
if (edac_dev->op_state == OP_OFFLINE) {
|
|
mutex_unlock(&device_ctls_mutex);
|
|
return;
|
|
}
|
|
|
|
/* Only poll controllers that are running polled and have a check */
|
|
if ((edac_dev->op_state == OP_RUNNING_POLL) &&
|
|
(edac_dev->edac_check != NULL)) {
|
|
edac_dev->edac_check(edac_dev);
|
|
}
|
|
|
|
mutex_unlock(&device_ctls_mutex);
|
|
|
|
/* Reschedule the workq for the next time period to start again
|
|
* if the number of msec is for 1 sec, then adjust to the next
|
|
* whole one second to save timers firing all over the period
|
|
* between integral seconds
|
|
*/
|
|
if (edac_dev->poll_msec == DEFAULT_POLL_INTERVAL)
|
|
edac_queue_work(&edac_dev->work, round_jiffies_relative(edac_dev->delay));
|
|
else
|
|
edac_queue_work(&edac_dev->work, edac_dev->delay);
|
|
}
|
|
|
|
/*
|
|
* edac_device_workq_setup
|
|
* initialize a workq item for this edac_device instance
|
|
* passing in the new delay period in msec
|
|
*/
|
|
static void edac_device_workq_setup(struct edac_device_ctl_info *edac_dev,
|
|
unsigned msec)
|
|
{
|
|
edac_dbg(0, "\n");
|
|
|
|
/* take the arg 'msec' and set it into the control structure
|
|
* to used in the time period calculation
|
|
* then calc the number of jiffies that represents. Also, force
|
|
* polling period to 1 second if it is smaller than that, as
|
|
* anything less than 1 second does not make sense.
|
|
*/
|
|
if (msec <= 1000) {
|
|
edac_device_printk(edac_dev, KERN_WARNING,
|
|
"Forcing polling period to 1 second\n");
|
|
msec = 1000;
|
|
}
|
|
|
|
edac_dev->poll_msec = msec;
|
|
edac_dev->delay = msecs_to_jiffies(msec);
|
|
|
|
if (edac_dev->defer_work)
|
|
INIT_DEFERRABLE_WORK(&edac_dev->work,
|
|
edac_device_workq_function);
|
|
else
|
|
INIT_DELAYED_WORK(&edac_dev->work, edac_device_workq_function);
|
|
|
|
/* optimize here for the 1 second case, which will be normal value, to
|
|
* fire ON the 1 second time event. This helps reduce all sorts of
|
|
* timers firing on sub-second basis, while they are happy
|
|
* to fire together on the 1 second exactly
|
|
*/
|
|
if (edac_dev->poll_msec == DEFAULT_POLL_INTERVAL)
|
|
edac_queue_work(&edac_dev->work, round_jiffies_relative(edac_dev->delay));
|
|
else
|
|
edac_queue_work(&edac_dev->work, edac_dev->delay);
|
|
}
|
|
|
|
/*
|
|
* edac_device_workq_teardown
|
|
* stop the workq processing on this edac_dev
|
|
*/
|
|
static void edac_device_workq_teardown(struct edac_device_ctl_info *edac_dev)
|
|
{
|
|
if (!edac_dev->edac_check)
|
|
return;
|
|
|
|
edac_dev->op_state = OP_OFFLINE;
|
|
|
|
edac_stop_work(&edac_dev->work);
|
|
}
|
|
|
|
/*
|
|
* edac_device_reset_delay_period
|
|
*
|
|
* need to stop any outstanding workq queued up at this time
|
|
* because we will be resetting the sleep time.
|
|
* Then restart the workq on the new delay
|
|
*/
|
|
void edac_device_reset_delay_period(struct edac_device_ctl_info *edac_dev,
|
|
unsigned long msec)
|
|
{
|
|
edac_dev->poll_msec = msec;
|
|
edac_dev->delay = msecs_to_jiffies(msec);
|
|
|
|
/* See comment in edac_device_workq_setup() above */
|
|
if (edac_dev->poll_msec == DEFAULT_POLL_INTERVAL)
|
|
edac_mod_work(&edac_dev->work, round_jiffies_relative(edac_dev->delay));
|
|
else
|
|
edac_mod_work(&edac_dev->work, edac_dev->delay);
|
|
}
|
|
|
|
int edac_device_alloc_index(void)
|
|
{
|
|
static atomic_t device_indexes = ATOMIC_INIT(0);
|
|
|
|
return atomic_inc_return(&device_indexes) - 1;
|
|
}
|
|
EXPORT_SYMBOL_GPL(edac_device_alloc_index);
|
|
|
|
int edac_device_add_device(struct edac_device_ctl_info *edac_dev)
|
|
{
|
|
edac_dbg(0, "\n");
|
|
|
|
#ifdef CONFIG_EDAC_DEBUG
|
|
if (edac_debug_level >= 3)
|
|
edac_device_dump_device(edac_dev);
|
|
#endif
|
|
mutex_lock(&device_ctls_mutex);
|
|
|
|
if (add_edac_dev_to_global_list(edac_dev))
|
|
goto fail0;
|
|
|
|
/* set load time so that error rate can be tracked */
|
|
edac_dev->start_time = jiffies;
|
|
|
|
/* create this instance's sysfs entries */
|
|
if (edac_device_create_sysfs(edac_dev)) {
|
|
edac_device_printk(edac_dev, KERN_WARNING,
|
|
"failed to create sysfs device\n");
|
|
goto fail1;
|
|
}
|
|
|
|
/* If there IS a check routine, then we are running POLLED */
|
|
if (edac_dev->edac_check != NULL) {
|
|
/* This instance is NOW RUNNING */
|
|
edac_dev->op_state = OP_RUNNING_POLL;
|
|
|
|
edac_device_workq_setup(edac_dev, edac_dev->poll_msec ?: DEFAULT_POLL_INTERVAL);
|
|
} else {
|
|
edac_dev->op_state = OP_RUNNING_INTERRUPT;
|
|
}
|
|
|
|
/* Report action taken */
|
|
edac_device_printk(edac_dev, KERN_INFO,
|
|
"Giving out device to module %s controller %s: DEV %s (%s)\n",
|
|
edac_dev->mod_name, edac_dev->ctl_name, edac_dev->dev_name,
|
|
edac_op_state_to_string(edac_dev->op_state));
|
|
|
|
mutex_unlock(&device_ctls_mutex);
|
|
return 0;
|
|
|
|
fail1:
|
|
/* Some error, so remove the entry from the lsit */
|
|
del_edac_device_from_global_list(edac_dev);
|
|
|
|
fail0:
|
|
mutex_unlock(&device_ctls_mutex);
|
|
return 1;
|
|
}
|
|
EXPORT_SYMBOL_GPL(edac_device_add_device);
|
|
|
|
struct edac_device_ctl_info *edac_device_del_device(struct device *dev)
|
|
{
|
|
struct edac_device_ctl_info *edac_dev;
|
|
|
|
edac_dbg(0, "\n");
|
|
|
|
mutex_lock(&device_ctls_mutex);
|
|
|
|
/* Find the structure on the list, if not there, then leave */
|
|
edac_dev = find_edac_device_by_dev(dev);
|
|
if (edac_dev == NULL) {
|
|
mutex_unlock(&device_ctls_mutex);
|
|
return NULL;
|
|
}
|
|
|
|
/* mark this instance as OFFLINE */
|
|
edac_dev->op_state = OP_OFFLINE;
|
|
|
|
/* deregister from global list */
|
|
del_edac_device_from_global_list(edac_dev);
|
|
|
|
mutex_unlock(&device_ctls_mutex);
|
|
|
|
/* clear workq processing on this instance */
|
|
edac_device_workq_teardown(edac_dev);
|
|
|
|
/* Tear down the sysfs entries for this instance */
|
|
edac_device_remove_sysfs(edac_dev);
|
|
|
|
edac_printk(KERN_INFO, EDAC_MC,
|
|
"Removed device %d for %s %s: DEV %s\n",
|
|
edac_dev->dev_idx,
|
|
edac_dev->mod_name, edac_dev->ctl_name, edac_dev_name(edac_dev));
|
|
|
|
return edac_dev;
|
|
}
|
|
EXPORT_SYMBOL_GPL(edac_device_del_device);
|
|
|
|
static inline int edac_device_get_log_ce(struct edac_device_ctl_info *edac_dev)
|
|
{
|
|
return edac_dev->log_ce;
|
|
}
|
|
|
|
static inline int edac_device_get_log_ue(struct edac_device_ctl_info *edac_dev)
|
|
{
|
|
return edac_dev->log_ue;
|
|
}
|
|
|
|
static inline int edac_device_get_panic_on_ce(struct edac_device_ctl_info
|
|
*edac_dev)
|
|
{
|
|
return edac_dev->panic_on_ce;
|
|
}
|
|
|
|
static inline int edac_device_get_panic_on_ue(struct edac_device_ctl_info
|
|
*edac_dev)
|
|
{
|
|
return edac_dev->panic_on_ue;
|
|
}
|
|
|
|
void edac_device_handle_ce(struct edac_device_ctl_info *edac_dev,
|
|
int inst_nr, int block_nr, const char *msg)
|
|
{
|
|
struct edac_device_instance *instance;
|
|
struct edac_device_block *block = NULL;
|
|
|
|
if ((inst_nr >= edac_dev->nr_instances) || (inst_nr < 0)) {
|
|
edac_device_printk(edac_dev, KERN_ERR,
|
|
"INTERNAL ERROR: 'instance' out of range "
|
|
"(%d >= %d)\n", inst_nr,
|
|
edac_dev->nr_instances);
|
|
return;
|
|
}
|
|
|
|
instance = edac_dev->instances + inst_nr;
|
|
|
|
if ((block_nr >= instance->nr_blocks) || (block_nr < 0)) {
|
|
edac_device_printk(edac_dev, KERN_ERR,
|
|
"INTERNAL ERROR: instance %d 'block' "
|
|
"out of range (%d >= %d)\n",
|
|
inst_nr, block_nr,
|
|
instance->nr_blocks);
|
|
return;
|
|
}
|
|
|
|
if (instance->nr_blocks > 0) {
|
|
block = instance->blocks + block_nr;
|
|
block->counters.ce_count++;
|
|
}
|
|
|
|
/* Propagate the count up the 'totals' tree */
|
|
instance->counters.ce_count++;
|
|
edac_dev->counters.ce_count++;
|
|
|
|
if (edac_device_get_log_ce(edac_dev))
|
|
edac_device_printk(edac_dev, KERN_WARNING,
|
|
"CE: %s instance: %s block: %s '%s'\n",
|
|
edac_dev->ctl_name, instance->name,
|
|
block ? block->name : "N/A", msg);
|
|
|
|
if (edac_device_get_panic_on_ce(edac_dev))
|
|
panic("EDAC %s: CE instance: %s block %s '%s'\n",
|
|
edac_dev->ctl_name, instance->name,
|
|
block ? block->name : "N/A", msg);
|
|
}
|
|
EXPORT_SYMBOL_GPL(edac_device_handle_ce);
|
|
|
|
void edac_device_handle_ue(struct edac_device_ctl_info *edac_dev,
|
|
int inst_nr, int block_nr, const char *msg)
|
|
{
|
|
struct edac_device_instance *instance;
|
|
struct edac_device_block *block = NULL;
|
|
|
|
if ((inst_nr >= edac_dev->nr_instances) || (inst_nr < 0)) {
|
|
edac_device_printk(edac_dev, KERN_ERR,
|
|
"INTERNAL ERROR: 'instance' out of range "
|
|
"(%d >= %d)\n", inst_nr,
|
|
edac_dev->nr_instances);
|
|
return;
|
|
}
|
|
|
|
instance = edac_dev->instances + inst_nr;
|
|
|
|
if ((block_nr >= instance->nr_blocks) || (block_nr < 0)) {
|
|
edac_device_printk(edac_dev, KERN_ERR,
|
|
"INTERNAL ERROR: instance %d 'block' "
|
|
"out of range (%d >= %d)\n",
|
|
inst_nr, block_nr,
|
|
instance->nr_blocks);
|
|
return;
|
|
}
|
|
|
|
if (instance->nr_blocks > 0) {
|
|
block = instance->blocks + block_nr;
|
|
block->counters.ue_count++;
|
|
}
|
|
|
|
/* Propagate the count up the 'totals' tree */
|
|
instance->counters.ue_count++;
|
|
edac_dev->counters.ue_count++;
|
|
|
|
if (edac_device_get_log_ue(edac_dev))
|
|
edac_device_printk(edac_dev, KERN_EMERG,
|
|
"UE: %s instance: %s block: %s '%s'\n",
|
|
edac_dev->ctl_name, instance->name,
|
|
block ? block->name : "N/A", msg);
|
|
|
|
if (edac_device_get_panic_on_ue(edac_dev))
|
|
panic("EDAC %s: UE instance: %s block %s '%s'\n",
|
|
edac_dev->ctl_name, instance->name,
|
|
block ? block->name : "N/A", msg);
|
|
}
|
|
EXPORT_SYMBOL_GPL(edac_device_handle_ue);
|