Merge a4dec04c7f ("Merge tag 'dma-mapping-5.12' of git://git.infradead.org/users/hch/dma-mapping") into android-mainline

Steps on the way to 5.12-rc1

Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: I90e0e534d9ed015f2de519498011dcd9ca06ef75
This commit is contained in:
Greg Kroah-Hartman
2021-03-06 19:59:53 +01:00
103 changed files with 2565 additions and 351 deletions

View File

@@ -109,6 +109,7 @@ ForEachMacros:
- 'css_for_each_child'
- 'css_for_each_descendant_post'
- 'css_for_each_descendant_pre'
- 'cxl_for_each_cmd'
- 'device_for_each_child_node'
- 'dma_fence_chain_for_each'
- 'do_for_each_ftrace_op'

View File

@@ -0,0 +1,26 @@
What: /sys/bus/cxl/devices/memX/firmware_version
Date: December, 2020
KernelVersion: v5.12
Contact: linux-cxl@vger.kernel.org
Description:
(RO) "FW Revision" string as reported by the Identify
Memory Device Output Payload in the CXL-2.0
specification.
What: /sys/bus/cxl/devices/memX/ram/size
Date: December, 2020
KernelVersion: v5.12
Contact: linux-cxl@vger.kernel.org
Description:
(RO) "Volatile Only Capacity" as bytes. Represents the
identically named field in the Identify Memory Device Output
Payload in the CXL-2.0 specification.
What: /sys/bus/cxl/devices/memX/pmem/size
Date: December, 2020
KernelVersion: v5.12
Contact: linux-cxl@vger.kernel.org
Description:
(RO) "Persistent Only Capacity" as bytes. Represents the
identically named field in the Identify Memory Device Output
Payload in the CXL-2.0 specification.

View File

@@ -526,46 +526,6 @@ for the kernel vs the device.
If you don't understand how cache line coherency works between a processor and
an I/O device, you should not be using this part of the API.
::
void *
dma_alloc_noncoherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, enum dma_data_direction dir,
gfp_t gfp)
This routine allocates a region of <size> bytes of consistent memory. It
returns a pointer to the allocated region (in the processor's virtual address
space) or NULL if the allocation failed. The returned memory may or may not
be in the kernel direct mapping. Drivers must not call virt_to_page on
the returned memory region.
It also returns a <dma_handle> which may be cast to an unsigned integer the
same width as the bus and given to the device as the DMA address base of
the region.
The dir parameter specified if data is read and/or written by the device,
see dma_map_single() for details.
The gfp parameter allows the caller to specify the ``GFP_`` flags (see
kmalloc()) for the allocation, but rejects flags used to specify a memory
zone such as GFP_DMA or GFP_HIGHMEM.
Before giving the memory to the device, dma_sync_single_for_device() needs
to be called, and before reading memory written by the device,
dma_sync_single_for_cpu(), just like for streaming DMA mappings that are
reused.
::
void
dma_free_noncoherent(struct device *dev, size_t size, void *cpu_addr,
dma_addr_t dma_handle, enum dma_data_direction dir)
Free a region of memory previously allocated using dma_alloc_noncoherent().
dev, size and dma_handle and dir must all be the same as those passed into
dma_alloc_noncoherent(). cpu_addr must be the virtual address returned by
dma_alloc_noncoherent().
::
struct page *
@@ -600,9 +560,29 @@ reused.
dma_addr_t dma_handle, enum dma_data_direction dir)
Free a region of memory previously allocated using dma_alloc_pages().
dev, size and dma_handle and dir must all be the same as those passed into
dma_alloc_noncoherent(). page must be the pointer returned by
dma_alloc_pages().
dev, size, dma_handle and dir must all be the same as those passed into
dma_alloc_pages(). page must be the pointer returned by dma_alloc_pages().
::
void *
dma_alloc_noncoherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, enum dma_data_direction dir,
gfp_t gfp)
This routine is a convenient wrapper around dma_alloc_pages that returns the
kernel virtual address for the allocated memory instead of the page structure.
::
void
dma_free_noncoherent(struct device *dev, size_t size, void *cpu_addr,
dma_addr_t dma_handle, enum dma_data_direction dir)
Free a region of memory previously allocated using dma_alloc_noncoherent().
dev, size, dma_handle and dir must all be the same as those passed into
dma_alloc_noncoherent(). cpu_addr must be the virtual address returned by
dma_alloc_noncoherent().
::

View File

@@ -28,6 +28,9 @@ SoCs has each of these instances form a cluster and combine multiple clusters
into a single IP block present within the Main NavSS. The interrupt lines from
all these clusters are multiplexed and routed to different processor subsystems
over a limited number of common interrupt output lines of an Interrupt Router.
The AM64x SoCS also uses a single IP block comprising of multiple clusters,
but the number of clusters are smaller, and the interrupt output lines are
connected directly to various processors.
Mailbox Device Node:
====================
@@ -42,6 +45,7 @@ Required properties:
"ti,omap4-mailbox" for OMAP44xx, OMAP54xx, AM33xx,
AM43xx and DRA7xx SoCs
"ti,am654-mailbox" for K3 AM65x and J721E SoCs
"ti,am64-mailbox" for K3 AM64x SoCs
- reg: Contains the mailbox register address range (base
address and length)
- interrupts: Contains the interrupt information for the mailbox

View File

@@ -24,6 +24,7 @@ properties:
- qcom,msm8998-apcs-hmss-global
- qcom,qcs404-apcs-apps-global
- qcom,sc7180-apss-shared
- qcom,sc8180x-apss-shared
- qcom,sdm660-apcs-hmss-global
- qcom,sdm845-apss-shared
- qcom,sm8150-apss-shared
@@ -33,9 +34,11 @@ properties:
clocks:
description: phandles to the parent clocks of the clock driver
minItems: 2
items:
- description: primary pll parent of the clock driver
- description: auxiliary parent
- description: reference clock
'#mbox-cells':
const: 1
@@ -44,9 +47,11 @@ properties:
const: 0
clock-names:
minItems: 2
items:
- const: pll
- const: aux
- const: ref
required:
- compatible
@@ -55,6 +60,35 @@ required:
additionalProperties: false
allOf:
- if:
properties:
compatible:
enum:
- qcom,ipq6018-apcs-apps-global
- qcom,ipq8074-apcs-apps-global
- qcom,msm8916-apcs-kpss-global
- qcom,msm8994-apcs-kpss-global
- qcom,msm8996-apcs-hmss-global
- qcom,msm8998-apcs-hmss-global
- qcom,qcs404-apcs-apps-global
- qcom,sc7180-apss-shared
- qcom,sdm660-apcs-hmss-global
- qcom,sdm845-apss-shared
- qcom,sm8150-apss-shared
then:
properties:
clocks:
maxItems: 2
- if:
properties:
compatible:
enum:
- qcom,sdx55-apcs-gcc
then:
properties:
clocks:
maxItems: 3
examples:
# Example apcs with msm8996

View File

@@ -0,0 +1,12 @@
.. SPDX-License-Identifier: GPL-2.0
====================
Compute Express Link
====================
.. toctree::
:maxdepth: 1
memory-devices
.. only:: subproject and html

View File

@@ -0,0 +1,46 @@
.. SPDX-License-Identifier: GPL-2.0
.. include:: <isonum.txt>
===================================
Compute Express Link Memory Devices
===================================
A Compute Express Link Memory Device is a CXL component that implements the
CXL.mem protocol. It contains some amount of volatile memory, persistent memory,
or both. It is enumerated as a PCI device for configuration and passing
messages over an MMIO mailbox. Its contribution to the System Physical
Address space is handled via HDM (Host Managed Device Memory) decoders
that optionally define a device's contribution to an interleaved address
range across multiple devices underneath a host-bridge or interleaved
across host-bridges.
Driver Infrastructure
=====================
This section covers the driver infrastructure for a CXL memory device.
CXL Memory Device
-----------------
.. kernel-doc:: drivers/cxl/mem.c
:doc: cxl mem
.. kernel-doc:: drivers/cxl/mem.c
:internal:
CXL Bus
-------
.. kernel-doc:: drivers/cxl/bus.c
:doc: cxl bus
External Interfaces
===================
CXL IOCTL Interface
-------------------
.. kernel-doc:: include/uapi/linux/cxl_mem.h
:doc: UAPI
.. kernel-doc:: include/uapi/linux/cxl_mem.h
:internal:

View File

@@ -35,6 +35,7 @@ available subsections can be seen below.
usb/index
firewire
pci/index
cxl/index
spi
i2c
ipmb

View File

@@ -1040,8 +1040,8 @@ The keyctl syscall functions are:
"key" is the ID of the key to be watched.
"queue_fd" is a file descriptor referring to an open "/dev/watch_queue"
which manages the buffer into which notifications will be delivered.
"queue_fd" is a file descriptor referring to an open pipe which
manages the buffer into which notifications will be delivered.
"filter" is either NULL to remove a watch or a filter specification to
indicate what events are required from the key.

View File

@@ -353,6 +353,7 @@ Code Seq# Include File Comments
<mailto:michael.klein@puffin.lb.shuttle.de>
0xCC 00-0F drivers/misc/ibmvmc.h pseries VMC driver
0xCD 01 linux/reiserfs_fs.h
0xCE 01-02 uapi/linux/cxl_mem.h Compute Express Link Memory Devices
0xCF 02 fs/cifs/ioctl.c
0xDB 00-0F drivers/char/mwave/mwavepub.h
0xDD 00-3F ZFCP device driver see drivers/s390/scsi/

View File

@@ -4434,6 +4434,17 @@ M: Miguel Ojeda <miguel.ojeda.sandonis@gmail.com>
S: Maintained
F: include/linux/compiler_attributes.h
COMPUTE EXPRESS LINK (CXL)
M: Alison Schofield <alison.schofield@intel.com>
M: Vishal Verma <vishal.l.verma@intel.com>
M: Ira Weiny <ira.weiny@intel.com>
M: Ben Widawsky <ben.widawsky@intel.com>
M: Dan Williams <dan.j.williams@intel.com>
L: linux-cxl@vger.kernel.org
S: Maintained
F: drivers/cxl/
F: include/uapi/linux/cxl_mem.h
CONEXANT ACCESSRUNNER USB DRIVER
L: accessrunner-general@lists.sourceforge.net
S: Orphan

View File

@@ -863,6 +863,9 @@ ifdef CONFIG_FTRACE_MCOUNT_USE_CC
endif
endif
endif
ifdef CONFIG_FTRACE_MCOUNT_USE_OBJTOOL
CC_FLAGS_USING += -DCC_USING_NOP_MCOUNT
endif
ifdef CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT
ifdef CONFIG_HAVE_C_RECORDMCOUNT
BUILD_C_RECORDMCOUNT := y
@@ -910,7 +913,8 @@ KBUILD_LDFLAGS += -mllvm -import-instr-limit=5
endif
ifdef CONFIG_LTO
KBUILD_CFLAGS += $(CC_FLAGS_LTO)
KBUILD_CFLAGS += -fno-lto $(CC_FLAGS_LTO)
KBUILD_AFLAGS += -fno-lto
export CC_FLAGS_LTO
endif
@@ -1281,6 +1285,10 @@ uapi-asm-generic:
PHONY += prepare-objtool prepare-resolve_btfids
prepare-objtool: $(objtool_target)
ifeq ($(SKIP_STACK_VALIDATION),1)
ifdef CONFIG_FTRACE_MCOUNT_USE_OBJTOOL
@echo "error: Cannot generate __mcount_loc for CONFIG_DYNAMIC_FTRACE=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel" >&2
@false
endif
ifdef CONFIG_UNWINDER_ORC
@echo "error: Cannot generate ORC metadata for CONFIG_UNWINDER_ORC=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel" >&2
@false

View File

@@ -389,7 +389,10 @@ ENTRY(ret_from_interrupt)
*/
ENTRY(sys_clone)
SAVE_SWITCH_STACK
subi sp, sp, 4 /* make space for tls pointer */
stw r8, 0(sp) /* pass tls pointer (r8) via stack (5th argument) */
call nios2_clone
addi sp, sp, 4
RESTORE_SWITCH_STACK
ret

View File

@@ -32,8 +32,6 @@ EXPORT_SYMBOL(memory_start);
unsigned long memory_end;
EXPORT_SYMBOL(memory_end);
unsigned long memory_size;
static struct pt_regs fake_regs = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0};
@@ -141,16 +139,22 @@ asmlinkage void __init nios2_boot_init(unsigned r4, unsigned r5, unsigned r6,
parse_early_param();
}
static void __init find_limits(unsigned long *min, unsigned long *max_low,
unsigned long *max_high)
{
*max_low = PFN_DOWN(memblock_get_current_limit());
*min = PFN_UP(memblock_start_of_DRAM());
*max_high = PFN_DOWN(memblock_end_of_DRAM());
}
void __init setup_arch(char **cmdline_p)
{
int dram_start;
console_verbose();
dram_start = memblock_start_of_DRAM();
memory_size = memblock_phys_mem_size();
memory_start = PAGE_ALIGN((unsigned long)__pa(_end));
memory_end = (unsigned long) CONFIG_NIOS2_MEM_BASE + memory_size;
memory_start = memblock_start_of_DRAM();
memory_end = memblock_end_of_DRAM();
init_mm.start_code = (unsigned long) _stext;
init_mm.end_code = (unsigned long) _etext;
@@ -161,11 +165,10 @@ void __init setup_arch(char **cmdline_p)
/* Keep a copy of command line */
*cmdline_p = boot_command_line;
min_low_pfn = PFN_UP(memory_start);
max_low_pfn = PFN_DOWN(memory_end);
find_limits(&min_low_pfn, &max_low_pfn, &max_pfn);
max_mapnr = max_low_pfn;
memblock_reserve(dram_start, memory_start - dram_start);
memblock_reserve(__pa_symbol(_stext), _end - _stext);
#ifdef CONFIG_BLK_DEV_INITRD
if (initrd_start) {
memblock_reserve(virt_to_phys((void *)initrd_start),

View File

@@ -22,6 +22,7 @@ asmlinkage int sys_cacheflush(unsigned long addr, unsigned long len,
unsigned int op)
{
struct vm_area_struct *vma;
struct mm_struct *mm = current->mm;
if (len == 0)
return 0;
@@ -34,16 +35,22 @@ asmlinkage int sys_cacheflush(unsigned long addr, unsigned long len,
if (addr + len < addr)
return -EFAULT;
if (mmap_read_lock_killable(mm))
return -EINTR;
/*
* Verify that the specified address region actually belongs
* to this process.
*/
vma = find_vma(current->mm, addr);
if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end)
vma = find_vma(mm, addr);
if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end) {
mmap_read_unlock(mm);
return -EFAULT;
}
flush_cache_range(vma, addr, addr + len);
mmap_read_unlock(mm);
return 0;
}

View File

@@ -175,7 +175,7 @@ config SMP
Management" code will be disabled if you say Y here.
See also <file:Documentation/admin-guide/lockup-watchdogs.rst> and the SMP-HOWTO
available at <http://www.tldp.org/docs.html#howto>.
available at <https://www.tldp.org/docs.html#howto>.
If you don't know what to do here, say N.

View File

@@ -154,6 +154,10 @@ static off_t get_hdrs_offset(int kernelfd, const char *filename)
offset -= LOOKBACK;
/* skip a.out header */
offset += AOUT_TEXT_OFFSET;
if (offset < 0) {
errno = -EINVAL;
die("Calculated a negative offset, probably elftoaout generated an invalid image. Did you use a recent elftoaout ?");
}
if (lseek(kernelfd, offset, SEEK_SET) < 0)
die("lseek");
if (read(kernelfd, buffer, BUFSIZE) != BUFSIZE)

View File

@@ -65,9 +65,8 @@ CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_WCACHE=y
CONFIG_ATA_OVER_ETH=m
CONFIG_SUNVDC=m
CONFIG_IDE=y
CONFIG_BLK_DEV_IDECD=y
CONFIG_BLK_DEV_ALI15X3=y
CONFIG_ATA=y
CONFIG_PATA_ALI=y
CONFIG_RAID_ATTRS=m
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
@@ -235,3 +234,9 @@ CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRC16=m
CONFIG_LIBCRC32C=m
CONFIG_VCC=m
CONFIG_ATA=y
CONFIG_PATA_CMD64X=y
CONFIG_HAPPYMEAL=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_DEVTMPFS=y

View File

@@ -18,7 +18,7 @@
*
* When we spin, we try to use an operation that will cause the
* current cpu strand to block, and therefore make the core fully
* available to any other other runnable strands. There are two
* available to any other runnable strands. There are two
* options, based upon cpu capabilities.
*
* On all cpus prior to SPARC-T4 we do three dummy reads of the

View File

@@ -25,7 +25,7 @@ static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr, int
return x;
}
#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
#define xchg(ptr,x) ({(__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)));})
/* Emulate cmpxchg() the same way we emulate atomics,
* by hashing the object address and indexing into an array

View File

@@ -57,36 +57,40 @@ static inline int sparc_validate_prot(unsigned long prot, unsigned long addr)
{
if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM | PROT_ADI))
return 0;
if (prot & PROT_ADI) {
if (!adi_capable())
return 0;
if (addr) {
struct vm_area_struct *vma;
vma = find_vma(current->mm, addr);
if (vma) {
/* ADI can not be enabled on PFN
* mapped pages
*/
if (vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP))
return 0;
/* Mergeable pages can become unmergeable
* if ADI is enabled on them even if they
* have identical data on them. This can be
* because ADI enabled pages with identical
* data may still not have identical ADI
* tags on them. Disallow ADI on mergeable
* pages.
*/
if (vma->vm_flags & VM_MERGEABLE)
return 0;
}
}
}
return 1;
}
#define arch_validate_flags(vm_flags) arch_validate_flags(vm_flags)
/* arch_validate_flags() - Ensure combination of flags is valid for a
* VMA.
*/
static inline bool arch_validate_flags(unsigned long vm_flags)
{
/* If ADI is being enabled on this VMA, check for ADI
* capability on the platform and ensure VMA is suitable
* for ADI
*/
if (vm_flags & VM_SPARC_ADI) {
if (!adi_capable())
return false;
/* ADI can not be enabled on PFN mapped pages */
if (vm_flags & (VM_PFNMAP | VM_MIXEDMAP))
return false;
/* Mergeable pages can become unmergeable
* if ADI is enabled on them even if they
* have identical data on them. This can be
* because ADI enabled pages with identical
* data may still not have identical ADI
* tags on them. Disallow ADI on mergeable
* pages.
*/
if (vm_flags & VM_MERGEABLE)
return false;
}
return true;
}
#endif /* CONFIG_SPARC64 */
#endif /* __ASSEMBLY__ */

View File

@@ -113,7 +113,7 @@ extern unsigned long last_valid_pfn;
extern void *srmmu_nocache_pool;
#define __nocache_pa(VADDR) (((unsigned long)VADDR) - SRMMU_NOCACHE_VADDR + __pa((unsigned long)srmmu_nocache_pool))
#define __nocache_va(PADDR) (__va((unsigned long)PADDR) - (unsigned long)srmmu_nocache_pool + SRMMU_NOCACHE_VADDR)
#define __nocache_fix(VADDR) __va(__nocache_pa(VADDR))
#define __nocache_fix(VADDR) ((__typeof__(VADDR))__va(__nocache_pa(VADDR)))
/* Accessing the MMU control register. */
unsigned int srmmu_get_mmureg(void);

View File

@@ -9,18 +9,6 @@
#include <uapi/asm/signal.h>
#ifndef __ASSEMBLY__
/*
* DJHR
* SA_STATIC_ALLOC is used for the sparc32 system to indicate that this
* interrupt handler's irq structure should be statically allocated
* by the request_irq routine.
* The alternative is that arch/sparc/kernel/irq.c has carnal knowledge
* of interrupt usage and that sucks. Also without a flag like this
* it may be possible for the free_irq routine to attempt to free
* statically allocated data.. which is NOT GOOD.
*
*/
#define SA_STATIC_ALLOC 0x8000
#define __ARCH_HAS_KA_RESTORER
#define __ARCH_HAS_SA_RESTORER

View File

@@ -994,7 +994,7 @@ do_syscall:
andcc %l5, _TIF_SYSCALL_TRACE, %g0
mov %i4, %o4
bne linux_syscall_trace
mov %i0, %l5
mov %i0, %l6
2:
call %l7
mov %i5, %o5
@@ -1003,16 +1003,15 @@ do_syscall:
st %o0, [%sp + STACKFRAME_SZ + PT_I0]
ret_sys_call:
ld [%curptr + TI_FLAGS], %l6
ld [%curptr + TI_FLAGS], %l5
cmp %o0, -ERESTART_RESTARTBLOCK
ld [%sp + STACKFRAME_SZ + PT_PSR], %g3
set PSR_C, %g2
bgeu 1f
andcc %l6, _TIF_SYSCALL_TRACE, %g0
andcc %l5, _TIF_SYSCALL_TRACE, %g0
/* System call success, clear Carry condition code. */
andn %g3, %g2, %g3
clr %l6
st %g3, [%sp + STACKFRAME_SZ + PT_PSR]
bne linux_syscall_trace2
ld [%sp + STACKFRAME_SZ + PT_NPC], %l1 /* pc = npc */
@@ -1027,7 +1026,6 @@ ret_sys_call:
sub %g0, %o0, %o0
or %g3, %g2, %g3
st %o0, [%sp + STACKFRAME_SZ + PT_I0]
mov 1, %l6
st %g3, [%sp + STACKFRAME_SZ + PT_PSR]
bne linux_syscall_trace2
ld [%sp + STACKFRAME_SZ + PT_NPC], %l1 /* pc = npc */

View File

@@ -50,6 +50,7 @@ static void led_blink(struct timer_list *unused)
add_timer(&led_blink_timer);
}
#ifdef CONFIG_PROC_FS
static int led_proc_show(struct seq_file *m, void *v)
{
if (get_auxio() & AUXIO_LED)
@@ -111,6 +112,7 @@ static const struct proc_ops led_proc_ops = {
.proc_release = single_release,
.proc_write = led_proc_write,
};
#endif
static struct proc_dir_entry *led;

View File

@@ -552,9 +552,8 @@ static void pci_of_scan_bus(struct pci_pbm_info *pbm,
pci_info(bus, "scan_bus[%pOF] bus no %d\n",
node, bus->number);
child = NULL;
prev_devfn = -1;
while ((child = of_get_next_child(node, child)) != NULL) {
for_each_child_of_node(node, child) {
if (ofpci_verbose)
pci_info(bus, " * %pOF\n", child);
reg = of_get_property(child, "reg", &reglen);

View File

@@ -183,7 +183,7 @@ void exit_thread(struct task_struct *tsk)
#ifndef CONFIG_SMP
if (last_task_used_math == tsk) {
#else
if (test_ti_thread_flag(task_thread_info(tsk), TIF_USEDFPU)) {
if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) {
#endif
/* Keep process from leaving FPU in a bogon state. */
put_psr(get_psr() | PSR_EF);

View File

@@ -75,7 +75,7 @@ signal_p:
ld [%sp + STACKFRAME_SZ + PT_PSR], %t_psr
mov %g2, %o2
mov %l5, %o1
mov %l6, %o1
call do_notify_resume
add %sp, STACKFRAME_SZ, %o0 ! pt_regs ptr

View File

@@ -400,8 +400,8 @@ static int setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs,
else {
regs->u_regs[UREG_I7] = (unsigned long)(&(sf->insns[0]) - 2);
/* mov __NR_sigreturn, %g1 */
err |= __put_user(0x821020d8, &sf->insns[0]);
/* mov __NR_rt_sigreturn, %g1 */
err |= __put_user(0x82102065, &sf->insns[0]);
/* t 0x10 */
err |= __put_user(0x91d02010, &sf->insns[1]);

View File

@@ -428,7 +428,7 @@ static int process_dreg_info(struct vio_driver_state *vio,
struct vio_dring_register *pkt)
{
struct vio_dring_state *dr;
int i, len;
int i;
viodbg(HS, "GOT DRING_REG INFO ident[%llx] "
"ndesc[%u] dsz[%u] opt[0x%x] ncookies[%u]\n",
@@ -482,9 +482,7 @@ static int process_dreg_info(struct vio_driver_state *vio,
pkt->num_descr, pkt->descr_size, pkt->options,
pkt->num_cookies);
len = (sizeof(*pkt) +
(dr->ncookies * sizeof(struct ldc_trans_cookie)));
if (send_ctrl(vio, &pkt->tag, len) < 0)
if (send_ctrl(vio, &pkt->tag, struct_size(pkt, cookies, dr->ncookies)) < 0)
goto send_nack;
vio->dr_state |= VIO_DR_STATE_RXREG;

View File

@@ -142,6 +142,7 @@ __bzero:
ZERO_LAST_BLOCKS(%o0, 0x48, %g2)
ZERO_LAST_BLOCKS(%o0, 0x08, %g2)
13:
EXT(12b, 13b, 21f)
be 8f
andcc %o1, 4, %g0

View File

@@ -197,6 +197,9 @@ unsigned long __init bootmem_init(unsigned long *pages_avail)
size = memblock_phys_mem_size() - memblock_reserved_size();
*pages_avail = (size >> PAGE_SHIFT) - high_pages;
/* Only allow low memory to be allocated via memblock allocation */
memblock_set_current_limit(max_low_pfn << PAGE_SHIFT);
return max_pfn;
}

View File

@@ -351,7 +351,7 @@ pgtable_t pte_alloc_one(struct mm_struct *mm)
pte_t *ptep;
struct page *page;
if ((ptep = pte_alloc_one_kernel(mm)) == 0)
if (!(ptep = pte_alloc_one_kernel(mm)))
return NULL;
page = pfn_to_page(__nocache_pa((unsigned long)ptep) >> PAGE_SHIFT);
spin_lock(&mm->page_table_lock);
@@ -689,7 +689,7 @@ static void __init srmmu_early_allocate_ptable_skeleton(unsigned long start,
pgdp = pgd_offset_k(start);
p4dp = p4d_offset(pgdp, start);
pudp = pud_offset(p4dp, start);
if (pud_none(*(pud_t *)__nocache_fix(pudp))) {
if (pud_none(*__nocache_fix(pudp))) {
pmdp = __srmmu_get_nocache(
SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE);
if (pmdp == NULL)
@@ -698,7 +698,7 @@ static void __init srmmu_early_allocate_ptable_skeleton(unsigned long start,
pud_set(__nocache_fix(pudp), pmdp);
}
pmdp = pmd_offset(__nocache_fix(pudp), start);
if (srmmu_pmd_none(*(pmd_t *)__nocache_fix(pmdp))) {
if (srmmu_pmd_none(*__nocache_fix(pmdp))) {
ptep = __srmmu_get_nocache(PTE_SIZE, PTE_SIZE);
if (ptep == NULL)
early_pgtable_allocfail("pte");
@@ -810,11 +810,11 @@ static void __init srmmu_inherit_prom_mappings(unsigned long start,
p4dp = p4d_offset(pgdp, start);
pudp = pud_offset(p4dp, start);
if (what == 2) {
*(pgd_t *)__nocache_fix(pgdp) = __pgd(probed);
*__nocache_fix(pgdp) = __pgd(probed);
start += PGDIR_SIZE;
continue;
}
if (pud_none(*(pud_t *)__nocache_fix(pudp))) {
if (pud_none(*__nocache_fix(pudp))) {
pmdp = __srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE,
SRMMU_PMD_TABLE_SIZE);
if (pmdp == NULL)
@@ -822,13 +822,13 @@ static void __init srmmu_inherit_prom_mappings(unsigned long start,
memset(__nocache_fix(pmdp), 0, SRMMU_PMD_TABLE_SIZE);
pud_set(__nocache_fix(pudp), pmdp);
}
pmdp = pmd_offset(__nocache_fix(pgdp), start);
pmdp = pmd_offset(__nocache_fix(pudp), start);
if (what == 1) {
*(pmd_t *)__nocache_fix(pmdp) = __pmd(probed);
start += PMD_SIZE;
continue;
}
if (srmmu_pmd_none(*(pmd_t *)__nocache_fix(pmdp))) {
if (srmmu_pmd_none(*__nocache_fix(pmdp))) {
ptep = __srmmu_get_nocache(PTE_SIZE, PTE_SIZE);
if (ptep == NULL)
early_pgtable_allocfail("pte");
@@ -836,7 +836,7 @@ static void __init srmmu_inherit_prom_mappings(unsigned long start,
pmd_set(__nocache_fix(pmdp), ptep);
}
ptep = pte_offset_kernel(__nocache_fix(pmdp), start);
*(pte_t *)__nocache_fix(ptep) = __pte(probed);
*__nocache_fix(ptep) = __pte(probed);
start += PAGE_SIZE;
}
}
@@ -850,7 +850,7 @@ static void __init do_large_mapping(unsigned long vaddr, unsigned long phys_base
unsigned long big_pte;
big_pte = KERNEL_PTE(phys_base >> 4);
*(pgd_t *)__nocache_fix(pgdp) = __pgd(big_pte);
*__nocache_fix(pgdp) = __pgd(big_pte);
}
/* Map sp_bank entry SP_ENTRY, starting at virtual address VBASE. */
@@ -940,7 +940,7 @@ void __init srmmu_paging_init(void)
srmmu_ctx_table_phys = (ctxd_t *)__nocache_pa(srmmu_context_table);
for (i = 0; i < num_contexts; i++)
srmmu_ctxd_set((ctxd_t *)__nocache_fix(&srmmu_context_table[i]), srmmu_swapper_pg_dir);
srmmu_ctxd_set(__nocache_fix(&srmmu_context_table[i]), srmmu_swapper_pg_dir);
flush_cache_all();
srmmu_set_ctable_ptr((unsigned long)srmmu_ctx_table_phys);

View File

@@ -97,6 +97,8 @@ config X86
select ARCH_SUPPORTS_DEBUG_PAGEALLOC
select ARCH_SUPPORTS_NUMA_BALANCING if X86_64
select ARCH_SUPPORTS_KMAP_LOCAL_FORCE_MAP if NR_CPUS <= 4096
select ARCH_SUPPORTS_LTO_CLANG if X86_64
select ARCH_SUPPORTS_LTO_CLANG_THIN if X86_64
select ARCH_USE_BUILTIN_BSWAP
select ARCH_USE_QUEUED_RWLOCKS
select ARCH_USE_QUEUED_SPINLOCKS
@@ -169,6 +171,7 @@ config X86
select HAVE_CONTEXT_TRACKING if X86_64
select HAVE_CONTEXT_TRACKING_OFFSTACK if HAVE_CONTEXT_TRACKING
select HAVE_C_RECORDMCOUNT
select HAVE_OBJTOOL_MCOUNT if STACK_VALIDATION
select HAVE_DEBUG_KMEMLEAK
select HAVE_DMA_CONTIGUOUS
select HAVE_DYNAMIC_FTRACE

View File

@@ -169,6 +169,11 @@ ifeq ($(ACCUMULATE_OUTGOING_ARGS), 1)
KBUILD_CFLAGS += $(call cc-option,-maccumulate-outgoing-args,)
endif
ifdef CONFIG_LTO_CLANG
KBUILD_LDFLAGS += -plugin-opt=-code-model=kernel \
-plugin-opt=-stack-alignment=$(if $(CONFIG_X86_32),4,8)
endif
# Workaround for a gcc prelease that unfortunately was shipped in a suse release
KBUILD_CFLAGS += -Wno-sign-compare
#

View File

@@ -91,7 +91,7 @@ ifneq ($(RETPOLINE_VDSO_CFLAGS),)
endif
endif
$(vobjs): KBUILD_CFLAGS := $(filter-out $(GCC_PLUGINS_CFLAGS) $(RETPOLINE_CFLAGS),$(KBUILD_CFLAGS)) $(CFL)
$(vobjs): KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_LTO) $(GCC_PLUGINS_CFLAGS) $(RETPOLINE_CFLAGS),$(KBUILD_CFLAGS)) $(CFL)
#
# vDSO code runs in userspace and -pg doesn't help with profiling anyway.
@@ -150,6 +150,7 @@ KBUILD_CFLAGS_32 := $(filter-out -fno-pic,$(KBUILD_CFLAGS_32))
KBUILD_CFLAGS_32 := $(filter-out -mfentry,$(KBUILD_CFLAGS_32))
KBUILD_CFLAGS_32 := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS_32))
KBUILD_CFLAGS_32 := $(filter-out $(RETPOLINE_CFLAGS),$(KBUILD_CFLAGS_32))
KBUILD_CFLAGS_32 := $(filter-out $(CC_FLAGS_LTO),$(KBUILD_CFLAGS_32))
KBUILD_CFLAGS_32 += -m32 -msoft-float -mregparm=0 -fpic
KBUILD_CFLAGS_32 += -fno-stack-protector
KBUILD_CFLAGS_32 += $(call cc-option, -foptimize-sibling-calls)

View File

@@ -4,5 +4,9 @@
# itself be stack-protected
CFLAGS_cpu.o := -fno-stack-protector
# Clang may incorrectly inline functions with stack protector enabled into
# __restore_processor_state(): https://bugs.llvm.org/show_bug.cgi?id=47479
CFLAGS_REMOVE_cpu.o := $(CC_FLAGS_LTO)
obj-$(CONFIG_PM_SLEEP) += cpu.o
obj-$(CONFIG_HIBERNATION) += hibernate_$(BITS).o hibernate_asm_$(BITS).o hibernate.o

View File

@@ -14,6 +14,7 @@
#include <linux/ctype.h>
#include <linux/err.h>
#include <linux/seq_file.h>
#include <linux/uidgid.h>
#include <keys/system_keyring.h>
#include "blacklist.h"
@@ -37,7 +38,7 @@ static int blacklist_vet_description(const char *desc)
found_colon:
desc++;
for (; *desc; desc++) {
if (!isxdigit(*desc))
if (!isxdigit(*desc) || isupper(*desc))
return -EINVAL;
n++;
}
@@ -78,7 +79,7 @@ static struct key_type key_type_blacklist = {
/**
* mark_hash_blacklisted - Add a hash to the system blacklist
* @hash - The hash as a hex string with a type prefix (eg. "tbs:23aa429783")
* @hash: The hash as a hex string with a type prefix (eg. "tbs:23aa429783")
*/
int mark_hash_blacklisted(const char *hash)
{
@@ -156,13 +157,12 @@ static int __init blacklist_init(void)
blacklist_keyring =
keyring_alloc(".blacklist",
KUIDT_INIT(0), KGIDT_INIT(0),
current_cred(),
GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, current_cred(),
(KEY_POS_ALL & ~KEY_POS_SETATTR) |
KEY_USR_VIEW | KEY_USR_READ |
KEY_USR_SEARCH,
KEY_ALLOC_NOT_IN_QUOTA |
KEY_FLAG_KEEP,
KEY_ALLOC_SET_KEEP,
NULL, NULL);
if (IS_ERR(blacklist_keyring))
panic("Can't allocate system blacklist keyring\n");

View File

@@ -11,6 +11,7 @@
#include <linux/cred.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/uidgid.h>
#include <linux/verification.h>
#include <keys/asymmetric-type.h>
#include <keys/system_keyring.h>
@@ -98,7 +99,7 @@ static __init int system_trusted_keyring_init(void)
builtin_trusted_keys =
keyring_alloc(".builtin_trusted_keys",
KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, current_cred(),
((KEY_POS_ALL & ~KEY_POS_SETATTR) |
KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH),
KEY_ALLOC_NOT_IN_QUOTA,
@@ -109,7 +110,7 @@ static __init int system_trusted_keyring_init(void)
#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
secondary_trusted_keys =
keyring_alloc(".secondary_trusted_keys",
KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, current_cred(),
((KEY_POS_ALL & ~KEY_POS_SETATTR) |
KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH |
KEY_USR_WRITE),

View File

@@ -152,7 +152,8 @@ EXPORT_SYMBOL_GPL(asymmetric_key_generate_id);
/**
* asymmetric_key_id_same - Return true if two asymmetric keys IDs are the same.
* @kid_1, @kid_2: The key IDs to compare
* @kid1: The key ID to compare
* @kid2: The key ID to compare
*/
bool asymmetric_key_id_same(const struct asymmetric_key_id *kid1,
const struct asymmetric_key_id *kid2)
@@ -168,7 +169,8 @@ EXPORT_SYMBOL_GPL(asymmetric_key_id_same);
/**
* asymmetric_key_id_partial - Return true if two asymmetric keys IDs
* partially match
* @kid_1, @kid_2: The key IDs to compare
* @kid1: The key ID to compare
* @kid2: The key ID to compare
*/
bool asymmetric_key_id_partial(const struct asymmetric_key_id *kid1,
const struct asymmetric_key_id *kid2)

View File

@@ -41,10 +41,9 @@ struct pkcs7_signed_info {
*
* This contains the generated digest of _either_ the Content Data or
* the Authenticated Attributes [RFC2315 9.3]. If the latter, one of
* the attributes contains the digest of the the Content Data within
* it.
* the attributes contains the digest of the Content Data within it.
*
* THis also contains the issuing cert serial number and issuer's name
* This also contains the issuing cert serial number and issuer's name
* [PKCS#7 or CMS ver 1] or issuing cert's SKID [CMS ver 3].
*/
struct public_key_signature *sig;

View File

@@ -16,7 +16,7 @@
#include <crypto/public_key.h>
#include "pkcs7_parser.h"
/**
/*
* Check the trust on one PKCS#7 SignedInfo block.
*/
static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,

View File

@@ -141,11 +141,10 @@ int pkcs7_get_digest(struct pkcs7_message *pkcs7, const u8 **buf, u32 *len,
*buf = sinfo->sig->digest;
*len = sinfo->sig->digest_size;
for (i = 0; i < HASH_ALGO__LAST; i++)
if (!strcmp(hash_algo_name[i], sinfo->sig->hash_algo)) {
*hash_algo = i;
break;
}
i = match_string(hash_algo_name, HASH_ALGO__LAST,
sinfo->sig->hash_algo);
if (i >= 0)
*hash_algo = i;
return 0;
}

View File

@@ -6,6 +6,7 @@ menu "Device Drivers"
source "drivers/amba/Kconfig"
source "drivers/eisa/Kconfig"
source "drivers/pci/Kconfig"
source "drivers/cxl/Kconfig"
source "drivers/pcmcia/Kconfig"
source "drivers/rapidio/Kconfig"

View File

@@ -73,6 +73,7 @@ obj-$(CONFIG_NVM) += lightnvm/
obj-y += base/ block/ misc/ mfd/ nfc/
obj-$(CONFIG_LIBNVDIMM) += nvdimm/
obj-$(CONFIG_DAX) += dax/
obj-$(CONFIG_CXL_BUS) += cxl/
obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf/
obj-$(CONFIG_NUBUS) += nubus/
obj-y += macintosh/

53
drivers/cxl/Kconfig Normal file
View File

@@ -0,0 +1,53 @@
# SPDX-License-Identifier: GPL-2.0-only
menuconfig CXL_BUS
tristate "CXL (Compute Express Link) Devices Support"
depends on PCI
help
CXL is a bus that is electrically compatible with PCI Express, but
layers three protocols on that signalling (CXL.io, CXL.cache, and
CXL.mem). The CXL.cache protocol allows devices to hold cachelines
locally, the CXL.mem protocol allows devices to be fully coherent
memory targets, the CXL.io protocol is equivalent to PCI Express.
Say 'y' to enable support for the configuration and management of
devices supporting these protocols.
if CXL_BUS
config CXL_MEM
tristate "CXL.mem: Memory Devices"
help
The CXL.mem protocol allows a device to act as a provider of
"System RAM" and/or "Persistent Memory" that is fully coherent
as if the memory was attached to the typical CPU memory
controller.
Say 'y/m' to enable a driver (named "cxl_mem.ko" when built as
a module) that will attach to CXL.mem devices for
configuration, provisioning, and health monitoring. This
driver is required for dynamic provisioning of CXL.mem
attached memory which is a prerequisite for persistent memory
support. Typically volatile memory is mapped by platform
firmware and included in the platform memory map, but in some
cases the OS is responsible for mapping that memory. See
Chapter 2.3 Type 3 CXL Device in the CXL 2.0 specification.
If unsure say 'm'.
config CXL_MEM_RAW_COMMANDS
bool "RAW Command Interface for Memory Devices"
depends on CXL_MEM
help
Enable CXL RAW command interface.
The CXL driver ioctl interface may assign a kernel ioctl command
number for each specification defined opcode. At any given point in
time the number of opcodes that the specification defines and a device
may implement may exceed the kernel's set of associated ioctl function
numbers. The mismatch is either by omission, specification is too new,
or by design. When prototyping new hardware, or developing / debugging
the driver it is useful to be able to submit any possible command to
the hardware, even commands that may crash the kernel due to their
potential impact to memory currently in use by the kernel.
If developing CXL hardware or the driver say Y, otherwise say N.
endif

7
drivers/cxl/Makefile Normal file
View File

@@ -0,0 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_CXL_BUS) += cxl_bus.o
obj-$(CONFIG_CXL_MEM) += cxl_mem.o
ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=CXL
cxl_bus-y := bus.o
cxl_mem-y := mem.o

29
drivers/cxl/bus.c Normal file
View File

@@ -0,0 +1,29 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
#include <linux/device.h>
#include <linux/module.h>
/**
* DOC: cxl bus
*
* The CXL bus provides namespace for control devices and a rendezvous
* point for cross-device interleave coordination.
*/
struct bus_type cxl_bus_type = {
.name = "cxl",
};
EXPORT_SYMBOL_GPL(cxl_bus_type);
static __init int cxl_bus_init(void)
{
return bus_register(&cxl_bus_type);
}
static void cxl_bus_exit(void)
{
bus_unregister(&cxl_bus_type);
}
module_init(cxl_bus_init);
module_exit(cxl_bus_exit);
MODULE_LICENSE("GPL v2");

95
drivers/cxl/cxl.h Normal file
View File

@@ -0,0 +1,95 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright(c) 2020 Intel Corporation. */
#ifndef __CXL_H__
#define __CXL_H__
#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/io.h>
/* CXL 2.0 8.2.8.1 Device Capabilities Array Register */
#define CXLDEV_CAP_ARRAY_OFFSET 0x0
#define CXLDEV_CAP_ARRAY_CAP_ID 0
#define CXLDEV_CAP_ARRAY_ID_MASK GENMASK_ULL(15, 0)
#define CXLDEV_CAP_ARRAY_COUNT_MASK GENMASK_ULL(47, 32)
/* CXL 2.0 8.2.8.2 CXL Device Capability Header Register */
#define CXLDEV_CAP_HDR_CAP_ID_MASK GENMASK(15, 0)
/* CXL 2.0 8.2.8.2.1 CXL Device Capabilities */
#define CXLDEV_CAP_CAP_ID_DEVICE_STATUS 0x1
#define CXLDEV_CAP_CAP_ID_PRIMARY_MAILBOX 0x2
#define CXLDEV_CAP_CAP_ID_SECONDARY_MAILBOX 0x3
#define CXLDEV_CAP_CAP_ID_MEMDEV 0x4000
/* CXL 2.0 8.2.8.4 Mailbox Registers */
#define CXLDEV_MBOX_CAPS_OFFSET 0x00
#define CXLDEV_MBOX_CAP_PAYLOAD_SIZE_MASK GENMASK(4, 0)
#define CXLDEV_MBOX_CTRL_OFFSET 0x04
#define CXLDEV_MBOX_CTRL_DOORBELL BIT(0)
#define CXLDEV_MBOX_CMD_OFFSET 0x08
#define CXLDEV_MBOX_CMD_COMMAND_OPCODE_MASK GENMASK_ULL(15, 0)
#define CXLDEV_MBOX_CMD_PAYLOAD_LENGTH_MASK GENMASK_ULL(36, 16)
#define CXLDEV_MBOX_STATUS_OFFSET 0x10
#define CXLDEV_MBOX_STATUS_RET_CODE_MASK GENMASK_ULL(47, 32)
#define CXLDEV_MBOX_BG_CMD_STATUS_OFFSET 0x18
#define CXLDEV_MBOX_PAYLOAD_OFFSET 0x20
/* CXL 2.0 8.2.8.5.1.1 Memory Device Status Register */
#define CXLMDEV_STATUS_OFFSET 0x0
#define CXLMDEV_DEV_FATAL BIT(0)
#define CXLMDEV_FW_HALT BIT(1)
#define CXLMDEV_STATUS_MEDIA_STATUS_MASK GENMASK(3, 2)
#define CXLMDEV_MS_NOT_READY 0
#define CXLMDEV_MS_READY 1
#define CXLMDEV_MS_ERROR 2
#define CXLMDEV_MS_DISABLED 3
#define CXLMDEV_READY(status) \
(FIELD_GET(CXLMDEV_STATUS_MEDIA_STATUS_MASK, status) == \
CXLMDEV_MS_READY)
#define CXLMDEV_MBOX_IF_READY BIT(4)
#define CXLMDEV_RESET_NEEDED_MASK GENMASK(7, 5)
#define CXLMDEV_RESET_NEEDED_NOT 0
#define CXLMDEV_RESET_NEEDED_COLD 1
#define CXLMDEV_RESET_NEEDED_WARM 2
#define CXLMDEV_RESET_NEEDED_HOT 3
#define CXLMDEV_RESET_NEEDED_CXL 4
#define CXLMDEV_RESET_NEEDED(status) \
(FIELD_GET(CXLMDEV_RESET_NEEDED_MASK, status) != \
CXLMDEV_RESET_NEEDED_NOT)
struct cxl_memdev;
/**
* struct cxl_mem - A CXL memory device
* @pdev: The PCI device associated with this CXL device.
* @regs: IO mappings to the device's MMIO
* @status_regs: CXL 2.0 8.2.8.3 Device Status Registers
* @mbox_regs: CXL 2.0 8.2.8.4 Mailbox Registers
* @memdev_regs: CXL 2.0 8.2.8.5 Memory Device Registers
* @payload_size: Size of space for payload
* (CXL 2.0 8.2.8.4.3 Mailbox Capabilities Register)
* @mbox_mutex: Mutex to synchronize mailbox access.
* @firmware_version: Firmware version for the memory device.
* @enabled_commands: Hardware commands found enabled in CEL.
* @pmem_range: Persistent memory capacity information.
* @ram_range: Volatile memory capacity information.
*/
struct cxl_mem {
struct pci_dev *pdev;
void __iomem *regs;
struct cxl_memdev *cxlmd;
void __iomem *status_regs;
void __iomem *mbox_regs;
void __iomem *memdev_regs;
size_t payload_size;
struct mutex mbox_mutex; /* Protects device mailbox and firmware */
char firmware_version[0x10];
unsigned long *enabled_cmds;
struct range pmem_range;
struct range ram_range;
};
extern struct bus_type cxl_bus_type;
#endif /* __CXL_H__ */

1552
drivers/cxl/mem.c Normal file

File diff suppressed because it is too large Load Diff

31
drivers/cxl/pci.h Normal file
View File

@@ -0,0 +1,31 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
#ifndef __CXL_PCI_H__
#define __CXL_PCI_H__
#define CXL_MEMORY_PROGIF 0x10
/*
* See section 8.1 Configuration Space Registers in the CXL 2.0
* Specification
*/
#define PCI_DVSEC_HEADER1_LENGTH_MASK GENMASK(31, 20)
#define PCI_DVSEC_VENDOR_ID_CXL 0x1E98
#define PCI_DVSEC_ID_CXL 0x0
#define PCI_DVSEC_ID_CXL_REGLOC_OFFSET 0x8
#define PCI_DVSEC_ID_CXL_REGLOC_BLOCK1_OFFSET 0xC
/* BAR Indicator Register (BIR) */
#define CXL_REGLOC_BIR_MASK GENMASK(2, 0)
/* Register Block Identifier (RBI) */
#define CXL_REGLOC_RBI_MASK GENMASK(15, 8)
#define CXL_REGLOC_RBI_EMPTY 0
#define CXL_REGLOC_RBI_COMPONENT 1
#define CXL_REGLOC_RBI_VIRT 2
#define CXL_REGLOC_RBI_MEMDEV 3
#define CXL_REGLOC_ADDR_MASK GENMASK(31, 16)
#endif /* __CXL_PCI_H__ */

View File

@@ -179,7 +179,10 @@ static int dax_bus_remove(struct device *dev)
struct dax_device_driver *dax_drv = to_dax_drv(dev->driver);
struct dev_dax *dev_dax = to_dev_dax(dev);
return dax_drv->remove(dev_dax);
if (dax_drv->remove)
dax_drv->remove(dev_dax);
return 0;
}
static struct bus_type dax_bus_type = {
@@ -1038,7 +1041,7 @@ static ssize_t range_parse(const char *opt, size_t len, struct range *range)
{
unsigned long long addr = 0;
char *start, *end, *str;
ssize_t rc = EINVAL;
ssize_t rc = -EINVAL;
str = kstrdup(opt, GFP_KERNEL);
if (!str)
@@ -1392,6 +1395,13 @@ int __dax_driver_register(struct dax_device_driver *dax_drv,
struct device_driver *drv = &dax_drv->drv;
int rc = 0;
/*
* dax_bus_probe() calls dax_drv->probe() unconditionally.
* So better be safe than sorry and ensure it is provided.
*/
if (!dax_drv->probe)
return -EINVAL;
INIT_LIST_HEAD(&dax_drv->ids);
drv->owner = module;
drv->name = mod_name;
@@ -1409,7 +1419,15 @@ int __dax_driver_register(struct dax_device_driver *dax_drv,
mutex_unlock(&dax_bus_lock);
if (rc)
return rc;
return driver_register(drv);
rc = driver_register(drv);
if (rc && dax_drv->match_always) {
mutex_lock(&dax_bus_lock);
match_always_count -= dax_drv->match_always;
mutex_unlock(&dax_bus_lock);
}
return rc;
}
EXPORT_SYMBOL_GPL(__dax_driver_register);

View File

@@ -39,7 +39,7 @@ struct dax_device_driver {
struct list_head ids;
int match_always;
int (*probe)(struct dev_dax *dev);
int (*remove)(struct dev_dax *dev);
void (*remove)(struct dev_dax *dev);
};
int __dax_driver_register(struct dax_device_driver *dax_drv,

View File

@@ -452,15 +452,9 @@ int dev_dax_probe(struct dev_dax *dev_dax)
}
EXPORT_SYMBOL_GPL(dev_dax_probe);
static int dev_dax_remove(struct dev_dax *dev_dax)
{
/* all probe actions are unwound by devm */
return 0;
}
static struct dax_device_driver device_dax_driver = {
.probe = dev_dax_probe,
.remove = dev_dax_remove,
/* all probe actions are unwound by devm, so .remove isn't necessary */
.match_always = 1,
};

View File

@@ -136,7 +136,7 @@ err_res_name:
}
#ifdef CONFIG_MEMORY_HOTREMOVE
static int dev_dax_kmem_remove(struct dev_dax *dev_dax)
static void dev_dax_kmem_remove(struct dev_dax *dev_dax)
{
int i, success = 0;
struct device *dev = &dev_dax->dev;
@@ -176,11 +176,9 @@ static int dev_dax_kmem_remove(struct dev_dax *dev_dax)
kfree(data);
dev_set_drvdata(dev, NULL);
}
return 0;
}
#else
static int dev_dax_kmem_remove(struct dev_dax *dev_dax)
static void dev_dax_kmem_remove(struct dev_dax *dev_dax)
{
/*
* Without hotremove purposely leak the request_mem_region() for the
@@ -190,7 +188,6 @@ static int dev_dax_kmem_remove(struct dev_dax *dev_dax)
* request_mem_region().
*/
any_hotremove_failed = true;
return 0;
}
#endif /* CONFIG_MEMORY_HOTREMOVE */

View File

@@ -41,10 +41,9 @@ static int dax_pmem_compat_release(struct device *dev, void *data)
return 0;
}
static int dax_pmem_compat_remove(struct device *dev)
static void dax_pmem_compat_remove(struct device *dev)
{
device_for_each_child(dev, NULL, dax_pmem_compat_release);
return 0;
}
static struct nd_device_driver dax_pmem_compat_driver = {

View File

@@ -1187,34 +1187,6 @@ static void *iommu_dma_alloc(struct device *dev, size_t size,
return cpu_addr;
}
#ifdef CONFIG_DMA_REMAP
static void *iommu_dma_alloc_noncoherent(struct device *dev, size_t size,
dma_addr_t *handle, enum dma_data_direction dir, gfp_t gfp)
{
if (!gfpflags_allow_blocking(gfp)) {
struct page *page;
page = dma_common_alloc_pages(dev, size, handle, dir, gfp);
if (!page)
return NULL;
return page_address(page);
}
return iommu_dma_alloc_remap(dev, size, handle, gfp | __GFP_ZERO,
PAGE_KERNEL, 0);
}
static void iommu_dma_free_noncoherent(struct device *dev, size_t size,
void *cpu_addr, dma_addr_t handle, enum dma_data_direction dir)
{
__iommu_dma_unmap(dev, handle, size);
__iommu_dma_free(dev, size, cpu_addr);
}
#else
#define iommu_dma_alloc_noncoherent NULL
#define iommu_dma_free_noncoherent NULL
#endif /* CONFIG_DMA_REMAP */
static int iommu_dma_mmap(struct device *dev, struct vm_area_struct *vma,
void *cpu_addr, dma_addr_t dma_addr, size_t size,
unsigned long attrs)
@@ -1285,8 +1257,6 @@ static const struct dma_map_ops iommu_dma_ops = {
.free = iommu_dma_free,
.alloc_pages = dma_common_alloc_pages,
.free_pages = dma_common_free_pages,
.alloc_noncoherent = iommu_dma_alloc_noncoherent,
.free_noncoherent = iommu_dma_free_noncoherent,
.mmap = iommu_dma_mmap,
.get_sgtable = iommu_dma_get_sgtable,
.map_page = iommu_dma_map_page,

View File

@@ -238,19 +238,19 @@ struct mhuv2_mbox_chan_priv {
};
/* Macro for reading a bitfield within a physically mapped packed struct */
#define readl_relaxed_bitfield(_regptr, _field) \
#define readl_relaxed_bitfield(_regptr, _type, _field) \
({ \
u32 _regval; \
_regval = readl_relaxed((_regptr)); \
(*(typeof((_regptr)))(&_regval))._field; \
(*(_type *)(&_regval))._field; \
})
/* Macro for writing a bitfield within a physically mapped packed struct */
#define writel_relaxed_bitfield(_value, _regptr, _field) \
#define writel_relaxed_bitfield(_value, _regptr, _type, _field) \
({ \
u32 _regval; \
_regval = readl_relaxed(_regptr); \
(*(typeof(_regptr))(&_regval))._field = _value; \
(*(_type *)(&_regval))._field = _value; \
writel_relaxed(_regval, _regptr); \
})
@@ -496,7 +496,7 @@ static const struct mhuv2_protocol_ops mhuv2_data_transfer_ops = {
/* Interrupt handlers */
static struct mbox_chan *get_irq_chan_comb(struct mhuv2 *mhu, u32 *reg)
static struct mbox_chan *get_irq_chan_comb(struct mhuv2 *mhu, u32 __iomem *reg)
{
struct mbox_chan *chans = mhu->mbox.chans;
int channel = 0, i, offset = 0, windows, protocol, ch_wn;
@@ -699,7 +699,9 @@ static irqreturn_t mhuv2_receiver_interrupt(int irq, void *arg)
ret = IRQ_HANDLED;
}
kfree(data);
if (!IS_ERR(data))
kfree(data);
return ret;
}
@@ -969,8 +971,8 @@ static int mhuv2_tx_init(struct amba_device *adev, struct mhuv2 *mhu,
mhu->mbox.ops = &mhuv2_sender_ops;
mhu->send = reg;
mhu->windows = readl_relaxed_bitfield(&mhu->send->mhu_cfg, num_ch);
mhu->minor = readl_relaxed_bitfield(&mhu->send->aidr, arch_minor_rev);
mhu->windows = readl_relaxed_bitfield(&mhu->send->mhu_cfg, struct mhu_cfg_t, num_ch);
mhu->minor = readl_relaxed_bitfield(&mhu->send->aidr, struct aidr_t, arch_minor_rev);
spin_lock_init(&mhu->doorbell_pending_lock);
@@ -990,7 +992,7 @@ static int mhuv2_tx_init(struct amba_device *adev, struct mhuv2 *mhu,
mhu->mbox.txdone_poll = false;
mhu->irq = adev->irq[0];
writel_relaxed_bitfield(1, &mhu->send->int_en, chcomb);
writel_relaxed_bitfield(1, &mhu->send->int_en, struct int_en_t, chcomb);
/* Disable all channel interrupts */
for (i = 0; i < mhu->windows; i++)
@@ -1023,8 +1025,8 @@ static int mhuv2_rx_init(struct amba_device *adev, struct mhuv2 *mhu,
mhu->mbox.ops = &mhuv2_receiver_ops;
mhu->recv = reg;
mhu->windows = readl_relaxed_bitfield(&mhu->recv->mhu_cfg, num_ch);
mhu->minor = readl_relaxed_bitfield(&mhu->recv->aidr, arch_minor_rev);
mhu->windows = readl_relaxed_bitfield(&mhu->recv->mhu_cfg, struct mhu_cfg_t, num_ch);
mhu->minor = readl_relaxed_bitfield(&mhu->recv->aidr, struct aidr_t, arch_minor_rev);
mhu->irq = adev->irq[0];
if (!mhu->irq) {
@@ -1045,7 +1047,7 @@ static int mhuv2_rx_init(struct amba_device *adev, struct mhuv2 *mhu,
writel_relaxed(0xFFFFFFFF, &mhu->recv->ch_wn[i].mask_set);
if (mhu->minor)
writel_relaxed_bitfield(1, &mhu->recv->int_en, chcomb);
writel_relaxed_bitfield(1, &mhu->recv->int_en, struct int_en_t, chcomb);
return 0;
}

View File

@@ -3,7 +3,7 @@
* OMAP mailbox driver
*
* Copyright (C) 2006-2009 Nokia Corporation. All rights reserved.
* Copyright (C) 2013-2019 Texas Instruments Incorporated - https://www.ti.com
* Copyright (C) 2013-2021 Texas Instruments Incorporated - https://www.ti.com
*
* Contact: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
* Suman Anna <s-anna@ti.com>
@@ -663,6 +663,10 @@ static const struct of_device_id omap_mailbox_of_match[] = {
.compatible = "ti,am654-mailbox",
.data = &omap4_data,
},
{
.compatible = "ti,am64-mailbox",
.data = &omap4_data,
},
{
/* end */
},

View File

@@ -61,11 +61,15 @@ static const struct qcom_apcs_ipc_data apps_shared_apcs_data = {
.offset = 12, .clk_name = NULL
};
static const struct qcom_apcs_ipc_data sdx55_apcs_data = {
.offset = 0x1008, .clk_name = "qcom-sdx55-acps-clk"
};
static const struct regmap_config apcs_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
.val_bits = 32,
.max_register = 0xFFC,
.max_register = 0x1008,
.fast_io = true,
};
@@ -159,9 +163,11 @@ static const struct of_device_id qcom_apcs_ipc_of_match[] = {
{ .compatible = "qcom,msm8998-apcs-hmss-global", .data = &msm8998_apcs_data },
{ .compatible = "qcom,qcs404-apcs-apps-global", .data = &msm8916_apcs_data },
{ .compatible = "qcom,sc7180-apss-shared", .data = &apps_shared_apcs_data },
{ .compatible = "qcom,sc8180x-apss-shared", .data = &apps_shared_apcs_data },
{ .compatible = "qcom,sdm660-apcs-hmss-global", .data = &sdm660_apcs_data },
{ .compatible = "qcom,sdm845-apss-shared", .data = &apps_shared_apcs_data },
{ .compatible = "qcom,sm8150-apss-shared", .data = &apps_shared_apcs_data },
{ .compatible = "qcom,sdx55-apcs-gcc", .data = &sdx55_apcs_data },
{}
};
MODULE_DEVICE_TABLE(of, qcom_apcs_ipc_of_match);

View File

@@ -35,7 +35,7 @@
#define SPRD_MBOX_IRQ_CLR BIT(0)
/* Bit and mask definiation for outbox's SPRD_MBOX_FIFO_STS register */
#define SPRD_OUTBOX_FIFO_FULL BIT(0)
#define SPRD_OUTBOX_FIFO_FULL BIT(2)
#define SPRD_OUTBOX_FIFO_WR_SHIFT 16
#define SPRD_OUTBOX_FIFO_RD_SHIFT 24
#define SPRD_OUTBOX_FIFO_POS_MASK GENMASK(7, 0)

View File

@@ -98,7 +98,9 @@ struct tegra_hsp {
unsigned int num_ss;
unsigned int num_db;
unsigned int num_si;
spinlock_t lock;
struct lock_class_key lock_key;
struct list_head doorbells;
struct tegra_hsp_mailbox *mailboxes;
@@ -775,6 +777,18 @@ static int tegra_hsp_probe(struct platform_device *pdev)
return err;
}
lockdep_register_key(&hsp->lock_key);
lockdep_set_class(&hsp->lock, &hsp->lock_key);
return 0;
}
static int tegra_hsp_remove(struct platform_device *pdev)
{
struct tegra_hsp *hsp = platform_get_drvdata(pdev);
lockdep_unregister_key(&hsp->lock_key);
return 0;
}
@@ -834,6 +848,7 @@ static struct platform_driver tegra_hsp_driver = {
.pm = &tegra_hsp_pm_ops,
},
.probe = tegra_hsp_probe,
.remove = tegra_hsp_remove,
};
static int __init tegra_hsp_init(void)

View File

@@ -310,11 +310,10 @@ static int nd_blk_probe(struct device *dev)
return nsblk_attach_disk(nsblk);
}
static int nd_blk_remove(struct device *dev)
static void nd_blk_remove(struct device *dev)
{
if (is_nd_btt(dev))
nvdimm_namespace_detach_btt(to_nd_btt(dev));
return 0;
}
static struct nd_device_driver nd_blk_driver = {

View File

@@ -113,18 +113,17 @@ static int nvdimm_bus_remove(struct device *dev)
struct nd_device_driver *nd_drv = to_nd_device_driver(dev->driver);
struct module *provider = to_bus_provider(dev);
struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
int rc = 0;
if (nd_drv->remove) {
debug_nvdimm_lock(dev);
rc = nd_drv->remove(dev);
nd_drv->remove(dev);
debug_nvdimm_unlock(dev);
}
dev_dbg(&nvdimm_bus->dev, "%s.remove(%s) = %d\n", dev->driver->name,
dev_name(dev), rc);
dev_dbg(&nvdimm_bus->dev, "%s.remove(%s)\n", dev->driver->name,
dev_name(dev));
module_put(provider);
return rc;
return 0;
}
static void nvdimm_bus_shutdown(struct device *dev)
@@ -427,7 +426,7 @@ static void free_badrange_list(struct list_head *badrange_list)
list_del_init(badrange_list);
}
static int nd_bus_remove(struct device *dev)
static void nd_bus_remove(struct device *dev)
{
struct nvdimm_bus *nvdimm_bus = to_nvdimm_bus(dev);
@@ -446,8 +445,6 @@ static int nd_bus_remove(struct device *dev)
spin_unlock(&nvdimm_bus->badrange.lock);
nvdimm_bus_destroy_ndctl(nvdimm_bus);
return 0;
}
static int nd_bus_probe(struct device *dev)

View File

@@ -113,19 +113,14 @@ static int nvdimm_probe(struct device *dev)
return rc;
}
static int nvdimm_remove(struct device *dev)
static void nvdimm_remove(struct device *dev)
{
struct nvdimm_drvdata *ndd = dev_get_drvdata(dev);
if (!ndd)
return 0;
nvdimm_bus_lock(dev);
dev_set_drvdata(dev, NULL);
nvdimm_bus_unlock(dev);
put_ndd(ndd);
return 0;
}
static struct nd_device_driver nvdimm_driver = {

View File

@@ -563,7 +563,7 @@ static int nd_pmem_probe(struct device *dev)
return pmem_attach_disk(dev, ndns);
}
static int nd_pmem_remove(struct device *dev)
static void nd_pmem_remove(struct device *dev)
{
struct pmem_device *pmem = dev_get_drvdata(dev);
@@ -578,8 +578,6 @@ static int nd_pmem_remove(struct device *dev)
pmem->bb_state = NULL;
}
nvdimm_flush(to_nd_region(dev->parent), NULL);
return 0;
}
static void nd_pmem_shutdown(struct device *dev)

View File

@@ -87,7 +87,7 @@ static int child_unregister(struct device *dev, void *data)
return 0;
}
static int nd_region_remove(struct device *dev)
static void nd_region_remove(struct device *dev)
{
struct nd_region *nd_region = to_nd_region(dev);
@@ -108,8 +108,6 @@ static int nd_region_remove(struct device *dev)
*/
sysfs_put(nd_region->bb_state);
nd_region->bb_state = NULL;
return 0;
}
static int child_notify(struct device *dev, void *data)

View File

@@ -186,7 +186,7 @@ static int d7s_probe(struct platform_device *op)
p->regs = of_ioremap(&op->resource[0], 0, sizeof(u8), "d7s");
if (!p->regs) {
printk(KERN_ERR PFX "Cannot map chip registers\n");
goto out_free;
goto out;
}
err = misc_register(&d7s_miscdev);
@@ -228,8 +228,6 @@ out:
out_iounmap:
of_iounmap(&op->resource[0], p->regs, sizeof(u8));
out_free:
goto out;
}

View File

@@ -12,7 +12,6 @@
#include <linux/keyctl.h>
#include <linux/oid_registry.h>
#include <crypto/akcipher.h>
/*
* Cryptographic data for the public-key subtype of the asymmetric key type.

View File

@@ -2,7 +2,7 @@
/*
* Copyright (C) 2010 IBM Corporation
* Copyright (C) 2010 Politecnico di Torino, Italy
* TORSEC group -- http://security.polito.it
* TORSEC group -- https://security.polito.it
*
* Authors:
* Mimi Zohar <zohar@us.ibm.com>

View File

@@ -22,11 +22,6 @@ struct dma_map_ops {
gfp_t gfp);
void (*free_pages)(struct device *dev, size_t size, struct page *vaddr,
dma_addr_t dma_handle, enum dma_data_direction dir);
void *(*alloc_noncoherent)(struct device *dev, size_t size,
dma_addr_t *dma_handle, enum dma_data_direction dir,
gfp_t gfp);
void (*free_noncoherent)(struct device *dev, size_t size, void *vaddr,
dma_addr_t dma_handle, enum dma_data_direction dir);
int (*mmap)(struct device *, struct vm_area_struct *,
void *, dma_addr_t, size_t, unsigned long attrs);

View File

@@ -263,10 +263,19 @@ struct page *dma_alloc_pages(struct device *dev, size_t size,
dma_addr_t *dma_handle, enum dma_data_direction dir, gfp_t gfp);
void dma_free_pages(struct device *dev, size_t size, struct page *page,
dma_addr_t dma_handle, enum dma_data_direction dir);
void *dma_alloc_noncoherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, enum dma_data_direction dir, gfp_t gfp);
void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
dma_addr_t dma_handle, enum dma_data_direction dir);
static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, enum dma_data_direction dir, gfp_t gfp)
{
struct page *page = dma_alloc_pages(dev, size, dma_handle, dir, gfp);
return page ? page_address(page) : NULL;
}
static inline void dma_free_noncoherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle, enum dma_data_direction dir)
{
dma_free_pages(dev, size, virt_to_page(vaddr), dma_handle, dir);
}
static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
size_t size, enum dma_data_direction dir, unsigned long attrs)

View File

@@ -289,6 +289,7 @@ extern struct key *key_alloc(struct key_type *type,
#define KEY_ALLOC_BUILT_IN 0x0004 /* Key is built into kernel */
#define KEY_ALLOC_BYPASS_RESTRICTION 0x0008 /* Override the check on restricted keyrings */
#define KEY_ALLOC_UID_KEYRING 0x0010 /* allocating a user or user session keyring */
#define KEY_ALLOC_SET_KEEP 0x0020 /* Set the KEEP flag on the key/keyring */
extern void key_revoke(struct key *key);
extern void key_invalidate(struct key *key);
@@ -360,7 +361,7 @@ static inline struct key *request_key(struct key_type *type,
* completion of keys undergoing construction with a non-interruptible wait.
*/
#define request_key_net(type, description, net, callout_info) \
request_key_tag(type, description, net->key_domain, callout_info);
request_key_tag(type, description, net->key_domain, callout_info)
/**
* request_key_net_rcu - Request a key for a net namespace under RCU conditions
@@ -372,7 +373,7 @@ static inline struct key *request_key(struct key_type *type,
* network namespace are used.
*/
#define request_key_net_rcu(type, description, net) \
request_key_rcu(type, description, net->key_domain);
request_key_rcu(type, description, net->key_domain)
#endif /* CONFIG_NET */
extern int wait_for_key_construction(struct key *key, bool intr);

View File

@@ -26,7 +26,7 @@ struct nd_device_driver {
struct device_driver drv;
unsigned long type;
int (*probe)(struct device *dev);
int (*remove)(struct device *dev);
void (*remove)(struct device *dev);
void (*shutdown)(struct device *dev);
void (*notify)(struct device *dev, enum nvdimm_event event);
};

View File

@@ -51,6 +51,7 @@
#define PCI_BASE_CLASS_MEMORY 0x05
#define PCI_CLASS_MEMORY_RAM 0x0500
#define PCI_CLASS_MEMORY_FLASH 0x0501
#define PCI_CLASS_MEMORY_CXL 0x0502
#define PCI_CLASS_MEMORY_OTHER 0x0580
#define PCI_BASE_CLASS_BRIDGE 0x06

View File

@@ -8,6 +8,8 @@
#ifndef _LINUX_VERIFICATION_H
#define _LINUX_VERIFICATION_H
#include <linux/types.h>
/*
* Indicate that both builtin trusted keys and secondary trusted keys
* should be used.

View File

@@ -0,0 +1,172 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
* CXL IOCTLs for Memory Devices
*/
#ifndef _UAPI_CXL_MEM_H_
#define _UAPI_CXL_MEM_H_
#include <linux/types.h>
/**
* DOC: UAPI
*
* Not all of all commands that the driver supports are always available for use
* by userspace. Userspace must check the results from the QUERY command in
* order to determine the live set of commands.
*/
#define CXL_MEM_QUERY_COMMANDS _IOR(0xCE, 1, struct cxl_mem_query_commands)
#define CXL_MEM_SEND_COMMAND _IOWR(0xCE, 2, struct cxl_send_command)
#define CXL_CMDS \
___C(INVALID, "Invalid Command"), \
___C(IDENTIFY, "Identify Command"), \
___C(RAW, "Raw device command"), \
___C(GET_SUPPORTED_LOGS, "Get Supported Logs"), \
___C(GET_FW_INFO, "Get FW Info"), \
___C(GET_PARTITION_INFO, "Get Partition Information"), \
___C(GET_LSA, "Get Label Storage Area"), \
___C(GET_HEALTH_INFO, "Get Health Info"), \
___C(GET_LOG, "Get Log"), \
___C(MAX, "invalid / last command")
#define ___C(a, b) CXL_MEM_COMMAND_ID_##a
enum { CXL_CMDS };
#undef ___C
#define ___C(a, b) { b }
static const struct {
const char *name;
} cxl_command_names[] = { CXL_CMDS };
/*
* Here's how this actually breaks out:
* cxl_command_names[] = {
* [CXL_MEM_COMMAND_ID_INVALID] = { "Invalid Command" },
* [CXL_MEM_COMMAND_ID_IDENTIFY] = { "Identify Command" },
* ...
* [CXL_MEM_COMMAND_ID_MAX] = { "invalid / last command" },
* };
*/
#undef ___C
/**
* struct cxl_command_info - Command information returned from a query.
* @id: ID number for the command.
* @flags: Flags that specify command behavior.
* @size_in: Expected input size, or -1 if variable length.
* @size_out: Expected output size, or -1 if variable length.
*
* Represents a single command that is supported by both the driver and the
* hardware. This is returned as part of an array from the query ioctl. The
* following would be a command that takes a variable length input and returns 0
* bytes of output.
*
* - @id = 10
* - @flags = 0
* - @size_in = -1
* - @size_out = 0
*
* See struct cxl_mem_query_commands.
*/
struct cxl_command_info {
__u32 id;
__u32 flags;
#define CXL_MEM_COMMAND_FLAG_MASK GENMASK(0, 0)
__s32 size_in;
__s32 size_out;
};
/**
* struct cxl_mem_query_commands - Query supported commands.
* @n_commands: In/out parameter. When @n_commands is > 0, the driver will
* return min(num_support_commands, n_commands). When @n_commands
* is 0, driver will return the number of total supported commands.
* @rsvd: Reserved for future use.
* @commands: Output array of supported commands. This array must be allocated
* by userspace to be at least min(num_support_commands, @n_commands)
*
* Allow userspace to query the available commands supported by both the driver,
* and the hardware. Commands that aren't supported by either the driver, or the
* hardware are not returned in the query.
*
* Examples:
*
* - { .n_commands = 0 } // Get number of supported commands
* - { .n_commands = 15, .commands = buf } // Return first 15 (or less)
* supported commands
*
* See struct cxl_command_info.
*/
struct cxl_mem_query_commands {
/*
* Input: Number of commands to return (space allocated by user)
* Output: Number of commands supported by the driver/hardware
*
* If n_commands is 0, kernel will only return number of commands and
* not try to populate commands[], thus allowing userspace to know how
* much space to allocate
*/
__u32 n_commands;
__u32 rsvd;
struct cxl_command_info __user commands[]; /* out: supported commands */
};
/**
* struct cxl_send_command - Send a command to a memory device.
* @id: The command to send to the memory device. This must be one of the
* commands returned by the query command.
* @flags: Flags for the command (input).
* @raw: Special fields for raw commands
* @raw.opcode: Opcode passed to hardware when using the RAW command.
* @raw.rsvd: Must be zero.
* @rsvd: Must be zero.
* @retval: Return value from the memory device (output).
* @in: Parameters associated with input payload.
* @in.size: Size of the payload to provide to the device (input).
* @in.rsvd: Must be zero.
* @in.payload: Pointer to memory for payload input, payload is little endian.
* @out: Parameters associated with output payload.
* @out.size: Size of the payload received from the device (input/output). This
* field is filled in by userspace to let the driver know how much
* space was allocated for output. It is populated by the driver to
* let userspace know how large the output payload actually was.
* @out.rsvd: Must be zero.
* @out.payload: Pointer to memory for payload output, payload is little endian.
*
* Mechanism for userspace to send a command to the hardware for processing. The
* driver will do basic validation on the command sizes. In some cases even the
* payload may be introspected. Userspace is required to allocate large enough
* buffers for size_out which can be variable length in certain situations.
*/
struct cxl_send_command {
__u32 id;
__u32 flags;
union {
struct {
__u16 opcode;
__u16 rsvd;
} raw;
__u32 rsvd;
};
__u32 retval;
struct {
__s32 size;
__u32 rsvd;
__u64 payload;
} in;
struct {
__s32 size;
__u32 rsvd;
__u64 payload;
} out;
};
#endif

View File

@@ -2313,8 +2313,8 @@ config MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS
If unsure, say N.
config TRIM_UNUSED_KSYMS
bool "Trim unused exported kernel symbols"
depends on BROKEN
bool "Trim unused exported kernel symbols" if EXPERT
depends on !COMPILE_TEST
help
The kernel and some modules make many symbols available for
other modules to use via EXPORT_SYMBOL() and variants. Depending

View File

@@ -21,6 +21,7 @@
#define DMA_MAP_BENCHMARK _IOWR('d', 1, struct map_benchmark)
#define DMA_MAP_MAX_THREADS 1024
#define DMA_MAP_MAX_SECONDS 300
#define DMA_MAP_MAX_TRANS_DELAY (10 * NSEC_PER_MSEC)
#define DMA_MAP_BIDIRECTIONAL 0
#define DMA_MAP_TO_DEVICE 1
@@ -36,7 +37,8 @@ struct map_benchmark {
__s32 node; /* which numa node this benchmark will run on */
__u32 dma_bits; /* DMA addressing capability */
__u32 dma_dir; /* DMA data direction */
__u8 expansion[84]; /* For future use */
__u32 dma_trans_ns; /* time for DMA transmission in ns */
__u8 expansion[80]; /* For future use */
};
struct map_benchmark_data {
@@ -87,6 +89,9 @@ static int map_benchmark_thread(void *data)
map_etime = ktime_get();
map_delta = ktime_sub(map_etime, map_stime);
/* Pretend DMA is transmitting */
ndelay(map->bparam.dma_trans_ns);
unmap_stime = ktime_get();
dma_unmap_single(map->dev, dma_addr, PAGE_SIZE, map->dir);
unmap_etime = ktime_get();
@@ -218,6 +223,11 @@ static long map_benchmark_ioctl(struct file *file, unsigned int cmd,
return -EINVAL;
}
if (map->bparam.dma_trans_ns > DMA_MAP_MAX_TRANS_DELAY) {
pr_err("invalid transmission delay\n");
return -EINVAL;
}
if (map->bparam.node != NUMA_NO_NODE &&
!node_possible(map->bparam.node)) {
pr_err("invalid numa node\n");

View File

@@ -517,46 +517,6 @@ void dma_free_pages(struct device *dev, size_t size, struct page *page,
}
EXPORT_SYMBOL_GPL(dma_free_pages);
void *dma_alloc_noncoherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, enum dma_data_direction dir, gfp_t gfp)
{
const struct dma_map_ops *ops = get_dma_ops(dev);
void *vaddr;
if (!ops || !ops->alloc_noncoherent) {
struct page *page;
page = dma_alloc_pages(dev, size, dma_handle, dir, gfp);
if (!page)
return NULL;
return page_address(page);
}
size = PAGE_ALIGN(size);
vaddr = ops->alloc_noncoherent(dev, size, dma_handle, dir, gfp);
if (vaddr)
debug_dma_map_page(dev, virt_to_page(vaddr), 0, size, dir,
*dma_handle);
return vaddr;
}
EXPORT_SYMBOL_GPL(dma_alloc_noncoherent);
void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
dma_addr_t dma_handle, enum dma_data_direction dir)
{
const struct dma_map_ops *ops = get_dma_ops(dev);
if (!ops || !ops->free_noncoherent) {
dma_free_pages(dev, size, virt_to_page(vaddr), dma_handle, dir);
return;
}
size = PAGE_ALIGN(size);
debug_dma_unmap_page(dev, dma_handle, size, dir);
ops->free_noncoherent(dev, size, vaddr, dma_handle, dir);
}
EXPORT_SYMBOL_GPL(dma_free_noncoherent);
int dma_supported(struct device *dev, u64 mask)
{
const struct dma_map_ops *ops = get_dma_ops(dev);

View File

@@ -60,6 +60,11 @@ config HAVE_NOP_MCOUNT
help
Arch supports the gcc options -pg with -mrecord-mcount and -nop-mcount
config HAVE_OBJTOOL_MCOUNT
bool
help
Arch supports objtool --mcount
config HAVE_C_RECORDMCOUNT
bool
help
@@ -612,10 +617,18 @@ config FTRACE_MCOUNT_USE_CC
depends on !FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY
depends on FTRACE_MCOUNT_RECORD
config FTRACE_MCOUNT_USE_OBJTOOL
def_bool y
depends on HAVE_OBJTOOL_MCOUNT
depends on !FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY
depends on !FTRACE_MCOUNT_USE_CC
depends on FTRACE_MCOUNT_RECORD
config FTRACE_MCOUNT_USE_RECORDMCOUNT
def_bool y
depends on !FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY
depends on !FTRACE_MCOUNT_USE_CC
depends on !FTRACE_MCOUNT_USE_OBJTOOL
depends on FTRACE_MCOUNT_RECORD
config TRACING_MAP

View File

@@ -413,7 +413,7 @@ static void put_watch(struct watch *watch)
}
/**
* init_watch_queue - Initialise a watch
* init_watch - Initialise a watch
* @watch: The watch to initialise.
* @wqueue: The queue to assign.
*

View File

@@ -210,7 +210,7 @@ config SAMPLE_WATCHDOG
depends on CC_CAN_LINK
config SAMPLE_WATCH_QUEUE
bool "Build example /dev/watch_queue notification consumer"
bool "Build example watch_queue notification API consumer"
depends on CC_CAN_LINK && HEADERS_INSTALL
help
Build example userspace program to use the new mount_notify(),

View File

@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
/* Use /dev/watch_queue to watch for notifications.
/* Use watch_queue API to watch for notifications.
*
* Copyright (C) 2020 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)

View File

@@ -218,27 +218,11 @@ cmd_record_mcount = $(if $(findstring $(strip $(CC_FLAGS_FTRACE)),$(_c_flags)),
endif # CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT
ifdef CONFIG_STACK_VALIDATION
ifndef CONFIG_LTO_CLANG
ifneq ($(SKIP_STACK_VALIDATION),1)
__objtool_obj := $(objtree)/tools/objtool/objtool
objtool_args = $(if $(CONFIG_UNWINDER_ORC),orc generate,check)
objtool_args += $(if $(part-of-module), --module,)
ifndef CONFIG_FRAME_POINTER
objtool_args += --no-fp
endif
ifdef CONFIG_GCOV_KERNEL
objtool_args += --no-unreachable
endif
ifdef CONFIG_RETPOLINE
objtool_args += --retpoline
endif
ifdef CONFIG_X86_SMAP
objtool_args += --uaccess
endif
# 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory
# 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file
# 'OBJECT_FILES_NON_STANDARD_foo.o := 'n': override directory skip for a file
@@ -250,6 +234,7 @@ objtool_obj = $(if $(patsubst y%,, \
$(__objtool_obj))
endif # SKIP_STACK_VALIDATION
endif # CONFIG_LTO_CLANG
endif # CONFIG_STACK_VALIDATION
# Rebuild all objects when objtool changes, or is enabled/disabled.

View File

@@ -222,6 +222,18 @@ dtc_cpp_flags = -Wp,-MMD,$(depfile).pre.tmp -nostdinc \
$(addprefix -I,$(DTC_INCLUDE)) \
-undef -D__DTS__
# Objtool arguments are also needed for modfinal with LTO, so we define
# then here to avoid duplication.
objtool_args = \
$(if $(CONFIG_UNWINDER_ORC),orc generate,check) \
$(if $(part-of-module), --module,) \
$(if $(CONFIG_FRAME_POINTER),, --no-fp) \
$(if $(or $(CONFIG_GCOV_KERNEL),$(CONFIG_LTO_CLANG)), \
--no-unreachable,) \
$(if $(CONFIG_RETPOLINE), --retpoline,) \
$(if $(CONFIG_X86_SMAP), --uaccess,) \
$(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount,)
# Useful for describing the dependency of composite objects
# Usage:
# $(call multi_depend, multi_used_targets, suffix_to_remove, suffix_to_add)

View File

@@ -9,7 +9,7 @@ __modfinal:
include include/config/auto.conf
include $(srctree)/scripts/Kbuild.include
# for c_flags
# for c_flags and objtool_args
include $(srctree)/scripts/Makefile.lib
# find all modules listed in modules.order
@@ -34,10 +34,23 @@ ifdef CONFIG_LTO_CLANG
# With CONFIG_LTO_CLANG, reuse the object file we compiled for modpost to
# avoid a second slow LTO link
prelink-ext := .lto
endif
# ELF processing was skipped earlier because we didn't have native code,
# so let's now process the prelinked binary before we link the module.
ifdef CONFIG_STACK_VALIDATION
ifneq ($(SKIP_STACK_VALIDATION),1)
cmd_ld_ko_o += \
$(objtree)/tools/objtool/objtool $(objtool_args) \
$(@:.ko=$(prelink-ext).o);
endif # SKIP_STACK_VALIDATION
endif # CONFIG_STACK_VALIDATION
endif # CONFIG_LTO_CLANG
quiet_cmd_ld_ko_o = LD [M] $@
cmd_ld_ko_o = \
cmd_ld_ko_o += \
$(LD) -r $(KBUILD_LDFLAGS) \
$(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \
-T scripts/module.lds -o $@ $(filter %.o, $^); \

View File

@@ -103,14 +103,36 @@ modpost_link()
objtool_link()
{
local objtoolcmd;
local objtoolopt;
if [ "${CONFIG_LTO_CLANG} ${CONFIG_STACK_VALIDATION}" = "y y" ]; then
# Don't perform vmlinux validation unless explicitly requested,
# but run objtool on vmlinux.o now that we have an object file.
if [ -n "${CONFIG_UNWINDER_ORC}" ]; then
objtoolcmd="orc generate"
fi
objtoolopt="${objtoolopt} --duplicate"
if [ -n "${CONFIG_FTRACE_MCOUNT_USE_OBJTOOL}" ]; then
objtoolopt="${objtoolopt} --mcount"
fi
fi
if [ -n "${CONFIG_VMLINUX_VALIDATION}" ]; then
objtoolopt="check"
objtoolopt="${objtoolopt} --noinstr"
fi
if [ -n "${objtoolopt}" ]; then
if [ -z "${objtoolcmd}" ]; then
objtoolcmd="check"
fi
objtoolopt="${objtoolopt} --vmlinux"
if [ -z "${CONFIG_FRAME_POINTER}" ]; then
objtoolopt="${objtoolopt} --no-fp"
fi
if [ -n "${CONFIG_GCOV_KERNEL}" ]; then
if [ -n "${CONFIG_GCOV_KERNEL}" ] || [ -n "${CONFIG_LTO_CLANG}" ]; then
objtoolopt="${objtoolopt} --no-unreachable"
fi
if [ -n "${CONFIG_RETPOLINE}" ]; then
@@ -120,7 +142,7 @@ objtool_link()
objtoolopt="${objtoolopt} --uaccess"
fi
info OBJTOOL ${1}
tools/objtool/objtool ${objtoolopt} ${1}
tools/objtool/objtool ${objtoolcmd} ${objtoolopt} ${1}
fi
}

View File

@@ -38,13 +38,12 @@ __init int ima_mok_init(void)
(KEY_POS_ALL & ~KEY_POS_SETATTR) |
KEY_USR_VIEW | KEY_USR_READ |
KEY_USR_WRITE | KEY_USR_SEARCH,
KEY_ALLOC_NOT_IN_QUOTA,
KEY_ALLOC_NOT_IN_QUOTA |
KEY_ALLOC_SET_KEEP,
restriction, NULL);
if (IS_ERR(ima_blacklist_keyring))
panic("Can't allocate IMA blacklist keyring.");
set_bit(KEY_FLAG_KEEP, &ima_blacklist_keyring->flags);
return 0;
}
device_initcall(ima_mok_init);

View File

@@ -119,7 +119,7 @@ config KEY_NOTIFICATIONS
bool "Provide key/keyring change notifications"
depends on KEYS && WATCH_QUEUE
help
This option provides support for getting change notifications on keys
and keyrings on which the caller has View permission. This makes use
of the /dev/watch_queue misc device to handle the notification
buffer and provides KEYCTL_WATCH_KEY to enable/disable watches.
This option provides support for getting change notifications
on keys and keyrings on which the caller has View permission.
This makes use of pipes to handle the notification buffer and
provides KEYCTL_WATCH_KEY to enable/disable watches.

View File

@@ -121,8 +121,7 @@ int big_key_preparse(struct key_preparsed_payload *prep)
*path = file->f_path;
path_get(path);
fput(file);
memzero_explicit(buf, enclen);
kvfree(buf);
kvfree_sensitive(buf, enclen);
} else {
/* Just store the data in a buffer */
void *data = kmalloc(datalen, GFP_KERNEL);
@@ -140,8 +139,7 @@ err_fput:
err_enckey:
kfree_sensitive(enckey);
error:
memzero_explicit(buf, enclen);
kvfree(buf);
kvfree_sensitive(buf, enclen);
return ret;
}
@@ -273,8 +271,7 @@ long big_key_read(const struct key *key, char *buffer, size_t buflen)
err_fput:
fput(file);
error:
memzero_explicit(buf, enclen);
kvfree(buf);
kvfree_sensitive(buf, enclen);
} else {
ret = datalen;
memcpy(buffer, key->payload.data[big_key_data], datalen);

View File

@@ -303,6 +303,8 @@ struct key *key_alloc(struct key_type *type, const char *desc,
key->flags |= 1 << KEY_FLAG_BUILTIN;
if (flags & KEY_ALLOC_UID_KEYRING)
key->flags |= 1 << KEY_FLAG_UID_KEYRING;
if (flags & KEY_ALLOC_SET_KEEP)
key->flags |= 1 << KEY_FLAG_KEEP;
#ifdef KEY_DEBUGGING
key->magic = KEY_DEBUG_MAGIC;

View File

@@ -506,7 +506,7 @@ error:
* keyring, otherwise replace the link to the matching key with a link to the
* new key.
*
* The key must grant the caller Link permission and the the keyring must grant
* The key must grant the caller Link permission and the keyring must grant
* the caller Write permission. Furthermore, if an additional link is created,
* the keyring's quota will be extended.
*

View File

@@ -166,8 +166,6 @@ long keyctl_pkey_query(key_serial_t id,
struct kernel_pkey_query res;
long ret;
memset(&params, 0, sizeof(params));
ret = keyctl_pkey_params_get(id, _info, &params);
if (ret < 0)
goto error;

View File

@@ -452,7 +452,7 @@ static void keyring_describe(const struct key *keyring, struct seq_file *m)
struct keyring_read_iterator_context {
size_t buflen;
size_t count;
key_serial_t __user *buffer;
key_serial_t *buffer;
};
static int keyring_read_iterator(const void *object, void *data)
@@ -479,7 +479,7 @@ static int keyring_read_iterator(const void *object, void *data)
* times.
*/
static long keyring_read(const struct key *keyring,
char __user *buffer, size_t buflen)
char *buffer, size_t buflen)
{
struct keyring_read_iterator_context ctx;
long ret;
@@ -491,7 +491,7 @@ static long keyring_read(const struct key *keyring,
/* Copy as many key IDs as fit into the buffer */
if (buffer && buflen) {
ctx.buffer = (key_serial_t __user *)buffer;
ctx.buffer = (key_serial_t *)buffer;
ctx.buflen = buflen;
ctx.count = 0;
ret = assoc_array_iterate(&keyring->keys,
@@ -881,7 +881,7 @@ found:
*
* Keys are matched to the type provided and are then filtered by the match
* function, which is given the description to use in any way it sees fit. The
* match function may use any attributes of a key that it wishes to to
* match function may use any attributes of a key that it wishes to
* determine the match. Normally the match function from the key type would be
* used.
*
@@ -1204,7 +1204,7 @@ static int keyring_detect_cycle_iterator(const void *object,
}
/*
* See if a cycle will will be created by inserting acyclic tree B in acyclic
* See if a cycle will be created by inserting acyclic tree B in acyclic
* tree A at the topmost level (ie: as a direct child of A).
*
* Since we are adding B to A at the top level, checking for cycles should just

View File

@@ -783,6 +783,7 @@ try_again:
if (need_perm != KEY_AUTHTOKEN_OVERRIDE &&
need_perm != KEY_DEFER_PERM_CHECK)
goto invalid_key;
break;
case 0:
break;
}

View File

@@ -18,7 +18,7 @@
#include <objtool/builtin.h>
#include <objtool/objtool.h>
bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats, validate_dup, vmlinux;
bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats, validate_dup, vmlinux, mcount, noinstr;
static const char * const check_usage[] = {
"objtool check [<options>] file.o",
@@ -34,13 +34,15 @@ const struct option check_options[] = {
OPT_BOOLEAN('a', "uaccess", &uaccess, "enable uaccess checking"),
OPT_BOOLEAN('s', "stats", &stats, "print statistics"),
OPT_BOOLEAN('d', "duplicate", &validate_dup, "duplicate validation for vmlinux.o"),
OPT_BOOLEAN('n', "noinstr", &noinstr, "noinstr validation for vmlinux.o"),
OPT_BOOLEAN('l', "vmlinux", &vmlinux, "vmlinux.o validation"),
OPT_BOOLEAN('M', "mcount", &mcount, "generate __mcount_loc"),
OPT_END(),
};
int cmd_check(int argc, const char **argv)
{
const char *objname, *s;
const char *objname;
struct objtool_file *file;
int ret;
@@ -51,10 +53,6 @@ int cmd_check(int argc, const char **argv)
objname = argv[0];
s = strstr(objname, "vmlinux.o");
if (s && !s[9])
vmlinux = true;
file = objtool_open_read(objname);
if (!file)
return 1;

View File

@@ -249,7 +249,7 @@ static void init_insn_state(struct insn_state *state, struct section *sec)
* not correctly determine insn->call_dest->sec (external symbols do
* not have a section).
*/
if (vmlinux && sec)
if (vmlinux && noinstr && sec)
state->noinstr = sec->noinstr;
}
@@ -548,6 +548,78 @@ static int create_static_call_sections(struct objtool_file *file)
return 0;
}
static int create_mcount_loc_sections(struct objtool_file *file)
{
struct section *sec, *reloc_sec;
struct reloc *reloc;
unsigned long *loc;
struct instruction *insn;
int idx;
sec = find_section_by_name(file->elf, "__mcount_loc");
if (sec) {
INIT_LIST_HEAD(&file->mcount_loc_list);
WARN("file already has __mcount_loc section, skipping");
return 0;
}
if (list_empty(&file->mcount_loc_list))
return 0;
idx = 0;
list_for_each_entry(insn, &file->mcount_loc_list, mcount_loc_node)
idx++;
sec = elf_create_section(file->elf, "__mcount_loc", 0, sizeof(unsigned long), idx);
if (!sec)
return -1;
reloc_sec = elf_create_reloc_section(file->elf, sec, SHT_RELA);
if (!reloc_sec)
return -1;
idx = 0;
list_for_each_entry(insn, &file->mcount_loc_list, mcount_loc_node) {
loc = (unsigned long *)sec->data->d_buf + idx;
memset(loc, 0, sizeof(unsigned long));
reloc = malloc(sizeof(*reloc));
if (!reloc) {
perror("malloc");
return -1;
}
memset(reloc, 0, sizeof(*reloc));
if (insn->sec->sym) {
reloc->sym = insn->sec->sym;
reloc->addend = insn->offset;
} else {
reloc->sym = find_symbol_containing(insn->sec, insn->offset);
if (!reloc->sym) {
WARN("missing symbol for insn at offset 0x%lx\n",
insn->offset);
return -1;
}
reloc->addend = insn->offset - reloc->sym->offset;
}
reloc->type = R_X86_64_64;
reloc->offset = idx * sizeof(unsigned long);
reloc->sec = reloc_sec;
elf_add_reloc(file->elf, reloc);
idx++;
}
if (elf_rebuild_reloc_section(file->elf, reloc_sec))
return -1;
return 0;
}
/*
* Warnings shouldn't be reported for ignored functions.
*/
@@ -975,6 +1047,22 @@ static int add_call_destinations(struct objtool_file *file)
insn->type = INSN_NOP;
}
if (mcount && !strcmp(insn->call_dest->name, "__fentry__")) {
if (reloc) {
reloc->type = R_NONE;
elf_write_reloc(file->elf, reloc);
}
elf_write_insn(file->elf, insn->sec,
insn->offset, insn->len,
arch_nop_insn(insn->len));
insn->type = INSN_NOP;
list_add_tail(&insn->mcount_loc_node,
&file->mcount_loc_list);
}
/*
* Whatever stack impact regular CALLs have, should be undone
* by the RETURN of the called function.
@@ -3048,6 +3136,13 @@ int check(struct objtool_file *file)
goto out;
warnings += ret;
if (mcount) {
ret = create_mcount_loc_sections(file);
if (ret < 0)
goto out;
warnings += ret;
}
out:
/*
* For now, don't fail the kernel build on fatal warnings. These

View File

@@ -8,7 +8,7 @@
#include <subcmd/parse-options.h>
extern const struct option check_options[];
extern bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats, validate_dup, vmlinux;
extern bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats, validate_dup, vmlinux, mcount, noinstr;
extern int cmd_check(int argc, const char **argv);
extern int cmd_orc(int argc, const char **argv);

View File

@@ -40,6 +40,7 @@ struct instruction {
struct list_head list;
struct hlist_node hash;
struct list_head static_call_node;
struct list_head mcount_loc_node;
struct section *sec;
unsigned long offset;
unsigned int len;

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