1
0
Fork 0

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
  ...
hifive-unleashed-5.1
Linus Torvalds 2015-02-14 09:22:35 -08:00
commit 83e047c104
161 changed files with 4476 additions and 797 deletions

View File

@ -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

View File

@ -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>;
};

View File

@ -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;
};

View File

@ -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;
};

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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

View File

@ -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>

View File

@ -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

View File

@ -87,6 +87,7 @@
isl12057: isl12057@68 {
compatible = "isil,isl12057";
reg = <0x68>;
isil,irq2-can-wakeup-machine;
};
g762: g762@3e {

View File

@ -93,6 +93,7 @@
isl12057: isl12057@68 {
compatible = "isil,isl12057";
reg = <0x68>;
isil,irq2-can-wakeup-machine;
};
g762: g762@3e {

View File

@ -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>;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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)

View File

@ -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

View File

@ -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;
}

View File

@ -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));
}

View File

@ -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 =

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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",

View File

@ -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)

View File

@ -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.");
}

View File

@ -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());

View File

@ -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));
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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,

View File

@ -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,

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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();

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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",

View File

@ -6,7 +6,7 @@
# for more details.
#
#
KASAN_SANITIZE := n
subdir- := rm
obj-y += init.o

View File

@ -6,6 +6,7 @@
# for more details.
#
#
KASAN_SANITIZE := n
always := realmode.bin realmode.relocs

View File

@ -3,6 +3,7 @@
#
KBUILD_CFLAGS += $(DISABLE_LTO)
KASAN_SANITIZE := n
VDSO64-$(CONFIG_X86_64) := y
VDSOX32-$(CONFIG_X86_X32_ABI) := y

View File

@ -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,

View File

@ -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 */

View File

@ -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;

View File

@ -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;

View File

@ -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);
}

View File

@ -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

View File

@ -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,

View File

@ -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';

View File

@ -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';

View File

@ -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");

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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) {

View File

@ -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

View File

@ -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

View File

@ -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");

View File

@ -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,

View File

@ -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) {

View File

@ -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);

View File

@ -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,

View File

@ -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;

View File

@ -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");

View File

@ -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;
}

View File

@ -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' : ' ',

View File

@ -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:

View File

@ -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);
}

View File

@ -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);

View File

@ -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)) {

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 ? */

View File

@ -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:

View File

@ -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)

View File

@ -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

View File

@ -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,

View File

@ -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);

View File

@ -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);

View File

@ -478,6 +478,7 @@
#define KERNEL_CTORS() . = ALIGN(8); \
VMLINUX_SYMBOL(__ctors_start) = .; \
*(.ctors) \
*(SORT(.init_array.*)) \
*(.init_array) \
VMLINUX_SYMBOL(__ctors_end) = .;
#else

View File

@ -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,

View File

@ -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