Merge branch 'akpm' (patches from Andrew)
Merge fourth set of updates from Andrew Morton: - the rest of lib/ - checkpatch updates - a few misc things - kasan: kernel address sanitizer - the rtc tree * emailed patches from Andrew Morton <akpm@linux-foundation.org>: (108 commits) ARM: mvebu: enable Armada 38x RTC driver in mvebu_v7_defconfig ARM: mvebu: add Device Tree description of RTC on Armada 38x MAINTAINERS: add the RTC driver for the Armada38x drivers/rtc/rtc-armada38x: add a new RTC driver for recent mvebu SoCs rtc: armada38x: add the device tree binding documentation rtc: rtc-ab-b5ze-s3: add sub-minute alarm support rtc: add support for Abracon AB-RTCMC-32.768kHz-B5ZE-S3 I2C RTC chip of: add vendor prefix for Abracon Corporation drivers/rtc/rtc-rk808.c: fix rtc time reading issue drivers/rtc/rtc-isl12057.c: constify struct regmap_config drivers/rtc/rtc-at91sam9.c: constify struct regmap_config drivers/rtc/rtc-imxdi.c: add more known register bits drivers/rtc/rtc-imxdi.c: trivial clean up code ARM: mvebu: ISL12057 rtc chip can now wake up RN102, RN102 and RN2120 rtc: rtc-isl12057: add isil,irq2-can-wakeup-machine property for in-tree users drivers/rtc/rtc-isl12057.c: add alarm support to Intersil ISL12057 RTC driver drivers/rtc/rtc-pcf2123.c: add support for devicetree kprobes: makes kprobes/enabled works correctly for optimized kprobes. kprobes: set kprobes_all_disarmed earlier to enable re-optimization. init: remove CONFIG_INIT_FALLBACK ...
This commit is contained in:
commit
83e047c104
|
@ -9,6 +9,7 @@ document for it just like any other devices.
|
|||
|
||||
Compatible Vendor / Chip
|
||||
========== =============
|
||||
abracon,abb5zes3 AB-RTCMC-32.768kHz-B5ZE-S3: Real Time Clock/Calendar Module with I2C Interface
|
||||
ad,ad7414 SMBus/I2C Digital Temperature Sensor in 6-Pin SOT with SMBus Alert and Over Temperature Pin
|
||||
ad,adm9240 ADM9240: Complete System Hardware Monitor for uProcessor-Based Systems
|
||||
adi,adt7461 +/-1C TDM Extended Temp Range I.C
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
* Real Time Clock of the Armada 38x SoCs
|
||||
|
||||
RTC controller for the Armada 38x SoCs
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "marvell,armada-380-rtc"
|
||||
- reg: a list of base address and size pairs, one for each entry in
|
||||
reg-names
|
||||
- reg names: should contain:
|
||||
* "rtc" for the RTC registers
|
||||
* "rtc-soc" for the SoC related registers and among them the one
|
||||
related to the interrupt.
|
||||
- interrupts: IRQ line for the RTC.
|
||||
|
||||
Example:
|
||||
|
||||
rtc@a3800 {
|
||||
compatible = "marvell,armada-380-rtc";
|
||||
reg = <0xa3800 0x20>, <0x184a0 0x0c>;
|
||||
reg-names = "rtc", "rtc-soc";
|
||||
interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
|
@ -0,0 +1,78 @@
|
|||
Intersil ISL12057 I2C RTC/Alarm chip
|
||||
|
||||
ISL12057 is a trivial I2C device (it has simple device tree bindings,
|
||||
consisting of a compatible field, an address and possibly an interrupt
|
||||
line).
|
||||
|
||||
Nonetheless, it also supports an option boolean property
|
||||
("isil,irq2-can-wakeup-machine") to handle the specific use-case found
|
||||
on at least three in-tree users of the chip (NETGEAR ReadyNAS 102, 104
|
||||
and 2120 ARM-based NAS); On those devices, the IRQ#2 pin of the chip
|
||||
(associated with the alarm supported by the driver) is not connected
|
||||
to the SoC but to a PMIC. It allows the device to be powered up when
|
||||
RTC alarm rings. In order to mark the device has a wakeup source and
|
||||
get access to the 'wakealarm' sysfs entry, this specific property can
|
||||
be set when the IRQ#2 pin of the chip is not connected to the SoC but
|
||||
can wake up the device.
|
||||
|
||||
Required properties supported by the device:
|
||||
|
||||
- "compatible": must be "isil,isl12057"
|
||||
- "reg": I2C bus address of the device
|
||||
|
||||
Optional properties:
|
||||
|
||||
- "isil,irq2-can-wakeup-machine": mark the chip as a wakeup source,
|
||||
independently of the availability of an IRQ line connected to the
|
||||
SoC.
|
||||
|
||||
- "interrupt-parent", "interrupts": for passing the interrupt line
|
||||
of the SoC connected to IRQ#2 of the RTC chip.
|
||||
|
||||
|
||||
Example isl12057 node without IRQ#2 pin connected (no alarm support):
|
||||
|
||||
isl12057: isl12057@68 {
|
||||
compatible = "isil,isl12057";
|
||||
reg = <0x68>;
|
||||
};
|
||||
|
||||
|
||||
Example isl12057 node with IRQ#2 pin connected to main SoC via MPP6 (note
|
||||
that the pinctrl-related properties below are given for completeness and
|
||||
may not be required or may be different depending on your system or
|
||||
SoC, and the main function of the MPP used as IRQ line, i.e.
|
||||
"interrupt-parent" and "interrupts" are usually sufficient):
|
||||
|
||||
pinctrl {
|
||||
...
|
||||
|
||||
rtc_alarm_pin: rtc_alarm_pin {
|
||||
marvell,pins = "mpp6";
|
||||
marvell,function = "gpio";
|
||||
};
|
||||
|
||||
...
|
||||
|
||||
};
|
||||
|
||||
...
|
||||
|
||||
isl12057: isl12057@68 {
|
||||
compatible = "isil,isl12057";
|
||||
reg = <0x68>;
|
||||
pinctrl-0 = <&rtc_alarm_pin>;
|
||||
pinctrl-names = "default";
|
||||
interrupt-parent = <&gpio0>;
|
||||
interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
|
||||
};
|
||||
|
||||
|
||||
Example isl12057 node without IRQ#2 pin connected to the SoC but to a
|
||||
PMIC, allowing the device to be started based on configured alarm:
|
||||
|
||||
isl12057: isl12057@68 {
|
||||
compatible = "isil,isl12057";
|
||||
reg = <0x68>;
|
||||
isil,irq2-can-wakeup-machine;
|
||||
};
|
|
@ -0,0 +1,16 @@
|
|||
NXP PCF2123 SPI Real Time Clock
|
||||
|
||||
Required properties:
|
||||
- compatible: should be: "nxp,rtc-pcf2123"
|
||||
- reg: should be the SPI slave chipselect address
|
||||
|
||||
Optional properties:
|
||||
- spi-cs-high: PCF2123 needs chipselect high
|
||||
|
||||
Example:
|
||||
|
||||
rtc: nxp,rtc-pcf2123@3 {
|
||||
compatible = "nxp,rtc-pcf2123"
|
||||
reg = <3>
|
||||
spi-cs-high;
|
||||
};
|
|
@ -4,6 +4,7 @@ This isn't an exhaustive list, but you should add new prefixes to it before
|
|||
using them to avoid name-space collisions.
|
||||
|
||||
abilis Abilis Systems
|
||||
abcn Abracon Corporation
|
||||
active-semi Active-Semi International Inc
|
||||
ad Avionic Design GmbH
|
||||
adapteva Adapteva, Inc.
|
||||
|
|
|
@ -0,0 +1,170 @@
|
|||
Kernel address sanitizer
|
||||
================
|
||||
|
||||
0. Overview
|
||||
===========
|
||||
|
||||
Kernel Address sanitizer (KASan) is a dynamic memory error detector. It provides
|
||||
a fast and comprehensive solution for finding use-after-free and out-of-bounds
|
||||
bugs.
|
||||
|
||||
KASan uses compile-time instrumentation for checking every memory access,
|
||||
therefore you will need a certain version of GCC > 4.9.2
|
||||
|
||||
Currently KASan is supported only for x86_64 architecture and requires that the
|
||||
kernel be built with the SLUB allocator.
|
||||
|
||||
1. Usage
|
||||
=========
|
||||
|
||||
To enable KASAN configure kernel with:
|
||||
|
||||
CONFIG_KASAN = y
|
||||
|
||||
and choose between CONFIG_KASAN_OUTLINE and CONFIG_KASAN_INLINE. Outline/inline
|
||||
is compiler instrumentation types. The former produces smaller binary the
|
||||
latter is 1.1 - 2 times faster. Inline instrumentation requires GCC 5.0 or
|
||||
latter.
|
||||
|
||||
Currently KASAN works only with the SLUB memory allocator.
|
||||
For better bug detection and nicer report, enable CONFIG_STACKTRACE and put
|
||||
at least 'slub_debug=U' in the boot cmdline.
|
||||
|
||||
To disable instrumentation for specific files or directories, add a line
|
||||
similar to the following to the respective kernel Makefile:
|
||||
|
||||
For a single file (e.g. main.o):
|
||||
KASAN_SANITIZE_main.o := n
|
||||
|
||||
For all files in one directory:
|
||||
KASAN_SANITIZE := n
|
||||
|
||||
1.1 Error reports
|
||||
==========
|
||||
|
||||
A typical out of bounds access report looks like this:
|
||||
|
||||
==================================================================
|
||||
BUG: AddressSanitizer: out of bounds access in kmalloc_oob_right+0x65/0x75 [test_kasan] at addr ffff8800693bc5d3
|
||||
Write of size 1 by task modprobe/1689
|
||||
=============================================================================
|
||||
BUG kmalloc-128 (Not tainted): kasan error
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
Disabling lock debugging due to kernel taint
|
||||
INFO: Allocated in kmalloc_oob_right+0x3d/0x75 [test_kasan] age=0 cpu=0 pid=1689
|
||||
__slab_alloc+0x4b4/0x4f0
|
||||
kmem_cache_alloc_trace+0x10b/0x190
|
||||
kmalloc_oob_right+0x3d/0x75 [test_kasan]
|
||||
init_module+0x9/0x47 [test_kasan]
|
||||
do_one_initcall+0x99/0x200
|
||||
load_module+0x2cb3/0x3b20
|
||||
SyS_finit_module+0x76/0x80
|
||||
system_call_fastpath+0x12/0x17
|
||||
INFO: Slab 0xffffea0001a4ef00 objects=17 used=7 fp=0xffff8800693bd728 flags=0x100000000004080
|
||||
INFO: Object 0xffff8800693bc558 @offset=1368 fp=0xffff8800693bc720
|
||||
|
||||
Bytes b4 ffff8800693bc548: 00 00 00 00 00 00 00 00 5a 5a 5a 5a 5a 5a 5a 5a ........ZZZZZZZZ
|
||||
Object ffff8800693bc558: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
|
||||
Object ffff8800693bc568: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
|
||||
Object ffff8800693bc578: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
|
||||
Object ffff8800693bc588: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
|
||||
Object ffff8800693bc598: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
|
||||
Object ffff8800693bc5a8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
|
||||
Object ffff8800693bc5b8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
|
||||
Object ffff8800693bc5c8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b a5 kkkkkkkkkkkkkkk.
|
||||
Redzone ffff8800693bc5d8: cc cc cc cc cc cc cc cc ........
|
||||
Padding ffff8800693bc718: 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZ
|
||||
CPU: 0 PID: 1689 Comm: modprobe Tainted: G B 3.18.0-rc1-mm1+ #98
|
||||
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.7.5-0-ge51488c-20140602_164612-nilsson.home.kraxel.org 04/01/2014
|
||||
ffff8800693bc000 0000000000000000 ffff8800693bc558 ffff88006923bb78
|
||||
ffffffff81cc68ae 00000000000000f3 ffff88006d407600 ffff88006923bba8
|
||||
ffffffff811fd848 ffff88006d407600 ffffea0001a4ef00 ffff8800693bc558
|
||||
Call Trace:
|
||||
[<ffffffff81cc68ae>] dump_stack+0x46/0x58
|
||||
[<ffffffff811fd848>] print_trailer+0xf8/0x160
|
||||
[<ffffffffa00026a7>] ? kmem_cache_oob+0xc3/0xc3 [test_kasan]
|
||||
[<ffffffff811ff0f5>] object_err+0x35/0x40
|
||||
[<ffffffffa0002065>] ? kmalloc_oob_right+0x65/0x75 [test_kasan]
|
||||
[<ffffffff8120b9fa>] kasan_report_error+0x38a/0x3f0
|
||||
[<ffffffff8120a79f>] ? kasan_poison_shadow+0x2f/0x40
|
||||
[<ffffffff8120b344>] ? kasan_unpoison_shadow+0x14/0x40
|
||||
[<ffffffff8120a79f>] ? kasan_poison_shadow+0x2f/0x40
|
||||
[<ffffffffa00026a7>] ? kmem_cache_oob+0xc3/0xc3 [test_kasan]
|
||||
[<ffffffff8120a995>] __asan_store1+0x75/0xb0
|
||||
[<ffffffffa0002601>] ? kmem_cache_oob+0x1d/0xc3 [test_kasan]
|
||||
[<ffffffffa0002065>] ? kmalloc_oob_right+0x65/0x75 [test_kasan]
|
||||
[<ffffffffa0002065>] kmalloc_oob_right+0x65/0x75 [test_kasan]
|
||||
[<ffffffffa00026b0>] init_module+0x9/0x47 [test_kasan]
|
||||
[<ffffffff810002d9>] do_one_initcall+0x99/0x200
|
||||
[<ffffffff811e4e5c>] ? __vunmap+0xec/0x160
|
||||
[<ffffffff81114f63>] load_module+0x2cb3/0x3b20
|
||||
[<ffffffff8110fd70>] ? m_show+0x240/0x240
|
||||
[<ffffffff81115f06>] SyS_finit_module+0x76/0x80
|
||||
[<ffffffff81cd3129>] system_call_fastpath+0x12/0x17
|
||||
Memory state around the buggy address:
|
||||
ffff8800693bc300: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
|
||||
ffff8800693bc380: fc fc 00 00 00 00 00 00 00 00 00 00 00 00 00 fc
|
||||
ffff8800693bc400: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
|
||||
ffff8800693bc480: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
|
||||
ffff8800693bc500: fc fc fc fc fc fc fc fc fc fc fc 00 00 00 00 00
|
||||
>ffff8800693bc580: 00 00 00 00 00 00 00 00 00 00 03 fc fc fc fc fc
|
||||
^
|
||||
ffff8800693bc600: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
|
||||
ffff8800693bc680: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
|
||||
ffff8800693bc700: fc fc fc fc fb fb fb fb fb fb fb fb fb fb fb fb
|
||||
ffff8800693bc780: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
|
||||
ffff8800693bc800: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
|
||||
==================================================================
|
||||
|
||||
First sections describe slub object where bad access happened.
|
||||
See 'SLUB Debug output' section in Documentation/vm/slub.txt for details.
|
||||
|
||||
In the last section the report shows memory state around the accessed address.
|
||||
Reading this part requires some more understanding of how KASAN works.
|
||||
|
||||
Each 8 bytes of memory are encoded in one shadow byte as accessible,
|
||||
partially accessible, freed or they can be part of a redzone.
|
||||
We use the following encoding for each shadow byte: 0 means that all 8 bytes
|
||||
of the corresponding memory region are accessible; number N (1 <= N <= 7) means
|
||||
that the first N bytes are accessible, and other (8 - N) bytes are not;
|
||||
any negative value indicates that the entire 8-byte word is inaccessible.
|
||||
We use different negative values to distinguish between different kinds of
|
||||
inaccessible memory like redzones or freed memory (see mm/kasan/kasan.h).
|
||||
|
||||
In the report above the arrows point to the shadow byte 03, which means that
|
||||
the accessed address is partially accessible.
|
||||
|
||||
|
||||
2. Implementation details
|
||||
========================
|
||||
|
||||
From a high level, our approach to memory error detection is similar to that
|
||||
of kmemcheck: use shadow memory to record whether each byte of memory is safe
|
||||
to access, and use compile-time instrumentation to check shadow memory on each
|
||||
memory access.
|
||||
|
||||
AddressSanitizer dedicates 1/8 of kernel memory to its shadow memory
|
||||
(e.g. 16TB to cover 128TB on x86_64) and uses direct mapping with a scale and
|
||||
offset to translate a memory address to its corresponding shadow address.
|
||||
|
||||
Here is the function witch translate an address to its corresponding shadow
|
||||
address:
|
||||
|
||||
static inline void *kasan_mem_to_shadow(const void *addr)
|
||||
{
|
||||
return ((unsigned long)addr >> KASAN_SHADOW_SCALE_SHIFT)
|
||||
+ KASAN_SHADOW_OFFSET;
|
||||
}
|
||||
|
||||
where KASAN_SHADOW_SCALE_SHIFT = 3.
|
||||
|
||||
Compile-time instrumentation used for checking memory accesses. Compiler inserts
|
||||
function calls (__asan_load*(addr), __asan_store*(addr)) before each memory
|
||||
access of size 1, 2, 4, 8 or 16. These functions check whether memory access is
|
||||
valid or not by checking corresponding shadow memory.
|
||||
|
||||
GCC 5.0 has possibility to perform inline instrumentation. Instead of making
|
||||
function calls GCC directly inserts the code to check the shadow memory.
|
||||
This option significantly enlarges kernel but it gives x1.1-x2 performance
|
||||
boost over outline instrumented kernel.
|
|
@ -42,7 +42,6 @@
|
|||
MODULE_DESCRIPTION("V4L2 PCI Skeleton Driver");
|
||||
MODULE_AUTHOR("Hans Verkuil");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DEVICE_TABLE(pci, skeleton_pci_tbl);
|
||||
|
||||
/**
|
||||
* struct skeleton - All internal data for one instance of device
|
||||
|
@ -95,6 +94,7 @@ static const struct pci_device_id skeleton_pci_tbl[] = {
|
|||
/* { PCI_DEVICE(PCI_VENDOR_ID_, PCI_DEVICE_ID_) }, */
|
||||
{ 0, }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, skeleton_pci_tbl);
|
||||
|
||||
/*
|
||||
* HDTV: this structure has the capabilities of the HDTV receiver.
|
||||
|
|
|
@ -12,6 +12,8 @@ ffffc90000000000 - ffffe8ffffffffff (=45 bits) vmalloc/ioremap space
|
|||
ffffe90000000000 - ffffe9ffffffffff (=40 bits) hole
|
||||
ffffea0000000000 - ffffeaffffffffff (=40 bits) virtual memory map (1TB)
|
||||
... unused hole ...
|
||||
ffffec0000000000 - fffffc0000000000 (=44 bits) kasan shadow memory (16TB)
|
||||
... unused hole ...
|
||||
ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks
|
||||
... unused hole ...
|
||||
ffffffff80000000 - ffffffffa0000000 (=512 MB) kernel text mapping, from phys 0
|
||||
|
|
|
@ -1173,6 +1173,7 @@ M: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
|
|||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: arch/arm/mach-mvebu/
|
||||
F: drivers/rtc/armada38x-rtc
|
||||
|
||||
ARM/Marvell Berlin SoC support
|
||||
M: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
|
||||
|
|
3
Makefile
3
Makefile
|
@ -423,7 +423,7 @@ export MAKE AWK GENKSYMS INSTALLKERNEL PERL PYTHON UTS_MACHINE
|
|||
export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
|
||||
|
||||
export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
|
||||
export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE CFLAGS_GCOV
|
||||
export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE CFLAGS_GCOV CFLAGS_KASAN
|
||||
export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
|
||||
export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE
|
||||
export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL
|
||||
|
@ -781,6 +781,7 @@ ifeq ($(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-goto.sh $(CC)), y)
|
|||
KBUILD_CFLAGS += -DCC_HAVE_ASM_GOTO
|
||||
endif
|
||||
|
||||
include $(srctree)/scripts/Makefile.kasan
|
||||
include $(srctree)/scripts/Makefile.extrawarn
|
||||
|
||||
# Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments
|
||||
|
|
|
@ -87,6 +87,7 @@
|
|||
isl12057: isl12057@68 {
|
||||
compatible = "isil,isl12057";
|
||||
reg = <0x68>;
|
||||
isil,irq2-can-wakeup-machine;
|
||||
};
|
||||
|
||||
g762: g762@3e {
|
||||
|
|
|
@ -93,6 +93,7 @@
|
|||
isl12057: isl12057@68 {
|
||||
compatible = "isil,isl12057";
|
||||
reg = <0x68>;
|
||||
isil,irq2-can-wakeup-machine;
|
||||
};
|
||||
|
||||
g762: g762@3e {
|
||||
|
|
|
@ -381,6 +381,13 @@
|
|||
clocks = <&gateclk 4>;
|
||||
};
|
||||
|
||||
rtc@a3800 {
|
||||
compatible = "marvell,armada-380-rtc";
|
||||
reg = <0xa3800 0x20>, <0x184a0 0x0c>;
|
||||
reg-names = "rtc", "rtc-soc";
|
||||
interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
||||
|
||||
sata@a8000 {
|
||||
compatible = "marvell,armada-380-ahci";
|
||||
reg = <0xa8000 0x2000>;
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
isl12057: isl12057@68 {
|
||||
compatible = "isil,isl12057";
|
||||
reg = <0x68>;
|
||||
isil,irq2-can-wakeup-machine;
|
||||
};
|
||||
|
||||
/* Controller for rear fan #1 of 3 (Protechnic
|
||||
|
|
|
@ -112,6 +112,7 @@ CONFIG_LEDS_TRIGGER_HEARTBEAT=y
|
|||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_S35390A=y
|
||||
CONFIG_RTC_DRV_MV=y
|
||||
CONFIG_RTC_DRV_ARMADA38X=y
|
||||
CONFIG_DMADEVICES=y
|
||||
CONFIG_MV_XOR=y
|
||||
# CONFIG_IOMMU_SUPPORT is not set
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
void *module_alloc(unsigned long size)
|
||||
{
|
||||
return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
|
||||
GFP_KERNEL, PAGE_KERNEL_EXEC, NUMA_NO_NODE,
|
||||
GFP_KERNEL, PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
|
||||
__builtin_return_address(0));
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -35,8 +35,8 @@
|
|||
void *module_alloc(unsigned long size)
|
||||
{
|
||||
return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
|
||||
GFP_KERNEL, PAGE_KERNEL_EXEC, NUMA_NO_NODE,
|
||||
__builtin_return_address(0));
|
||||
GFP_KERNEL, PAGE_KERNEL_EXEC, 0,
|
||||
NUMA_NO_NODE, __builtin_return_address(0));
|
||||
}
|
||||
|
||||
enum aarch64_reloc_op {
|
||||
|
|
|
@ -217,14 +217,12 @@ static ssize_t show_number_of_sets(struct cache_info *this_leaf, char *buf)
|
|||
|
||||
static ssize_t show_shared_cpu_map(struct cache_info *this_leaf, char *buf)
|
||||
{
|
||||
ssize_t len;
|
||||
cpumask_t shared_cpu_map;
|
||||
|
||||
cpumask_and(&shared_cpu_map,
|
||||
&this_leaf->shared_cpu_map, cpu_online_mask);
|
||||
len = cpumask_scnprintf(buf, NR_CPUS+1, &shared_cpu_map);
|
||||
len += sprintf(buf+len, "\n");
|
||||
return len;
|
||||
return scnprintf(buf, PAGE_SIZE, "%*pb\n",
|
||||
cpumask_pr_args(&shared_cpu_map));
|
||||
}
|
||||
|
||||
static ssize_t show_type(struct cache_info *this_leaf, char *buf)
|
||||
|
|
|
@ -47,7 +47,7 @@ static DEFINE_SPINLOCK(dbe_lock);
|
|||
void *module_alloc(unsigned long size)
|
||||
{
|
||||
return __vmalloc_node_range(size, 1, MODULE_START, MODULE_END,
|
||||
GFP_KERNEL, PAGE_KERNEL, NUMA_NO_NODE,
|
||||
GFP_KERNEL, PAGE_KERNEL, 0, NUMA_NO_NODE,
|
||||
__builtin_return_address(0));
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -162,7 +162,6 @@ void __init nlm_smp_setup(void)
|
|||
unsigned int boot_cpu;
|
||||
int num_cpus, i, ncore, node;
|
||||
volatile u32 *cpu_ready = nlm_get_boot_data(BOOT_CPU_READY);
|
||||
char buf[64];
|
||||
|
||||
boot_cpu = hard_smp_processor_id();
|
||||
cpumask_clear(&phys_cpu_present_mask);
|
||||
|
@ -189,10 +188,10 @@ void __init nlm_smp_setup(void)
|
|||
}
|
||||
}
|
||||
|
||||
cpumask_scnprintf(buf, ARRAY_SIZE(buf), &phys_cpu_present_mask);
|
||||
pr_info("Physical CPU mask: %s\n", buf);
|
||||
cpumask_scnprintf(buf, ARRAY_SIZE(buf), cpu_possible_mask);
|
||||
pr_info("Possible CPU mask: %s\n", buf);
|
||||
pr_info("Physical CPU mask: %*pb\n",
|
||||
cpumask_pr_args(&phys_cpu_present_mask));
|
||||
pr_info("Possible CPU mask: %*pb\n",
|
||||
cpumask_pr_args(cpu_possible_mask));
|
||||
|
||||
/* check with the cores we have woken up */
|
||||
for (ncore = 0, i = 0; i < NLM_NR_NODES; i++)
|
||||
|
@ -209,7 +208,6 @@ static int nlm_parse_cpumask(cpumask_t *wakeup_mask)
|
|||
{
|
||||
uint32_t core0_thr_mask, core_thr_mask;
|
||||
int threadmode, i, j;
|
||||
char buf[64];
|
||||
|
||||
core0_thr_mask = 0;
|
||||
for (i = 0; i < NLM_THREADS_PER_CORE; i++)
|
||||
|
@ -244,8 +242,7 @@ static int nlm_parse_cpumask(cpumask_t *wakeup_mask)
|
|||
return threadmode;
|
||||
|
||||
unsupp:
|
||||
cpumask_scnprintf(buf, ARRAY_SIZE(buf), wakeup_mask);
|
||||
panic("Unsupported CPU mask %s", buf);
|
||||
panic("Unsupported CPU mask %*pb", cpumask_pr_args(wakeup_mask));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -219,7 +219,7 @@ void *module_alloc(unsigned long size)
|
|||
* init_data correctly */
|
||||
return __vmalloc_node_range(size, 1, VMALLOC_START, VMALLOC_END,
|
||||
GFP_KERNEL | __GFP_HIGHMEM,
|
||||
PAGE_KERNEL_RWX, NUMA_NO_NODE,
|
||||
PAGE_KERNEL_RWX, 0, NUMA_NO_NODE,
|
||||
__builtin_return_address(0));
|
||||
}
|
||||
|
||||
|
|
|
@ -607,19 +607,16 @@ static ssize_t shared_cpu_map_show(struct kobject *k, struct kobj_attribute *att
|
|||
{
|
||||
struct cache_index_dir *index;
|
||||
struct cache *cache;
|
||||
int len;
|
||||
int n = 0;
|
||||
int ret;
|
||||
|
||||
index = kobj_to_cache_index_dir(k);
|
||||
cache = index->cache;
|
||||
len = PAGE_SIZE - 2;
|
||||
|
||||
if (len > 1) {
|
||||
n = cpumask_scnprintf(buf, len, &cache->shared_cpu_map);
|
||||
buf[n++] = '\n';
|
||||
buf[n] = '\0';
|
||||
}
|
||||
return n;
|
||||
ret = scnprintf(buf, PAGE_SIZE - 1, "%*pb\n",
|
||||
cpumask_pr_args(&cache->shared_cpu_map));
|
||||
buf[ret++] = '\n';
|
||||
buf[ret] = '\0';
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct kobj_attribute cache_shared_cpu_map_attr =
|
||||
|
|
|
@ -131,10 +131,8 @@ static int ics_opal_set_affinity(struct irq_data *d,
|
|||
|
||||
wanted_server = xics_get_irq_server(d->irq, cpumask, 1);
|
||||
if (wanted_server < 0) {
|
||||
char cpulist[128];
|
||||
cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask);
|
||||
pr_warning("%s: No online cpus in the mask %s for irq %d\n",
|
||||
__func__, cpulist, d->irq);
|
||||
pr_warning("%s: No online cpus in the mask %*pb for irq %d\n",
|
||||
__func__, cpumask_pr_args(cpumask), d->irq);
|
||||
return -1;
|
||||
}
|
||||
server = ics_opal_mangle_server(wanted_server);
|
||||
|
|
|
@ -140,11 +140,8 @@ static int ics_rtas_set_affinity(struct irq_data *d,
|
|||
|
||||
irq_server = xics_get_irq_server(d->irq, cpumask, 1);
|
||||
if (irq_server == -1) {
|
||||
char cpulist[128];
|
||||
cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask);
|
||||
printk(KERN_WARNING
|
||||
"%s: No online cpus in the mask %s for irq %d\n",
|
||||
__func__, cpulist, d->irq);
|
||||
pr_warning("%s: No online cpus in the mask %*pb for irq %d\n",
|
||||
__func__, cpumask_pr_args(cpumask), d->irq);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ void *module_alloc(unsigned long size)
|
|||
if (PAGE_ALIGN(size) > MODULES_LEN)
|
||||
return NULL;
|
||||
return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
|
||||
GFP_KERNEL, PAGE_KERNEL, NUMA_NO_NODE,
|
||||
GFP_KERNEL, PAGE_KERNEL, 0, NUMA_NO_NODE,
|
||||
__builtin_return_address(0));
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -29,7 +29,7 @@ static void *module_map(unsigned long size)
|
|||
if (PAGE_ALIGN(size) > MODULES_LEN)
|
||||
return NULL;
|
||||
return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
|
||||
GFP_KERNEL, PAGE_KERNEL, NUMA_NO_NODE,
|
||||
GFP_KERNEL, PAGE_KERNEL, 0, NUMA_NO_NODE,
|
||||
__builtin_return_address(0));
|
||||
}
|
||||
#else
|
||||
|
|
|
@ -909,11 +909,8 @@ static void hardwall_destroy(struct hardwall_info *info)
|
|||
static int hardwall_proc_show(struct seq_file *sf, void *v)
|
||||
{
|
||||
struct hardwall_info *info = sf->private;
|
||||
char buf[256];
|
||||
|
||||
int rc = cpulist_scnprintf(buf, sizeof(buf), &info->cpumask);
|
||||
buf[rc++] = '\n';
|
||||
seq_write(sf, buf, rc);
|
||||
seq_printf(sf, "%*pbl\n", cpumask_pr_args(&info->cpumask));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,10 +45,9 @@ static int show_cpuinfo(struct seq_file *m, void *v)
|
|||
int n = ptr_to_cpu(v);
|
||||
|
||||
if (n == 0) {
|
||||
char buf[NR_CPUS*5];
|
||||
cpulist_scnprintf(buf, sizeof(buf), cpu_online_mask);
|
||||
seq_printf(m, "cpu count\t: %d\n", num_online_cpus());
|
||||
seq_printf(m, "cpu list\t: %s\n", buf);
|
||||
seq_printf(m, "cpu list\t: %*pbl\n",
|
||||
cpumask_pr_args(cpu_online_mask));
|
||||
seq_printf(m, "model name\t: %s\n", chip_model);
|
||||
seq_printf(m, "flags\t\t:\n"); /* nothing for now */
|
||||
seq_printf(m, "cpu MHz\t\t: %llu.%06llu\n",
|
||||
|
|
|
@ -215,12 +215,11 @@ early_param("mem", setup_mem); /* compatibility with x86 */
|
|||
|
||||
static int __init setup_isolnodes(char *str)
|
||||
{
|
||||
char buf[MAX_NUMNODES * 5];
|
||||
if (str == NULL || nodelist_parse(str, isolnodes) != 0)
|
||||
return -EINVAL;
|
||||
|
||||
nodelist_scnprintf(buf, sizeof(buf), isolnodes);
|
||||
pr_info("Set isolnodes value to '%s'\n", buf);
|
||||
pr_info("Set isolnodes value to '%*pbl'\n",
|
||||
nodemask_pr_args(&isolnodes));
|
||||
return 0;
|
||||
}
|
||||
early_param("isolnodes", setup_isolnodes);
|
||||
|
@ -1315,11 +1314,9 @@ early_param("disabled_cpus", disabled_cpus);
|
|||
|
||||
void __init print_disabled_cpus(void)
|
||||
{
|
||||
if (!cpumask_empty(&disabled_map)) {
|
||||
char buf[100];
|
||||
cpulist_scnprintf(buf, sizeof(buf), &disabled_map);
|
||||
pr_info("CPUs not available for Linux: %s\n", buf);
|
||||
}
|
||||
if (!cpumask_empty(&disabled_map))
|
||||
pr_info("CPUs not available for Linux: %*pbl\n",
|
||||
cpumask_pr_args(&disabled_map));
|
||||
}
|
||||
|
||||
static void __init setup_cpu_maps(void)
|
||||
|
|
|
@ -115,7 +115,6 @@ void flush_remote(unsigned long cache_pfn, unsigned long cache_control,
|
|||
struct cpumask cache_cpumask_copy, tlb_cpumask_copy;
|
||||
struct cpumask *cache_cpumask, *tlb_cpumask;
|
||||
HV_PhysAddr cache_pa;
|
||||
char cache_buf[NR_CPUS*5], tlb_buf[NR_CPUS*5];
|
||||
|
||||
mb(); /* provided just to simplify "magic hypervisor" mode */
|
||||
|
||||
|
@ -149,13 +148,12 @@ void flush_remote(unsigned long cache_pfn, unsigned long cache_control,
|
|||
asids, asidcount);
|
||||
if (rc == 0)
|
||||
return;
|
||||
cpumask_scnprintf(cache_buf, sizeof(cache_buf), &cache_cpumask_copy);
|
||||
cpumask_scnprintf(tlb_buf, sizeof(tlb_buf), &tlb_cpumask_copy);
|
||||
|
||||
pr_err("hv_flush_remote(%#llx, %#lx, %p [%s], %#lx, %#lx, %#lx, %p [%s], %p, %d) = %d\n",
|
||||
cache_pa, cache_control, cache_cpumask, cache_buf,
|
||||
(unsigned long)tlb_va, tlb_length, tlb_pgsize,
|
||||
tlb_cpumask, tlb_buf, asids, asidcount, rc);
|
||||
pr_err("hv_flush_remote(%#llx, %#lx, %p [%*pb], %#lx, %#lx, %#lx, %p [%*pb], %p, %d) = %d\n",
|
||||
cache_pa, cache_control, cache_cpumask,
|
||||
cpumask_pr_args(&cache_cpumask_copy),
|
||||
(unsigned long)tlb_va, tlb_length, tlb_pgsize, tlb_cpumask,
|
||||
cpumask_pr_args(&tlb_cpumask_copy), asids, asidcount, rc);
|
||||
panic("Unsafe to continue.");
|
||||
}
|
||||
|
||||
|
|
|
@ -353,15 +353,13 @@ static int __init setup_ktext(char *str)
|
|||
|
||||
/* Neighborhood ktext pages on specified mask */
|
||||
else if (cpulist_parse(str, &ktext_mask) == 0) {
|
||||
char buf[NR_CPUS * 5];
|
||||
cpulist_scnprintf(buf, sizeof(buf), &ktext_mask);
|
||||
if (cpumask_weight(&ktext_mask) > 1) {
|
||||
ktext_small = 1;
|
||||
pr_info("ktext: using caching neighborhood %s with small pages\n",
|
||||
buf);
|
||||
pr_info("ktext: using caching neighborhood %*pbl with small pages\n",
|
||||
cpumask_pr_args(&ktext_mask));
|
||||
} else {
|
||||
pr_info("ktext: caching on cpu %s with one huge page\n",
|
||||
buf);
|
||||
pr_info("ktext: caching on cpu %*pbl with one huge page\n",
|
||||
cpumask_pr_args(&ktext_mask));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -492,11 +490,9 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
|
|||
struct cpumask bad;
|
||||
cpumask_andnot(&bad, &ktext_mask, cpu_possible_mask);
|
||||
cpumask_and(&ktext_mask, &ktext_mask, cpu_possible_mask);
|
||||
if (!cpumask_empty(&bad)) {
|
||||
char buf[NR_CPUS * 5];
|
||||
cpulist_scnprintf(buf, sizeof(buf), &bad);
|
||||
pr_info("ktext: not using unavailable cpus %s\n", buf);
|
||||
}
|
||||
if (!cpumask_empty(&bad))
|
||||
pr_info("ktext: not using unavailable cpus %*pbl\n",
|
||||
cpumask_pr_args(&bad));
|
||||
if (cpumask_empty(&ktext_mask)) {
|
||||
pr_warn("ktext: no valid cpus; caching on %d\n",
|
||||
smp_processor_id());
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
void *module_alloc(unsigned long size)
|
||||
{
|
||||
return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
|
||||
GFP_KERNEL, PAGE_KERNEL_EXEC, NUMA_NO_NODE,
|
||||
GFP_KERNEL, PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
|
||||
__builtin_return_address(0));
|
||||
}
|
||||
|
||||
|
|
|
@ -85,6 +85,7 @@ config X86
|
|||
select HAVE_CMPXCHG_LOCAL
|
||||
select HAVE_CMPXCHG_DOUBLE
|
||||
select HAVE_ARCH_KMEMCHECK
|
||||
select HAVE_ARCH_KASAN if X86_64 && SPARSEMEM_VMEMMAP
|
||||
select HAVE_USER_RETURN_NOTIFIER
|
||||
select ARCH_BINFMT_ELF_RANDOMIZE_PIE
|
||||
select HAVE_ARCH_JUMP_LABEL
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
# Set it to -DSVGA_MODE=NORMAL_VGA if you just want the EGA/VGA mode.
|
||||
# The number is the same as you would ordinarily press at bootup.
|
||||
|
||||
KASAN_SANITIZE := n
|
||||
|
||||
SVGA_MODE := -DSVGA_MODE=NORMAL_VGA
|
||||
|
||||
targets := vmlinux.bin setup.bin setup.elf bzImage
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
# (see scripts/Makefile.lib size_append)
|
||||
# compressed vmlinux.bin.all + u32 size of vmlinux.bin.all
|
||||
|
||||
KASAN_SANITIZE := n
|
||||
|
||||
targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \
|
||||
vmlinux.bin.xz vmlinux.bin.lzo vmlinux.bin.lz4
|
||||
|
||||
|
|
|
@ -13,8 +13,7 @@
|
|||
#include <asm/setup.h>
|
||||
#include <asm/desc.h>
|
||||
|
||||
#undef memcpy /* Use memcpy from misc.c */
|
||||
|
||||
#include "../string.h"
|
||||
#include "eboot.h"
|
||||
|
||||
static efi_system_table_t *sys_table;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
* we just keep it from happening
|
||||
*/
|
||||
#undef CONFIG_PARAVIRT
|
||||
#undef CONFIG_KASAN
|
||||
#ifdef CONFIG_X86_32
|
||||
#define _ASM_X86_DESC_H 1
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef _ASM_X86_KASAN_H
|
||||
#define _ASM_X86_KASAN_H
|
||||
|
||||
/*
|
||||
* Compiler uses shadow offset assuming that addresses start
|
||||
* from 0. Kernel addresses don't start from 0, so shadow
|
||||
* for kernel really starts from compiler's shadow offset +
|
||||
* 'kernel address space start' >> KASAN_SHADOW_SCALE_SHIFT
|
||||
*/
|
||||
#define KASAN_SHADOW_START (KASAN_SHADOW_OFFSET + \
|
||||
(0xffff800000000000ULL >> 3))
|
||||
/* 47 bits for kernel address -> (47 - 3) bits for shadow */
|
||||
#define KASAN_SHADOW_END (KASAN_SHADOW_START + (1ULL << (47 - 3)))
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
extern pte_t kasan_zero_pte[];
|
||||
extern pte_t kasan_zero_pmd[];
|
||||
extern pte_t kasan_zero_pud[];
|
||||
|
||||
#ifdef CONFIG_KASAN
|
||||
void __init kasan_map_early_shadow(pgd_t *pgd);
|
||||
void __init kasan_init(void);
|
||||
#else
|
||||
static inline void kasan_map_early_shadow(pgd_t *pgd) { }
|
||||
static inline void kasan_init(void) { }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,17 +1,23 @@
|
|||
#ifndef _ASM_X86_PAGE_64_DEFS_H
|
||||
#define _ASM_X86_PAGE_64_DEFS_H
|
||||
|
||||
#define THREAD_SIZE_ORDER 2
|
||||
#ifdef CONFIG_KASAN
|
||||
#define KASAN_STACK_ORDER 1
|
||||
#else
|
||||
#define KASAN_STACK_ORDER 0
|
||||
#endif
|
||||
|
||||
#define THREAD_SIZE_ORDER (2 + KASAN_STACK_ORDER)
|
||||
#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
|
||||
#define CURRENT_MASK (~(THREAD_SIZE - 1))
|
||||
|
||||
#define EXCEPTION_STACK_ORDER 0
|
||||
#define EXCEPTION_STACK_ORDER (0 + KASAN_STACK_ORDER)
|
||||
#define EXCEPTION_STKSZ (PAGE_SIZE << EXCEPTION_STACK_ORDER)
|
||||
|
||||
#define DEBUG_STACK_ORDER (EXCEPTION_STACK_ORDER + 1)
|
||||
#define DEBUG_STKSZ (PAGE_SIZE << DEBUG_STACK_ORDER)
|
||||
|
||||
#define IRQ_STACK_ORDER 2
|
||||
#define IRQ_STACK_ORDER (2 + KASAN_STACK_ORDER)
|
||||
#define IRQ_STACK_SIZE (PAGE_SIZE << IRQ_STACK_ORDER)
|
||||
|
||||
#define DOUBLEFAULT_STACK 1
|
||||
|
|
|
@ -27,11 +27,12 @@ static __always_inline void *__inline_memcpy(void *to, const void *from, size_t
|
|||
function. */
|
||||
|
||||
#define __HAVE_ARCH_MEMCPY 1
|
||||
extern void *__memcpy(void *to, const void *from, size_t len);
|
||||
|
||||
#ifndef CONFIG_KMEMCHECK
|
||||
#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4
|
||||
extern void *memcpy(void *to, const void *from, size_t len);
|
||||
#else
|
||||
extern void *__memcpy(void *to, const void *from, size_t len);
|
||||
#define memcpy(dst, src, len) \
|
||||
({ \
|
||||
size_t __len = (len); \
|
||||
|
@ -53,9 +54,11 @@ extern void *__memcpy(void *to, const void *from, size_t len);
|
|||
|
||||
#define __HAVE_ARCH_MEMSET
|
||||
void *memset(void *s, int c, size_t n);
|
||||
void *__memset(void *s, int c, size_t n);
|
||||
|
||||
#define __HAVE_ARCH_MEMMOVE
|
||||
void *memmove(void *dest, const void *src, size_t count);
|
||||
void *__memmove(void *dest, const void *src, size_t count);
|
||||
|
||||
int memcmp(const void *cs, const void *ct, size_t count);
|
||||
size_t strlen(const char *s);
|
||||
|
@ -63,6 +66,19 @@ char *strcpy(char *dest, const char *src);
|
|||
char *strcat(char *dest, const char *src);
|
||||
int strcmp(const char *cs, const char *ct);
|
||||
|
||||
#if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)
|
||||
|
||||
/*
|
||||
* For files that not instrumented (e.g. mm/slub.c) we
|
||||
* should use not instrumented version of mem* functions.
|
||||
*/
|
||||
|
||||
#undef memcpy
|
||||
#define memcpy(dst, src, len) __memcpy(dst, src, len)
|
||||
#define memmove(dst, src, len) __memmove(dst, src, len)
|
||||
#define memset(s, c, n) __memset(s, c, n)
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* _ASM_X86_STRING_64_H */
|
||||
|
|
|
@ -16,6 +16,10 @@ CFLAGS_REMOVE_ftrace.o = -pg
|
|||
CFLAGS_REMOVE_early_printk.o = -pg
|
||||
endif
|
||||
|
||||
KASAN_SANITIZE_head$(BITS).o := n
|
||||
KASAN_SANITIZE_dumpstack.o := n
|
||||
KASAN_SANITIZE_dumpstack_$(BITS).o := n
|
||||
|
||||
CFLAGS_irq.o := -I$(src)/../include/asm/trace
|
||||
|
||||
obj-y := process_$(BITS).o signal.o entry_$(BITS).o
|
||||
|
|
|
@ -952,20 +952,18 @@ static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf,
|
|||
static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf,
|
||||
int type, char *buf)
|
||||
{
|
||||
ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf;
|
||||
int n = 0;
|
||||
const struct cpumask *mask = to_cpumask(this_leaf->shared_cpu_map);
|
||||
int ret;
|
||||
|
||||
if (len > 1) {
|
||||
const struct cpumask *mask;
|
||||
|
||||
mask = to_cpumask(this_leaf->shared_cpu_map);
|
||||
n = type ?
|
||||
cpulist_scnprintf(buf, len-2, mask) :
|
||||
cpumask_scnprintf(buf, len-2, mask);
|
||||
buf[n++] = '\n';
|
||||
buf[n] = '\0';
|
||||
}
|
||||
return n;
|
||||
if (type)
|
||||
ret = scnprintf(buf, PAGE_SIZE - 1, "%*pbl",
|
||||
cpumask_pr_args(mask));
|
||||
else
|
||||
ret = scnprintf(buf, PAGE_SIZE - 1, "%*pb",
|
||||
cpumask_pr_args(mask));
|
||||
buf[ret++] = '\n';
|
||||
buf[ret] = '\0';
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline ssize_t show_shared_cpu_map(struct _cpuid4_info *leaf, char *buf,
|
||||
|
|
|
@ -265,7 +265,10 @@ int __die(const char *str, struct pt_regs *regs, long err)
|
|||
printk("SMP ");
|
||||
#endif
|
||||
#ifdef CONFIG_DEBUG_PAGEALLOC
|
||||
printk("DEBUG_PAGEALLOC");
|
||||
printk("DEBUG_PAGEALLOC ");
|
||||
#endif
|
||||
#ifdef CONFIG_KASAN
|
||||
printk("KASAN");
|
||||
#endif
|
||||
printk("\n");
|
||||
if (notify_die(DIE_OOPS, str, regs, err,
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <asm/bios_ebda.h>
|
||||
#include <asm/bootparam_utils.h>
|
||||
#include <asm/microcode.h>
|
||||
#include <asm/kasan.h>
|
||||
|
||||
/*
|
||||
* Manage page tables very early on.
|
||||
|
@ -46,7 +47,7 @@ static void __init reset_early_page_tables(void)
|
|||
|
||||
next_early_pgt = 0;
|
||||
|
||||
write_cr3(__pa(early_level4_pgt));
|
||||
write_cr3(__pa_nodebug(early_level4_pgt));
|
||||
}
|
||||
|
||||
/* Create a new PMD entry */
|
||||
|
@ -59,7 +60,7 @@ int __init early_make_pgtable(unsigned long address)
|
|||
pmdval_t pmd, *pmd_p;
|
||||
|
||||
/* Invalid address or early pgt is done ? */
|
||||
if (physaddr >= MAXMEM || read_cr3() != __pa(early_level4_pgt))
|
||||
if (physaddr >= MAXMEM || read_cr3() != __pa_nodebug(early_level4_pgt))
|
||||
return -1;
|
||||
|
||||
again:
|
||||
|
@ -158,6 +159,8 @@ asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data)
|
|||
/* Kill off the identity-map trampoline */
|
||||
reset_early_page_tables();
|
||||
|
||||
kasan_map_early_shadow(early_level4_pgt);
|
||||
|
||||
/* clear bss before set_intr_gate with early_idt_handler */
|
||||
clear_bss();
|
||||
|
||||
|
@ -179,6 +182,8 @@ asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data)
|
|||
/* set init_level4_pgt kernel high mapping*/
|
||||
init_level4_pgt[511] = early_level4_pgt[511];
|
||||
|
||||
kasan_map_early_shadow(init_level4_pgt);
|
||||
|
||||
x86_64_start_reservations(real_mode_data);
|
||||
}
|
||||
|
||||
|
|
|
@ -514,8 +514,38 @@ ENTRY(phys_base)
|
|||
/* This must match the first entry in level2_kernel_pgt */
|
||||
.quad 0x0000000000000000
|
||||
|
||||
#ifdef CONFIG_KASAN
|
||||
#define FILL(VAL, COUNT) \
|
||||
.rept (COUNT) ; \
|
||||
.quad (VAL) ; \
|
||||
.endr
|
||||
|
||||
NEXT_PAGE(kasan_zero_pte)
|
||||
FILL(kasan_zero_page - __START_KERNEL_map + _KERNPG_TABLE, 512)
|
||||
NEXT_PAGE(kasan_zero_pmd)
|
||||
FILL(kasan_zero_pte - __START_KERNEL_map + _KERNPG_TABLE, 512)
|
||||
NEXT_PAGE(kasan_zero_pud)
|
||||
FILL(kasan_zero_pmd - __START_KERNEL_map + _KERNPG_TABLE, 512)
|
||||
|
||||
#undef FILL
|
||||
#endif
|
||||
|
||||
|
||||
#include "../../x86/xen/xen-head.S"
|
||||
|
||||
__PAGE_ALIGNED_BSS
|
||||
NEXT_PAGE(empty_zero_page)
|
||||
.skip PAGE_SIZE
|
||||
|
||||
#ifdef CONFIG_KASAN
|
||||
/*
|
||||
* This page used as early shadow. We don't use empty_zero_page
|
||||
* at early stages, stack instrumentation could write some garbage
|
||||
* to this page.
|
||||
* Latter we reuse it as zero shadow for large ranges of memory
|
||||
* that allowed to access, but not instrumented by kasan
|
||||
* (vmalloc/vmemmap ...).
|
||||
*/
|
||||
NEXT_PAGE(kasan_zero_page)
|
||||
.skip PAGE_SIZE
|
||||
#endif
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <linux/fs.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/kasan.h>
|
||||
#include <linux/bug.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/gfp.h>
|
||||
|
@ -83,13 +84,22 @@ static unsigned long int get_module_load_offset(void)
|
|||
|
||||
void *module_alloc(unsigned long size)
|
||||
{
|
||||
void *p;
|
||||
|
||||
if (PAGE_ALIGN(size) > MODULES_LEN)
|
||||
return NULL;
|
||||
return __vmalloc_node_range(size, 1,
|
||||
|
||||
p = __vmalloc_node_range(size, MODULE_ALIGN,
|
||||
MODULES_VADDR + get_module_load_offset(),
|
||||
MODULES_END, GFP_KERNEL | __GFP_HIGHMEM,
|
||||
PAGE_KERNEL_EXEC, NUMA_NO_NODE,
|
||||
PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
|
||||
__builtin_return_address(0));
|
||||
if (p && (kasan_module_alloc(p, size) < 0)) {
|
||||
vfree(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
|
|
|
@ -89,6 +89,7 @@
|
|||
#include <asm/cacheflush.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/bugs.h>
|
||||
#include <asm/kasan.h>
|
||||
|
||||
#include <asm/vsyscall.h>
|
||||
#include <asm/cpu.h>
|
||||
|
@ -1174,6 +1175,8 @@ void __init setup_arch(char **cmdline_p)
|
|||
|
||||
x86_init.paging.pagetable_init();
|
||||
|
||||
kasan_init();
|
||||
|
||||
if (boot_cpu_data.cpuid_level >= 0) {
|
||||
/* A CPU has %cr4 if and only if it has CPUID */
|
||||
mmu_cr4_features = read_cr4();
|
||||
|
|
|
@ -50,13 +50,19 @@ EXPORT_SYMBOL(csum_partial);
|
|||
#undef memset
|
||||
#undef memmove
|
||||
|
||||
extern void *__memset(void *, int, __kernel_size_t);
|
||||
extern void *__memcpy(void *, const void *, __kernel_size_t);
|
||||
extern void *__memmove(void *, const void *, __kernel_size_t);
|
||||
extern void *memset(void *, int, __kernel_size_t);
|
||||
extern void *memcpy(void *, const void *, __kernel_size_t);
|
||||
extern void *__memcpy(void *, const void *, __kernel_size_t);
|
||||
extern void *memmove(void *, const void *, __kernel_size_t);
|
||||
|
||||
EXPORT_SYMBOL(__memset);
|
||||
EXPORT_SYMBOL(__memcpy);
|
||||
EXPORT_SYMBOL(__memmove);
|
||||
|
||||
EXPORT_SYMBOL(memset);
|
||||
EXPORT_SYMBOL(memcpy);
|
||||
EXPORT_SYMBOL(__memcpy);
|
||||
EXPORT_SYMBOL(memmove);
|
||||
|
||||
#ifndef CONFIG_DEBUG_VIRTUAL
|
||||
|
|
|
@ -53,6 +53,8 @@
|
|||
.Lmemcpy_e_e:
|
||||
.previous
|
||||
|
||||
.weak memcpy
|
||||
|
||||
ENTRY(__memcpy)
|
||||
ENTRY(memcpy)
|
||||
CFI_STARTPROC
|
||||
|
@ -199,8 +201,8 @@ ENDPROC(__memcpy)
|
|||
* only outcome...
|
||||
*/
|
||||
.section .altinstructions, "a"
|
||||
altinstruction_entry memcpy,.Lmemcpy_c,X86_FEATURE_REP_GOOD,\
|
||||
altinstruction_entry __memcpy,.Lmemcpy_c,X86_FEATURE_REP_GOOD,\
|
||||
.Lmemcpy_e-.Lmemcpy_c,.Lmemcpy_e-.Lmemcpy_c
|
||||
altinstruction_entry memcpy,.Lmemcpy_c_e,X86_FEATURE_ERMS, \
|
||||
altinstruction_entry __memcpy,.Lmemcpy_c_e,X86_FEATURE_ERMS, \
|
||||
.Lmemcpy_e_e-.Lmemcpy_c_e,.Lmemcpy_e_e-.Lmemcpy_c_e
|
||||
.previous
|
||||
|
|
|
@ -24,7 +24,10 @@
|
|||
* Output:
|
||||
* rax: dest
|
||||
*/
|
||||
.weak memmove
|
||||
|
||||
ENTRY(memmove)
|
||||
ENTRY(__memmove)
|
||||
CFI_STARTPROC
|
||||
|
||||
/* Handle more 32 bytes in loop */
|
||||
|
@ -220,4 +223,5 @@ ENTRY(memmove)
|
|||
.Lmemmove_end_forward-.Lmemmove_begin_forward, \
|
||||
.Lmemmove_end_forward_efs-.Lmemmove_begin_forward_efs
|
||||
.previous
|
||||
ENDPROC(__memmove)
|
||||
ENDPROC(memmove)
|
||||
|
|
|
@ -56,6 +56,8 @@
|
|||
.Lmemset_e_e:
|
||||
.previous
|
||||
|
||||
.weak memset
|
||||
|
||||
ENTRY(memset)
|
||||
ENTRY(__memset)
|
||||
CFI_STARTPROC
|
||||
|
@ -147,8 +149,8 @@ ENDPROC(__memset)
|
|||
* feature to implement the right patch order.
|
||||
*/
|
||||
.section .altinstructions,"a"
|
||||
altinstruction_entry memset,.Lmemset_c,X86_FEATURE_REP_GOOD,\
|
||||
.Lfinal-memset,.Lmemset_e-.Lmemset_c
|
||||
altinstruction_entry memset,.Lmemset_c_e,X86_FEATURE_ERMS, \
|
||||
.Lfinal-memset,.Lmemset_e_e-.Lmemset_c_e
|
||||
altinstruction_entry __memset,.Lmemset_c,X86_FEATURE_REP_GOOD,\
|
||||
.Lfinal-__memset,.Lmemset_e-.Lmemset_c
|
||||
altinstruction_entry __memset,.Lmemset_c_e,X86_FEATURE_ERMS, \
|
||||
.Lfinal-__memset,.Lmemset_e_e-.Lmemset_c_e
|
||||
.previous
|
||||
|
|
|
@ -20,6 +20,9 @@ obj-$(CONFIG_HIGHMEM) += highmem_32.o
|
|||
|
||||
obj-$(CONFIG_KMEMCHECK) += kmemcheck/
|
||||
|
||||
KASAN_SANITIZE_kasan_init_$(BITS).o := n
|
||||
obj-$(CONFIG_KASAN) += kasan_init_$(BITS).o
|
||||
|
||||
obj-$(CONFIG_MMIOTRACE) += mmiotrace.o
|
||||
mmiotrace-y := kmmio.o pf_in.o mmio-mod.o
|
||||
obj-$(CONFIG_MMIOTRACE_TEST) += testmmiotrace.o
|
||||
|
|
|
@ -0,0 +1,206 @@
|
|||
#include <linux/bootmem.h>
|
||||
#include <linux/kasan.h>
|
||||
#include <linux/kdebug.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#include <asm/tlbflush.h>
|
||||
#include <asm/sections.h>
|
||||
|
||||
extern pgd_t early_level4_pgt[PTRS_PER_PGD];
|
||||
extern struct range pfn_mapped[E820_X_MAX];
|
||||
|
||||
extern unsigned char kasan_zero_page[PAGE_SIZE];
|
||||
|
||||
static int __init map_range(struct range *range)
|
||||
{
|
||||
unsigned long start;
|
||||
unsigned long end;
|
||||
|
||||
start = (unsigned long)kasan_mem_to_shadow(pfn_to_kaddr(range->start));
|
||||
end = (unsigned long)kasan_mem_to_shadow(pfn_to_kaddr(range->end));
|
||||
|
||||
/*
|
||||
* end + 1 here is intentional. We check several shadow bytes in advance
|
||||
* to slightly speed up fastpath. In some rare cases we could cross
|
||||
* boundary of mapped shadow, so we just map some more here.
|
||||
*/
|
||||
return vmemmap_populate(start, end + 1, NUMA_NO_NODE);
|
||||
}
|
||||
|
||||
static void __init clear_pgds(unsigned long start,
|
||||
unsigned long end)
|
||||
{
|
||||
for (; start < end; start += PGDIR_SIZE)
|
||||
pgd_clear(pgd_offset_k(start));
|
||||
}
|
||||
|
||||
void __init kasan_map_early_shadow(pgd_t *pgd)
|
||||
{
|
||||
int i;
|
||||
unsigned long start = KASAN_SHADOW_START;
|
||||
unsigned long end = KASAN_SHADOW_END;
|
||||
|
||||
for (i = pgd_index(start); start < end; i++) {
|
||||
pgd[i] = __pgd(__pa_nodebug(kasan_zero_pud)
|
||||
| _KERNPG_TABLE);
|
||||
start += PGDIR_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
static int __init zero_pte_populate(pmd_t *pmd, unsigned long addr,
|
||||
unsigned long end)
|
||||
{
|
||||
pte_t *pte = pte_offset_kernel(pmd, addr);
|
||||
|
||||
while (addr + PAGE_SIZE <= end) {
|
||||
WARN_ON(!pte_none(*pte));
|
||||
set_pte(pte, __pte(__pa_nodebug(kasan_zero_page)
|
||||
| __PAGE_KERNEL_RO));
|
||||
addr += PAGE_SIZE;
|
||||
pte = pte_offset_kernel(pmd, addr);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init zero_pmd_populate(pud_t *pud, unsigned long addr,
|
||||
unsigned long end)
|
||||
{
|
||||
int ret = 0;
|
||||
pmd_t *pmd = pmd_offset(pud, addr);
|
||||
|
||||
while (IS_ALIGNED(addr, PMD_SIZE) && addr + PMD_SIZE <= end) {
|
||||
WARN_ON(!pmd_none(*pmd));
|
||||
set_pmd(pmd, __pmd(__pa_nodebug(kasan_zero_pte)
|
||||
| __PAGE_KERNEL_RO));
|
||||
addr += PMD_SIZE;
|
||||
pmd = pmd_offset(pud, addr);
|
||||
}
|
||||
if (addr < end) {
|
||||
if (pmd_none(*pmd)) {
|
||||
void *p = vmemmap_alloc_block(PAGE_SIZE, NUMA_NO_NODE);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
set_pmd(pmd, __pmd(__pa_nodebug(p) | _KERNPG_TABLE));
|
||||
}
|
||||
ret = zero_pte_populate(pmd, addr, end);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int __init zero_pud_populate(pgd_t *pgd, unsigned long addr,
|
||||
unsigned long end)
|
||||
{
|
||||
int ret = 0;
|
||||
pud_t *pud = pud_offset(pgd, addr);
|
||||
|
||||
while (IS_ALIGNED(addr, PUD_SIZE) && addr + PUD_SIZE <= end) {
|
||||
WARN_ON(!pud_none(*pud));
|
||||
set_pud(pud, __pud(__pa_nodebug(kasan_zero_pmd)
|
||||
| __PAGE_KERNEL_RO));
|
||||
addr += PUD_SIZE;
|
||||
pud = pud_offset(pgd, addr);
|
||||
}
|
||||
|
||||
if (addr < end) {
|
||||
if (pud_none(*pud)) {
|
||||
void *p = vmemmap_alloc_block(PAGE_SIZE, NUMA_NO_NODE);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
set_pud(pud, __pud(__pa_nodebug(p) | _KERNPG_TABLE));
|
||||
}
|
||||
ret = zero_pmd_populate(pud, addr, end);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __init zero_pgd_populate(unsigned long addr, unsigned long end)
|
||||
{
|
||||
int ret = 0;
|
||||
pgd_t *pgd = pgd_offset_k(addr);
|
||||
|
||||
while (IS_ALIGNED(addr, PGDIR_SIZE) && addr + PGDIR_SIZE <= end) {
|
||||
WARN_ON(!pgd_none(*pgd));
|
||||
set_pgd(pgd, __pgd(__pa_nodebug(kasan_zero_pud)
|
||||
| __PAGE_KERNEL_RO));
|
||||
addr += PGDIR_SIZE;
|
||||
pgd = pgd_offset_k(addr);
|
||||
}
|
||||
|
||||
if (addr < end) {
|
||||
if (pgd_none(*pgd)) {
|
||||
void *p = vmemmap_alloc_block(PAGE_SIZE, NUMA_NO_NODE);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
set_pgd(pgd, __pgd(__pa_nodebug(p) | _KERNPG_TABLE));
|
||||
}
|
||||
ret = zero_pud_populate(pgd, addr, end);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void __init populate_zero_shadow(const void *start, const void *end)
|
||||
{
|
||||
if (zero_pgd_populate((unsigned long)start, (unsigned long)end))
|
||||
panic("kasan: unable to map zero shadow!");
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_KASAN_INLINE
|
||||
static int kasan_die_handler(struct notifier_block *self,
|
||||
unsigned long val,
|
||||
void *data)
|
||||
{
|
||||
if (val == DIE_GPF) {
|
||||
pr_emerg("CONFIG_KASAN_INLINE enabled");
|
||||
pr_emerg("GPF could be caused by NULL-ptr deref or user memory access");
|
||||
}
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static struct notifier_block kasan_die_notifier = {
|
||||
.notifier_call = kasan_die_handler,
|
||||
};
|
||||
#endif
|
||||
|
||||
void __init kasan_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
#ifdef CONFIG_KASAN_INLINE
|
||||
register_die_notifier(&kasan_die_notifier);
|
||||
#endif
|
||||
|
||||
memcpy(early_level4_pgt, init_level4_pgt, sizeof(early_level4_pgt));
|
||||
load_cr3(early_level4_pgt);
|
||||
|
||||
clear_pgds(KASAN_SHADOW_START, KASAN_SHADOW_END);
|
||||
|
||||
populate_zero_shadow((void *)KASAN_SHADOW_START,
|
||||
kasan_mem_to_shadow((void *)PAGE_OFFSET));
|
||||
|
||||
for (i = 0; i < E820_X_MAX; i++) {
|
||||
if (pfn_mapped[i].end == 0)
|
||||
break;
|
||||
|
||||
if (map_range(&pfn_mapped[i]))
|
||||
panic("kasan: unable to allocate shadow!");
|
||||
}
|
||||
populate_zero_shadow(kasan_mem_to_shadow((void *)PAGE_OFFSET + MAXMEM),
|
||||
kasan_mem_to_shadow((void *)__START_KERNEL_map));
|
||||
|
||||
vmemmap_populate((unsigned long)kasan_mem_to_shadow(_stext),
|
||||
(unsigned long)kasan_mem_to_shadow(_end),
|
||||
NUMA_NO_NODE);
|
||||
|
||||
populate_zero_shadow(kasan_mem_to_shadow((void *)MODULES_END),
|
||||
(void *)KASAN_SHADOW_END);
|
||||
|
||||
memset(kasan_zero_page, 0, PAGE_SIZE);
|
||||
|
||||
load_cr3(init_level4_pgt);
|
||||
init_task.kasan_depth = 0;
|
||||
}
|
|
@ -794,7 +794,6 @@ int early_cpu_to_node(int cpu)
|
|||
void debug_cpumask_set_cpu(int cpu, int node, bool enable)
|
||||
{
|
||||
struct cpumask *mask;
|
||||
char buf[64];
|
||||
|
||||
if (node == NUMA_NO_NODE) {
|
||||
/* early_cpu_to_node() already emits a warning and trace */
|
||||
|
@ -812,10 +811,9 @@ void debug_cpumask_set_cpu(int cpu, int node, bool enable)
|
|||
else
|
||||
cpumask_clear_cpu(cpu, mask);
|
||||
|
||||
cpulist_scnprintf(buf, sizeof(buf), mask);
|
||||
printk(KERN_DEBUG "%s cpu %d node %d: mask now %s\n",
|
||||
printk(KERN_DEBUG "%s cpu %d node %d: mask now %*pbl\n",
|
||||
enable ? "numa_add_cpu" : "numa_remove_cpu",
|
||||
cpu, node, buf);
|
||||
cpu, node, cpumask_pr_args(mask));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -273,20 +273,6 @@ static inline void uv_clear_nmi(int cpu)
|
|||
}
|
||||
}
|
||||
|
||||
/* Print non-responding cpus */
|
||||
static void uv_nmi_nr_cpus_pr(char *fmt)
|
||||
{
|
||||
static char cpu_list[1024];
|
||||
int len = sizeof(cpu_list);
|
||||
int c = cpumask_weight(uv_nmi_cpu_mask);
|
||||
int n = cpulist_scnprintf(cpu_list, len, uv_nmi_cpu_mask);
|
||||
|
||||
if (n >= len-1)
|
||||
strcpy(&cpu_list[len - 6], "...\n");
|
||||
|
||||
printk(fmt, c, cpu_list);
|
||||
}
|
||||
|
||||
/* Ping non-responding cpus attemping to force them into the NMI handler */
|
||||
static void uv_nmi_nr_cpus_ping(void)
|
||||
{
|
||||
|
@ -371,16 +357,19 @@ static void uv_nmi_wait(int master)
|
|||
break;
|
||||
|
||||
/* if not all made it in, send IPI NMI to them */
|
||||
uv_nmi_nr_cpus_pr(KERN_ALERT
|
||||
"UV: Sending NMI IPI to %d non-responding CPUs: %s\n");
|
||||
pr_alert("UV: Sending NMI IPI to %d non-responding CPUs: %*pbl\n",
|
||||
cpumask_weight(uv_nmi_cpu_mask),
|
||||
cpumask_pr_args(uv_nmi_cpu_mask));
|
||||
|
||||
uv_nmi_nr_cpus_ping();
|
||||
|
||||
/* if all cpus are in, then done */
|
||||
if (!uv_nmi_wait_cpus(0))
|
||||
break;
|
||||
|
||||
uv_nmi_nr_cpus_pr(KERN_ALERT
|
||||
"UV: %d CPUs not in NMI loop: %s\n");
|
||||
pr_alert("UV: %d CPUs not in NMI loop: %*pbl\n",
|
||||
cpumask_weight(uv_nmi_cpu_mask),
|
||||
cpumask_pr_args(uv_nmi_cpu_mask));
|
||||
} while (0);
|
||||
|
||||
pr_alert("UV: %d of %d CPUs in NMI\n",
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
# for more details.
|
||||
#
|
||||
#
|
||||
|
||||
KASAN_SANITIZE := n
|
||||
subdir- := rm
|
||||
|
||||
obj-y += init.o
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
# for more details.
|
||||
#
|
||||
#
|
||||
KASAN_SANITIZE := n
|
||||
|
||||
always := realmode.bin realmode.relocs
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#
|
||||
|
||||
KBUILD_CFLAGS += $(DISABLE_LTO)
|
||||
KASAN_SANITIZE := n
|
||||
|
||||
VDSO64-$(CONFIG_X86_64) := y
|
||||
VDSOX32-$(CONFIG_X86_X32_ABI) := y
|
||||
|
|
|
@ -574,12 +574,9 @@ void machine_power_off(void)
|
|||
static int
|
||||
c_show(struct seq_file *f, void *slot)
|
||||
{
|
||||
char buf[NR_CPUS * 5];
|
||||
|
||||
cpulist_scnprintf(buf, sizeof(buf), cpu_online_mask);
|
||||
/* high-level stuff */
|
||||
seq_printf(f, "CPU count\t: %u\n"
|
||||
"CPU list\t: %s\n"
|
||||
"CPU list\t: %*pbl\n"
|
||||
"vendor_id\t: Tensilica\n"
|
||||
"model\t\t: Xtensa " XCHAL_HW_VERSION_NAME "\n"
|
||||
"core ID\t\t: " XCHAL_CORE_ID "\n"
|
||||
|
@ -588,7 +585,7 @@ c_show(struct seq_file *f, void *slot)
|
|||
"cpu MHz\t\t: %lu.%02lu\n"
|
||||
"bogomips\t: %lu.%02lu\n",
|
||||
num_online_cpus(),
|
||||
buf,
|
||||
cpumask_pr_args(cpu_online_mask),
|
||||
XCHAL_BUILD_UNIQUE_ID,
|
||||
XCHAL_HAVE_BE ? "big" : "little",
|
||||
ccount_freq/1000000,
|
||||
|
|
|
@ -245,7 +245,7 @@ static ssize_t print_cpus_offline(struct device *dev,
|
|||
if (!alloc_cpumask_var(&offline, GFP_KERNEL))
|
||||
return -ENOMEM;
|
||||
cpumask_andnot(offline, cpu_possible_mask, cpu_online_mask);
|
||||
n = cpulist_scnprintf(buf, len, offline);
|
||||
n = scnprintf(buf, len, "%*pbl", cpumask_pr_args(offline));
|
||||
free_cpumask_var(offline);
|
||||
|
||||
/* display offline cpus >= nr_cpu_ids */
|
||||
|
|
|
@ -605,7 +605,8 @@ static ssize_t print_nodes_state(enum node_states state, char *buf)
|
|||
{
|
||||
int n;
|
||||
|
||||
n = nodelist_scnprintf(buf, PAGE_SIZE-2, node_states[state]);
|
||||
n = scnprintf(buf, PAGE_SIZE - 1, "%*pbl",
|
||||
nodemask_pr_args(&node_states[state]));
|
||||
buf[n++] = '\n';
|
||||
buf[n] = '\0';
|
||||
return n;
|
||||
|
|
|
@ -806,8 +806,8 @@ static int cci_pmu_event_init(struct perf_event *event)
|
|||
static ssize_t pmu_attr_cpumask_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
int n = cpulist_scnprintf(buf, PAGE_SIZE - 2, &pmu->cpus);
|
||||
|
||||
int n = scnprintf(buf, PAGE_SIZE - 1, "%*pbl",
|
||||
cpumask_pr_args(&pmu->cpus));
|
||||
buf[n++] = '\n';
|
||||
buf[n] = '\0';
|
||||
return n;
|
||||
|
|
|
@ -2048,7 +2048,7 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
|
|||
goto fail_out;
|
||||
}
|
||||
|
||||
clk->name = kstrdup(hw->init->name, GFP_KERNEL);
|
||||
clk->name = kstrdup_const(hw->init->name, GFP_KERNEL);
|
||||
if (!clk->name) {
|
||||
pr_err("%s: could not allocate clk->name\n", __func__);
|
||||
ret = -ENOMEM;
|
||||
|
@ -2075,7 +2075,7 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
|
|||
|
||||
/* copy each string name in case parent_names is __initdata */
|
||||
for (i = 0; i < clk->num_parents; i++) {
|
||||
clk->parent_names[i] = kstrdup(hw->init->parent_names[i],
|
||||
clk->parent_names[i] = kstrdup_const(hw->init->parent_names[i],
|
||||
GFP_KERNEL);
|
||||
if (!clk->parent_names[i]) {
|
||||
pr_err("%s: could not copy parent_names\n", __func__);
|
||||
|
@ -2090,10 +2090,10 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
|
|||
|
||||
fail_parent_names_copy:
|
||||
while (--i >= 0)
|
||||
kfree(clk->parent_names[i]);
|
||||
kfree_const(clk->parent_names[i]);
|
||||
kfree(clk->parent_names);
|
||||
fail_parent_names:
|
||||
kfree(clk->name);
|
||||
kfree_const(clk->name);
|
||||
fail_name:
|
||||
kfree(clk);
|
||||
fail_out:
|
||||
|
@ -2112,10 +2112,10 @@ static void __clk_release(struct kref *ref)
|
|||
|
||||
kfree(clk->parents);
|
||||
while (--i >= 0)
|
||||
kfree(clk->parent_names[i]);
|
||||
kfree_const(clk->parent_names[i]);
|
||||
|
||||
kfree(clk->parent_names);
|
||||
kfree(clk->name);
|
||||
kfree_const(clk->name);
|
||||
kfree(clk);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ KBUILD_CFLAGS := $(cflags-y) \
|
|||
$(call cc-option,-fno-stack-protector)
|
||||
|
||||
GCOV_PROFILE := n
|
||||
KASAN_SANITIZE := n
|
||||
|
||||
lib-y := efi-stub-helper.o
|
||||
lib-$(CONFIG_EFI_ARMSTUB) += arm-stub.o fdt.o
|
||||
|
|
|
@ -5,6 +5,10 @@
|
|||
/* error code which can't be mistaken for valid address */
|
||||
#define EFI_ERROR (~0UL)
|
||||
|
||||
#undef memcpy
|
||||
#undef memset
|
||||
#undef memmove
|
||||
|
||||
void efi_char16_printk(efi_system_table_t *, efi_char16_t *);
|
||||
|
||||
efi_status_t efi_open_volume(efi_system_table_t *sys_table_arg, void *__image,
|
||||
|
|
|
@ -1399,8 +1399,8 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun
|
|||
|
||||
static ssize_t atkbd_show_force_release(struct atkbd *atkbd, char *buf)
|
||||
{
|
||||
size_t len = bitmap_scnlistprintf(buf, PAGE_SIZE - 2,
|
||||
atkbd->force_release_mask, ATKBD_KEYMAP_SIZE);
|
||||
size_t len = scnprintf(buf, PAGE_SIZE - 1, "%*pbl",
|
||||
ATKBD_KEYMAP_SIZE, atkbd->force_release_mask);
|
||||
|
||||
buf[len++] = '\n';
|
||||
buf[len] = '\0';
|
||||
|
|
|
@ -190,7 +190,7 @@ static ssize_t gpio_keys_attr_show_helper(struct gpio_keys_drvdata *ddata,
|
|||
__set_bit(bdata->button->code, bits);
|
||||
}
|
||||
|
||||
ret = bitmap_scnlistprintf(buf, PAGE_SIZE - 2, bits, n_events);
|
||||
ret = scnprintf(buf, PAGE_SIZE - 1, "%*pbl", n_events, bits);
|
||||
buf[ret++] = '\n';
|
||||
buf[ret] = '\0';
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include <net/vxlan.h>
|
||||
|
||||
MODULE_VERSION(DRV_VER);
|
||||
MODULE_DEVICE_TABLE(pci, be_dev_ids);
|
||||
MODULE_DESCRIPTION(DRV_DESC " " DRV_VER);
|
||||
MODULE_AUTHOR("Emulex Corporation");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -292,7 +292,6 @@ static inline int mpipe_instance(struct net_device *dev)
|
|||
*/
|
||||
static bool network_cpus_init(void)
|
||||
{
|
||||
char buf[1024];
|
||||
int rc;
|
||||
|
||||
if (network_cpus_string == NULL)
|
||||
|
@ -314,8 +313,8 @@ static bool network_cpus_init(void)
|
|||
return false;
|
||||
}
|
||||
|
||||
cpulist_scnprintf(buf, sizeof(buf), &network_cpus_map);
|
||||
pr_info("Linux network CPUs: %s\n", buf);
|
||||
pr_info("Linux network CPUs: %*pbl\n",
|
||||
cpumask_pr_args(&network_cpus_map));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -2410,9 +2410,8 @@ static int __init network_cpus_setup(char *str)
|
|||
if (cpumask_empty(&network_cpus_map)) {
|
||||
pr_warn("Ignoring network_cpus='%s'\n", str);
|
||||
} else {
|
||||
char buf[1024];
|
||||
cpulist_scnprintf(buf, sizeof(buf), &network_cpus_map);
|
||||
pr_info("Linux network CPUs: %s\n", buf);
|
||||
pr_info("Linux network CPUs: %*pbl\n",
|
||||
cpumask_pr_args(&network_cpus_map));
|
||||
network_cpus_used = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -291,26 +291,15 @@ static ssize_t read_file_slot(struct file *file, char __user *user_buf,
|
|||
{
|
||||
struct ath9k_htc_priv *priv = file->private_data;
|
||||
char buf[512];
|
||||
unsigned int len = 0;
|
||||
unsigned int len;
|
||||
|
||||
spin_lock_bh(&priv->tx.tx_lock);
|
||||
|
||||
len += scnprintf(buf + len, sizeof(buf) - len, "TX slot bitmap : ");
|
||||
|
||||
len += bitmap_scnprintf(buf + len, sizeof(buf) - len,
|
||||
priv->tx.tx_slot, MAX_TX_BUF_NUM);
|
||||
|
||||
len += scnprintf(buf + len, sizeof(buf) - len, "\n");
|
||||
|
||||
len += scnprintf(buf + len, sizeof(buf) - len,
|
||||
"Used slots : %d\n",
|
||||
bitmap_weight(priv->tx.tx_slot, MAX_TX_BUF_NUM));
|
||||
|
||||
len = scnprintf(buf, sizeof(buf),
|
||||
"TX slot bitmap : %*pb\n"
|
||||
"Used slots : %d\n",
|
||||
MAX_TX_BUF_NUM, priv->tx.tx_slot,
|
||||
bitmap_weight(priv->tx.tx_slot, MAX_TX_BUF_NUM));
|
||||
spin_unlock_bh(&priv->tx.tx_lock);
|
||||
|
||||
if (len > sizeof(buf))
|
||||
len = sizeof(buf);
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
}
|
||||
|
||||
|
|
|
@ -214,14 +214,10 @@ DEBUGFS_DECLARE_RO_FILE(name, _read_bufsize)
|
|||
static char *carl9170_debugfs_mem_usage_read(struct ar9170 *ar, char *buf,
|
||||
size_t bufsize, ssize_t *len)
|
||||
{
|
||||
ADD(buf, *len, bufsize, "jar: [");
|
||||
|
||||
spin_lock_bh(&ar->mem_lock);
|
||||
|
||||
*len += bitmap_scnprintf(&buf[*len], bufsize - *len,
|
||||
ar->mem_bitmap, ar->fw.mem_blocks);
|
||||
|
||||
ADD(buf, *len, bufsize, "]\n");
|
||||
ADD(buf, *len, bufsize, "jar: [%*pb]\n",
|
||||
ar->fw.mem_blocks, ar->mem_bitmap);
|
||||
|
||||
ADD(buf, *len, bufsize, "cookies: used:%3d / total:%3d, allocs:%d\n",
|
||||
bitmap_weight(ar->mem_bitmap, ar->fw.mem_blocks),
|
||||
|
@ -316,17 +312,13 @@ static char *carl9170_debugfs_ampdu_state_read(struct ar9170 *ar, char *buf,
|
|||
cnt, iter->tid, iter->bsn, iter->snx, iter->hsn,
|
||||
iter->max, iter->state, iter->counter);
|
||||
|
||||
ADD(buf, *len, bufsize, "\tWindow: [");
|
||||
|
||||
*len += bitmap_scnprintf(&buf[*len], bufsize - *len,
|
||||
iter->bitmap, CARL9170_BAW_BITS);
|
||||
ADD(buf, *len, bufsize, "\tWindow: [%*pb,W]\n",
|
||||
CARL9170_BAW_BITS, iter->bitmap);
|
||||
|
||||
#define BM_STR_OFF(offset) \
|
||||
((CARL9170_BAW_BITS - (offset) - 1) / 4 + \
|
||||
(CARL9170_BAW_BITS - (offset) - 1) / 32 + 1)
|
||||
|
||||
ADD(buf, *len, bufsize, ",W]\n");
|
||||
|
||||
offset = BM_STR_OFF(0);
|
||||
ADD(buf, *len, bufsize, "\tBase Seq: %*s\n", offset, "T");
|
||||
|
||||
|
@ -448,12 +440,8 @@ static char *carl9170_debugfs_vif_dump_read(struct ar9170 *ar, char *buf,
|
|||
ADD(buf, *len, bufsize, "registered VIFs:%d \\ %d\n",
|
||||
ar->vifs, ar->fw.vif_num);
|
||||
|
||||
ADD(buf, *len, bufsize, "VIF bitmap: [");
|
||||
|
||||
*len += bitmap_scnprintf(&buf[*len], bufsize - *len,
|
||||
&ar->vif_bitmap, ar->fw.vif_num);
|
||||
|
||||
ADD(buf, *len, bufsize, "]\n");
|
||||
ADD(buf, *len, bufsize, "VIF bitmap: [%*pb]\n",
|
||||
ar->fw.vif_num, &ar->vif_bitmap);
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(iter, &ar->vif_list, list) {
|
||||
|
|
|
@ -153,6 +153,17 @@ config RTC_DRV_88PM80X
|
|||
This driver can also be built as a module. If so, the module
|
||||
will be called rtc-88pm80x.
|
||||
|
||||
config RTC_DRV_ABB5ZES3
|
||||
depends on I2C
|
||||
select REGMAP_I2C
|
||||
tristate "Abracon AB-RTCMC-32.768kHz-B5ZE-S3"
|
||||
help
|
||||
If you say yes here you get support for the Abracon
|
||||
AB-RTCMC-32.768kHz-B5ZE-S3 I2C RTC chip.
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called rtc-ab-b5ze-s3.
|
||||
|
||||
config RTC_DRV_AS3722
|
||||
tristate "ams AS3722 RTC driver"
|
||||
depends on MFD_AS3722
|
||||
|
@ -1269,6 +1280,16 @@ config RTC_DRV_MV
|
|||
This driver can also be built as a module. If so, the module
|
||||
will be called rtc-mv.
|
||||
|
||||
config RTC_DRV_ARMADA38X
|
||||
tristate "Armada 38x Marvell SoC RTC"
|
||||
depends on ARCH_MVEBU
|
||||
help
|
||||
If you say yes here you will get support for the in-chip RTC
|
||||
that can be found in the Armada 38x Marvell's SoC device
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called armada38x-rtc.
|
||||
|
||||
config RTC_DRV_PS3
|
||||
tristate "PS3 RTC"
|
||||
depends on PPC_PS3
|
||||
|
|
|
@ -24,6 +24,8 @@ obj-$(CONFIG_RTC_DRV_88PM860X) += rtc-88pm860x.o
|
|||
obj-$(CONFIG_RTC_DRV_88PM80X) += rtc-88pm80x.o
|
||||
obj-$(CONFIG_RTC_DRV_AB3100) += rtc-ab3100.o
|
||||
obj-$(CONFIG_RTC_DRV_AB8500) += rtc-ab8500.o
|
||||
obj-$(CONFIG_RTC_DRV_ABB5ZES3) += rtc-ab-b5ze-s3.o
|
||||
obj-$(CONFIG_RTC_DRV_ARMADA38X) += rtc-armada38x.o
|
||||
obj-$(CONFIG_RTC_DRV_AS3722) += rtc-as3722.o
|
||||
obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o
|
||||
obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,320 @@
|
|||
/*
|
||||
* RTC driver for the Armada 38x Marvell SoCs
|
||||
*
|
||||
* Copyright (C) 2015 Marvell
|
||||
*
|
||||
* Gregory Clement <gregory.clement@free-electrons.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/rtc.h>
|
||||
|
||||
#define RTC_STATUS 0x0
|
||||
#define RTC_STATUS_ALARM1 BIT(0)
|
||||
#define RTC_STATUS_ALARM2 BIT(1)
|
||||
#define RTC_IRQ1_CONF 0x4
|
||||
#define RTC_IRQ1_AL_EN BIT(0)
|
||||
#define RTC_IRQ1_FREQ_EN BIT(1)
|
||||
#define RTC_IRQ1_FREQ_1HZ BIT(2)
|
||||
#define RTC_TIME 0xC
|
||||
#define RTC_ALARM1 0x10
|
||||
|
||||
#define SOC_RTC_INTERRUPT 0x8
|
||||
#define SOC_RTC_ALARM1 BIT(0)
|
||||
#define SOC_RTC_ALARM2 BIT(1)
|
||||
#define SOC_RTC_ALARM1_MASK BIT(2)
|
||||
#define SOC_RTC_ALARM2_MASK BIT(3)
|
||||
|
||||
struct armada38x_rtc {
|
||||
struct rtc_device *rtc_dev;
|
||||
void __iomem *regs;
|
||||
void __iomem *regs_soc;
|
||||
spinlock_t lock;
|
||||
int irq;
|
||||
};
|
||||
|
||||
/*
|
||||
* According to the datasheet, the OS should wait 5us after every
|
||||
* register write to the RTC hard macro so that the required update
|
||||
* can occur without holding off the system bus
|
||||
*/
|
||||
static void rtc_delayed_write(u32 val, struct armada38x_rtc *rtc, int offset)
|
||||
{
|
||||
writel(val, rtc->regs + offset);
|
||||
udelay(5);
|
||||
}
|
||||
|
||||
static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
||||
{
|
||||
struct armada38x_rtc *rtc = dev_get_drvdata(dev);
|
||||
unsigned long time, time_check, flags;
|
||||
|
||||
spin_lock_irqsave(&rtc->lock, flags);
|
||||
|
||||
time = readl(rtc->regs + RTC_TIME);
|
||||
/*
|
||||
* WA for failing time set attempts. As stated in HW ERRATA if
|
||||
* more than one second between two time reads is detected
|
||||
* then read once again.
|
||||
*/
|
||||
time_check = readl(rtc->regs + RTC_TIME);
|
||||
if ((time_check - time) > 1)
|
||||
time_check = readl(rtc->regs + RTC_TIME);
|
||||
|
||||
spin_unlock_irqrestore(&rtc->lock, flags);
|
||||
|
||||
rtc_time_to_tm(time_check, tm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm)
|
||||
{
|
||||
struct armada38x_rtc *rtc = dev_get_drvdata(dev);
|
||||
int ret = 0;
|
||||
unsigned long time, flags;
|
||||
|
||||
ret = rtc_tm_to_time(tm, &time);
|
||||
|
||||
if (ret)
|
||||
goto out;
|
||||
/*
|
||||
* Setting the RTC time not always succeeds. According to the
|
||||
* errata we need to first write on the status register and
|
||||
* then wait for 100ms before writing to the time register to be
|
||||
* sure that the data will be taken into account.
|
||||
*/
|
||||
spin_lock_irqsave(&rtc->lock, flags);
|
||||
|
||||
rtc_delayed_write(0, rtc, RTC_STATUS);
|
||||
|
||||
spin_unlock_irqrestore(&rtc->lock, flags);
|
||||
|
||||
msleep(100);
|
||||
|
||||
spin_lock_irqsave(&rtc->lock, flags);
|
||||
|
||||
rtc_delayed_write(time, rtc, RTC_TIME);
|
||||
|
||||
spin_unlock_irqrestore(&rtc->lock, flags);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int armada38x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
|
||||
{
|
||||
struct armada38x_rtc *rtc = dev_get_drvdata(dev);
|
||||
unsigned long time, flags;
|
||||
u32 val;
|
||||
|
||||
spin_lock_irqsave(&rtc->lock, flags);
|
||||
|
||||
time = readl(rtc->regs + RTC_ALARM1);
|
||||
val = readl(rtc->regs + RTC_IRQ1_CONF) & RTC_IRQ1_AL_EN;
|
||||
|
||||
spin_unlock_irqrestore(&rtc->lock, flags);
|
||||
|
||||
alrm->enabled = val ? 1 : 0;
|
||||
rtc_time_to_tm(time, &alrm->time);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int armada38x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
|
||||
{
|
||||
struct armada38x_rtc *rtc = dev_get_drvdata(dev);
|
||||
unsigned long time, flags;
|
||||
int ret = 0;
|
||||
u32 val;
|
||||
|
||||
ret = rtc_tm_to_time(&alrm->time, &time);
|
||||
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
spin_lock_irqsave(&rtc->lock, flags);
|
||||
|
||||
rtc_delayed_write(time, rtc, RTC_ALARM1);
|
||||
|
||||
if (alrm->enabled) {
|
||||
rtc_delayed_write(RTC_IRQ1_AL_EN, rtc, RTC_IRQ1_CONF);
|
||||
val = readl(rtc->regs_soc + SOC_RTC_INTERRUPT);
|
||||
writel(val | SOC_RTC_ALARM1_MASK,
|
||||
rtc->regs_soc + SOC_RTC_INTERRUPT);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&rtc->lock, flags);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int armada38x_rtc_alarm_irq_enable(struct device *dev,
|
||||
unsigned int enabled)
|
||||
{
|
||||
struct armada38x_rtc *rtc = dev_get_drvdata(dev);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&rtc->lock, flags);
|
||||
|
||||
if (enabled)
|
||||
rtc_delayed_write(RTC_IRQ1_AL_EN, rtc, RTC_IRQ1_CONF);
|
||||
else
|
||||
rtc_delayed_write(0, rtc, RTC_IRQ1_CONF);
|
||||
|
||||
spin_unlock_irqrestore(&rtc->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t armada38x_rtc_alarm_irq(int irq, void *data)
|
||||
{
|
||||
struct armada38x_rtc *rtc = data;
|
||||
u32 val;
|
||||
int event = RTC_IRQF | RTC_AF;
|
||||
|
||||
dev_dbg(&rtc->rtc_dev->dev, "%s:irq(%d)\n", __func__, irq);
|
||||
|
||||
spin_lock(&rtc->lock);
|
||||
|
||||
val = readl(rtc->regs_soc + SOC_RTC_INTERRUPT);
|
||||
|
||||
writel(val & ~SOC_RTC_ALARM1, rtc->regs_soc + SOC_RTC_INTERRUPT);
|
||||
val = readl(rtc->regs + RTC_IRQ1_CONF);
|
||||
/* disable all the interrupts for alarm 1 */
|
||||
rtc_delayed_write(0, rtc, RTC_IRQ1_CONF);
|
||||
/* Ack the event */
|
||||
rtc_delayed_write(RTC_STATUS_ALARM1, rtc, RTC_STATUS);
|
||||
|
||||
spin_unlock(&rtc->lock);
|
||||
|
||||
if (val & RTC_IRQ1_FREQ_EN) {
|
||||
if (val & RTC_IRQ1_FREQ_1HZ)
|
||||
event |= RTC_UF;
|
||||
else
|
||||
event |= RTC_PF;
|
||||
}
|
||||
|
||||
rtc_update_irq(rtc->rtc_dev, 1, event);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct rtc_class_ops armada38x_rtc_ops = {
|
||||
.read_time = armada38x_rtc_read_time,
|
||||
.set_time = armada38x_rtc_set_time,
|
||||
.read_alarm = armada38x_rtc_read_alarm,
|
||||
.set_alarm = armada38x_rtc_set_alarm,
|
||||
.alarm_irq_enable = armada38x_rtc_alarm_irq_enable,
|
||||
};
|
||||
|
||||
static __init int armada38x_rtc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res;
|
||||
struct armada38x_rtc *rtc;
|
||||
int ret;
|
||||
|
||||
rtc = devm_kzalloc(&pdev->dev, sizeof(struct armada38x_rtc),
|
||||
GFP_KERNEL);
|
||||
if (!rtc)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&rtc->lock);
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc");
|
||||
rtc->regs = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(rtc->regs))
|
||||
return PTR_ERR(rtc->regs);
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc-soc");
|
||||
rtc->regs_soc = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(rtc->regs_soc))
|
||||
return PTR_ERR(rtc->regs_soc);
|
||||
|
||||
rtc->irq = platform_get_irq(pdev, 0);
|
||||
|
||||
if (rtc->irq < 0) {
|
||||
dev_err(&pdev->dev, "no irq\n");
|
||||
return rtc->irq;
|
||||
}
|
||||
if (devm_request_irq(&pdev->dev, rtc->irq, armada38x_rtc_alarm_irq,
|
||||
0, pdev->name, rtc) < 0) {
|
||||
dev_warn(&pdev->dev, "Interrupt not available.\n");
|
||||
rtc->irq = -1;
|
||||
/*
|
||||
* If there is no interrupt available then we can't
|
||||
* use the alarm
|
||||
*/
|
||||
armada38x_rtc_ops.set_alarm = NULL;
|
||||
armada38x_rtc_ops.alarm_irq_enable = NULL;
|
||||
}
|
||||
platform_set_drvdata(pdev, rtc);
|
||||
if (rtc->irq != -1)
|
||||
device_init_wakeup(&pdev->dev, 1);
|
||||
|
||||
rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
|
||||
&armada38x_rtc_ops, THIS_MODULE);
|
||||
if (IS_ERR(rtc->rtc_dev)) {
|
||||
ret = PTR_ERR(rtc->rtc_dev);
|
||||
dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int armada38x_rtc_suspend(struct device *dev)
|
||||
{
|
||||
if (device_may_wakeup(dev)) {
|
||||
struct armada38x_rtc *rtc = dev_get_drvdata(dev);
|
||||
|
||||
return enable_irq_wake(rtc->irq);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int armada38x_rtc_resume(struct device *dev)
|
||||
{
|
||||
if (device_may_wakeup(dev)) {
|
||||
struct armada38x_rtc *rtc = dev_get_drvdata(dev);
|
||||
|
||||
return disable_irq_wake(rtc->irq);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(armada38x_rtc_pm_ops,
|
||||
armada38x_rtc_suspend, armada38x_rtc_resume);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id armada38x_rtc_of_match_table[] = {
|
||||
{ .compatible = "marvell,armada-380-rtc", },
|
||||
{}
|
||||
};
|
||||
#endif
|
||||
|
||||
static struct platform_driver armada38x_rtc_driver = {
|
||||
.driver = {
|
||||
.name = "armada38x-rtc",
|
||||
.pm = &armada38x_rtc_pm_ops,
|
||||
.of_match_table = of_match_ptr(armada38x_rtc_of_match_table),
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver_probe(armada38x_rtc_driver, armada38x_rtc_probe);
|
||||
|
||||
MODULE_DESCRIPTION("Marvell Armada 38x RTC driver");
|
||||
MODULE_AUTHOR("Gregory CLEMENT <gregory.clement@free-electrons.com>");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -313,7 +313,7 @@ static const struct rtc_class_ops at91_rtc_ops = {
|
|||
.alarm_irq_enable = at91_rtc_alarm_irq_enable,
|
||||
};
|
||||
|
||||
static struct regmap_config gpbr_regmap_config = {
|
||||
static const struct regmap_config gpbr_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
|
|
|
@ -50,22 +50,58 @@
|
|||
#define DCAMR_UNSET 0xFFFFFFFF /* doomsday - 1 sec */
|
||||
|
||||
#define DCR 0x10 /* Control Reg */
|
||||
#define DCR_TDCHL (1 << 30) /* Tamper-detect configuration hard lock */
|
||||
#define DCR_TDCSL (1 << 29) /* Tamper-detect configuration soft lock */
|
||||
#define DCR_KSSL (1 << 27) /* Key-select soft lock */
|
||||
#define DCR_MCHL (1 << 20) /* Monotonic-counter hard lock */
|
||||
#define DCR_MCSL (1 << 19) /* Monotonic-counter soft lock */
|
||||
#define DCR_TCHL (1 << 18) /* Timer-counter hard lock */
|
||||
#define DCR_TCSL (1 << 17) /* Timer-counter soft lock */
|
||||
#define DCR_FSHL (1 << 16) /* Failure state hard lock */
|
||||
#define DCR_TCE (1 << 3) /* Time Counter Enable */
|
||||
#define DCR_MCE (1 << 2) /* Monotonic Counter Enable */
|
||||
|
||||
#define DSR 0x14 /* Status Reg */
|
||||
#define DSR_WBF (1 << 10) /* Write Busy Flag */
|
||||
#define DSR_WNF (1 << 9) /* Write Next Flag */
|
||||
#define DSR_WCF (1 << 8) /* Write Complete Flag */
|
||||
#define DSR_WTD (1 << 23) /* Wire-mesh tamper detected */
|
||||
#define DSR_ETBD (1 << 22) /* External tamper B detected */
|
||||
#define DSR_ETAD (1 << 21) /* External tamper A detected */
|
||||
#define DSR_EBD (1 << 20) /* External boot detected */
|
||||
#define DSR_SAD (1 << 19) /* SCC alarm detected */
|
||||
#define DSR_TTD (1 << 18) /* Temperatur tamper detected */
|
||||
#define DSR_CTD (1 << 17) /* Clock tamper detected */
|
||||
#define DSR_VTD (1 << 16) /* Voltage tamper detected */
|
||||
#define DSR_WBF (1 << 10) /* Write Busy Flag (synchronous) */
|
||||
#define DSR_WNF (1 << 9) /* Write Next Flag (synchronous) */
|
||||
#define DSR_WCF (1 << 8) /* Write Complete Flag (synchronous)*/
|
||||
#define DSR_WEF (1 << 7) /* Write Error Flag */
|
||||
#define DSR_CAF (1 << 4) /* Clock Alarm Flag */
|
||||
#define DSR_MCO (1 << 3) /* monotonic counter overflow */
|
||||
#define DSR_TCO (1 << 2) /* time counter overflow */
|
||||
#define DSR_NVF (1 << 1) /* Non-Valid Flag */
|
||||
#define DSR_SVF (1 << 0) /* Security Violation Flag */
|
||||
|
||||
#define DIER 0x18 /* Interrupt Enable Reg */
|
||||
#define DIER 0x18 /* Interrupt Enable Reg (synchronous) */
|
||||
#define DIER_WNIE (1 << 9) /* Write Next Interrupt Enable */
|
||||
#define DIER_WCIE (1 << 8) /* Write Complete Interrupt Enable */
|
||||
#define DIER_WEIE (1 << 7) /* Write Error Interrupt Enable */
|
||||
#define DIER_CAIE (1 << 4) /* Clock Alarm Interrupt Enable */
|
||||
#define DIER_SVIE (1 << 0) /* Security-violation Interrupt Enable */
|
||||
|
||||
#define DMCR 0x1c /* DryIce Monotonic Counter Reg */
|
||||
|
||||
#define DTCR 0x28 /* DryIce Tamper Configuration Reg */
|
||||
#define DTCR_MOE (1 << 9) /* monotonic overflow enabled */
|
||||
#define DTCR_TOE (1 << 8) /* time overflow enabled */
|
||||
#define DTCR_WTE (1 << 7) /* wire-mesh tamper enabled */
|
||||
#define DTCR_ETBE (1 << 6) /* external B tamper enabled */
|
||||
#define DTCR_ETAE (1 << 5) /* external A tamper enabled */
|
||||
#define DTCR_EBE (1 << 4) /* external boot tamper enabled */
|
||||
#define DTCR_SAIE (1 << 3) /* SCC enabled */
|
||||
#define DTCR_TTE (1 << 2) /* temperature tamper enabled */
|
||||
#define DTCR_CTE (1 << 1) /* clock tamper enabled */
|
||||
#define DTCR_VTE (1 << 0) /* voltage tamper enabled */
|
||||
|
||||
#define DGPR 0x3c /* DryIce General Purpose Reg */
|
||||
|
||||
/**
|
||||
* struct imxdi_dev - private imxdi rtc data
|
||||
|
@ -313,7 +349,7 @@ static irqreturn_t dryice_norm_irq(int irq, void *dev_id)
|
|||
dier = __raw_readl(imxdi->ioaddr + DIER);
|
||||
|
||||
/* handle write complete and write error cases */
|
||||
if ((dier & DIER_WCIE)) {
|
||||
if (dier & DIER_WCIE) {
|
||||
/*If the write wait queue is empty then there is no pending
|
||||
operations. It means the interrupt is for DryIce -Security.
|
||||
IRQ must be returned as none.*/
|
||||
|
@ -322,7 +358,7 @@ static irqreturn_t dryice_norm_irq(int irq, void *dev_id)
|
|||
|
||||
/* DSR_WCF clears itself on DSR read */
|
||||
dsr = __raw_readl(imxdi->ioaddr + DSR);
|
||||
if ((dsr & (DSR_WCF | DSR_WEF))) {
|
||||
if (dsr & (DSR_WCF | DSR_WEF)) {
|
||||
/* mask the interrupt */
|
||||
di_int_disable(imxdi, DIER_WCIE);
|
||||
|
||||
|
@ -335,7 +371,7 @@ static irqreturn_t dryice_norm_irq(int irq, void *dev_id)
|
|||
}
|
||||
|
||||
/* handle the alarm case */
|
||||
if ((dier & DIER_CAIE)) {
|
||||
if (dier & DIER_CAIE) {
|
||||
/* DSR_WCF clears itself on DSR read */
|
||||
dsr = __raw_readl(imxdi->ioaddr + DSR);
|
||||
if (dsr & DSR_CAF) {
|
||||
|
|
|
@ -79,8 +79,10 @@
|
|||
#define ISL12057_MEM_MAP_LEN 0x10
|
||||
|
||||
struct isl12057_rtc_data {
|
||||
struct rtc_device *rtc;
|
||||
struct regmap *regmap;
|
||||
struct mutex lock;
|
||||
int irq;
|
||||
};
|
||||
|
||||
static void isl12057_rtc_regs_to_tm(struct rtc_time *tm, u8 *regs)
|
||||
|
@ -160,14 +162,47 @@ static int isl12057_i2c_validate_chip(struct regmap *regmap)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int isl12057_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
||||
static int _isl12057_rtc_clear_alarm(struct device *dev)
|
||||
{
|
||||
struct isl12057_rtc_data *data = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
ret = regmap_update_bits(data->regmap, ISL12057_REG_SR,
|
||||
ISL12057_REG_SR_A1F, 0);
|
||||
if (ret)
|
||||
dev_err(dev, "%s: clearing alarm failed (%d)\n", __func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _isl12057_rtc_update_alarm(struct device *dev, int enable)
|
||||
{
|
||||
struct isl12057_rtc_data *data = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
ret = regmap_update_bits(data->regmap, ISL12057_REG_INT,
|
||||
ISL12057_REG_INT_A1IE,
|
||||
enable ? ISL12057_REG_INT_A1IE : 0);
|
||||
if (ret)
|
||||
dev_err(dev, "%s: changing alarm interrupt flag failed (%d)\n",
|
||||
__func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: as we only read from device and do not perform any update, there is
|
||||
* no need for an equivalent function which would try and get driver's main
|
||||
* lock. Here, it is safe for everyone if we just use regmap internal lock
|
||||
* on the device when reading.
|
||||
*/
|
||||
static int _isl12057_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
||||
{
|
||||
struct isl12057_rtc_data *data = dev_get_drvdata(dev);
|
||||
u8 regs[ISL12057_RTC_SEC_LEN];
|
||||
unsigned int sr;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&data->lock);
|
||||
ret = regmap_read(data->regmap, ISL12057_REG_SR, &sr);
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: unable to read oscillator status flag (%d)\n",
|
||||
|
@ -187,8 +222,6 @@ static int isl12057_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
|||
__func__, ret);
|
||||
|
||||
out:
|
||||
mutex_unlock(&data->lock);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -197,6 +230,168 @@ out:
|
|||
return rtc_valid_tm(tm);
|
||||
}
|
||||
|
||||
static int isl12057_rtc_update_alarm(struct device *dev, int enable)
|
||||
{
|
||||
struct isl12057_rtc_data *data = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
mutex_lock(&data->lock);
|
||||
ret = _isl12057_rtc_update_alarm(dev, enable);
|
||||
mutex_unlock(&data->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int isl12057_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
|
||||
{
|
||||
struct isl12057_rtc_data *data = dev_get_drvdata(dev);
|
||||
struct rtc_time rtc_tm, *alarm_tm = &alarm->time;
|
||||
unsigned long rtc_secs, alarm_secs;
|
||||
u8 regs[ISL12057_A1_SEC_LEN];
|
||||
unsigned int ir;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&data->lock);
|
||||
ret = regmap_bulk_read(data->regmap, ISL12057_REG_A1_SC, regs,
|
||||
ISL12057_A1_SEC_LEN);
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: reading alarm section failed (%d)\n",
|
||||
__func__, ret);
|
||||
goto err_unlock;
|
||||
}
|
||||
|
||||
alarm_tm->tm_sec = bcd2bin(regs[0] & 0x7f);
|
||||
alarm_tm->tm_min = bcd2bin(regs[1] & 0x7f);
|
||||
alarm_tm->tm_hour = bcd2bin(regs[2] & 0x3f);
|
||||
alarm_tm->tm_mday = bcd2bin(regs[3] & 0x3f);
|
||||
alarm_tm->tm_wday = -1;
|
||||
|
||||
/*
|
||||
* The alarm section does not store year/month. We use the ones in rtc
|
||||
* section as a basis and increment month and then year if needed to get
|
||||
* alarm after current time.
|
||||
*/
|
||||
ret = _isl12057_rtc_read_time(dev, &rtc_tm);
|
||||
if (ret)
|
||||
goto err_unlock;
|
||||
|
||||
alarm_tm->tm_year = rtc_tm.tm_year;
|
||||
alarm_tm->tm_mon = rtc_tm.tm_mon;
|
||||
|
||||
ret = rtc_tm_to_time(&rtc_tm, &rtc_secs);
|
||||
if (ret)
|
||||
goto err_unlock;
|
||||
|
||||
ret = rtc_tm_to_time(alarm_tm, &alarm_secs);
|
||||
if (ret)
|
||||
goto err_unlock;
|
||||
|
||||
if (alarm_secs < rtc_secs) {
|
||||
if (alarm_tm->tm_mon == 11) {
|
||||
alarm_tm->tm_mon = 0;
|
||||
alarm_tm->tm_year += 1;
|
||||
} else {
|
||||
alarm_tm->tm_mon += 1;
|
||||
}
|
||||
}
|
||||
|
||||
ret = regmap_read(data->regmap, ISL12057_REG_INT, &ir);
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: reading alarm interrupt flag failed (%d)\n",
|
||||
__func__, ret);
|
||||
goto err_unlock;
|
||||
}
|
||||
|
||||
alarm->enabled = !!(ir & ISL12057_REG_INT_A1IE);
|
||||
|
||||
err_unlock:
|
||||
mutex_unlock(&data->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int isl12057_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
|
||||
{
|
||||
struct isl12057_rtc_data *data = dev_get_drvdata(dev);
|
||||
struct rtc_time *alarm_tm = &alarm->time;
|
||||
unsigned long rtc_secs, alarm_secs;
|
||||
u8 regs[ISL12057_A1_SEC_LEN];
|
||||
struct rtc_time rtc_tm;
|
||||
int ret, enable = 1;
|
||||
|
||||
mutex_lock(&data->lock);
|
||||
ret = _isl12057_rtc_read_time(dev, &rtc_tm);
|
||||
if (ret)
|
||||
goto err_unlock;
|
||||
|
||||
ret = rtc_tm_to_time(&rtc_tm, &rtc_secs);
|
||||
if (ret)
|
||||
goto err_unlock;
|
||||
|
||||
ret = rtc_tm_to_time(alarm_tm, &alarm_secs);
|
||||
if (ret)
|
||||
goto err_unlock;
|
||||
|
||||
/* If alarm time is before current time, disable the alarm */
|
||||
if (!alarm->enabled || alarm_secs <= rtc_secs) {
|
||||
enable = 0;
|
||||
} else {
|
||||
/*
|
||||
* Chip only support alarms up to one month in the future. Let's
|
||||
* return an error if we get something after that limit.
|
||||
* Comparison is done by incrementing rtc_tm month field by one
|
||||
* and checking alarm value is still below.
|
||||
*/
|
||||
if (rtc_tm.tm_mon == 11) { /* handle year wrapping */
|
||||
rtc_tm.tm_mon = 0;
|
||||
rtc_tm.tm_year += 1;
|
||||
} else {
|
||||
rtc_tm.tm_mon += 1;
|
||||
}
|
||||
|
||||
ret = rtc_tm_to_time(&rtc_tm, &rtc_secs);
|
||||
if (ret)
|
||||
goto err_unlock;
|
||||
|
||||
if (alarm_secs > rtc_secs) {
|
||||
dev_err(dev, "%s: max for alarm is one month (%d)\n",
|
||||
__func__, ret);
|
||||
ret = -EINVAL;
|
||||
goto err_unlock;
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable the alarm before modifying it */
|
||||
ret = _isl12057_rtc_update_alarm(dev, 0);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "%s: unable to disable the alarm (%d)\n",
|
||||
__func__, ret);
|
||||
goto err_unlock;
|
||||
}
|
||||
|
||||
/* Program alarm registers */
|
||||
regs[0] = bin2bcd(alarm_tm->tm_sec) & 0x7f;
|
||||
regs[1] = bin2bcd(alarm_tm->tm_min) & 0x7f;
|
||||
regs[2] = bin2bcd(alarm_tm->tm_hour) & 0x3f;
|
||||
regs[3] = bin2bcd(alarm_tm->tm_mday) & 0x3f;
|
||||
|
||||
ret = regmap_bulk_write(data->regmap, ISL12057_REG_A1_SC, regs,
|
||||
ISL12057_A1_SEC_LEN);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "%s: writing alarm section failed (%d)\n",
|
||||
__func__, ret);
|
||||
goto err_unlock;
|
||||
}
|
||||
|
||||
/* Enable or disable alarm */
|
||||
ret = _isl12057_rtc_update_alarm(dev, enable);
|
||||
|
||||
err_unlock:
|
||||
mutex_unlock(&data->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int isl12057_rtc_set_time(struct device *dev, struct rtc_time *tm)
|
||||
{
|
||||
struct isl12057_rtc_data *data = dev_get_drvdata(dev);
|
||||
|
@ -262,12 +457,85 @@ static int isl12057_check_rtc_status(struct device *dev, struct regmap *regmap)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
/*
|
||||
* One would expect the device to be marked as a wakeup source only
|
||||
* when an IRQ pin of the RTC is routed to an interrupt line of the
|
||||
* CPU. In practice, such an IRQ pin can be connected to a PMIC and
|
||||
* this allows the device to be powered up when RTC alarm rings. This
|
||||
* is for instance the case on ReadyNAS 102, 104 and 2120. On those
|
||||
* devices with no IRQ driectly connected to the SoC, the RTC chip
|
||||
* can be forced as a wakeup source by stating that explicitly in
|
||||
* the device's .dts file using the "isil,irq2-can-wakeup-machine"
|
||||
* boolean property. This will guarantee 'wakealarm' sysfs entry is
|
||||
* available on the device.
|
||||
*
|
||||
* The function below returns 1, i.e. the capability of the chip to
|
||||
* wakeup the device, based on IRQ availability or if the boolean
|
||||
* property has been set in the .dts file. Otherwise, it returns 0.
|
||||
*/
|
||||
|
||||
static bool isl12057_can_wakeup_machine(struct device *dev)
|
||||
{
|
||||
struct isl12057_rtc_data *data = dev_get_drvdata(dev);
|
||||
|
||||
return (data->irq || of_property_read_bool(dev->of_node,
|
||||
"isil,irq2-can-wakeup-machine"));
|
||||
}
|
||||
#else
|
||||
static bool isl12057_can_wakeup_machine(struct device *dev)
|
||||
{
|
||||
struct isl12057_rtc_data *data = dev_get_drvdata(dev);
|
||||
|
||||
return !!data->irq;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int isl12057_rtc_alarm_irq_enable(struct device *dev,
|
||||
unsigned int enable)
|
||||
{
|
||||
struct isl12057_rtc_data *rtc_data = dev_get_drvdata(dev);
|
||||
int ret = -ENOTTY;
|
||||
|
||||
if (rtc_data->irq)
|
||||
ret = isl12057_rtc_update_alarm(dev, enable);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static irqreturn_t isl12057_rtc_interrupt(int irq, void *data)
|
||||
{
|
||||
struct i2c_client *client = data;
|
||||
struct isl12057_rtc_data *rtc_data = dev_get_drvdata(&client->dev);
|
||||
struct rtc_device *rtc = rtc_data->rtc;
|
||||
int ret, handled = IRQ_NONE;
|
||||
unsigned int sr;
|
||||
|
||||
ret = regmap_read(rtc_data->regmap, ISL12057_REG_SR, &sr);
|
||||
if (!ret && (sr & ISL12057_REG_SR_A1F)) {
|
||||
dev_dbg(&client->dev, "RTC alarm!\n");
|
||||
|
||||
rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF);
|
||||
|
||||
/* Acknowledge and disable the alarm */
|
||||
_isl12057_rtc_clear_alarm(&client->dev);
|
||||
_isl12057_rtc_update_alarm(&client->dev, 0);
|
||||
|
||||
handled = IRQ_HANDLED;
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
static const struct rtc_class_ops rtc_ops = {
|
||||
.read_time = isl12057_rtc_read_time,
|
||||
.read_time = _isl12057_rtc_read_time,
|
||||
.set_time = isl12057_rtc_set_time,
|
||||
.read_alarm = isl12057_rtc_read_alarm,
|
||||
.set_alarm = isl12057_rtc_set_alarm,
|
||||
.alarm_irq_enable = isl12057_rtc_alarm_irq_enable,
|
||||
};
|
||||
|
||||
static struct regmap_config isl12057_rtc_regmap_config = {
|
||||
static const struct regmap_config isl12057_rtc_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
};
|
||||
|
@ -277,7 +545,6 @@ static int isl12057_probe(struct i2c_client *client,
|
|||
{
|
||||
struct device *dev = &client->dev;
|
||||
struct isl12057_rtc_data *data;
|
||||
struct rtc_device *rtc;
|
||||
struct regmap *regmap;
|
||||
int ret;
|
||||
|
||||
|
@ -310,10 +577,71 @@ static int isl12057_probe(struct i2c_client *client,
|
|||
data->regmap = regmap;
|
||||
dev_set_drvdata(dev, data);
|
||||
|
||||
rtc = devm_rtc_device_register(dev, DRV_NAME, &rtc_ops, THIS_MODULE);
|
||||
return PTR_ERR_OR_ZERO(rtc);
|
||||
if (client->irq > 0) {
|
||||
ret = devm_request_threaded_irq(dev, client->irq, NULL,
|
||||
isl12057_rtc_interrupt,
|
||||
IRQF_SHARED|IRQF_ONESHOT,
|
||||
DRV_NAME, client);
|
||||
if (!ret)
|
||||
data->irq = client->irq;
|
||||
else
|
||||
dev_err(dev, "%s: irq %d unavailable (%d)\n", __func__,
|
||||
client->irq, ret);
|
||||
}
|
||||
|
||||
if (isl12057_can_wakeup_machine(dev))
|
||||
device_init_wakeup(dev, true);
|
||||
|
||||
data->rtc = devm_rtc_device_register(dev, DRV_NAME, &rtc_ops,
|
||||
THIS_MODULE);
|
||||
ret = PTR_ERR_OR_ZERO(data->rtc);
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: unable to register RTC device (%d)\n",
|
||||
__func__, ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* We cannot support UIE mode if we do not have an IRQ line */
|
||||
if (!data->irq)
|
||||
data->rtc->uie_unsupported = 1;
|
||||
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int isl12057_remove(struct i2c_client *client)
|
||||
{
|
||||
if (isl12057_can_wakeup_machine(&client->dev))
|
||||
device_init_wakeup(&client->dev, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int isl12057_rtc_suspend(struct device *dev)
|
||||
{
|
||||
struct isl12057_rtc_data *rtc_data = dev_get_drvdata(dev);
|
||||
|
||||
if (rtc_data->irq && device_may_wakeup(dev))
|
||||
return enable_irq_wake(rtc_data->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int isl12057_rtc_resume(struct device *dev)
|
||||
{
|
||||
struct isl12057_rtc_data *rtc_data = dev_get_drvdata(dev);
|
||||
|
||||
if (rtc_data->irq && device_may_wakeup(dev))
|
||||
return disable_irq_wake(rtc_data->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(isl12057_rtc_pm_ops, isl12057_rtc_suspend,
|
||||
isl12057_rtc_resume);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id isl12057_dt_match[] = {
|
||||
{ .compatible = "isl,isl12057" },
|
||||
|
@ -331,9 +659,11 @@ static struct i2c_driver isl12057_driver = {
|
|||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
.pm = &isl12057_rtc_pm_ops,
|
||||
.of_match_table = of_match_ptr(isl12057_dt_match),
|
||||
},
|
||||
.probe = isl12057_probe,
|
||||
.remove = isl12057_remove,
|
||||
.id_table = isl12057_id,
|
||||
};
|
||||
module_i2c_driver(isl12057_driver);
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <linux/errno.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/rtc.h>
|
||||
|
@ -340,10 +341,19 @@ static int pcf2123_remove(struct spi_device *spi)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id pcf2123_dt_ids[] = {
|
||||
{ .compatible = "nxp,rtc-pcf2123", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, pcf2123_dt_ids);
|
||||
#endif
|
||||
|
||||
static struct spi_driver pcf2123_driver = {
|
||||
.driver = {
|
||||
.name = "rtc-pcf2123",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = of_match_ptr(pcf2123_dt_ids),
|
||||
},
|
||||
.probe = pcf2123_probe,
|
||||
.remove = pcf2123_remove,
|
||||
|
|
|
@ -67,15 +67,21 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
|
|||
/* Force an update of the shadowed registers right now */
|
||||
ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
|
||||
BIT_RTC_CTRL_REG_RTC_GET_TIME,
|
||||
0);
|
||||
BIT_RTC_CTRL_REG_RTC_GET_TIME);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to update bits rtc_ctrl: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* After we set the GET_TIME bit, the rtc time can't be read
|
||||
* immediately. So we should wait up to 31.25 us, about one cycle of
|
||||
* 32khz. If we clear the GET_TIME bit here, the time of i2c transfer
|
||||
* certainly more than 31.25us: 16 * 2.5us at 400kHz bus frequency.
|
||||
*/
|
||||
ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
|
||||
BIT_RTC_CTRL_REG_RTC_GET_TIME,
|
||||
BIT_RTC_CTRL_REG_RTC_GET_TIME);
|
||||
0);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to update bits rtc_ctrl: %d\n", ret);
|
||||
return ret;
|
||||
|
|
|
@ -48,7 +48,6 @@ static unsigned int be_iopoll_budget = 10;
|
|||
static unsigned int be_max_phys_size = 64;
|
||||
static unsigned int enable_msix = 1;
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table);
|
||||
MODULE_DESCRIPTION(DRV_DESC " " BUILD_STR);
|
||||
MODULE_VERSION(BUILD_STR);
|
||||
MODULE_AUTHOR("Emulex Corporation");
|
||||
|
|
|
@ -4658,10 +4658,10 @@ static ssize_t map_show(struct device_driver *ddp, char *buf)
|
|||
return scnprintf(buf, PAGE_SIZE, "0-%u\n",
|
||||
sdebug_store_sectors);
|
||||
|
||||
count = bitmap_scnlistprintf(buf, PAGE_SIZE, map_storep, map_size);
|
||||
|
||||
count = scnprintf(buf, PAGE_SIZE - 1, "%*pbl",
|
||||
(int)map_size, map_storep);
|
||||
buf[count++] = '\n';
|
||||
buf[count++] = 0;
|
||||
buf[count] = '\0';
|
||||
|
||||
return count;
|
||||
}
|
||||
|
|
|
@ -86,17 +86,14 @@ static void qset_print(struct seq_file *s, struct whc_qset *qset)
|
|||
static int di_print(struct seq_file *s, void *p)
|
||||
{
|
||||
struct whc *whc = s->private;
|
||||
char buf[72];
|
||||
int d;
|
||||
|
||||
for (d = 0; d < whc->n_devices; d++) {
|
||||
struct di_buf_entry *di = &whc->di_buf[d];
|
||||
|
||||
bitmap_scnprintf(buf, sizeof(buf),
|
||||
(unsigned long *)di->availability_info, UWB_NUM_MAS);
|
||||
|
||||
seq_printf(s, "DI[%d]\n", d);
|
||||
seq_printf(s, " availability: %s\n", buf);
|
||||
seq_printf(s, " availability: %*pb\n",
|
||||
UWB_NUM_MAS, (unsigned long *)di->availability_info);
|
||||
seq_printf(s, " %c%c key idx: %d dev addr: %d\n",
|
||||
(di->addr_sec_info & WHC_DI_SECURE) ? 'S' : ' ',
|
||||
(di->addr_sec_info & WHC_DI_DISABLE) ? 'D' : ' ',
|
||||
|
|
|
@ -49,14 +49,13 @@ static void wusbhc_rsv_complete_cb(struct uwb_rsv *rsv)
|
|||
struct wusbhc *wusbhc = rsv->pal_priv;
|
||||
struct device *dev = wusbhc->dev;
|
||||
struct uwb_mas_bm mas;
|
||||
char buf[72];
|
||||
|
||||
dev_dbg(dev, "%s: state = %d\n", __func__, rsv->state);
|
||||
switch (rsv->state) {
|
||||
case UWB_RSV_STATE_O_ESTABLISHED:
|
||||
uwb_rsv_get_usable_mas(rsv, &mas);
|
||||
bitmap_scnprintf(buf, sizeof(buf), mas.bm, UWB_NUM_MAS);
|
||||
dev_dbg(dev, "established reservation: %s\n", buf);
|
||||
dev_dbg(dev, "established reservation: %*pb\n",
|
||||
UWB_NUM_MAS, mas.bm);
|
||||
wusbhc_bwa_set(wusbhc, rsv->stream, &mas);
|
||||
break;
|
||||
case UWB_RSV_STATE_NONE:
|
||||
|
|
|
@ -496,10 +496,9 @@ void wa_rpipes_destroy(struct wahc *wa)
|
|||
struct device *dev = &wa->usb_iface->dev;
|
||||
|
||||
if (!bitmap_empty(wa->rpipe_bm, wa->rpipes)) {
|
||||
char buf[256];
|
||||
WARN_ON(1);
|
||||
bitmap_scnprintf(buf, sizeof(buf), wa->rpipe_bm, wa->rpipes);
|
||||
dev_err(dev, "BUG: pipes not released on exit: %s\n", buf);
|
||||
dev_err(dev, "BUG: pipes not released on exit: %*pb\n",
|
||||
wa->rpipes, wa->rpipe_bm);
|
||||
}
|
||||
kfree(wa->rpipe_bm);
|
||||
}
|
||||
|
|
|
@ -496,11 +496,8 @@ static void __exit wusbcore_exit(void)
|
|||
{
|
||||
clear_bit(0, wusb_cluster_id_table);
|
||||
if (!bitmap_empty(wusb_cluster_id_table, CLUSTER_IDS)) {
|
||||
char buf[256];
|
||||
bitmap_scnprintf(buf, sizeof(buf), wusb_cluster_id_table,
|
||||
CLUSTER_IDS);
|
||||
printk(KERN_ERR "BUG: WUSB Cluster IDs not released "
|
||||
"on exit: %s\n", buf);
|
||||
printk(KERN_ERR "BUG: WUSB Cluster IDs not released on exit: %*pb\n",
|
||||
CLUSTER_IDS, wusb_cluster_id_table);
|
||||
WARN_ON(1);
|
||||
}
|
||||
usb_unregister_notify(&wusb_usb_notifier);
|
||||
|
|
|
@ -619,11 +619,9 @@ static void uwb_drp_handle_alien_drp(struct uwb_rc *rc, struct uwb_ie_drp *drp_i
|
|||
struct device *dev = &rc->uwb_dev.dev;
|
||||
struct uwb_mas_bm mas;
|
||||
struct uwb_cnflt_alien *cnflt;
|
||||
char buf[72];
|
||||
unsigned long delay_us = UWB_MAS_LENGTH_US * UWB_MAS_PER_ZONE;
|
||||
|
||||
uwb_drp_ie_to_bm(&mas, drp_ie);
|
||||
bitmap_scnprintf(buf, sizeof(buf), mas.bm, UWB_NUM_MAS);
|
||||
|
||||
list_for_each_entry(cnflt, &rc->cnflt_alien_list, rc_node) {
|
||||
if (bitmap_equal(cnflt->mas.bm, mas.bm, UWB_NUM_MAS)) {
|
||||
|
|
|
@ -217,7 +217,6 @@ static int reservations_print(struct seq_file *s, void *p)
|
|||
struct uwb_dev_addr devaddr;
|
||||
char owner[UWB_ADDR_STRSIZE], target[UWB_ADDR_STRSIZE];
|
||||
bool is_owner;
|
||||
char buf[72];
|
||||
|
||||
uwb_dev_addr_print(owner, sizeof(owner), &rsv->owner->dev_addr);
|
||||
if (rsv->target.type == UWB_RSV_TARGET_DEV) {
|
||||
|
@ -234,8 +233,7 @@ static int reservations_print(struct seq_file *s, void *p)
|
|||
owner, target, uwb_rsv_state_str(rsv->state));
|
||||
seq_printf(s, " stream: %d type: %s\n",
|
||||
rsv->stream, uwb_rsv_type_str(rsv->type));
|
||||
bitmap_scnprintf(buf, sizeof(buf), rsv->mas.bm, UWB_NUM_MAS);
|
||||
seq_printf(s, " %s\n", buf);
|
||||
seq_printf(s, " %*pb\n", UWB_NUM_MAS, rsv->mas.bm);
|
||||
}
|
||||
|
||||
mutex_unlock(&rc->rsvs_mutex);
|
||||
|
@ -259,14 +257,10 @@ static const struct file_operations reservations_fops = {
|
|||
static int drp_avail_print(struct seq_file *s, void *p)
|
||||
{
|
||||
struct uwb_rc *rc = s->private;
|
||||
char buf[72];
|
||||
|
||||
bitmap_scnprintf(buf, sizeof(buf), rc->drp_avail.global, UWB_NUM_MAS);
|
||||
seq_printf(s, "global: %s\n", buf);
|
||||
bitmap_scnprintf(buf, sizeof(buf), rc->drp_avail.local, UWB_NUM_MAS);
|
||||
seq_printf(s, "local: %s\n", buf);
|
||||
bitmap_scnprintf(buf, sizeof(buf), rc->drp_avail.pending, UWB_NUM_MAS);
|
||||
seq_printf(s, "pending: %s\n", buf);
|
||||
seq_printf(s, "global: %*pb\n", UWB_NUM_MAS, rc->drp_avail.global);
|
||||
seq_printf(s, "local: %*pb\n", UWB_NUM_MAS, rc->drp_avail.local);
|
||||
seq_printf(s, "pending: %*pb\n", UWB_NUM_MAS, rc->drp_avail.pending);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
#include <linux/prefetch.h>
|
||||
#include <linux/ratelimit.h>
|
||||
#include <linux/list_lru.h>
|
||||
#include <linux/kasan.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "mount.h"
|
||||
|
||||
|
@ -1429,6 +1431,9 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name)
|
|||
}
|
||||
atomic_set(&p->u.count, 1);
|
||||
dname = p->name;
|
||||
if (IS_ENABLED(CONFIG_DCACHE_WORD_ACCESS))
|
||||
kasan_unpoison_shadow(dname,
|
||||
round_up(name->len + 1, sizeof(unsigned long)));
|
||||
} else {
|
||||
dname = dentry->d_iname;
|
||||
}
|
||||
|
|
|
@ -1639,9 +1639,9 @@ fetch_events:
|
|||
|
||||
spin_lock_irqsave(&ep->lock, flags);
|
||||
}
|
||||
__remove_wait_queue(&ep->wq, &wait);
|
||||
|
||||
set_current_state(TASK_RUNNING);
|
||||
__remove_wait_queue(&ep->wq, &wait);
|
||||
__set_current_state(TASK_RUNNING);
|
||||
}
|
||||
check_events:
|
||||
/* Is it worth to try to dig for events ? */
|
||||
|
|
|
@ -411,8 +411,9 @@ void kernfs_put(struct kernfs_node *kn)
|
|||
|
||||
if (kernfs_type(kn) == KERNFS_LINK)
|
||||
kernfs_put(kn->symlink.target_kn);
|
||||
if (!(kn->flags & KERNFS_STATIC_NAME))
|
||||
kfree(kn->name);
|
||||
|
||||
kfree_const(kn->name);
|
||||
|
||||
if (kn->iattr) {
|
||||
if (kn->iattr->ia_secdata)
|
||||
security_release_secctx(kn->iattr->ia_secdata,
|
||||
|
@ -506,15 +507,12 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root,
|
|||
const char *name, umode_t mode,
|
||||
unsigned flags)
|
||||
{
|
||||
char *dup_name = NULL;
|
||||
struct kernfs_node *kn;
|
||||
int ret;
|
||||
|
||||
if (!(flags & KERNFS_STATIC_NAME)) {
|
||||
name = dup_name = kstrdup(name, GFP_KERNEL);
|
||||
if (!name)
|
||||
return NULL;
|
||||
}
|
||||
name = kstrdup_const(name, GFP_KERNEL);
|
||||
if (!name)
|
||||
return NULL;
|
||||
|
||||
kn = kmem_cache_zalloc(kernfs_node_cache, GFP_KERNEL);
|
||||
if (!kn)
|
||||
|
@ -538,7 +536,7 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root,
|
|||
err_out2:
|
||||
kmem_cache_free(kernfs_node_cache, kn);
|
||||
err_out1:
|
||||
kfree(dup_name);
|
||||
kfree_const(name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1264,7 +1262,7 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent,
|
|||
/* rename kernfs_node */
|
||||
if (strcmp(kn->name, new_name) != 0) {
|
||||
error = -ENOMEM;
|
||||
new_name = kstrdup(new_name, GFP_KERNEL);
|
||||
new_name = kstrdup_const(new_name, GFP_KERNEL);
|
||||
if (!new_name)
|
||||
goto out;
|
||||
} else {
|
||||
|
@ -1285,9 +1283,7 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent,
|
|||
|
||||
kn->ns = new_ns;
|
||||
if (new_name) {
|
||||
if (!(kn->flags & KERNFS_STATIC_NAME))
|
||||
old_name = kn->name;
|
||||
kn->flags &= ~KERNFS_STATIC_NAME;
|
||||
old_name = kn->name;
|
||||
kn->name = new_name;
|
||||
}
|
||||
|
||||
|
@ -1297,7 +1293,7 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent,
|
|||
kernfs_link_sibling(kn);
|
||||
|
||||
kernfs_put(old_parent);
|
||||
kfree(old_name);
|
||||
kfree_const(old_name);
|
||||
|
||||
error = 0;
|
||||
out:
|
||||
|
|
|
@ -901,7 +901,6 @@ const struct file_operations kernfs_file_fops = {
|
|||
* @ops: kernfs operations for the file
|
||||
* @priv: private data for the file
|
||||
* @ns: optional namespace tag of the file
|
||||
* @name_is_static: don't copy file name
|
||||
* @key: lockdep key for the file's active_ref, %NULL to disable lockdep
|
||||
*
|
||||
* Returns the created node on success, ERR_PTR() value on error.
|
||||
|
@ -911,7 +910,6 @@ struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent,
|
|||
umode_t mode, loff_t size,
|
||||
const struct kernfs_ops *ops,
|
||||
void *priv, const void *ns,
|
||||
bool name_is_static,
|
||||
struct lock_class_key *key)
|
||||
{
|
||||
struct kernfs_node *kn;
|
||||
|
@ -919,8 +917,6 @@ struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent,
|
|||
int rc;
|
||||
|
||||
flags = KERNFS_FILE;
|
||||
if (name_is_static)
|
||||
flags |= KERNFS_STATIC_NAME;
|
||||
|
||||
kn = kernfs_new_node(parent, name, (mode & S_IALLUGO) | S_IFREG, flags);
|
||||
if (!kn)
|
||||
|
|
|
@ -201,7 +201,7 @@ static struct mount *alloc_vfsmnt(const char *name)
|
|||
goto out_free_cache;
|
||||
|
||||
if (name) {
|
||||
mnt->mnt_devname = kstrdup(name, GFP_KERNEL);
|
||||
mnt->mnt_devname = kstrdup_const(name, GFP_KERNEL);
|
||||
if (!mnt->mnt_devname)
|
||||
goto out_free_id;
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ static struct mount *alloc_vfsmnt(const char *name)
|
|||
|
||||
#ifdef CONFIG_SMP
|
||||
out_free_devname:
|
||||
kfree(mnt->mnt_devname);
|
||||
kfree_const(mnt->mnt_devname);
|
||||
#endif
|
||||
out_free_id:
|
||||
mnt_free_id(mnt);
|
||||
|
@ -568,7 +568,7 @@ int sb_prepare_remount_readonly(struct super_block *sb)
|
|||
|
||||
static void free_vfsmnt(struct mount *mnt)
|
||||
{
|
||||
kfree(mnt->mnt_devname);
|
||||
kfree_const(mnt->mnt_devname);
|
||||
#ifdef CONFIG_SMP
|
||||
free_percpu(mnt->mnt_pcp);
|
||||
#endif
|
||||
|
|
|
@ -316,12 +316,10 @@ static inline void task_context_switch_counts(struct seq_file *m,
|
|||
|
||||
static void task_cpus_allowed(struct seq_file *m, struct task_struct *task)
|
||||
{
|
||||
seq_puts(m, "Cpus_allowed:\t");
|
||||
seq_cpumask(m, &task->cpus_allowed);
|
||||
seq_putc(m, '\n');
|
||||
seq_puts(m, "Cpus_allowed_list:\t");
|
||||
seq_cpumask_list(m, &task->cpus_allowed);
|
||||
seq_putc(m, '\n');
|
||||
seq_printf(m, "Cpus_allowed:\t%*pb\n",
|
||||
cpumask_pr_args(&task->cpus_allowed));
|
||||
seq_printf(m, "Cpus_allowed_list:\t%*pbl\n",
|
||||
cpumask_pr_args(&task->cpus_allowed));
|
||||
}
|
||||
|
||||
int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
|
||||
|
|
|
@ -539,38 +539,6 @@ int seq_dentry(struct seq_file *m, struct dentry *dentry, const char *esc)
|
|||
return res;
|
||||
}
|
||||
|
||||
int seq_bitmap(struct seq_file *m, const unsigned long *bits,
|
||||
unsigned int nr_bits)
|
||||
{
|
||||
if (m->count < m->size) {
|
||||
int len = bitmap_scnprintf(m->buf + m->count,
|
||||
m->size - m->count, bits, nr_bits);
|
||||
if (m->count + len < m->size) {
|
||||
m->count += len;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
seq_set_overflow(m);
|
||||
return -1;
|
||||
}
|
||||
EXPORT_SYMBOL(seq_bitmap);
|
||||
|
||||
int seq_bitmap_list(struct seq_file *m, const unsigned long *bits,
|
||||
unsigned int nr_bits)
|
||||
{
|
||||
if (m->count < m->size) {
|
||||
int len = bitmap_scnlistprintf(m->buf + m->count,
|
||||
m->size - m->count, bits, nr_bits);
|
||||
if (m->count + len < m->size) {
|
||||
m->count += len;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
seq_set_overflow(m);
|
||||
return -1;
|
||||
}
|
||||
EXPORT_SYMBOL(seq_bitmap_list);
|
||||
|
||||
static void *single_start(struct seq_file *p, loff_t *pos)
|
||||
{
|
||||
return NULL + (*pos == 0);
|
||||
|
|
|
@ -295,7 +295,7 @@ int sysfs_add_file_mode_ns(struct kernfs_node *parent,
|
|||
key = attr->key ?: (struct lock_class_key *)&attr->skey;
|
||||
#endif
|
||||
kn = __kernfs_create_file(parent, attr->name, mode & 0777, size, ops,
|
||||
(void *)attr, ns, true, key);
|
||||
(void *)attr, ns, key);
|
||||
if (IS_ERR(kn)) {
|
||||
if (PTR_ERR(kn) == -EEXIST)
|
||||
sysfs_warn_dup(parent, attr->name);
|
||||
|
|
|
@ -478,6 +478,7 @@
|
|||
#define KERNEL_CTORS() . = ALIGN(8); \
|
||||
VMLINUX_SYMBOL(__ctors_start) = .; \
|
||||
*(.ctors) \
|
||||
*(SORT(.init_array.*)) \
|
||||
*(.init_array) \
|
||||
VMLINUX_SYMBOL(__ctors_end) = .;
|
||||
#else
|
||||
|
|
|
@ -52,16 +52,13 @@
|
|||
* bitmap_bitremap(oldbit, old, new, nbits) newbit = map(old, new)(oldbit)
|
||||
* bitmap_onto(dst, orig, relmap, nbits) *dst = orig relative to relmap
|
||||
* bitmap_fold(dst, orig, sz, nbits) dst bits = orig bits mod sz
|
||||
* bitmap_scnprintf(buf, len, src, nbits) Print bitmap src to buf
|
||||
* bitmap_parse(buf, buflen, dst, nbits) Parse bitmap dst from kernel buf
|
||||
* bitmap_parse_user(ubuf, ulen, dst, nbits) Parse bitmap dst from user buf
|
||||
* bitmap_scnlistprintf(buf, len, src, nbits) Print bitmap src as list to buf
|
||||
* bitmap_parselist(buf, dst, nbits) Parse bitmap dst from kernel buf
|
||||
* bitmap_parselist_user(buf, dst, nbits) Parse bitmap dst from user buf
|
||||
* bitmap_find_free_region(bitmap, bits, order) Find and allocate bit region
|
||||
* bitmap_release_region(bitmap, pos, order) Free specified bit region
|
||||
* bitmap_allocate_region(bitmap, pos, order) Allocate specified bit region
|
||||
* bitmap_print_to_pagebuf(list, buf, mask, nbits) Print bitmap src as list/hex
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -96,10 +93,10 @@ extern int __bitmap_equal(const unsigned long *bitmap1,
|
|||
const unsigned long *bitmap2, unsigned int nbits);
|
||||
extern void __bitmap_complement(unsigned long *dst, const unsigned long *src,
|
||||
unsigned int nbits);
|
||||
extern void __bitmap_shift_right(unsigned long *dst,
|
||||
const unsigned long *src, int shift, int bits);
|
||||
extern void __bitmap_shift_left(unsigned long *dst,
|
||||
const unsigned long *src, int shift, int bits);
|
||||
extern void __bitmap_shift_right(unsigned long *dst, const unsigned long *src,
|
||||
unsigned int shift, unsigned int nbits);
|
||||
extern void __bitmap_shift_left(unsigned long *dst, const unsigned long *src,
|
||||
unsigned int shift, unsigned int nbits);
|
||||
extern int __bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
|
||||
const unsigned long *bitmap2, unsigned int nbits);
|
||||
extern void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
|
||||
|
@ -147,14 +144,10 @@ bitmap_find_next_zero_area(unsigned long *map,
|
|||
align_mask, 0);
|
||||
}
|
||||
|
||||
extern int bitmap_scnprintf(char *buf, unsigned int len,
|
||||
const unsigned long *src, int nbits);
|
||||
extern int __bitmap_parse(const char *buf, unsigned int buflen, int is_user,
|
||||
unsigned long *dst, int nbits);
|
||||
extern int bitmap_parse_user(const char __user *ubuf, unsigned int ulen,
|
||||
unsigned long *dst, int nbits);
|
||||
extern int bitmap_scnlistprintf(char *buf, unsigned int len,
|
||||
const unsigned long *src, int nbits);
|
||||
extern int bitmap_parselist(const char *buf, unsigned long *maskp,
|
||||
int nmaskbits);
|
||||
extern int bitmap_parselist_user(const char __user *ubuf, unsigned int ulen,
|
||||
|
@ -170,7 +163,11 @@ extern void bitmap_fold(unsigned long *dst, const unsigned long *orig,
|
|||
extern int bitmap_find_free_region(unsigned long *bitmap, unsigned int bits, int order);
|
||||
extern void bitmap_release_region(unsigned long *bitmap, unsigned int pos, int order);
|
||||
extern int bitmap_allocate_region(unsigned long *bitmap, unsigned int pos, int order);
|
||||
extern void bitmap_copy_le(void *dst, const unsigned long *src, int nbits);
|
||||
#ifdef __BIG_ENDIAN
|
||||
extern void bitmap_copy_le(unsigned long *dst, const unsigned long *src, unsigned int nbits);
|
||||
#else
|
||||
#define bitmap_copy_le bitmap_copy
|
||||
#endif
|
||||
extern unsigned int bitmap_ord_to_pos(const unsigned long *bitmap, unsigned int ord, unsigned int nbits);
|
||||
extern int bitmap_print_to_pagebuf(bool list, char *buf,
|
||||
const unsigned long *maskp, int nmaskbits);
|
||||
|
@ -309,22 +306,22 @@ static inline int bitmap_weight(const unsigned long *src, unsigned int nbits)
|
|||
return __bitmap_weight(src, nbits);
|
||||
}
|
||||
|
||||
static inline void bitmap_shift_right(unsigned long *dst,
|
||||
const unsigned long *src, int n, int nbits)
|
||||
static inline void bitmap_shift_right(unsigned long *dst, const unsigned long *src,
|
||||
unsigned int shift, int nbits)
|
||||
{
|
||||
if (small_const_nbits(nbits))
|
||||
*dst = (*src & BITMAP_LAST_WORD_MASK(nbits)) >> n;
|
||||
*dst = (*src & BITMAP_LAST_WORD_MASK(nbits)) >> shift;
|
||||
else
|
||||
__bitmap_shift_right(dst, src, n, nbits);
|
||||
__bitmap_shift_right(dst, src, shift, nbits);
|
||||
}
|
||||
|
||||
static inline void bitmap_shift_left(unsigned long *dst,
|
||||
const unsigned long *src, int n, int nbits)
|
||||
static inline void bitmap_shift_left(unsigned long *dst, const unsigned long *src,
|
||||
unsigned int shift, unsigned int nbits)
|
||||
{
|
||||
if (small_const_nbits(nbits))
|
||||
*dst = (*src << n) & BITMAP_LAST_WORD_MASK(nbits);
|
||||
*dst = (*src << shift) & BITMAP_LAST_WORD_MASK(nbits);
|
||||
else
|
||||
__bitmap_shift_left(dst, src, n, nbits);
|
||||
__bitmap_shift_left(dst, src, shift, nbits);
|
||||
}
|
||||
|
||||
static inline int bitmap_parse(const char *buf, unsigned int buflen,
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
#define __deprecated __attribute__((deprecated))
|
||||
#define __packed __attribute__((packed))
|
||||
#define __weak __attribute__((weak))
|
||||
#define __alias(symbol) __attribute__((alias(#symbol)))
|
||||
|
||||
/*
|
||||
* it doesn't make sense on ARM (currently the only user of __naked) to trace
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue