mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 19:08:57 +09:00
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:
@@ -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'
|
||||
|
||||
26
Documentation/ABI/testing/sysfs-bus-cxl
Normal file
26
Documentation/ABI/testing/sysfs-bus-cxl
Normal 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.
|
||||
@@ -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().
|
||||
|
||||
::
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
12
Documentation/driver-api/cxl/index.rst
Normal file
12
Documentation/driver-api/cxl/index.rst
Normal file
@@ -0,0 +1,12 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
====================
|
||||
Compute Express Link
|
||||
====================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
memory-devices
|
||||
|
||||
.. only:: subproject and html
|
||||
46
Documentation/driver-api/cxl/memory-devices.rst
Normal file
46
Documentation/driver-api/cxl/memory-devices.rst
Normal 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:
|
||||
@@ -35,6 +35,7 @@ available subsections can be seen below.
|
||||
usb/index
|
||||
firewire
|
||||
pci/index
|
||||
cxl/index
|
||||
spi
|
||||
i2c
|
||||
ipmb
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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/
|
||||
|
||||
11
MAINTAINERS
11
MAINTAINERS
@@ -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
|
||||
|
||||
10
Makefile
10
Makefile
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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", ®len);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
#
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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
53
drivers/cxl/Kconfig
Normal 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
7
drivers/cxl/Makefile
Normal 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
29
drivers/cxl/bus.c
Normal 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
95
drivers/cxl/cxl.h
Normal 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
1552
drivers/cxl/mem.c
Normal file
File diff suppressed because it is too large
Load Diff
31
drivers/cxl/pci.h
Normal file
31
drivers/cxl/pci.h
Normal 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__ */
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
},
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
172
include/uapi/linux/cxl_mem.h
Normal file
172
include/uapi/linux/cxl_mem.h
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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, $^); \
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -166,8 +166,6 @@ long keyctl_pkey_query(key_serial_t id,
|
||||
struct kernel_pkey_query res;
|
||||
long ret;
|
||||
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
|
||||
ret = keyctl_pkey_params_get(id, _info, ¶ms);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user