mirror of
https://github.com/torvalds/linux.git
synced 2026-06-07 22:14:04 +02:00
LSK 17.05 v4.4-android
-----BEGIN PGP SIGNATURE----- iQFHBAABCAAxFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAlkwRwUTHGJyb29uaWVA a2VybmVsLm9yZwAKCRAk1otyXVSH0JgUB/9BulgrQKBSNWNtaqmvqiY/YmzSvBLd F+PBqy+1Gywy7vlXUNg9/y1gyCVewBgw7scIQ//cW6cJeu1cwsG50qoaWm9GsuNz eQXRKwvLx7y9rG4qdIJm2DV+uhEi3Yv8+AXBfVf8LlRGdgo6kyvNBvG9Fx+diXQg LqpqcG+wFsIe+nqFVoGn4yHB/1EHovRGWrOJHoPOsr9vzeDQOZwxJN73Z087ZYa9 OWcwGngv5BNQcybt3GG71hmBgzTeA3lnayVM9heT6zPl5xpx+boTzv6CxuLMD8cs +8i1c3jTin9xvS8hh3qSNh9y8lLNjdNX8D/5ZvoYnGLCRRMeHylUJP7W =dKU9 -----END PGP SIGNATURE----- Merge tag 'lsk-v4.4-17.05-android' of git://git.linaro.org/kernel/linux-linaro-stable.git LSK 17.05 v4.4-android * tag 'lsk-v4.4-17.05-android': (266 commits) BACKPORT: mm/slab: clean up DEBUG_PAGEALLOC processing code Linux 4.4.70 UPSTREAM: arm64: hibernate: Support DEBUG_PAGEALLOC BACKPORT: arm64: vmlinux.ld: Add mmuoff data sections and move mmuoff text into idmap BACKPORT: arm64: Create sections.h ANDROID: uid_sys_stats: defer io stats calulation for dead tasks ANDROID: AVB: Fix linter errors. ANDROID: AVB: Fix invalidate_vbmeta_submit(). drivers: char: mem: Check for address space wraparound with mmap() nfsd: encoders mustn't use unitialized values in error cases drm/edid: Add 10 bpc quirk for LGD 764 panel in HP zBook 17 G2 PCI: Freeze PME scan before suspending devices PCI: Fix pci_mmap_fits() for HAVE_PCI_RESOURCE_TO_USER platforms tracing/kprobes: Enforce kprobes teardown after testing osf_wait4(): fix infoleak genirq: Fix chained interrupt data ordering uwb: fix device quirk on big-endian hosts metag/uaccess: Check access_ok in strncpy_from_user metag/uaccess: Fix access_ok() iommu/vt-d: Flush the IOTLB to get rid of the initial kdump mappings ...
This commit is contained in:
commit
ad2fc3b29a
|
|
@ -11,24 +11,56 @@ in AArch64 Linux.
|
|||
The kernel configures the translation tables so that translations made
|
||||
via TTBR0 (i.e. userspace mappings) have the top byte (bits 63:56) of
|
||||
the virtual address ignored by the translation hardware. This frees up
|
||||
this byte for application use, with the following caveats:
|
||||
this byte for application use.
|
||||
|
||||
(1) The kernel requires that all user addresses passed to EL1
|
||||
are tagged with tag 0x00. This means that any syscall
|
||||
parameters containing user virtual addresses *must* have
|
||||
their top byte cleared before trapping to the kernel.
|
||||
|
||||
(2) Non-zero tags are not preserved when delivering signals.
|
||||
This means that signal handlers in applications making use
|
||||
of tags cannot rely on the tag information for user virtual
|
||||
addresses being maintained for fields inside siginfo_t.
|
||||
One exception to this rule is for signals raised in response
|
||||
to watchpoint debug exceptions, where the tag information
|
||||
will be preserved.
|
||||
Passing tagged addresses to the kernel
|
||||
--------------------------------------
|
||||
|
||||
(3) Special care should be taken when using tagged pointers,
|
||||
since it is likely that C compilers will not hazard two
|
||||
virtual addresses differing only in the upper byte.
|
||||
All interpretation of userspace memory addresses by the kernel assumes
|
||||
an address tag of 0x00.
|
||||
|
||||
This includes, but is not limited to, addresses found in:
|
||||
|
||||
- pointer arguments to system calls, including pointers in structures
|
||||
passed to system calls,
|
||||
|
||||
- the stack pointer (sp), e.g. when interpreting it to deliver a
|
||||
signal,
|
||||
|
||||
- the frame pointer (x29) and frame records, e.g. when interpreting
|
||||
them to generate a backtrace or call graph.
|
||||
|
||||
Using non-zero address tags in any of these locations may result in an
|
||||
error code being returned, a (fatal) signal being raised, or other modes
|
||||
of failure.
|
||||
|
||||
For these reasons, passing non-zero address tags to the kernel via
|
||||
system calls is forbidden, and using a non-zero address tag for sp is
|
||||
strongly discouraged.
|
||||
|
||||
Programs maintaining a frame pointer and frame records that use non-zero
|
||||
address tags may suffer impaired or inaccurate debug and profiling
|
||||
visibility.
|
||||
|
||||
|
||||
Preserving tags
|
||||
---------------
|
||||
|
||||
Non-zero tags are not preserved when delivering signals. This means that
|
||||
signal handlers in applications making use of tags cannot rely on the
|
||||
tag information for user virtual addresses being maintained for fields
|
||||
inside siginfo_t. One exception to this rule is for signals raised in
|
||||
response to watchpoint debug exceptions, where the tag information will
|
||||
be preserved.
|
||||
|
||||
The architecture prevents the use of a tagged PC, so the upper byte will
|
||||
be set to a sign-extension of bit 55 on exception return.
|
||||
|
||||
|
||||
Other considerations
|
||||
--------------------
|
||||
|
||||
Special care should be taken when using tagged pointers, since it is
|
||||
likely that C compilers will not hazard two virtual addresses differing
|
||||
only in the upper byte.
|
||||
|
|
|
|||
2
Makefile
2
Makefile
|
|
@ -1,6 +1,6 @@
|
|||
VERSION = 4
|
||||
PATCHLEVEL = 4
|
||||
SUBLEVEL = 66
|
||||
SUBLEVEL = 70
|
||||
EXTRAVERSION =
|
||||
NAME = Blurry Fish Butt
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
# CONFIG_DEVMEM is not set
|
||||
# CONFIG_FHANDLE is not set
|
||||
# CONFIG_INET_LRO is not set
|
||||
# CONFIG_MODULES is not set
|
||||
# CONFIG_OABI_COMPAT is not set
|
||||
# CONFIG_SYSVIPC is not set
|
||||
# CONFIG_USELIB is not set
|
||||
|
|
@ -29,7 +28,6 @@ CONFIG_HIGH_RES_TIMERS=y
|
|||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_INET6_AH=y
|
||||
CONFIG_INET6_DIAG_DESTROY=y
|
||||
CONFIG_INET6_ESP=y
|
||||
CONFIG_INET6_IPCOMP=y
|
||||
CONFIG_INET=y
|
||||
|
|
@ -72,7 +70,6 @@ CONFIG_MODVERSIONS=y
|
|||
CONFIG_NET=y
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_NETFILTER=y
|
||||
CONFIG_NETFILTER_TPROXY=y
|
||||
CONFIG_NETFILTER_XT_MATCH_COMMENT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
|
||||
|
|
@ -88,7 +85,6 @@ CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
|
|||
CONFIG_NETFILTER_XT_MATCH_POLICY=y
|
||||
CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
|
||||
CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
|
||||
CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y
|
||||
CONFIG_NETFILTER_XT_MATCH_QUOTA=y
|
||||
CONFIG_NETFILTER_XT_MATCH_SOCKET=y
|
||||
CONFIG_NETFILTER_XT_MATCH_STATE=y
|
||||
|
|
@ -173,5 +169,4 @@ CONFIG_USB_CONFIGFS_F_MTP=y
|
|||
CONFIG_USB_CONFIGFS_F_PTP=y
|
||||
CONFIG_USB_CONFIGFS_UEVENT=y
|
||||
CONFIG_USB_GADGET=y
|
||||
CONFIG_USB_OTG_WAKELOCK=y
|
||||
CONFIG_XFRM_USER=y
|
||||
|
|
|
|||
|
|
@ -1188,8 +1188,10 @@ SYSCALL_DEFINE4(osf_wait4, pid_t, pid, int __user *, ustatus, int, options,
|
|||
if (!access_ok(VERIFY_WRITE, ur, sizeof(*ur)))
|
||||
return -EFAULT;
|
||||
|
||||
err = 0;
|
||||
err |= put_user(status, ustatus);
|
||||
err = put_user(status, ustatus);
|
||||
if (ret < 0)
|
||||
return err ? err : ret;
|
||||
|
||||
err |= __put_user(r.ru_utime.tv_sec, &ur->ru_utime.tv_sec);
|
||||
err |= __put_user(r.ru_utime.tv_usec, &ur->ru_utime.tv_usec);
|
||||
err |= __put_user(r.ru_stime.tv_sec, &ur->ru_stime.tv_sec);
|
||||
|
|
|
|||
|
|
@ -162,9 +162,10 @@ spi1: spi@f8008000 {
|
|||
};
|
||||
|
||||
adc0: adc@f8018000 {
|
||||
atmel,adc-vref = <3300>;
|
||||
atmel,adc-channels-used = <0xfe>;
|
||||
pinctrl-0 = <
|
||||
&pinctrl_adc0_adtrg
|
||||
&pinctrl_adc0_ad0
|
||||
&pinctrl_adc0_ad1
|
||||
&pinctrl_adc0_ad2
|
||||
&pinctrl_adc0_ad3
|
||||
|
|
@ -172,8 +173,6 @@ &pinctrl_adc0_ad4
|
|||
&pinctrl_adc0_ad5
|
||||
&pinctrl_adc0_ad6
|
||||
&pinctrl_adc0_ad7
|
||||
&pinctrl_adc0_ad8
|
||||
&pinctrl_adc0_ad9
|
||||
>;
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
|||
|
|
@ -565,6 +565,7 @@ vdd_pnl_reg: regulator@1 {
|
|||
regulator-name = "+3VS,vdd_pnl";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-boot-on;
|
||||
gpio = <&gpio TEGRA_GPIO(A, 4) GPIO_ACTIVE_HIGH>;
|
||||
enable-active-high;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -73,7 +73,6 @@ obj-$(CONFIG_IWMMXT) += iwmmxt.o
|
|||
obj-$(CONFIG_PERF_EVENTS) += perf_regs.o perf_callchain.o
|
||||
obj-$(CONFIG_HW_PERF_EVENTS) += perf_event_xscale.o perf_event_v6.o \
|
||||
perf_event_v7.o
|
||||
CFLAGS_pj4-cp0.o := -marm
|
||||
AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
|
||||
obj-$(CONFIG_ARM_CPU_TOPOLOGY) += topology.o
|
||||
obj-$(CONFIG_VDSO) += vdso.o
|
||||
|
|
|
|||
|
|
@ -66,9 +66,13 @@ static void __init pj4_cp_access_write(u32 value)
|
|||
|
||||
__asm__ __volatile__ (
|
||||
"mcr p15, 0, %1, c1, c0, 2\n\t"
|
||||
#ifdef CONFIG_THUMB2_KERNEL
|
||||
"isb\n\t"
|
||||
#else
|
||||
"mrc p15, 0, %0, c1, c0, 2\n\t"
|
||||
"mov %0, %0\n\t"
|
||||
"sub pc, pc, #4\n\t"
|
||||
#endif
|
||||
: "=r" (temp) : "r" (value));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -208,9 +208,10 @@ int kvm_psci_version(struct kvm_vcpu *vcpu)
|
|||
|
||||
static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
int ret = 1;
|
||||
struct kvm *kvm = vcpu->kvm;
|
||||
unsigned long psci_fn = vcpu_get_reg(vcpu, 0) & ~((u32) 0);
|
||||
unsigned long val;
|
||||
int ret = 1;
|
||||
|
||||
switch (psci_fn) {
|
||||
case PSCI_0_2_FN_PSCI_VERSION:
|
||||
|
|
@ -230,7 +231,9 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
|
|||
break;
|
||||
case PSCI_0_2_FN_CPU_ON:
|
||||
case PSCI_0_2_FN64_CPU_ON:
|
||||
mutex_lock(&kvm->lock);
|
||||
val = kvm_psci_vcpu_on(vcpu);
|
||||
mutex_unlock(&kvm->lock);
|
||||
break;
|
||||
case PSCI_0_2_FN_AFFINITY_INFO:
|
||||
case PSCI_0_2_FN64_AFFINITY_INFO:
|
||||
|
|
@ -279,6 +282,7 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
|
|||
|
||||
static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct kvm *kvm = vcpu->kvm;
|
||||
unsigned long psci_fn = vcpu_get_reg(vcpu, 0) & ~((u32) 0);
|
||||
unsigned long val;
|
||||
|
||||
|
|
@ -288,7 +292,9 @@ static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
|
|||
val = PSCI_RET_SUCCESS;
|
||||
break;
|
||||
case KVM_PSCI_FN_CPU_ON:
|
||||
mutex_lock(&kvm->lock);
|
||||
val = kvm_psci_vcpu_on(vcpu);
|
||||
mutex_unlock(&kvm->lock);
|
||||
break;
|
||||
default:
|
||||
val = PSCI_RET_NOT_SUPPORTED;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/init.h>
|
||||
#include <asm/assembler.h>
|
||||
|
||||
#include "omap44xx.h"
|
||||
|
||||
|
|
@ -56,7 +57,7 @@ wait_2: ldr r2, =AUX_CORE_BOOT0_PA @ read from AuxCoreBoot0
|
|||
cmp r0, r4
|
||||
bne wait_2
|
||||
ldr r12, =API_HYP_ENTRY
|
||||
adr r0, hyp_boot
|
||||
badr r0, hyp_boot
|
||||
smc #0
|
||||
hyp_boot:
|
||||
b secondary_startup
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ generic-y += poll.h
|
|||
generic-y += preempt.h
|
||||
generic-y += resource.h
|
||||
generic-y += rwsem.h
|
||||
generic-y += sections.h
|
||||
generic-y += segment.h
|
||||
generic-y += sembuf.h
|
||||
generic-y += serial.h
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ static inline unsigned long __xchg_case_##name(unsigned long x, \
|
|||
" swp" #acq_lse #rel #sz "\t%" #w "3, %" #w "0, %2\n" \
|
||||
" nop\n" \
|
||||
" " #nop_lse) \
|
||||
: "=&r" (ret), "=&r" (tmp), "+Q" (*(u8 *)ptr) \
|
||||
: "=&r" (ret), "=&r" (tmp), "+Q" (*(unsigned long *)ptr) \
|
||||
: "r" (x) \
|
||||
: cl); \
|
||||
\
|
||||
|
|
|
|||
|
|
@ -18,6 +18,9 @@
|
|||
#ifndef __ASM_EXEC_H
|
||||
#define __ASM_EXEC_H
|
||||
|
||||
#include <linux/sched.h>
|
||||
|
||||
extern unsigned long arch_align_stack(unsigned long sp);
|
||||
void uao_thread_switch(struct task_struct *next);
|
||||
|
||||
#endif /* __ASM_EXEC_H */
|
||||
|
|
|
|||
|
|
@ -222,6 +222,16 @@ static inline pte_t pte_mknoncont(pte_t pte)
|
|||
return clear_pte_bit(pte, __pgprot(PTE_CONT));
|
||||
}
|
||||
|
||||
static inline pte_t pte_clear_rdonly(pte_t pte)
|
||||
{
|
||||
return clear_pte_bit(pte, __pgprot(PTE_RDONLY));
|
||||
}
|
||||
|
||||
static inline pte_t pte_mkpresent(pte_t pte)
|
||||
{
|
||||
return set_pte_bit(pte, __pgprot(PTE_VALID));
|
||||
}
|
||||
|
||||
static inline pmd_t pmd_mkcont(pmd_t pmd)
|
||||
{
|
||||
return __pmd(pmd_val(pmd) | PMD_SECT_CONT);
|
||||
|
|
|
|||
30
arch/arm64/include/asm/sections.h
Normal file
30
arch/arm64/include/asm/sections.h
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (C) 2016 ARM Limited
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __ASM_SECTIONS_H
|
||||
#define __ASM_SECTIONS_H
|
||||
|
||||
#include <asm-generic/sections.h>
|
||||
|
||||
extern char __alt_instructions[], __alt_instructions_end[];
|
||||
extern char __exception_text_start[], __exception_text_end[];
|
||||
extern char __hibernate_exit_text_start[], __hibernate_exit_text_end[];
|
||||
extern char __hyp_idmap_text_start[], __hyp_idmap_text_end[];
|
||||
extern char __hyp_text_start[], __hyp_text_end[];
|
||||
extern char __idmap_text_start[], __idmap_text_end[];
|
||||
extern char __irqentry_text_start[], __irqentry_text_end[];
|
||||
extern char __mmuoff_data_start[], __mmuoff_data_end[];
|
||||
|
||||
#endif /* __ASM_SECTIONS_H */
|
||||
|
|
@ -19,6 +19,7 @@
|
|||
#define __ASM_TRAP_H
|
||||
|
||||
#include <linux/list.h>
|
||||
#include <asm/sections.h>
|
||||
|
||||
struct pt_regs;
|
||||
|
||||
|
|
@ -37,9 +38,6 @@ void unregister_undef_hook(struct undef_hook *hook);
|
|||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
static inline int __in_irqentry_text(unsigned long ptr)
|
||||
{
|
||||
extern char __irqentry_text_start[];
|
||||
extern char __irqentry_text_end[];
|
||||
|
||||
return ptr >= (unsigned long)&__irqentry_text_start &&
|
||||
ptr < (unsigned long)&__irqentry_text_end;
|
||||
}
|
||||
|
|
@ -52,8 +50,6 @@ static inline int __in_irqentry_text(unsigned long ptr)
|
|||
|
||||
static inline int in_exception_text(unsigned long ptr)
|
||||
{
|
||||
extern char __exception_text_start[];
|
||||
extern char __exception_text_end[];
|
||||
int in;
|
||||
|
||||
in = ptr >= (unsigned long)&__exception_text_start &&
|
||||
|
|
|
|||
|
|
@ -108,11 +108,12 @@ static inline void set_fs(mm_segment_t fs)
|
|||
*/
|
||||
#define __range_ok(addr, size) \
|
||||
({ \
|
||||
unsigned long __addr = (unsigned long __force)(addr); \
|
||||
unsigned long flag, roksum; \
|
||||
__chk_user_ptr(addr); \
|
||||
asm("adds %1, %1, %3; ccmp %1, %4, #2, cc; cset %0, ls" \
|
||||
: "=&r" (flag), "=&r" (roksum) \
|
||||
: "1" (addr), "Ir" (size), \
|
||||
: "1" (__addr), "Ir" (size), \
|
||||
"r" (current_thread_info()->addr_limit) \
|
||||
: "cc"); \
|
||||
flag; \
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/sections.h>
|
||||
|
||||
/*
|
||||
* __boot_cpu_mode records what mode CPUs were booted in.
|
||||
|
|
@ -76,9 +77,11 @@ static inline bool is_kernel_in_hyp_mode(void)
|
|||
return el == CurrentEL_EL2;
|
||||
}
|
||||
|
||||
/* The section containing the hypervisor text */
|
||||
extern char __hyp_text_start[];
|
||||
extern char __hyp_text_end[];
|
||||
#ifdef CONFIG_ARM64_VHE
|
||||
extern void verify_cpu_run_el(void);
|
||||
#else
|
||||
static inline void verify_cpu_run_el(void) {}
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
|
|
|
|||
|
|
@ -25,14 +25,13 @@
|
|||
#include <asm/alternative.h>
|
||||
#include <asm/cpufeature.h>
|
||||
#include <asm/insn.h>
|
||||
#include <asm/sections.h>
|
||||
#include <linux/stop_machine.h>
|
||||
|
||||
#define __ALT_PTR(a,f) (u32 *)((void *)&(a)->f + (a)->f)
|
||||
#define ALT_ORIG_PTR(a) __ALT_PTR(a, orig_offset)
|
||||
#define ALT_REPL_PTR(a) __ALT_PTR(a, alt_offset)
|
||||
|
||||
extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
|
||||
|
||||
struct alt_region {
|
||||
struct alt_instr *begin;
|
||||
struct alt_instr *end;
|
||||
|
|
@ -124,8 +123,8 @@ static int __apply_alternatives_multi_stop(void *unused)
|
|||
{
|
||||
static int patched = 0;
|
||||
struct alt_region region = {
|
||||
.begin = __alt_instructions,
|
||||
.end = __alt_instructions_end,
|
||||
.begin = (struct alt_instr *)__alt_instructions,
|
||||
.end = (struct alt_instr *)__alt_instructions_end,
|
||||
};
|
||||
|
||||
/* We always have a CPU 0 at this point (__init) */
|
||||
|
|
|
|||
|
|
@ -463,7 +463,7 @@ ENDPROC(__primary_switched)
|
|||
* end early head section, begin head code that is also used for
|
||||
* hotplug and needs to have the same protections as the text region
|
||||
*/
|
||||
.section ".text","ax"
|
||||
.section ".idmap.text","ax"
|
||||
|
||||
ENTRY(kimage_vaddr)
|
||||
.quad _text - TEXT_OFFSET
|
||||
|
|
@ -584,6 +584,13 @@ set_cpu_boot_mode_flag:
|
|||
ret
|
||||
ENDPROC(set_cpu_boot_mode_flag)
|
||||
|
||||
/*
|
||||
* These values are written with the MMU off, but read with the MMU on.
|
||||
* Writers will invalidate the corresponding address, discarding up to a
|
||||
* 'Cache Writeback Granule' (CWG) worth of data. The linker script ensures
|
||||
* sufficient alignment that the CWG doesn't overlap another section.
|
||||
*/
|
||||
.pushsection ".mmuoff.data.write", "aw"
|
||||
/*
|
||||
* We need to find out the CPU boot mode long after boot, so we need to
|
||||
* store it in a writable variable.
|
||||
|
|
@ -591,11 +598,16 @@ ENDPROC(set_cpu_boot_mode_flag)
|
|||
* This is not in .bss, because we set it sufficiently early that the boot-time
|
||||
* zeroing of .bss would clobber it.
|
||||
*/
|
||||
.pushsection .data..cacheline_aligned
|
||||
.align L1_CACHE_SHIFT
|
||||
ENTRY(__boot_cpu_mode)
|
||||
.long BOOT_CPU_MODE_EL2
|
||||
.long BOOT_CPU_MODE_EL1
|
||||
/*
|
||||
* The booting CPU updates the failed status @__early_cpu_boot_status,
|
||||
* with MMU turned off.
|
||||
*/
|
||||
ENTRY(__early_cpu_boot_status)
|
||||
.long 0
|
||||
|
||||
.popsection
|
||||
|
||||
/*
|
||||
|
|
@ -662,7 +674,6 @@ ENDPROC(__secondary_switched)
|
|||
* Checks if the selected granule size is supported by the CPU.
|
||||
* If it isn't, park the CPU
|
||||
*/
|
||||
.section ".idmap.text", "ax"
|
||||
ENTRY(__enable_mmu)
|
||||
mrs x18, sctlr_el1 // preserve old SCTLR_EL1 value
|
||||
mrs x1, ID_AA64MMFR0_EL1
|
||||
|
|
|
|||
|
|
@ -53,12 +53,6 @@ extern int in_suspend;
|
|||
/* Do we need to reset el2? */
|
||||
#define el2_reset_needed() (is_hyp_mode_available() && !is_kernel_in_hyp_mode())
|
||||
|
||||
/*
|
||||
* Start/end of the hibernate exit code, this must be copied to a 'safe'
|
||||
* location in memory, and executed from there.
|
||||
*/
|
||||
extern char __hibernate_exit_text_start[], __hibernate_exit_text_end[];
|
||||
|
||||
/* temporary el2 vectors in the __hibernate_exit_text section. */
|
||||
extern char hibernate_el2_vectors[];
|
||||
|
||||
|
|
@ -240,6 +234,7 @@ static int create_safe_exec_page(void *src_start, size_t length,
|
|||
return rc;
|
||||
}
|
||||
|
||||
#define dcache_clean_range(start, end) __flush_dcache_area(start, (end - start))
|
||||
|
||||
int swsusp_arch_suspend(void)
|
||||
{
|
||||
|
|
@ -252,8 +247,13 @@ int swsusp_arch_suspend(void)
|
|||
if (__cpu_suspend_enter(&state)) {
|
||||
ret = swsusp_save();
|
||||
} else {
|
||||
/* Clean kernel to PoC for secondary core startup */
|
||||
__flush_dcache_area(LMADDR(KERNEL_START), KERNEL_END - KERNEL_START);
|
||||
/* Clean kernel core startup/idle code to PoC*/
|
||||
dcache_clean_range(__mmuoff_data_start, __mmuoff_data_end);
|
||||
dcache_clean_range(__idmap_text_start, __idmap_text_end);
|
||||
|
||||
/* Clean kvm setup code to PoC? */
|
||||
if (el2_reset_needed())
|
||||
dcache_clean_range(__hyp_idmap_text_start, __hyp_idmap_text_end);
|
||||
|
||||
/*
|
||||
* Tell the hibernation core that we've just restored
|
||||
|
|
@ -269,6 +269,33 @@ int swsusp_arch_suspend(void)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void _copy_pte(pte_t *dst_pte, pte_t *src_pte, unsigned long addr)
|
||||
{
|
||||
pte_t pte = *src_pte;
|
||||
|
||||
if (pte_valid(pte)) {
|
||||
/*
|
||||
* Resume will overwrite areas that may be marked
|
||||
* read only (code, rodata). Clear the RDONLY bit from
|
||||
* the temporary mappings we use during restore.
|
||||
*/
|
||||
set_pte(dst_pte, pte_clear_rdonly(pte));
|
||||
} else if (debug_pagealloc_enabled() && !pte_none(pte)) {
|
||||
/*
|
||||
* debug_pagealloc will removed the PTE_VALID bit if
|
||||
* the page isn't in use by the resume kernel. It may have
|
||||
* been in use by the original kernel, in which case we need
|
||||
* to put it back in our copy to do the restore.
|
||||
*
|
||||
* Before marking this entry valid, check the pfn should
|
||||
* be mapped.
|
||||
*/
|
||||
BUG_ON(!pfn_valid(pte_pfn(pte)));
|
||||
|
||||
set_pte(dst_pte, pte_mkpresent(pte_clear_rdonly(pte)));
|
||||
}
|
||||
}
|
||||
|
||||
static int copy_pte(pmd_t *dst_pmd, pmd_t *src_pmd, unsigned long start,
|
||||
unsigned long end)
|
||||
{
|
||||
|
|
@ -284,13 +311,7 @@ static int copy_pte(pmd_t *dst_pmd, pmd_t *src_pmd, unsigned long start,
|
|||
|
||||
src_pte = pte_offset_kernel(src_pmd, start);
|
||||
do {
|
||||
if (!pte_none(*src_pte))
|
||||
/*
|
||||
* Resume will overwrite areas that may be marked
|
||||
* read only (code, rodata). Clear the RDONLY bit from
|
||||
* the temporary mappings we use during restore.
|
||||
*/
|
||||
set_pte(dst_pte, __pte(pte_val(*src_pte) & ~PTE_RDONLY));
|
||||
_copy_pte(dst_pte, src_pte, addr);
|
||||
} while (dst_pte++, src_pte++, addr += PAGE_SIZE, addr != end);
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
#include <asm/insn.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm-generic/sections.h>
|
||||
#include <asm/sections.h>
|
||||
|
||||
#include "decode-insn.h"
|
||||
|
||||
|
|
@ -543,8 +543,6 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
|
|||
|
||||
bool arch_within_kprobe_blacklist(unsigned long addr)
|
||||
{
|
||||
extern char __idmap_text_start[], __idmap_text_end[];
|
||||
|
||||
if ((addr >= (unsigned long)__kprobes_text_start &&
|
||||
addr < (unsigned long)__kprobes_text_end) ||
|
||||
(addr >= (unsigned long)__entry_text_start &&
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
#include <asm/alternative.h>
|
||||
#include <asm/compat.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/exec.h>
|
||||
#include <asm/fpsimd.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/processor.h>
|
||||
|
|
@ -381,7 +382,7 @@ static void tls_thread_switch(struct task_struct *next)
|
|||
}
|
||||
|
||||
/* Restore the UAO state depending on next's addr_limit */
|
||||
static void uao_thread_switch(struct task_struct *next)
|
||||
void uao_thread_switch(struct task_struct *next)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_ARM64_UAO)) {
|
||||
if (task_thread_info(next)->addr_limit == KERNEL_DS)
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ ENTRY(__cpu_suspend_enter)
|
|||
ENDPROC(__cpu_suspend_enter)
|
||||
.ltorg
|
||||
|
||||
.pushsection ".idmap.text", "ax"
|
||||
ENTRY(cpu_resume)
|
||||
bl el2_setup // if in EL2 drop to EL1 cleanly
|
||||
/* enable the MMU early - so we can access sleep_save_stash by va */
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@
|
|||
#include <asm/smp_plat.h>
|
||||
|
||||
extern void secondary_holding_pen(void);
|
||||
volatile unsigned long secondary_holding_pen_release = INVALID_HWID;
|
||||
volatile unsigned long __section(".mmuoff.data.read")
|
||||
secondary_holding_pen_release = INVALID_HWID;
|
||||
|
||||
static phys_addr_t cpu_release_addr[NR_CPUS];
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include <asm/cacheflush.h>
|
||||
#include <asm/cpufeature.h>
|
||||
#include <asm/debug-monitors.h>
|
||||
#include <asm/exec.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/memory.h>
|
||||
#include <asm/mmu_context.h>
|
||||
|
|
@ -95,6 +96,7 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
|
|||
*/
|
||||
asm(ALTERNATIVE("nop", SET_PSTATE_PAN(1), ARM64_HAS_PAN,
|
||||
CONFIG_ARM64_PAN));
|
||||
uao_thread_switch(current);
|
||||
|
||||
/*
|
||||
* Restore HW breakpoint registers to sane values
|
||||
|
|
|
|||
|
|
@ -183,6 +183,25 @@ SECTIONS
|
|||
_data = .;
|
||||
_sdata = .;
|
||||
RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
|
||||
|
||||
/*
|
||||
* Data written with the MMU off but read with the MMU on requires
|
||||
* cache lines to be invalidated, discarding up to a Cache Writeback
|
||||
* Granule (CWG) of data from the cache. Keep the section that
|
||||
* requires this type of maintenance to be in its own Cache Writeback
|
||||
* Granule (CWG) area so the cache maintenance operations don't
|
||||
* interfere with adjacent data.
|
||||
*/
|
||||
.mmuoff.data.write : ALIGN(SZ_2K) {
|
||||
__mmuoff_data_start = .;
|
||||
*(.mmuoff.data.write)
|
||||
}
|
||||
. = ALIGN(SZ_2K);
|
||||
.mmuoff.data.read : {
|
||||
*(.mmuoff.data.read)
|
||||
__mmuoff_data_end = .;
|
||||
}
|
||||
|
||||
PECOFF_EDATA_PADDING
|
||||
_edata = .;
|
||||
|
||||
|
|
|
|||
|
|
@ -1055,8 +1055,8 @@ static int kvm_handle_cp_64(struct kvm_vcpu *vcpu,
|
|||
{
|
||||
struct sys_reg_params params;
|
||||
u32 hsr = kvm_vcpu_get_hsr(vcpu);
|
||||
int Rt = (hsr >> 5) & 0xf;
|
||||
int Rt2 = (hsr >> 10) & 0xf;
|
||||
int Rt = (hsr >> 5) & 0x1f;
|
||||
int Rt2 = (hsr >> 10) & 0x1f;
|
||||
|
||||
params.is_aarch32 = true;
|
||||
params.is_32bit = false;
|
||||
|
|
@ -1107,7 +1107,7 @@ static int kvm_handle_cp_32(struct kvm_vcpu *vcpu,
|
|||
{
|
||||
struct sys_reg_params params;
|
||||
u32 hsr = kvm_vcpu_get_hsr(vcpu);
|
||||
int Rt = (hsr >> 5) & 0xf;
|
||||
int Rt = (hsr >> 5) & 0x1f;
|
||||
|
||||
params.is_aarch32 = true;
|
||||
params.is_32bit = true;
|
||||
|
|
|
|||
|
|
@ -139,4 +139,43 @@ void __kernel_map_pages(struct page *page, int numpages, int enable)
|
|||
__pgprot(0),
|
||||
__pgprot(PTE_VALID));
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_HIBERNATION
|
||||
/*
|
||||
* When built with CONFIG_DEBUG_PAGEALLOC and CONFIG_HIBERNATION, this function
|
||||
* is used to determine if a linear map page has been marked as not-valid by
|
||||
* CONFIG_DEBUG_PAGEALLOC. Walk the page table and check the PTE_VALID bit.
|
||||
* This is based on kern_addr_valid(), which almost does what we need.
|
||||
*
|
||||
* Because this is only called on the kernel linear map, p?d_sect() implies
|
||||
* p?d_present(). When debug_pagealloc is enabled, sections mappings are
|
||||
* disabled.
|
||||
*/
|
||||
bool kernel_page_present(struct page *page)
|
||||
{
|
||||
pgd_t *pgd;
|
||||
pud_t *pud;
|
||||
pmd_t *pmd;
|
||||
pte_t *pte;
|
||||
unsigned long addr = (unsigned long)page_address(page);
|
||||
|
||||
pgd = pgd_offset_k(addr);
|
||||
if (pgd_none(*pgd))
|
||||
return false;
|
||||
|
||||
pud = pud_offset(pgd, addr);
|
||||
if (pud_none(*pud))
|
||||
return false;
|
||||
if (pud_sect(*pud))
|
||||
return true;
|
||||
|
||||
pmd = pmd_offset(pud, addr);
|
||||
if (pmd_none(*pmd))
|
||||
return false;
|
||||
if (pmd_sect(*pmd))
|
||||
return true;
|
||||
|
||||
pte = pte_offset_kernel(pmd, addr);
|
||||
return pte_valid(*pte);
|
||||
}
|
||||
#endif /* CONFIG_HIBERNATION */
|
||||
#endif /* CONFIG_DEBUG_PAGEALLOC */
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ ENDPROC(cpu_do_suspend)
|
|||
*
|
||||
* x0: Address of context pointer
|
||||
*/
|
||||
.pushsection ".idmap.text", "ax"
|
||||
ENTRY(cpu_do_resume)
|
||||
ldp x2, x3, [x0]
|
||||
ldp x4, x5, [x0, #16]
|
||||
|
|
@ -120,6 +121,7 @@ ENTRY(cpu_do_resume)
|
|||
isb
|
||||
ret
|
||||
ENDPROC(cpu_do_resume)
|
||||
.popsection
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -172,6 +174,7 @@ ENDPROC(idmap_cpu_replace_ttbr1)
|
|||
* Initialise the processor for turning the MMU on. Return in x0 the
|
||||
* value of the SCTLR_EL1 register.
|
||||
*/
|
||||
.pushsection ".idmap.text", "ax"
|
||||
ENTRY(__cpu_setup)
|
||||
tlbi vmalle1 // Invalidate local TLB
|
||||
dsb nsh
|
||||
|
|
@ -257,3 +260,4 @@ ENDPROC(__cpu_setup)
|
|||
crval:
|
||||
.word 0xfcffffff // clear
|
||||
.word 0x34d5d91d // set
|
||||
.popsection
|
||||
|
|
|
|||
|
|
@ -728,14 +728,14 @@ static int build_body(struct jit_ctx *ctx)
|
|||
int ret;
|
||||
|
||||
ret = build_insn(insn, ctx);
|
||||
|
||||
if (ctx->image == NULL)
|
||||
ctx->offset[i] = ctx->idx;
|
||||
|
||||
if (ret > 0) {
|
||||
i++;
|
||||
if (ctx->image == NULL)
|
||||
ctx->offset[i] = ctx->idx;
|
||||
continue;
|
||||
}
|
||||
if (ctx->image == NULL)
|
||||
ctx->offset[i] = ctx->idx;
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,24 +28,32 @@
|
|||
|
||||
#define segment_eq(a, b) ((a).seg == (b).seg)
|
||||
|
||||
#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
|
||||
/*
|
||||
* Explicitly allow NULL pointers here. Parts of the kernel such
|
||||
* as readv/writev use access_ok to validate pointers, but want
|
||||
* to allow NULL pointers for various reasons. NULL pointers are
|
||||
* safe to allow through because the first page is not mappable on
|
||||
* Meta.
|
||||
*
|
||||
* We also wish to avoid letting user code access the system area
|
||||
* and the kernel half of the address space.
|
||||
*/
|
||||
#define __user_bad(addr, size) (((addr) > 0 && (addr) < META_MEMORY_BASE) || \
|
||||
((addr) > PAGE_OFFSET && \
|
||||
(addr) < LINCORE_BASE))
|
||||
|
||||
static inline int __access_ok(unsigned long addr, unsigned long size)
|
||||
{
|
||||
return __kernel_ok || !__user_bad(addr, size);
|
||||
/*
|
||||
* Allow access to the user mapped memory area, but not the system area
|
||||
* before it. The check extends to the top of the address space when
|
||||
* kernel access is allowed (there's no real reason to user copy to the
|
||||
* system area in any case).
|
||||
*/
|
||||
if (likely(addr >= META_MEMORY_BASE && addr < get_fs().seg &&
|
||||
size <= get_fs().seg - addr))
|
||||
return true;
|
||||
/*
|
||||
* Explicitly allow NULL pointers here. Parts of the kernel such
|
||||
* as readv/writev use access_ok to validate pointers, but want
|
||||
* to allow NULL pointers for various reasons. NULL pointers are
|
||||
* safe to allow through because the first page is not mappable on
|
||||
* Meta.
|
||||
*/
|
||||
if (!addr)
|
||||
return true;
|
||||
/* Allow access to core code memory area... */
|
||||
if (addr >= LINCORE_CODE_BASE && addr <= LINCORE_CODE_LIMIT &&
|
||||
size <= LINCORE_CODE_LIMIT + 1 - addr)
|
||||
return true;
|
||||
/* ... but no other areas. */
|
||||
return false;
|
||||
}
|
||||
|
||||
#define access_ok(type, addr, size) __access_ok((unsigned long)(addr), \
|
||||
|
|
@ -186,8 +194,13 @@ do { \
|
|||
extern long __must_check __strncpy_from_user(char *dst, const char __user *src,
|
||||
long count);
|
||||
|
||||
#define strncpy_from_user(dst, src, count) __strncpy_from_user(dst, src, count)
|
||||
|
||||
static inline long
|
||||
strncpy_from_user(char *dst, const char __user *src, long count)
|
||||
{
|
||||
if (!access_ok(VERIFY_READ, src, 1))
|
||||
return -EFAULT;
|
||||
return __strncpy_from_user(dst, src, count);
|
||||
}
|
||||
/*
|
||||
* Return the size of a string (including the ending 0)
|
||||
*
|
||||
|
|
|
|||
|
|
@ -434,8 +434,8 @@ static int multu_func(struct pt_regs *regs, u32 ir)
|
|||
rs = regs->regs[MIPSInst_RS(ir)];
|
||||
res = (u64)rt * (u64)rs;
|
||||
rt = res;
|
||||
regs->lo = (s64)rt;
|
||||
regs->hi = (s64)(res >> 32);
|
||||
regs->lo = (s64)(s32)rt;
|
||||
regs->hi = (s64)(s32)(res >> 32);
|
||||
|
||||
MIPS_R2_STATS(muls);
|
||||
|
||||
|
|
@ -671,9 +671,9 @@ static int maddu_func(struct pt_regs *regs, u32 ir)
|
|||
res += ((((s64)rt) << 32) | (u32)rs);
|
||||
|
||||
rt = res;
|
||||
regs->lo = (s64)rt;
|
||||
regs->lo = (s64)(s32)rt;
|
||||
rs = res >> 32;
|
||||
regs->hi = (s64)rs;
|
||||
regs->hi = (s64)(s32)rs;
|
||||
|
||||
MIPS_R2_STATS(dsps);
|
||||
|
||||
|
|
@ -729,9 +729,9 @@ static int msubu_func(struct pt_regs *regs, u32 ir)
|
|||
res = ((((s64)rt) << 32) | (u32)rs) - res;
|
||||
|
||||
rt = res;
|
||||
regs->lo = (s64)rt;
|
||||
regs->lo = (s64)(s32)rt;
|
||||
rs = res >> 32;
|
||||
regs->hi = (s64)rs;
|
||||
regs->hi = (s64)(s32)rs;
|
||||
|
||||
MIPS_R2_STATS(dsps);
|
||||
|
||||
|
|
|
|||
|
|
@ -735,8 +735,14 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
|
|||
andis. r15,r14,(DBSR_IC|DBSR_BT)@h
|
||||
beq+ 1f
|
||||
|
||||
#ifdef CONFIG_RELOCATABLE
|
||||
ld r15,PACATOC(r13)
|
||||
ld r14,interrupt_base_book3e@got(r15)
|
||||
ld r15,__end_interrupts@got(r15)
|
||||
#else
|
||||
LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e)
|
||||
LOAD_REG_IMMEDIATE(r15,__end_interrupts)
|
||||
#endif
|
||||
cmpld cr0,r10,r14
|
||||
cmpld cr1,r10,r15
|
||||
blt+ cr0,1f
|
||||
|
|
@ -799,8 +805,14 @@ kernel_dbg_exc:
|
|||
andis. r15,r14,(DBSR_IC|DBSR_BT)@h
|
||||
beq+ 1f
|
||||
|
||||
#ifdef CONFIG_RELOCATABLE
|
||||
ld r15,PACATOC(r13)
|
||||
ld r14,interrupt_base_book3e@got(r15)
|
||||
ld r15,__end_interrupts@got(r15)
|
||||
#else
|
||||
LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e)
|
||||
LOAD_REG_IMMEDIATE(r15,__end_interrupts)
|
||||
#endif
|
||||
cmpld cr0,r10,r14
|
||||
cmpld cr1,r10,r15
|
||||
blt+ cr0,1f
|
||||
|
|
|
|||
|
|
@ -204,6 +204,8 @@ static void machine_check_process_queued_event(struct irq_work *work)
|
|||
{
|
||||
int index;
|
||||
|
||||
add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE);
|
||||
|
||||
/*
|
||||
* For now just print it to console.
|
||||
* TODO: log this error event to FSP or nvram.
|
||||
|
|
|
|||
|
|
@ -297,8 +297,6 @@ long machine_check_early(struct pt_regs *regs)
|
|||
|
||||
__this_cpu_inc(irq_stat.mce_exceptions);
|
||||
|
||||
add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE);
|
||||
|
||||
if (cur_cpu_spec && cur_cpu_spec->machine_check_early)
|
||||
handled = cur_cpu_spec->machine_check_early(regs);
|
||||
return handled;
|
||||
|
|
@ -704,6 +702,8 @@ void machine_check_exception(struct pt_regs *regs)
|
|||
|
||||
__this_cpu_inc(irq_stat.mce_exceptions);
|
||||
|
||||
add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE);
|
||||
|
||||
/* See if any machine dependent calls. In theory, we would want
|
||||
* to call the CPU first, and call the ppc_md. one if the CPU
|
||||
* one returns a positive number. However there is existing code
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ opal_tracepoint_entry:
|
|||
opal_tracepoint_return:
|
||||
std r3,STK_REG(R31)(r1)
|
||||
mr r4,r3
|
||||
ld r0,STK_REG(R23)(r1)
|
||||
ld r3,STK_REG(R23)(r1)
|
||||
bl __trace_opal_exit
|
||||
ld r3,STK_REG(R31)(r1)
|
||||
addi r1,r1,STACKFRAMESIZE
|
||||
|
|
|
|||
|
|
@ -280,7 +280,6 @@ int dlpar_detach_node(struct device_node *dn)
|
|||
if (rc)
|
||||
return rc;
|
||||
|
||||
of_node_put(dn); /* Must decrement the refcount */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -463,6 +463,20 @@ static void *nt_vmcoreinfo(void *ptr)
|
|||
return nt_init(ptr, 0, vmcoreinfo, size, "VMCOREINFO");
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize final note (needed for /proc/vmcore code)
|
||||
*/
|
||||
static void *nt_final(void *ptr)
|
||||
{
|
||||
Elf64_Nhdr *note;
|
||||
|
||||
note = (Elf64_Nhdr *) ptr;
|
||||
note->n_namesz = 0;
|
||||
note->n_descsz = 0;
|
||||
note->n_type = 0;
|
||||
return PTR_ADD(ptr, sizeof(Elf64_Nhdr));
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize ELF header (new kernel)
|
||||
*/
|
||||
|
|
@ -553,6 +567,7 @@ static void *notes_init(Elf64_Phdr *phdr, void *ptr, u64 notes_offset)
|
|||
ptr = fill_cpu_elf_notes(ptr, &sa_ext->sa, sa_ext->vx_regs);
|
||||
}
|
||||
ptr = nt_vmcoreinfo(ptr);
|
||||
ptr = nt_final(ptr);
|
||||
memset(phdr, 0, sizeof(*phdr));
|
||||
phdr->p_type = PT_NOTE;
|
||||
phdr->p_offset = notes_offset;
|
||||
|
|
|
|||
|
|
@ -308,6 +308,7 @@ ENTRY(system_call)
|
|||
lg %r14,__LC_VDSO_PER_CPU
|
||||
lmg %r0,%r10,__PT_R0(%r11)
|
||||
mvc __LC_RETURN_PSW(16),__PT_PSW(%r11)
|
||||
.Lsysc_exit_timer:
|
||||
stpt __LC_EXIT_TIMER
|
||||
mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
|
||||
lmg %r11,%r15,__PT_R11(%r11)
|
||||
|
|
@ -593,6 +594,7 @@ ENTRY(io_int_handler)
|
|||
lg %r14,__LC_VDSO_PER_CPU
|
||||
lmg %r0,%r10,__PT_R0(%r11)
|
||||
mvc __LC_RETURN_PSW(16),__PT_PSW(%r11)
|
||||
.Lio_exit_timer:
|
||||
stpt __LC_EXIT_TIMER
|
||||
mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
|
||||
lmg %r11,%r15,__PT_R11(%r11)
|
||||
|
|
@ -1118,15 +1120,23 @@ cleanup_critical:
|
|||
br %r14
|
||||
|
||||
.Lcleanup_sysc_restore:
|
||||
# check if stpt has been executed
|
||||
clg %r9,BASED(.Lcleanup_sysc_restore_insn)
|
||||
jh 0f
|
||||
mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
|
||||
cghi %r11,__LC_SAVE_AREA_ASYNC
|
||||
je 0f
|
||||
mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER
|
||||
0: clg %r9,BASED(.Lcleanup_sysc_restore_insn+8)
|
||||
je 1f
|
||||
lg %r9,24(%r11) # get saved pointer to pt_regs
|
||||
mvc __LC_RETURN_PSW(16),__PT_PSW(%r9)
|
||||
mvc 0(64,%r11),__PT_R8(%r9)
|
||||
lmg %r0,%r7,__PT_R0(%r9)
|
||||
0: lmg %r8,%r9,__LC_RETURN_PSW
|
||||
1: lmg %r8,%r9,__LC_RETURN_PSW
|
||||
br %r14
|
||||
.Lcleanup_sysc_restore_insn:
|
||||
.quad .Lsysc_exit_timer
|
||||
.quad .Lsysc_done - 4
|
||||
|
||||
.Lcleanup_io_tif:
|
||||
|
|
@ -1134,15 +1144,20 @@ cleanup_critical:
|
|||
br %r14
|
||||
|
||||
.Lcleanup_io_restore:
|
||||
# check if stpt has been executed
|
||||
clg %r9,BASED(.Lcleanup_io_restore_insn)
|
||||
je 0f
|
||||
jh 0f
|
||||
mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER
|
||||
0: clg %r9,BASED(.Lcleanup_io_restore_insn+8)
|
||||
je 1f
|
||||
lg %r9,24(%r11) # get saved r11 pointer to pt_regs
|
||||
mvc __LC_RETURN_PSW(16),__PT_PSW(%r9)
|
||||
mvc 0(64,%r11),__PT_R8(%r9)
|
||||
lmg %r0,%r7,__PT_R0(%r9)
|
||||
0: lmg %r8,%r9,__LC_RETURN_PSW
|
||||
1: lmg %r8,%r9,__LC_RETURN_PSW
|
||||
br %r14
|
||||
.Lcleanup_io_restore_insn:
|
||||
.quad .Lio_exit_timer
|
||||
.quad .Lio_done - 4
|
||||
|
||||
.Lcleanup_idle:
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
#ifndef BOOT_BOOT_H
|
||||
#define BOOT_BOOT_H
|
||||
|
||||
#define STACK_SIZE 512 /* Minimum number of bytes for stack */
|
||||
#define STACK_SIZE 1024 /* Minimum number of bytes for stack */
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ static inline size_t arch_copy_from_iter_pmem(void __pmem *addr, size_t bytes,
|
|||
|
||||
if (bytes < 8) {
|
||||
if (!IS_ALIGNED(dest, 4) || (bytes != 4))
|
||||
__arch_wb_cache_pmem(addr, 1);
|
||||
__arch_wb_cache_pmem(addr, bytes);
|
||||
} else {
|
||||
if (!IS_ALIGNED(dest, 8)) {
|
||||
dest = ALIGN(dest, boot_cpu_data.x86_clflush_size);
|
||||
|
|
|
|||
|
|
@ -1875,6 +1875,7 @@ static struct irq_chip ioapic_chip __read_mostly = {
|
|||
.irq_ack = irq_chip_ack_parent,
|
||||
.irq_eoi = ioapic_ack_level,
|
||||
.irq_set_affinity = ioapic_set_affinity,
|
||||
.irq_retrigger = irq_chip_retrigger_hierarchy,
|
||||
.flags = IRQCHIP_SKIP_SET_WAKE,
|
||||
};
|
||||
|
||||
|
|
@ -1886,6 +1887,7 @@ static struct irq_chip ioapic_ir_chip __read_mostly = {
|
|||
.irq_ack = irq_chip_ack_parent,
|
||||
.irq_eoi = ioapic_ir_ack_level,
|
||||
.irq_set_affinity = ioapic_set_affinity,
|
||||
.irq_retrigger = irq_chip_retrigger_hierarchy,
|
||||
.flags = IRQCHIP_SKIP_SET_WAKE,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ static void fpu__init_system_early_generic(struct cpuinfo_x86 *c)
|
|||
* Boot time FPU feature detection code:
|
||||
*/
|
||||
unsigned int mxcsr_feature_mask __read_mostly = 0xffffffffu;
|
||||
EXPORT_SYMBOL_GPL(mxcsr_feature_mask);
|
||||
|
||||
static void __init fpu__init_system_mxcsr(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
#endif
|
||||
|
||||
/* Ensure if the instruction can be boostable */
|
||||
extern int can_boost(kprobe_opcode_t *instruction);
|
||||
extern int can_boost(kprobe_opcode_t *instruction, void *addr);
|
||||
/* Recover instruction if given address is probed */
|
||||
extern unsigned long recover_probed_instruction(kprobe_opcode_t *buf,
|
||||
unsigned long addr);
|
||||
|
|
|
|||
|
|
@ -163,12 +163,12 @@ NOKPROBE_SYMBOL(skip_prefixes);
|
|||
* Returns non-zero if opcode is boostable.
|
||||
* RIP relative instructions are adjusted at copying time in 64 bits mode
|
||||
*/
|
||||
int can_boost(kprobe_opcode_t *opcodes)
|
||||
int can_boost(kprobe_opcode_t *opcodes, void *addr)
|
||||
{
|
||||
kprobe_opcode_t opcode;
|
||||
kprobe_opcode_t *orig_opcodes = opcodes;
|
||||
|
||||
if (search_exception_tables((unsigned long)opcodes))
|
||||
if (search_exception_tables((unsigned long)addr))
|
||||
return 0; /* Page fault may occur on this address. */
|
||||
|
||||
retry:
|
||||
|
|
@ -413,7 +413,7 @@ static int arch_copy_kprobe(struct kprobe *p)
|
|||
* __copy_instruction can modify the displacement of the instruction,
|
||||
* but it doesn't affect boostable check.
|
||||
*/
|
||||
if (can_boost(p->ainsn.insn))
|
||||
if (can_boost(p->ainsn.insn, p->addr))
|
||||
p->ainsn.boostable = 0;
|
||||
else
|
||||
p->ainsn.boostable = -1;
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ static int copy_optimized_instructions(u8 *dest, u8 *src)
|
|||
|
||||
while (len < RELATIVEJUMP_SIZE) {
|
||||
ret = __copy_instruction(dest + len, src + len);
|
||||
if (!ret || !can_boost(dest + len))
|
||||
if (!ret || !can_boost(dest + len, src + len))
|
||||
return -EINVAL;
|
||||
len += ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -296,7 +296,7 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
|
|||
|
||||
/* were we called with bad_dma_address? */
|
||||
badend = DMA_ERROR_CODE + (EMERGENCY_PAGES * PAGE_SIZE);
|
||||
if (unlikely((dma_addr >= DMA_ERROR_CODE) && (dma_addr < badend))) {
|
||||
if (unlikely(dma_addr < badend)) {
|
||||
WARN(1, KERN_ERR "Calgary: driver tried unmapping bad DMA "
|
||||
"address 0x%Lx\n", dma_addr);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -818,12 +818,6 @@ void kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
|
|||
if (!best)
|
||||
best = check_cpuid_limit(vcpu, function, index);
|
||||
|
||||
/*
|
||||
* Perfmon not yet supported for L2 guest.
|
||||
*/
|
||||
if (is_guest_mode(vcpu) && function == 0xa)
|
||||
best = NULL;
|
||||
|
||||
if (best) {
|
||||
*eax = best->eax;
|
||||
*ebx = best->ebx;
|
||||
|
|
|
|||
|
|
@ -7754,8 +7754,6 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu)
|
|||
case EXIT_REASON_TASK_SWITCH:
|
||||
return true;
|
||||
case EXIT_REASON_CPUID:
|
||||
if (kvm_register_read(vcpu, VCPU_REGS_RAX) == 0xa)
|
||||
return false;
|
||||
return true;
|
||||
case EXIT_REASON_HLT:
|
||||
return nested_cpu_has(vmcs12, CPU_BASED_HLT_EXITING);
|
||||
|
|
@ -7840,6 +7838,9 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu)
|
|||
return nested_cpu_has2(vmcs12, SECONDARY_EXEC_XSAVES);
|
||||
case EXIT_REASON_PCOMMIT:
|
||||
return nested_cpu_has2(vmcs12, SECONDARY_EXEC_PCOMMIT);
|
||||
case EXIT_REASON_PML_FULL:
|
||||
/* We don't expose PML support to L1. */
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
|
|
@ -9759,6 +9760,18 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
|
|||
|
||||
}
|
||||
|
||||
if (enable_pml) {
|
||||
/*
|
||||
* Conceptually we want to copy the PML address and index from
|
||||
* vmcs01 here, and then back to vmcs01 on nested vmexit. But,
|
||||
* since we always flush the log on each vmexit, this happens
|
||||
* to be equivalent to simply resetting the fields in vmcs02.
|
||||
*/
|
||||
ASSERT(vmx->pml_pg);
|
||||
vmcs_write64(PML_ADDRESS, page_to_phys(vmx->pml_pg));
|
||||
vmcs_write16(GUEST_PML_INDEX, PML_ENTITY_NUM - 1);
|
||||
}
|
||||
|
||||
if (nested_cpu_has_ept(vmcs12)) {
|
||||
kvm_mmu_unload(vcpu);
|
||||
nested_ept_init_mmu_context(vcpu);
|
||||
|
|
|
|||
|
|
@ -2960,6 +2960,12 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
|
|||
| KVM_VCPUEVENT_VALID_SMM))
|
||||
return -EINVAL;
|
||||
|
||||
/* INITs are latched while in SMM */
|
||||
if (events->flags & KVM_VCPUEVENT_VALID_SMM &&
|
||||
(events->smi.smm || events->smi.pending) &&
|
||||
vcpu->arch.mp_state == KVM_MP_STATE_INIT_RECEIVED)
|
||||
return -EINVAL;
|
||||
|
||||
process_nmi(vcpu);
|
||||
vcpu->arch.exception.pending = events->exception.injected;
|
||||
vcpu->arch.exception.nr = events->exception.nr;
|
||||
|
|
@ -3134,11 +3140,14 @@ static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu,
|
|||
}
|
||||
}
|
||||
|
||||
#define XSAVE_MXCSR_OFFSET 24
|
||||
|
||||
static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu,
|
||||
struct kvm_xsave *guest_xsave)
|
||||
{
|
||||
u64 xstate_bv =
|
||||
*(u64 *)&guest_xsave->region[XSAVE_HDR_OFFSET / sizeof(u32)];
|
||||
u32 mxcsr = *(u32 *)&guest_xsave->region[XSAVE_MXCSR_OFFSET / sizeof(u32)];
|
||||
|
||||
if (cpu_has_xsave) {
|
||||
/*
|
||||
|
|
@ -3146,11 +3155,13 @@ static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu,
|
|||
* CPUID leaf 0xD, index 0, EDX:EAX. This is for compatibility
|
||||
* with old userspace.
|
||||
*/
|
||||
if (xstate_bv & ~kvm_supported_xcr0())
|
||||
if (xstate_bv & ~kvm_supported_xcr0() ||
|
||||
mxcsr & ~mxcsr_feature_mask)
|
||||
return -EINVAL;
|
||||
load_xsave(vcpu, (u8 *)guest_xsave->region);
|
||||
} else {
|
||||
if (xstate_bv & ~XFEATURE_MASK_FPSSE)
|
||||
if (xstate_bv & ~XFEATURE_MASK_FPSSE ||
|
||||
mxcsr & ~mxcsr_feature_mask)
|
||||
return -EINVAL;
|
||||
memcpy(&vcpu->arch.guest_fpu.state.fxsave,
|
||||
guest_xsave->region, sizeof(struct fxregs_state));
|
||||
|
|
@ -4597,16 +4608,20 @@ static int emulator_cmpxchg_emulated(struct x86_emulate_ctxt *ctxt,
|
|||
|
||||
static int kernel_pio(struct kvm_vcpu *vcpu, void *pd)
|
||||
{
|
||||
/* TODO: String I/O for in kernel device */
|
||||
int r;
|
||||
int r = 0, i;
|
||||
|
||||
if (vcpu->arch.pio.in)
|
||||
r = kvm_io_bus_read(vcpu, KVM_PIO_BUS, vcpu->arch.pio.port,
|
||||
vcpu->arch.pio.size, pd);
|
||||
else
|
||||
r = kvm_io_bus_write(vcpu, KVM_PIO_BUS,
|
||||
vcpu->arch.pio.port, vcpu->arch.pio.size,
|
||||
pd);
|
||||
for (i = 0; i < vcpu->arch.pio.count; i++) {
|
||||
if (vcpu->arch.pio.in)
|
||||
r = kvm_io_bus_read(vcpu, KVM_PIO_BUS, vcpu->arch.pio.port,
|
||||
vcpu->arch.pio.size, pd);
|
||||
else
|
||||
r = kvm_io_bus_write(vcpu, KVM_PIO_BUS,
|
||||
vcpu->arch.pio.port, vcpu->arch.pio.size,
|
||||
pd);
|
||||
if (r)
|
||||
break;
|
||||
pd += vcpu->arch.pio.size;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
@ -4644,6 +4659,8 @@ static int emulator_pio_in_emulated(struct x86_emulate_ctxt *ctxt,
|
|||
if (vcpu->arch.pio.count)
|
||||
goto data_avail;
|
||||
|
||||
memset(vcpu->arch.pio_data, 0, size * count);
|
||||
|
||||
ret = emulator_pio_in_out(vcpu, size, port, val, count, true);
|
||||
if (ret) {
|
||||
data_avail:
|
||||
|
|
@ -6993,6 +7010,12 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
|
|||
mp_state->mp_state != KVM_MP_STATE_RUNNABLE)
|
||||
return -EINVAL;
|
||||
|
||||
/* INITs are latched while in SMM */
|
||||
if ((is_smm(vcpu) || vcpu->arch.smi_pending) &&
|
||||
(mp_state->mp_state == KVM_MP_STATE_SIPI_RECEIVED ||
|
||||
mp_state->mp_state == KVM_MP_STATE_INIT_RECEIVED))
|
||||
return -EINVAL;
|
||||
|
||||
if (mp_state->mp_state == KVM_MP_STATE_SIPI_RECEIVED) {
|
||||
vcpu->arch.mp_state = KVM_MP_STATE_INIT_RECEIVED;
|
||||
set_bit(KVM_APIC_SIPI, &vcpu->arch.apic->pending_events);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
#include <asm/intel-mid.h>
|
||||
#include <asm/io_apic.h>
|
||||
|
||||
#define TANGIER_EXT_TIMER0_MSI 15
|
||||
#define TANGIER_EXT_TIMER0_MSI 12
|
||||
|
||||
static struct platform_device wdt_dev = {
|
||||
.name = "intel_mid_wdt",
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ int poke_user(struct task_struct *child, long addr, long data)
|
|||
else if ((addr >= offsetof(struct user, u_debugreg[0])) &&
|
||||
(addr <= offsetof(struct user, u_debugreg[7]))) {
|
||||
addr -= offsetof(struct user, u_debugreg[0]);
|
||||
addr = addr >> 2;
|
||||
addr = addr >> 3;
|
||||
if ((addr == 4) || (addr == 5))
|
||||
return -EIO;
|
||||
child->thread.arch.debugregs[addr] = data;
|
||||
|
|
|
|||
|
|
@ -2038,7 +2038,8 @@ static unsigned long __init xen_read_phys_ulong(phys_addr_t addr)
|
|||
|
||||
/*
|
||||
* Translate a virtual address to a physical one without relying on mapped
|
||||
* page tables.
|
||||
* page tables. Don't rely on big pages being aligned in (guest) physical
|
||||
* space!
|
||||
*/
|
||||
static phys_addr_t __init xen_early_virt_to_phys(unsigned long vaddr)
|
||||
{
|
||||
|
|
@ -2059,7 +2060,7 @@ static phys_addr_t __init xen_early_virt_to_phys(unsigned long vaddr)
|
|||
sizeof(pud)));
|
||||
if (!pud_present(pud))
|
||||
return 0;
|
||||
pa = pud_pfn(pud) << PAGE_SHIFT;
|
||||
pa = pud_val(pud) & PTE_PFN_MASK;
|
||||
if (pud_large(pud))
|
||||
return pa + (vaddr & ~PUD_MASK);
|
||||
|
||||
|
|
@ -2067,7 +2068,7 @@ static phys_addr_t __init xen_early_virt_to_phys(unsigned long vaddr)
|
|||
sizeof(pmd)));
|
||||
if (!pmd_present(pmd))
|
||||
return 0;
|
||||
pa = pmd_pfn(pmd) << PAGE_SHIFT;
|
||||
pa = pmd_val(pmd) & PTE_PFN_MASK;
|
||||
if (pmd_large(pmd))
|
||||
return pa + (vaddr & ~PMD_MASK);
|
||||
|
||||
|
|
|
|||
|
|
@ -412,12 +412,13 @@ void blk_integrity_register(struct gendisk *disk, struct blk_integrity *template
|
|||
|
||||
bi->flags = BLK_INTEGRITY_VERIFY | BLK_INTEGRITY_GENERATE |
|
||||
template->flags;
|
||||
bi->interval_exp = ilog2(queue_logical_block_size(disk->queue));
|
||||
bi->interval_exp = template->interval_exp ? :
|
||||
ilog2(queue_logical_block_size(disk->queue));
|
||||
bi->profile = template->profile ? template->profile : &nop_profile;
|
||||
bi->tuple_size = template->tuple_size;
|
||||
bi->tag_size = template->tag_size;
|
||||
|
||||
blk_integrity_revalidate(disk);
|
||||
disk->queue->backing_dev_info.capabilities |= BDI_CAP_STABLE_WRITES;
|
||||
}
|
||||
EXPORT_SYMBOL(blk_integrity_register);
|
||||
|
||||
|
|
@ -430,26 +431,11 @@ EXPORT_SYMBOL(blk_integrity_register);
|
|||
*/
|
||||
void blk_integrity_unregister(struct gendisk *disk)
|
||||
{
|
||||
blk_integrity_revalidate(disk);
|
||||
disk->queue->backing_dev_info.capabilities &= ~BDI_CAP_STABLE_WRITES;
|
||||
memset(&disk->queue->integrity, 0, sizeof(struct blk_integrity));
|
||||
}
|
||||
EXPORT_SYMBOL(blk_integrity_unregister);
|
||||
|
||||
void blk_integrity_revalidate(struct gendisk *disk)
|
||||
{
|
||||
struct blk_integrity *bi = &disk->queue->integrity;
|
||||
|
||||
if (!(disk->flags & GENHD_FL_UP))
|
||||
return;
|
||||
|
||||
if (bi->profile)
|
||||
disk->queue->backing_dev_info.capabilities |=
|
||||
BDI_CAP_STABLE_WRITES;
|
||||
else
|
||||
disk->queue->backing_dev_info.capabilities &=
|
||||
~BDI_CAP_STABLE_WRITES;
|
||||
}
|
||||
|
||||
void blk_integrity_add(struct gendisk *disk)
|
||||
{
|
||||
if (kobject_init_and_add(&disk->integrity_kobj, &integrity_ktype,
|
||||
|
|
|
|||
|
|
@ -446,7 +446,6 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
|
|||
|
||||
if (disk->fops->revalidate_disk)
|
||||
disk->fops->revalidate_disk(disk);
|
||||
blk_integrity_revalidate(disk);
|
||||
check_disk_size_change(disk, bdev);
|
||||
bdev->bd_invalidated = 0;
|
||||
if (!get_capacity(disk) || !(state = check_partition(disk, bdev)))
|
||||
|
|
|
|||
|
|
@ -29,6 +29,11 @@ struct aead_sg_list {
|
|||
struct scatterlist sg[ALG_MAX_PAGES];
|
||||
};
|
||||
|
||||
struct aead_tfm {
|
||||
struct crypto_aead *aead;
|
||||
bool has_key;
|
||||
};
|
||||
|
||||
struct aead_ctx {
|
||||
struct aead_sg_list tsgl;
|
||||
/*
|
||||
|
|
@ -513,24 +518,146 @@ static struct proto_ops algif_aead_ops = {
|
|||
.poll = aead_poll,
|
||||
};
|
||||
|
||||
static int aead_check_key(struct socket *sock)
|
||||
{
|
||||
int err = 0;
|
||||
struct sock *psk;
|
||||
struct alg_sock *pask;
|
||||
struct aead_tfm *tfm;
|
||||
struct sock *sk = sock->sk;
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
|
||||
lock_sock(sk);
|
||||
if (ask->refcnt)
|
||||
goto unlock_child;
|
||||
|
||||
psk = ask->parent;
|
||||
pask = alg_sk(ask->parent);
|
||||
tfm = pask->private;
|
||||
|
||||
err = -ENOKEY;
|
||||
lock_sock_nested(psk, SINGLE_DEPTH_NESTING);
|
||||
if (!tfm->has_key)
|
||||
goto unlock;
|
||||
|
||||
if (!pask->refcnt++)
|
||||
sock_hold(psk);
|
||||
|
||||
ask->refcnt = 1;
|
||||
sock_put(psk);
|
||||
|
||||
err = 0;
|
||||
|
||||
unlock:
|
||||
release_sock(psk);
|
||||
unlock_child:
|
||||
release_sock(sk);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int aead_sendmsg_nokey(struct socket *sock, struct msghdr *msg,
|
||||
size_t size)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = aead_check_key(sock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return aead_sendmsg(sock, msg, size);
|
||||
}
|
||||
|
||||
static ssize_t aead_sendpage_nokey(struct socket *sock, struct page *page,
|
||||
int offset, size_t size, int flags)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = aead_check_key(sock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return aead_sendpage(sock, page, offset, size, flags);
|
||||
}
|
||||
|
||||
static int aead_recvmsg_nokey(struct socket *sock, struct msghdr *msg,
|
||||
size_t ignored, int flags)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = aead_check_key(sock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return aead_recvmsg(sock, msg, ignored, flags);
|
||||
}
|
||||
|
||||
static struct proto_ops algif_aead_ops_nokey = {
|
||||
.family = PF_ALG,
|
||||
|
||||
.connect = sock_no_connect,
|
||||
.socketpair = sock_no_socketpair,
|
||||
.getname = sock_no_getname,
|
||||
.ioctl = sock_no_ioctl,
|
||||
.listen = sock_no_listen,
|
||||
.shutdown = sock_no_shutdown,
|
||||
.getsockopt = sock_no_getsockopt,
|
||||
.mmap = sock_no_mmap,
|
||||
.bind = sock_no_bind,
|
||||
.accept = sock_no_accept,
|
||||
.setsockopt = sock_no_setsockopt,
|
||||
|
||||
.release = af_alg_release,
|
||||
.sendmsg = aead_sendmsg_nokey,
|
||||
.sendpage = aead_sendpage_nokey,
|
||||
.recvmsg = aead_recvmsg_nokey,
|
||||
.poll = aead_poll,
|
||||
};
|
||||
|
||||
static void *aead_bind(const char *name, u32 type, u32 mask)
|
||||
{
|
||||
return crypto_alloc_aead(name, type, mask);
|
||||
struct aead_tfm *tfm;
|
||||
struct crypto_aead *aead;
|
||||
|
||||
tfm = kzalloc(sizeof(*tfm), GFP_KERNEL);
|
||||
if (!tfm)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
aead = crypto_alloc_aead(name, type, mask);
|
||||
if (IS_ERR(aead)) {
|
||||
kfree(tfm);
|
||||
return ERR_CAST(aead);
|
||||
}
|
||||
|
||||
tfm->aead = aead;
|
||||
|
||||
return tfm;
|
||||
}
|
||||
|
||||
static void aead_release(void *private)
|
||||
{
|
||||
crypto_free_aead(private);
|
||||
struct aead_tfm *tfm = private;
|
||||
|
||||
crypto_free_aead(tfm->aead);
|
||||
kfree(tfm);
|
||||
}
|
||||
|
||||
static int aead_setauthsize(void *private, unsigned int authsize)
|
||||
{
|
||||
return crypto_aead_setauthsize(private, authsize);
|
||||
struct aead_tfm *tfm = private;
|
||||
|
||||
return crypto_aead_setauthsize(tfm->aead, authsize);
|
||||
}
|
||||
|
||||
static int aead_setkey(void *private, const u8 *key, unsigned int keylen)
|
||||
{
|
||||
return crypto_aead_setkey(private, key, keylen);
|
||||
struct aead_tfm *tfm = private;
|
||||
int err;
|
||||
|
||||
err = crypto_aead_setkey(tfm->aead, key, keylen);
|
||||
tfm->has_key = !err;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void aead_sock_destruct(struct sock *sk)
|
||||
|
|
@ -546,12 +673,14 @@ static void aead_sock_destruct(struct sock *sk)
|
|||
af_alg_release_parent(sk);
|
||||
}
|
||||
|
||||
static int aead_accept_parent(void *private, struct sock *sk)
|
||||
static int aead_accept_parent_nokey(void *private, struct sock *sk)
|
||||
{
|
||||
struct aead_ctx *ctx;
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
unsigned int len = sizeof(*ctx) + crypto_aead_reqsize(private);
|
||||
unsigned int ivlen = crypto_aead_ivsize(private);
|
||||
struct aead_tfm *tfm = private;
|
||||
struct crypto_aead *aead = tfm->aead;
|
||||
unsigned int len = sizeof(*ctx) + crypto_aead_reqsize(aead);
|
||||
unsigned int ivlen = crypto_aead_ivsize(aead);
|
||||
|
||||
ctx = sock_kmalloc(sk, len, GFP_KERNEL);
|
||||
if (!ctx)
|
||||
|
|
@ -577,7 +706,7 @@ static int aead_accept_parent(void *private, struct sock *sk)
|
|||
|
||||
ask->private = ctx;
|
||||
|
||||
aead_request_set_tfm(&ctx->aead_req, private);
|
||||
aead_request_set_tfm(&ctx->aead_req, aead);
|
||||
aead_request_set_callback(&ctx->aead_req, CRYPTO_TFM_REQ_MAY_BACKLOG,
|
||||
af_alg_complete, &ctx->completion);
|
||||
|
||||
|
|
@ -586,13 +715,25 @@ static int aead_accept_parent(void *private, struct sock *sk)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int aead_accept_parent(void *private, struct sock *sk)
|
||||
{
|
||||
struct aead_tfm *tfm = private;
|
||||
|
||||
if (!tfm->has_key)
|
||||
return -ENOKEY;
|
||||
|
||||
return aead_accept_parent_nokey(private, sk);
|
||||
}
|
||||
|
||||
static const struct af_alg_type algif_type_aead = {
|
||||
.bind = aead_bind,
|
||||
.release = aead_release,
|
||||
.setkey = aead_setkey,
|
||||
.setauthsize = aead_setauthsize,
|
||||
.accept = aead_accept_parent,
|
||||
.accept_nokey = aead_accept_parent_nokey,
|
||||
.ops = &algif_aead_ops,
|
||||
.ops_nokey = &algif_aead_ops_nokey,
|
||||
.name = "aead",
|
||||
.owner = THIS_MODULE
|
||||
};
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ obj-$(CONFIG_USB_PHY) += usb/
|
|||
obj-$(CONFIG_USB) += usb/
|
||||
obj-$(CONFIG_PCI) += usb/
|
||||
obj-$(CONFIG_USB_GADGET) += usb/
|
||||
obj-$(CONFIG_OF) += usb/
|
||||
obj-$(CONFIG_SERIO) += input/serio/
|
||||
obj-$(CONFIG_GAMEPORT) += input/gameport/
|
||||
obj-$(CONFIG_INPUT) += input/
|
||||
|
|
|
|||
|
|
@ -479,8 +479,14 @@ void drbd_bm_cleanup(struct drbd_device *device)
|
|||
* this masks out the remaining bits.
|
||||
* Returns the number of bits cleared.
|
||||
*/
|
||||
#ifndef BITS_PER_PAGE
|
||||
#define BITS_PER_PAGE (1UL << (PAGE_SHIFT + 3))
|
||||
#define BITS_PER_PAGE_MASK (BITS_PER_PAGE - 1)
|
||||
#else
|
||||
# if BITS_PER_PAGE != (1UL << (PAGE_SHIFT + 3))
|
||||
# error "ambiguous BITS_PER_PAGE"
|
||||
# endif
|
||||
#endif
|
||||
#define BITS_PER_LONG_MASK (BITS_PER_LONG - 1)
|
||||
static int bm_clear_surplus(struct drbd_bitmap *b)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -287,6 +287,9 @@ static int bcm_open(struct hci_uart *hu)
|
|||
|
||||
hu->priv = bcm;
|
||||
|
||||
if (!hu->tty->dev)
|
||||
goto out;
|
||||
|
||||
mutex_lock(&bcm_device_lock);
|
||||
list_for_each(p, &bcm_device_list) {
|
||||
struct bcm_device *dev = list_entry(p, struct bcm_device, list);
|
||||
|
|
@ -307,7 +310,7 @@ static int bcm_open(struct hci_uart *hu)
|
|||
}
|
||||
|
||||
mutex_unlock(&bcm_device_lock);
|
||||
|
||||
out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -307,6 +307,9 @@ static int intel_set_power(struct hci_uart *hu, bool powered)
|
|||
struct list_head *p;
|
||||
int err = -ENODEV;
|
||||
|
||||
if (!hu->tty->dev)
|
||||
return err;
|
||||
|
||||
mutex_lock(&intel_device_list_lock);
|
||||
|
||||
list_for_each(p, &intel_device_list) {
|
||||
|
|
@ -379,6 +382,9 @@ static void intel_busy_work(struct work_struct *work)
|
|||
struct intel_data *intel = container_of(work, struct intel_data,
|
||||
busy_work);
|
||||
|
||||
if (!intel->hu->tty->dev)
|
||||
return;
|
||||
|
||||
/* Link is busy, delay the suspend */
|
||||
mutex_lock(&intel_device_list_lock);
|
||||
list_for_each(p, &intel_device_list) {
|
||||
|
|
@ -913,6 +919,8 @@ static int intel_setup(struct hci_uart *hu)
|
|||
list_for_each(p, &intel_device_list) {
|
||||
struct intel_device *dev = list_entry(p, struct intel_device,
|
||||
list);
|
||||
if (!hu->tty->dev)
|
||||
break;
|
||||
if (hu->tty->dev->parent == dev->pdev->dev.parent) {
|
||||
if (device_may_wakeup(&dev->pdev->dev))
|
||||
idev = dev;
|
||||
|
|
@ -1094,6 +1102,9 @@ static int intel_enqueue(struct hci_uart *hu, struct sk_buff *skb)
|
|||
|
||||
BT_DBG("hu %p skb %p", hu, skb);
|
||||
|
||||
if (!hu->tty->dev)
|
||||
goto out_enqueue;
|
||||
|
||||
/* Be sure our controller is resumed and potential LPM transaction
|
||||
* completed before enqueuing any packet.
|
||||
*/
|
||||
|
|
@ -1110,7 +1121,7 @@ static int intel_enqueue(struct hci_uart *hu, struct sk_buff *skb)
|
|||
}
|
||||
}
|
||||
mutex_unlock(&intel_device_list_lock);
|
||||
|
||||
out_enqueue:
|
||||
skb_queue_tail(&intel->txq, skb);
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -888,6 +888,7 @@ static void msg_written_handler(struct ssif_info *ssif_info, int result,
|
|||
* for details on the intricacies of this.
|
||||
*/
|
||||
int left;
|
||||
unsigned char *data_to_send;
|
||||
|
||||
ssif_inc_stat(ssif_info, sent_messages_parts);
|
||||
|
||||
|
|
@ -896,6 +897,7 @@ static void msg_written_handler(struct ssif_info *ssif_info, int result,
|
|||
left = 32;
|
||||
/* Length byte. */
|
||||
ssif_info->multi_data[ssif_info->multi_pos] = left;
|
||||
data_to_send = ssif_info->multi_data + ssif_info->multi_pos;
|
||||
ssif_info->multi_pos += left;
|
||||
if (left < 32)
|
||||
/*
|
||||
|
|
@ -909,7 +911,7 @@ static void msg_written_handler(struct ssif_info *ssif_info, int result,
|
|||
rv = ssif_i2c_send(ssif_info, msg_written_handler,
|
||||
I2C_SMBUS_WRITE,
|
||||
SSIF_IPMI_MULTI_PART_REQUEST_MIDDLE,
|
||||
ssif_info->multi_data + ssif_info->multi_pos,
|
||||
data_to_send,
|
||||
I2C_SMBUS_BLOCK_DATA);
|
||||
if (rv < 0) {
|
||||
/* request failed, just return the error. */
|
||||
|
|
|
|||
|
|
@ -859,7 +859,11 @@ static int __init lp_setup (char *str)
|
|||
} else if (!strcmp(str, "auto")) {
|
||||
parport_nr[0] = LP_PARPORT_AUTO;
|
||||
} else if (!strcmp(str, "none")) {
|
||||
parport_nr[parport_ptr++] = LP_PARPORT_NONE;
|
||||
if (parport_ptr < LP_NO)
|
||||
parport_nr[parport_ptr++] = LP_PARPORT_NONE;
|
||||
else
|
||||
printk(KERN_INFO "lp: too many ports, %s ignored.\n",
|
||||
str);
|
||||
} else if (!strcmp(str, "reset")) {
|
||||
reset = 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -343,6 +343,11 @@ static const struct vm_operations_struct mmap_mem_ops = {
|
|||
static int mmap_mem(struct file *file, struct vm_area_struct *vma)
|
||||
{
|
||||
size_t size = vma->vm_end - vma->vm_start;
|
||||
phys_addr_t offset = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT;
|
||||
|
||||
/* It's illegal to wrap around the end of the physical address space. */
|
||||
if (offset + (phys_addr_t)size < offset)
|
||||
return -EINVAL;
|
||||
|
||||
if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size))
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -118,8 +118,7 @@ static int crb_recv(struct tpm_chip *chip, u8 *buf, size_t count)
|
|||
|
||||
memcpy_fromio(buf, priv->rsp, 6);
|
||||
expected = be32_to_cpup((__be32 *) &buf[2]);
|
||||
|
||||
if (expected > count)
|
||||
if (expected > count || expected < 6)
|
||||
return -EIO;
|
||||
|
||||
memcpy_fromio(&buf[6], &priv->rsp[6], expected - 6);
|
||||
|
|
|
|||
|
|
@ -78,7 +78,9 @@ obj-$(CONFIG_ARCH_TEGRA) += tegra/
|
|||
obj-$(CONFIG_ARCH_OMAP2PLUS) += ti/
|
||||
obj-$(CONFIG_ARCH_U8500) += ux500/
|
||||
obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/
|
||||
ifeq ($(CONFIG_COMMON_CLK), y)
|
||||
obj-$(CONFIG_X86) += x86/
|
||||
endif
|
||||
obj-$(CONFIG_ARCH_ZX) += zte/
|
||||
obj-$(CONFIG_ARCH_ZYNQ) += zynq/
|
||||
obj-$(CONFIG_H8300) += h8300/
|
||||
|
|
|
|||
|
|
@ -1126,23 +1126,10 @@ static u32 dce_v10_0_latency_watermark(struct dce10_wm_params *wm)
|
|||
a.full = dfixed_const(available_bandwidth);
|
||||
b.full = dfixed_const(wm->num_heads);
|
||||
a.full = dfixed_div(a, b);
|
||||
tmp = div_u64((u64) dmif_size * (u64) wm->disp_clk, mc_latency + 512);
|
||||
tmp = min(dfixed_trunc(a), tmp);
|
||||
|
||||
b.full = dfixed_const(mc_latency + 512);
|
||||
c.full = dfixed_const(wm->disp_clk);
|
||||
b.full = dfixed_div(b, c);
|
||||
|
||||
c.full = dfixed_const(dmif_size);
|
||||
b.full = dfixed_div(c, b);
|
||||
|
||||
tmp = min(dfixed_trunc(a), dfixed_trunc(b));
|
||||
|
||||
b.full = dfixed_const(1000);
|
||||
c.full = dfixed_const(wm->disp_clk);
|
||||
b.full = dfixed_div(c, b);
|
||||
c.full = dfixed_const(wm->bytes_per_pixel);
|
||||
b.full = dfixed_mul(b, c);
|
||||
|
||||
lb_fill_bw = min(tmp, dfixed_trunc(b));
|
||||
lb_fill_bw = min(tmp, wm->disp_clk * wm->bytes_per_pixel / 1000);
|
||||
|
||||
a.full = dfixed_const(max_src_lines_per_dst_line * wm->src_width * wm->bytes_per_pixel);
|
||||
b.full = dfixed_const(1000);
|
||||
|
|
@ -1250,14 +1237,14 @@ static void dce_v10_0_program_watermarks(struct amdgpu_device *adev,
|
|||
{
|
||||
struct drm_display_mode *mode = &amdgpu_crtc->base.mode;
|
||||
struct dce10_wm_params wm_low, wm_high;
|
||||
u32 pixel_period;
|
||||
u32 active_time;
|
||||
u32 line_time = 0;
|
||||
u32 latency_watermark_a = 0, latency_watermark_b = 0;
|
||||
u32 tmp, wm_mask, lb_vblank_lead_lines = 0;
|
||||
|
||||
if (amdgpu_crtc->base.enabled && num_heads && mode) {
|
||||
pixel_period = 1000000 / (u32)mode->clock;
|
||||
line_time = min((u32)mode->crtc_htotal * pixel_period, (u32)65535);
|
||||
active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock;
|
||||
line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535);
|
||||
|
||||
/* watermark for high clocks */
|
||||
if (adev->pm.dpm_enabled) {
|
||||
|
|
@ -1272,7 +1259,7 @@ static void dce_v10_0_program_watermarks(struct amdgpu_device *adev,
|
|||
|
||||
wm_high.disp_clk = mode->clock;
|
||||
wm_high.src_width = mode->crtc_hdisplay;
|
||||
wm_high.active_time = mode->crtc_hdisplay * pixel_period;
|
||||
wm_high.active_time = active_time;
|
||||
wm_high.blank_time = line_time - wm_high.active_time;
|
||||
wm_high.interlaced = false;
|
||||
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
|
||||
|
|
@ -1311,7 +1298,7 @@ static void dce_v10_0_program_watermarks(struct amdgpu_device *adev,
|
|||
|
||||
wm_low.disp_clk = mode->clock;
|
||||
wm_low.src_width = mode->crtc_hdisplay;
|
||||
wm_low.active_time = mode->crtc_hdisplay * pixel_period;
|
||||
wm_low.active_time = active_time;
|
||||
wm_low.blank_time = line_time - wm_low.active_time;
|
||||
wm_low.interlaced = false;
|
||||
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
|
||||
|
|
|
|||
|
|
@ -1114,23 +1114,10 @@ static u32 dce_v11_0_latency_watermark(struct dce10_wm_params *wm)
|
|||
a.full = dfixed_const(available_bandwidth);
|
||||
b.full = dfixed_const(wm->num_heads);
|
||||
a.full = dfixed_div(a, b);
|
||||
tmp = div_u64((u64) dmif_size * (u64) wm->disp_clk, mc_latency + 512);
|
||||
tmp = min(dfixed_trunc(a), tmp);
|
||||
|
||||
b.full = dfixed_const(mc_latency + 512);
|
||||
c.full = dfixed_const(wm->disp_clk);
|
||||
b.full = dfixed_div(b, c);
|
||||
|
||||
c.full = dfixed_const(dmif_size);
|
||||
b.full = dfixed_div(c, b);
|
||||
|
||||
tmp = min(dfixed_trunc(a), dfixed_trunc(b));
|
||||
|
||||
b.full = dfixed_const(1000);
|
||||
c.full = dfixed_const(wm->disp_clk);
|
||||
b.full = dfixed_div(c, b);
|
||||
c.full = dfixed_const(wm->bytes_per_pixel);
|
||||
b.full = dfixed_mul(b, c);
|
||||
|
||||
lb_fill_bw = min(tmp, dfixed_trunc(b));
|
||||
lb_fill_bw = min(tmp, wm->disp_clk * wm->bytes_per_pixel / 1000);
|
||||
|
||||
a.full = dfixed_const(max_src_lines_per_dst_line * wm->src_width * wm->bytes_per_pixel);
|
||||
b.full = dfixed_const(1000);
|
||||
|
|
@ -1238,14 +1225,14 @@ static void dce_v11_0_program_watermarks(struct amdgpu_device *adev,
|
|||
{
|
||||
struct drm_display_mode *mode = &amdgpu_crtc->base.mode;
|
||||
struct dce10_wm_params wm_low, wm_high;
|
||||
u32 pixel_period;
|
||||
u32 active_time;
|
||||
u32 line_time = 0;
|
||||
u32 latency_watermark_a = 0, latency_watermark_b = 0;
|
||||
u32 tmp, wm_mask, lb_vblank_lead_lines = 0;
|
||||
|
||||
if (amdgpu_crtc->base.enabled && num_heads && mode) {
|
||||
pixel_period = 1000000 / (u32)mode->clock;
|
||||
line_time = min((u32)mode->crtc_htotal * pixel_period, (u32)65535);
|
||||
active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock;
|
||||
line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535);
|
||||
|
||||
/* watermark for high clocks */
|
||||
if (adev->pm.dpm_enabled) {
|
||||
|
|
@ -1260,7 +1247,7 @@ static void dce_v11_0_program_watermarks(struct amdgpu_device *adev,
|
|||
|
||||
wm_high.disp_clk = mode->clock;
|
||||
wm_high.src_width = mode->crtc_hdisplay;
|
||||
wm_high.active_time = mode->crtc_hdisplay * pixel_period;
|
||||
wm_high.active_time = active_time;
|
||||
wm_high.blank_time = line_time - wm_high.active_time;
|
||||
wm_high.interlaced = false;
|
||||
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
|
||||
|
|
@ -1299,7 +1286,7 @@ static void dce_v11_0_program_watermarks(struct amdgpu_device *adev,
|
|||
|
||||
wm_low.disp_clk = mode->clock;
|
||||
wm_low.src_width = mode->crtc_hdisplay;
|
||||
wm_low.active_time = mode->crtc_hdisplay * pixel_period;
|
||||
wm_low.active_time = active_time;
|
||||
wm_low.blank_time = line_time - wm_low.active_time;
|
||||
wm_low.interlaced = false;
|
||||
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
|
||||
|
|
|
|||
|
|
@ -1096,23 +1096,10 @@ static u32 dce_v8_0_latency_watermark(struct dce8_wm_params *wm)
|
|||
a.full = dfixed_const(available_bandwidth);
|
||||
b.full = dfixed_const(wm->num_heads);
|
||||
a.full = dfixed_div(a, b);
|
||||
tmp = div_u64((u64) dmif_size * (u64) wm->disp_clk, mc_latency + 512);
|
||||
tmp = min(dfixed_trunc(a), tmp);
|
||||
|
||||
b.full = dfixed_const(mc_latency + 512);
|
||||
c.full = dfixed_const(wm->disp_clk);
|
||||
b.full = dfixed_div(b, c);
|
||||
|
||||
c.full = dfixed_const(dmif_size);
|
||||
b.full = dfixed_div(c, b);
|
||||
|
||||
tmp = min(dfixed_trunc(a), dfixed_trunc(b));
|
||||
|
||||
b.full = dfixed_const(1000);
|
||||
c.full = dfixed_const(wm->disp_clk);
|
||||
b.full = dfixed_div(c, b);
|
||||
c.full = dfixed_const(wm->bytes_per_pixel);
|
||||
b.full = dfixed_mul(b, c);
|
||||
|
||||
lb_fill_bw = min(tmp, dfixed_trunc(b));
|
||||
lb_fill_bw = min(tmp, wm->disp_clk * wm->bytes_per_pixel / 1000);
|
||||
|
||||
a.full = dfixed_const(max_src_lines_per_dst_line * wm->src_width * wm->bytes_per_pixel);
|
||||
b.full = dfixed_const(1000);
|
||||
|
|
@ -1220,14 +1207,14 @@ static void dce_v8_0_program_watermarks(struct amdgpu_device *adev,
|
|||
{
|
||||
struct drm_display_mode *mode = &amdgpu_crtc->base.mode;
|
||||
struct dce8_wm_params wm_low, wm_high;
|
||||
u32 pixel_period;
|
||||
u32 active_time;
|
||||
u32 line_time = 0;
|
||||
u32 latency_watermark_a = 0, latency_watermark_b = 0;
|
||||
u32 tmp, wm_mask, lb_vblank_lead_lines = 0;
|
||||
|
||||
if (amdgpu_crtc->base.enabled && num_heads && mode) {
|
||||
pixel_period = 1000000 / (u32)mode->clock;
|
||||
line_time = min((u32)mode->crtc_htotal * pixel_period, (u32)65535);
|
||||
active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock;
|
||||
line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535);
|
||||
|
||||
/* watermark for high clocks */
|
||||
if (adev->pm.dpm_enabled) {
|
||||
|
|
@ -1242,7 +1229,7 @@ static void dce_v8_0_program_watermarks(struct amdgpu_device *adev,
|
|||
|
||||
wm_high.disp_clk = mode->clock;
|
||||
wm_high.src_width = mode->crtc_hdisplay;
|
||||
wm_high.active_time = mode->crtc_hdisplay * pixel_period;
|
||||
wm_high.active_time = active_time;
|
||||
wm_high.blank_time = line_time - wm_high.active_time;
|
||||
wm_high.interlaced = false;
|
||||
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
|
||||
|
|
@ -1281,7 +1268,7 @@ static void dce_v8_0_program_watermarks(struct amdgpu_device *adev,
|
|||
|
||||
wm_low.disp_clk = mode->clock;
|
||||
wm_low.src_width = mode->crtc_hdisplay;
|
||||
wm_low.active_time = mode->crtc_hdisplay * pixel_period;
|
||||
wm_low.active_time = active_time;
|
||||
wm_low.blank_time = line_time - wm_low.active_time;
|
||||
wm_low.interlaced = false;
|
||||
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
|
||||
|
|
|
|||
|
|
@ -75,6 +75,8 @@
|
|||
#define EDID_QUIRK_FORCE_12BPC (1 << 9)
|
||||
/* Force 6bpc */
|
||||
#define EDID_QUIRK_FORCE_6BPC (1 << 10)
|
||||
/* Force 10bpc */
|
||||
#define EDID_QUIRK_FORCE_10BPC (1 << 11)
|
||||
|
||||
struct detailed_mode_closure {
|
||||
struct drm_connector *connector;
|
||||
|
|
@ -117,6 +119,9 @@ static struct edid_quirk {
|
|||
{ "FCM", 13600, EDID_QUIRK_PREFER_LARGE_75 |
|
||||
EDID_QUIRK_DETAILED_IN_CM },
|
||||
|
||||
/* LGD panel of HP zBook 17 G2, eDP 10 bpc, but reports unknown bpc */
|
||||
{ "LGD", 764, EDID_QUIRK_FORCE_10BPC },
|
||||
|
||||
/* LG Philips LCD LP154W01-A5 */
|
||||
{ "LPL", 0, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE },
|
||||
{ "LPL", 0x2a00, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE },
|
||||
|
|
@ -4306,6 +4311,9 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
|
|||
if (quirks & EDID_QUIRK_FORCE_8BPC)
|
||||
connector->display_info.bpc = 8;
|
||||
|
||||
if (quirks & EDID_QUIRK_FORCE_10BPC)
|
||||
connector->display_info.bpc = 10;
|
||||
|
||||
if (quirks & EDID_QUIRK_FORCE_12BPC)
|
||||
connector->display_info.bpc = 12;
|
||||
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ nvkm_therm_update(struct nvkm_therm *therm, int mode)
|
|||
poll = false;
|
||||
}
|
||||
|
||||
if (list_empty(&therm->alarm.head) && poll)
|
||||
if (poll)
|
||||
nvkm_timer_alarm(tmr, 1000000000ULL, &therm->alarm);
|
||||
spin_unlock_irqrestore(&therm->lock, flags);
|
||||
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ nvkm_fan_update(struct nvkm_fan *fan, bool immediate, int target)
|
|||
spin_unlock_irqrestore(&fan->lock, flags);
|
||||
|
||||
/* schedule next fan update, if not at target speed already */
|
||||
if (list_empty(&fan->alarm.head) && target != duty) {
|
||||
if (target != duty) {
|
||||
u16 bump_period = fan->bios.bump_period;
|
||||
u16 slow_down_period = fan->bios.slow_down_period;
|
||||
u64 delay;
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ nvkm_fantog_update(struct nvkm_fantog *fan, int percent)
|
|||
duty = !nvkm_gpio_get(gpio, 0, DCB_GPIO_FAN, 0xff);
|
||||
nvkm_gpio_set(gpio, 0, DCB_GPIO_FAN, 0xff, duty);
|
||||
|
||||
if (list_empty(&fan->alarm.head) && percent != (duty * 100)) {
|
||||
if (percent != (duty * 100)) {
|
||||
u64 next_change = (percent * fan->period_us) / 100;
|
||||
if (!duty)
|
||||
next_change = fan->period_us - next_change;
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ alarm_timer_callback(struct nvkm_alarm *alarm)
|
|||
spin_unlock_irqrestore(&therm->sensor.alarm_program_lock, flags);
|
||||
|
||||
/* schedule the next poll in one second */
|
||||
if (therm->func->temp_get(therm) >= 0 && list_empty(&alarm->head))
|
||||
if (therm->func->temp_get(therm) >= 0)
|
||||
nvkm_timer_alarm(tmr, 1000000000ULL, alarm);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,23 +36,29 @@ nvkm_timer_alarm_trigger(struct nvkm_timer *tmr)
|
|||
unsigned long flags;
|
||||
LIST_HEAD(exec);
|
||||
|
||||
/* move any due alarms off the pending list */
|
||||
/* Process pending alarms. */
|
||||
spin_lock_irqsave(&tmr->lock, flags);
|
||||
list_for_each_entry_safe(alarm, atemp, &tmr->alarms, head) {
|
||||
if (alarm->timestamp <= nvkm_timer_read(tmr))
|
||||
list_move_tail(&alarm->head, &exec);
|
||||
/* Have we hit the earliest alarm that hasn't gone off? */
|
||||
if (alarm->timestamp > nvkm_timer_read(tmr)) {
|
||||
/* Schedule it. If we didn't race, we're done. */
|
||||
tmr->func->alarm_init(tmr, alarm->timestamp);
|
||||
if (alarm->timestamp > nvkm_timer_read(tmr))
|
||||
break;
|
||||
}
|
||||
|
||||
/* Move to completed list. We'll drop the lock before
|
||||
* executing the callback so it can reschedule itself.
|
||||
*/
|
||||
list_move_tail(&alarm->head, &exec);
|
||||
}
|
||||
|
||||
/* reschedule interrupt for next alarm time */
|
||||
if (!list_empty(&tmr->alarms)) {
|
||||
alarm = list_first_entry(&tmr->alarms, typeof(*alarm), head);
|
||||
tmr->func->alarm_init(tmr, alarm->timestamp);
|
||||
} else {
|
||||
/* Shut down interrupt if no more pending alarms. */
|
||||
if (list_empty(&tmr->alarms))
|
||||
tmr->func->alarm_fini(tmr);
|
||||
}
|
||||
spin_unlock_irqrestore(&tmr->lock, flags);
|
||||
|
||||
/* execute any pending alarm handlers */
|
||||
/* Execute completed callbacks. */
|
||||
list_for_each_entry_safe(alarm, atemp, &exec, head) {
|
||||
list_del_init(&alarm->head);
|
||||
alarm->func(alarm);
|
||||
|
|
@ -65,24 +71,37 @@ nvkm_timer_alarm(struct nvkm_timer *tmr, u32 nsec, struct nvkm_alarm *alarm)
|
|||
struct nvkm_alarm *list;
|
||||
unsigned long flags;
|
||||
|
||||
alarm->timestamp = nvkm_timer_read(tmr) + nsec;
|
||||
|
||||
/* append new alarm to list, in soonest-alarm-first order */
|
||||
/* Remove alarm from pending list.
|
||||
*
|
||||
* This both protects against the corruption of the list,
|
||||
* and implements alarm rescheduling/cancellation.
|
||||
*/
|
||||
spin_lock_irqsave(&tmr->lock, flags);
|
||||
if (!nsec) {
|
||||
if (!list_empty(&alarm->head))
|
||||
list_del(&alarm->head);
|
||||
} else {
|
||||
list_del_init(&alarm->head);
|
||||
|
||||
if (nsec) {
|
||||
/* Insert into pending list, ordered earliest to latest. */
|
||||
alarm->timestamp = nvkm_timer_read(tmr) + nsec;
|
||||
list_for_each_entry(list, &tmr->alarms, head) {
|
||||
if (list->timestamp > alarm->timestamp)
|
||||
break;
|
||||
}
|
||||
|
||||
list_add_tail(&alarm->head, &list->head);
|
||||
|
||||
/* Update HW if this is now the earliest alarm. */
|
||||
list = list_first_entry(&tmr->alarms, typeof(*list), head);
|
||||
if (list == alarm) {
|
||||
tmr->func->alarm_init(tmr, alarm->timestamp);
|
||||
/* This shouldn't happen if callers aren't stupid.
|
||||
*
|
||||
* Worst case scenario is that it'll take roughly
|
||||
* 4 seconds for the next alarm to trigger.
|
||||
*/
|
||||
WARN_ON(alarm->timestamp <= nvkm_timer_read(tmr));
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&tmr->lock, flags);
|
||||
|
||||
/* process pending alarms */
|
||||
nvkm_timer_alarm_trigger(tmr);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -76,8 +76,8 @@ nv04_timer_intr(struct nvkm_timer *tmr)
|
|||
u32 stat = nvkm_rd32(device, NV04_PTIMER_INTR_0);
|
||||
|
||||
if (stat & 0x00000001) {
|
||||
nvkm_timer_alarm_trigger(tmr);
|
||||
nvkm_wr32(device, NV04_PTIMER_INTR_0, 0x00000001);
|
||||
nvkm_timer_alarm_trigger(tmr);
|
||||
stat &= ~0x00000001;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -66,8 +66,11 @@ static int ttm_bo_vm_fault_idle(struct ttm_buffer_object *bo,
|
|||
if (vmf->flags & FAULT_FLAG_RETRY_NOWAIT)
|
||||
goto out_unlock;
|
||||
|
||||
ttm_bo_reference(bo);
|
||||
up_read(&vma->vm_mm->mmap_sem);
|
||||
(void) ttm_bo_wait(bo, false, true, false);
|
||||
ttm_bo_unreserve(bo);
|
||||
ttm_bo_unref(&bo);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
|
|
@ -114,8 +117,10 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
|
|||
|
||||
if (vmf->flags & FAULT_FLAG_ALLOW_RETRY) {
|
||||
if (!(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) {
|
||||
ttm_bo_reference(bo);
|
||||
up_read(&vma->vm_mm->mmap_sem);
|
||||
(void) ttm_bo_wait_unreserved(bo);
|
||||
ttm_bo_unref(&bo);
|
||||
}
|
||||
|
||||
return VM_FAULT_RETRY;
|
||||
|
|
@ -160,6 +165,13 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
|
|||
ret = ttm_bo_vm_fault_idle(bo, vma, vmf);
|
||||
if (unlikely(ret != 0)) {
|
||||
retval = ret;
|
||||
|
||||
if (retval == VM_FAULT_RETRY &&
|
||||
!(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) {
|
||||
/* The BO has already been unreserved. */
|
||||
return retval;
|
||||
}
|
||||
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -184,9 +184,9 @@ static const struct iio_chan_spec_ext_info ad7303_ext_info[] = {
|
|||
.address = (chan), \
|
||||
.scan_type = { \
|
||||
.sign = 'u', \
|
||||
.realbits = '8', \
|
||||
.storagebits = '8', \
|
||||
.shift = '0', \
|
||||
.realbits = 8, \
|
||||
.storagebits = 8, \
|
||||
.shift = 0, \
|
||||
}, \
|
||||
.ext_info = ad7303_ext_info, \
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,6 @@
|
|||
#define AS3935_TUNE_CAP 0x08
|
||||
#define AS3935_CALIBRATE 0x3D
|
||||
|
||||
#define AS3935_WRITE_DATA BIT(15)
|
||||
#define AS3935_READ_DATA BIT(14)
|
||||
#define AS3935_ADDRESS(x) ((x) << 8)
|
||||
|
||||
|
|
@ -105,7 +104,7 @@ static int as3935_write(struct as3935_state *st,
|
|||
{
|
||||
u8 *buf = st->buf;
|
||||
|
||||
buf[0] = (AS3935_WRITE_DATA | AS3935_ADDRESS(reg)) >> 8;
|
||||
buf[0] = AS3935_ADDRESS(reg) >> 8;
|
||||
buf[1] = val;
|
||||
|
||||
return spi_write(st->spi, buf, 2);
|
||||
|
|
|
|||
|
|
@ -277,8 +277,8 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
|
|||
fl6.saddr = src_in->sin6_addr;
|
||||
fl6.flowi6_oif = addr->bound_dev_if;
|
||||
|
||||
dst = ip6_route_output(addr->net, NULL, &fl6);
|
||||
if ((ret = dst->error))
|
||||
ret = ipv6_stub->ipv6_dst_lookup(addr->net, NULL, &dst, &fl6);
|
||||
if (ret < 0)
|
||||
goto put;
|
||||
|
||||
if (ipv6_addr_any(&fl6.saddr)) {
|
||||
|
|
|
|||
|
|
@ -863,7 +863,7 @@ int ib_device_register_sysfs(struct ib_device *device,
|
|||
free_port_list_attributes(device);
|
||||
|
||||
err_unregister:
|
||||
device_unregister(class_dev);
|
||||
device_del(class_dev);
|
||||
|
||||
err:
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -2491,6 +2491,7 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
|
|||
mlx4_ib_delete_counters_table(ibdev, &ibdev->counters_table[i]);
|
||||
|
||||
err_map:
|
||||
mlx4_ib_free_eqs(dev, ibdev);
|
||||
iounmap(ibdev->uar_map);
|
||||
|
||||
err_uar:
|
||||
|
|
|
|||
|
|
@ -1105,7 +1105,8 @@ static void _mlx4_ib_mcg_port_cleanup(struct mlx4_ib_demux_ctx *ctx, int destroy
|
|||
while ((p = rb_first(&ctx->mcg_table)) != NULL) {
|
||||
group = rb_entry(p, struct mcast_group, node);
|
||||
if (atomic_read(&group->refcount))
|
||||
mcg_warn_group(group, "group refcount %d!!! (pointer %p)\n", atomic_read(&group->refcount), group);
|
||||
mcg_debug_group(group, "group refcount %d!!! (pointer %p)\n",
|
||||
atomic_read(&group->refcount), group);
|
||||
|
||||
force_clean_group(group);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,13 +41,13 @@
|
|||
|
||||
#include "qib.h"
|
||||
|
||||
#define BITS_PER_PAGE (PAGE_SIZE*BITS_PER_BYTE)
|
||||
#define BITS_PER_PAGE_MASK (BITS_PER_PAGE-1)
|
||||
#define RVT_BITS_PER_PAGE (PAGE_SIZE*BITS_PER_BYTE)
|
||||
#define RVT_BITS_PER_PAGE_MASK (RVT_BITS_PER_PAGE-1)
|
||||
|
||||
static inline unsigned mk_qpn(struct qib_qpn_table *qpt,
|
||||
struct qpn_map *map, unsigned off)
|
||||
{
|
||||
return (map - qpt->map) * BITS_PER_PAGE + off;
|
||||
return (map - qpt->map) * RVT_BITS_PER_PAGE + off;
|
||||
}
|
||||
|
||||
static inline unsigned find_next_offset(struct qib_qpn_table *qpt,
|
||||
|
|
@ -59,7 +59,7 @@ static inline unsigned find_next_offset(struct qib_qpn_table *qpt,
|
|||
if (((off & qpt->mask) >> 1) >= n)
|
||||
off = (off | qpt->mask) + 2;
|
||||
} else
|
||||
off = find_next_zero_bit(map->page, BITS_PER_PAGE, off);
|
||||
off = find_next_zero_bit(map->page, RVT_BITS_PER_PAGE, off);
|
||||
return off;
|
||||
}
|
||||
|
||||
|
|
@ -147,8 +147,8 @@ static int alloc_qpn(struct qib_devdata *dd, struct qib_qpn_table *qpt,
|
|||
qpn = 2;
|
||||
if (qpt->mask && ((qpn & qpt->mask) >> 1) >= dd->n_krcv_queues)
|
||||
qpn = (qpn | qpt->mask) + 2;
|
||||
offset = qpn & BITS_PER_PAGE_MASK;
|
||||
map = &qpt->map[qpn / BITS_PER_PAGE];
|
||||
offset = qpn & RVT_BITS_PER_PAGE_MASK;
|
||||
map = &qpt->map[qpn / RVT_BITS_PER_PAGE];
|
||||
max_scan = qpt->nmaps - !offset;
|
||||
for (i = 0;;) {
|
||||
if (unlikely(!map->page)) {
|
||||
|
|
@ -173,7 +173,7 @@ static int alloc_qpn(struct qib_devdata *dd, struct qib_qpn_table *qpt,
|
|||
* We just need to be sure we don't loop
|
||||
* forever.
|
||||
*/
|
||||
} while (offset < BITS_PER_PAGE && qpn < QPN_MAX);
|
||||
} while (offset < RVT_BITS_PER_PAGE && qpn < QPN_MAX);
|
||||
/*
|
||||
* In order to keep the number of pages allocated to a
|
||||
* minimum, we scan the all existing pages before increasing
|
||||
|
|
@ -204,9 +204,9 @@ static void free_qpn(struct qib_qpn_table *qpt, u32 qpn)
|
|||
{
|
||||
struct qpn_map *map;
|
||||
|
||||
map = qpt->map + qpn / BITS_PER_PAGE;
|
||||
map = qpt->map + qpn / RVT_BITS_PER_PAGE;
|
||||
if (map->page)
|
||||
clear_bit(qpn & BITS_PER_PAGE_MASK, map->page);
|
||||
clear_bit(qpn & RVT_BITS_PER_PAGE_MASK, map->page);
|
||||
}
|
||||
|
||||
static inline unsigned qpn_hash(struct qib_ibdev *dev, u32 qpn)
|
||||
|
|
|
|||
|
|
@ -281,8 +281,11 @@ void ipoib_delete_debug_files(struct net_device *dev)
|
|||
{
|
||||
struct ipoib_dev_priv *priv = netdev_priv(dev);
|
||||
|
||||
WARN_ONCE(!priv->mcg_dentry, "null mcg debug file\n");
|
||||
WARN_ONCE(!priv->path_dentry, "null path debug file\n");
|
||||
debugfs_remove(priv->mcg_dentry);
|
||||
debugfs_remove(priv->path_dentry);
|
||||
priv->mcg_dentry = priv->path_dentry = NULL;
|
||||
}
|
||||
|
||||
int ipoib_register_debugfs(void)
|
||||
|
|
|
|||
|
|
@ -106,6 +106,33 @@ static struct ib_client ipoib_client = {
|
|||
.get_net_dev_by_params = ipoib_get_net_dev_by_params,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
|
||||
static int ipoib_netdev_event(struct notifier_block *this,
|
||||
unsigned long event, void *ptr)
|
||||
{
|
||||
struct netdev_notifier_info *ni = ptr;
|
||||
struct net_device *dev = ni->dev;
|
||||
|
||||
if (dev->netdev_ops->ndo_open != ipoib_open)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
switch (event) {
|
||||
case NETDEV_REGISTER:
|
||||
ipoib_create_debug_files(dev);
|
||||
break;
|
||||
case NETDEV_CHANGENAME:
|
||||
ipoib_delete_debug_files(dev);
|
||||
ipoib_create_debug_files(dev);
|
||||
break;
|
||||
case NETDEV_UNREGISTER:
|
||||
ipoib_delete_debug_files(dev);
|
||||
break;
|
||||
}
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
int ipoib_open(struct net_device *dev)
|
||||
{
|
||||
struct ipoib_dev_priv *priv = netdev_priv(dev);
|
||||
|
|
@ -1595,8 +1622,6 @@ void ipoib_dev_cleanup(struct net_device *dev)
|
|||
|
||||
ASSERT_RTNL();
|
||||
|
||||
ipoib_delete_debug_files(dev);
|
||||
|
||||
/* Delete any child interfaces first */
|
||||
list_for_each_entry_safe(cpriv, tcpriv, &priv->child_intfs, list) {
|
||||
/* Stop GC on child */
|
||||
|
|
@ -1908,8 +1933,6 @@ static struct net_device *ipoib_add_port(const char *format,
|
|||
goto register_failed;
|
||||
}
|
||||
|
||||
ipoib_create_debug_files(priv->dev);
|
||||
|
||||
if (ipoib_cm_add_mode_attr(priv->dev))
|
||||
goto sysfs_failed;
|
||||
if (ipoib_add_pkey_attr(priv->dev))
|
||||
|
|
@ -1924,7 +1947,6 @@ static struct net_device *ipoib_add_port(const char *format,
|
|||
return priv->dev;
|
||||
|
||||
sysfs_failed:
|
||||
ipoib_delete_debug_files(priv->dev);
|
||||
unregister_netdev(priv->dev);
|
||||
|
||||
register_failed:
|
||||
|
|
@ -2006,6 +2028,12 @@ static void ipoib_remove_one(struct ib_device *device, void *client_data)
|
|||
kfree(dev_list);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
|
||||
static struct notifier_block ipoib_netdev_notifier = {
|
||||
.notifier_call = ipoib_netdev_event,
|
||||
};
|
||||
#endif
|
||||
|
||||
static int __init ipoib_init_module(void)
|
||||
{
|
||||
int ret;
|
||||
|
|
@ -2057,6 +2085,9 @@ static int __init ipoib_init_module(void)
|
|||
if (ret)
|
||||
goto err_client;
|
||||
|
||||
#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
|
||||
register_netdevice_notifier(&ipoib_netdev_notifier);
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
err_client:
|
||||
|
|
@ -2074,6 +2105,9 @@ static int __init ipoib_init_module(void)
|
|||
|
||||
static void __exit ipoib_cleanup_module(void)
|
||||
{
|
||||
#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
|
||||
unregister_netdevice_notifier(&ipoib_netdev_notifier);
|
||||
#endif
|
||||
ipoib_netlink_fini();
|
||||
ib_unregister_client(&ipoib_client);
|
||||
ib_sa_unregister_client(&ipoib_sa_client);
|
||||
|
|
|
|||
|
|
@ -85,8 +85,6 @@ int __ipoib_vlan_add(struct ipoib_dev_priv *ppriv, struct ipoib_dev_priv *priv,
|
|||
goto register_failed;
|
||||
}
|
||||
|
||||
ipoib_create_debug_files(priv->dev);
|
||||
|
||||
/* RTNL childs don't need proprietary sysfs entries */
|
||||
if (type == IPOIB_LEGACY_CHILD) {
|
||||
if (ipoib_cm_add_mode_attr(priv->dev))
|
||||
|
|
@ -107,7 +105,6 @@ int __ipoib_vlan_add(struct ipoib_dev_priv *ppriv, struct ipoib_dev_priv *priv,
|
|||
|
||||
sysfs_failed:
|
||||
result = -ENOMEM;
|
||||
ipoib_delete_debug_files(priv->dev);
|
||||
unregister_netdevice(priv->dev);
|
||||
|
||||
register_failed:
|
||||
|
|
|
|||
|
|
@ -2005,11 +2005,14 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
|
|||
if (context_copied(context)) {
|
||||
u16 did_old = context_domain_id(context);
|
||||
|
||||
if (did_old >= 0 && did_old < cap_ndoms(iommu->cap))
|
||||
if (did_old >= 0 && did_old < cap_ndoms(iommu->cap)) {
|
||||
iommu->flush.flush_context(iommu, did_old,
|
||||
(((u16)bus) << 8) | devfn,
|
||||
DMA_CCMD_MASK_NOBIT,
|
||||
DMA_CCMD_DEVICE_INVL);
|
||||
iommu->flush.flush_iotlb(iommu, did_old, 0, 0,
|
||||
DMA_TLB_DSI_FLUSH);
|
||||
}
|
||||
}
|
||||
|
||||
pgd = domain->pgd;
|
||||
|
|
|
|||
|
|
@ -296,15 +296,15 @@ static int ktd2692_parse_dt(struct ktd2692_context *led, struct device *dev,
|
|||
return -ENXIO;
|
||||
|
||||
led->ctrl_gpio = devm_gpiod_get(dev, "ctrl", GPIOD_ASIS);
|
||||
if (IS_ERR(led->ctrl_gpio)) {
|
||||
ret = PTR_ERR(led->ctrl_gpio);
|
||||
ret = PTR_ERR_OR_ZERO(led->ctrl_gpio);
|
||||
if (ret) {
|
||||
dev_err(dev, "cannot get ctrl-gpios %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
led->aux_gpio = devm_gpiod_get(dev, "aux", GPIOD_ASIS);
|
||||
if (IS_ERR(led->aux_gpio)) {
|
||||
ret = PTR_ERR(led->aux_gpio);
|
||||
ret = PTR_ERR_OR_ZERO(led->aux_gpio);
|
||||
if (ret) {
|
||||
dev_err(dev, "cannot get aux-gpios %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -357,6 +357,7 @@ config DM_LOG_USERSPACE
|
|||
config DM_RAID
|
||||
tristate "RAID 1/4/5/6/10 target"
|
||||
depends on BLK_DEV_DM
|
||||
select MD_RAID0
|
||||
select MD_RAID1
|
||||
select MD_RAID10
|
||||
select MD_RAID456
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ static DEFINE_SPINLOCK(param_spinlock);
|
|||
* Buffers are freed after this timeout
|
||||
*/
|
||||
static unsigned dm_bufio_max_age = DM_BUFIO_DEFAULT_AGE_SECS;
|
||||
static unsigned dm_bufio_retain_bytes = DM_BUFIO_DEFAULT_RETAIN_BYTES;
|
||||
static unsigned long dm_bufio_retain_bytes = DM_BUFIO_DEFAULT_RETAIN_BYTES;
|
||||
|
||||
static unsigned long dm_bufio_peak_allocated;
|
||||
static unsigned long dm_bufio_allocated_kmem_cache;
|
||||
|
|
@ -914,10 +914,11 @@ static void __get_memory_limit(struct dm_bufio_client *c,
|
|||
{
|
||||
unsigned long buffers;
|
||||
|
||||
if (ACCESS_ONCE(dm_bufio_cache_size) != dm_bufio_cache_size_latch) {
|
||||
mutex_lock(&dm_bufio_clients_lock);
|
||||
__cache_size_refresh();
|
||||
mutex_unlock(&dm_bufio_clients_lock);
|
||||
if (unlikely(ACCESS_ONCE(dm_bufio_cache_size) != dm_bufio_cache_size_latch)) {
|
||||
if (mutex_trylock(&dm_bufio_clients_lock)) {
|
||||
__cache_size_refresh();
|
||||
mutex_unlock(&dm_bufio_clients_lock);
|
||||
}
|
||||
}
|
||||
|
||||
buffers = dm_bufio_cache_size_per_client >>
|
||||
|
|
@ -1513,10 +1514,10 @@ static bool __try_evict_buffer(struct dm_buffer *b, gfp_t gfp)
|
|||
return true;
|
||||
}
|
||||
|
||||
static unsigned get_retain_buffers(struct dm_bufio_client *c)
|
||||
static unsigned long get_retain_buffers(struct dm_bufio_client *c)
|
||||
{
|
||||
unsigned retain_bytes = ACCESS_ONCE(dm_bufio_retain_bytes);
|
||||
return retain_bytes / c->block_size;
|
||||
unsigned long retain_bytes = ACCESS_ONCE(dm_bufio_retain_bytes);
|
||||
return retain_bytes >> (c->sectors_per_block_bits + SECTOR_SHIFT);
|
||||
}
|
||||
|
||||
static unsigned long __scan(struct dm_bufio_client *c, unsigned long nr_to_scan,
|
||||
|
|
@ -1526,7 +1527,7 @@ static unsigned long __scan(struct dm_bufio_client *c, unsigned long nr_to_scan,
|
|||
struct dm_buffer *b, *tmp;
|
||||
unsigned long freed = 0;
|
||||
unsigned long count = nr_to_scan;
|
||||
unsigned retain_target = get_retain_buffers(c);
|
||||
unsigned long retain_target = get_retain_buffers(c);
|
||||
|
||||
for (l = 0; l < LIST_SIZE; l++) {
|
||||
list_for_each_entry_safe_reverse(b, tmp, &c->lru[l], lru_list) {
|
||||
|
|
@ -1752,11 +1753,19 @@ static bool older_than(struct dm_buffer *b, unsigned long age_hz)
|
|||
static void __evict_old_buffers(struct dm_bufio_client *c, unsigned long age_hz)
|
||||
{
|
||||
struct dm_buffer *b, *tmp;
|
||||
unsigned retain_target = get_retain_buffers(c);
|
||||
unsigned count;
|
||||
unsigned long retain_target = get_retain_buffers(c);
|
||||
unsigned long count;
|
||||
LIST_HEAD(write_list);
|
||||
|
||||
dm_bufio_lock(c);
|
||||
|
||||
__check_watermark(c, &write_list);
|
||||
if (unlikely(!list_empty(&write_list))) {
|
||||
dm_bufio_unlock(c);
|
||||
__flush_write_list(&write_list);
|
||||
dm_bufio_lock(c);
|
||||
}
|
||||
|
||||
count = c->n_buffers[LIST_CLEAN] + c->n_buffers[LIST_DIRTY];
|
||||
list_for_each_entry_safe_reverse(b, tmp, &c->lru[LIST_CLEAN], lru_list) {
|
||||
if (count <= retain_target)
|
||||
|
|
@ -1781,6 +1790,8 @@ static void cleanup_old_buffers(void)
|
|||
|
||||
mutex_lock(&dm_bufio_clients_lock);
|
||||
|
||||
__cache_size_refresh();
|
||||
|
||||
list_for_each_entry(c, &dm_bufio_all_clients, client_list)
|
||||
__evict_old_buffers(c, max_age_hz);
|
||||
|
||||
|
|
@ -1904,7 +1915,7 @@ MODULE_PARM_DESC(max_cache_size_bytes, "Size of metadata cache");
|
|||
module_param_named(max_age_seconds, dm_bufio_max_age, uint, S_IRUGO | S_IWUSR);
|
||||
MODULE_PARM_DESC(max_age_seconds, "Max age of a buffer in seconds");
|
||||
|
||||
module_param_named(retain_bytes, dm_bufio_retain_bytes, uint, S_IRUGO | S_IWUSR);
|
||||
module_param_named(retain_bytes, dm_bufio_retain_bytes, ulong, S_IRUGO | S_IWUSR);
|
||||
MODULE_PARM_DESC(retain_bytes, "Try to keep at least this many bytes cached in memory");
|
||||
|
||||
module_param_named(peak_allocated_bytes, dm_bufio_peak_allocated, ulong, S_IRUGO | S_IWUSR);
|
||||
|
|
|
|||
|
|
@ -1326,17 +1326,19 @@ void dm_cache_metadata_set_stats(struct dm_cache_metadata *cmd,
|
|||
|
||||
int dm_cache_commit(struct dm_cache_metadata *cmd, bool clean_shutdown)
|
||||
{
|
||||
int r;
|
||||
int r = -EINVAL;
|
||||
flags_mutator mutator = (clean_shutdown ? set_clean_shutdown :
|
||||
clear_clean_shutdown);
|
||||
|
||||
WRITE_LOCK(cmd);
|
||||
if (cmd->fail_io)
|
||||
goto out;
|
||||
|
||||
r = __commit_transaction(cmd, mutator);
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
r = __begin_transaction(cmd);
|
||||
|
||||
out:
|
||||
WRITE_UNLOCK(cmd);
|
||||
return r;
|
||||
|
|
@ -1348,7 +1350,8 @@ int dm_cache_get_free_metadata_block_count(struct dm_cache_metadata *cmd,
|
|||
int r = -EINVAL;
|
||||
|
||||
READ_LOCK(cmd);
|
||||
r = dm_sm_get_nr_free(cmd->metadata_sm, result);
|
||||
if (!cmd->fail_io)
|
||||
r = dm_sm_get_nr_free(cmd->metadata_sm, result);
|
||||
READ_UNLOCK(cmd);
|
||||
|
||||
return r;
|
||||
|
|
@ -1360,7 +1363,8 @@ int dm_cache_get_metadata_dev_size(struct dm_cache_metadata *cmd,
|
|||
int r = -EINVAL;
|
||||
|
||||
READ_LOCK(cmd);
|
||||
r = dm_sm_get_nr_blocks(cmd->metadata_sm, result);
|
||||
if (!cmd->fail_io)
|
||||
r = dm_sm_get_nr_blocks(cmd->metadata_sm, result);
|
||||
READ_UNLOCK(cmd);
|
||||
|
||||
return r;
|
||||
|
|
|
|||
|
|
@ -961,18 +961,18 @@ static int metadata_commit(struct era_metadata *md)
|
|||
}
|
||||
}
|
||||
|
||||
r = save_sm_root(md);
|
||||
if (r) {
|
||||
DMERR("%s: save_sm_root failed", __func__);
|
||||
return r;
|
||||
}
|
||||
|
||||
r = dm_tm_pre_commit(md->tm);
|
||||
if (r) {
|
||||
DMERR("%s: pre commit failed", __func__);
|
||||
return r;
|
||||
}
|
||||
|
||||
r = save_sm_root(md);
|
||||
if (r) {
|
||||
DMERR("%s: save_sm_root failed", __func__);
|
||||
return r;
|
||||
}
|
||||
|
||||
r = superblock_lock(md, &sblock);
|
||||
if (r) {
|
||||
DMERR("%s: superblock lock failed", __func__);
|
||||
|
|
|
|||
|
|
@ -1843,7 +1843,7 @@ static int ctl_ioctl(uint command, struct dm_ioctl __user *user)
|
|||
if (r)
|
||||
goto out;
|
||||
|
||||
param->data_size = sizeof(*param);
|
||||
param->data_size = offsetof(struct dm_ioctl, data);
|
||||
r = fn(param, input_param_size);
|
||||
|
||||
if (unlikely(param->flags & DM_BUFFER_FULL_FLAG) &&
|
||||
|
|
|
|||
|
|
@ -485,11 +485,11 @@ static int __write_initial_superblock(struct dm_pool_metadata *pmd)
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = save_sm_roots(pmd);
|
||||
r = dm_tm_pre_commit(pmd->tm);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = dm_tm_pre_commit(pmd->tm);
|
||||
r = save_sm_roots(pmd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
|
|
|||
|
|
@ -12,11 +12,14 @@
|
|||
|
||||
#define DM_MSG_PREFIX "verity-avb"
|
||||
|
||||
/* Set via module parameter. */
|
||||
/* Set via module parameters. */
|
||||
static char avb_vbmeta_device[64];
|
||||
static char avb_invalidate_on_error[4];
|
||||
|
||||
static void invalidate_vbmeta_endio(struct bio *bio)
|
||||
{
|
||||
if (bio->bi_error)
|
||||
DMERR("invalidate_vbmeta_endio: error %d", bio->bi_error);
|
||||
complete(bio->bi_private);
|
||||
}
|
||||
|
||||
|
|
@ -30,20 +33,19 @@ static int invalidate_vbmeta_submit(struct bio *bio,
|
|||
bio->bi_private = &wait;
|
||||
bio->bi_end_io = invalidate_vbmeta_endio;
|
||||
bio->bi_bdev = bdev;
|
||||
bio->bi_rw = rw;
|
||||
|
||||
bio->bi_iter.bi_sector = 0;
|
||||
if (access_last_sector) {
|
||||
sector_t last_sector = (i_size_read(bdev->bd_inode)>>SECTOR_SHIFT) - 1;
|
||||
sector_t last_sector;
|
||||
|
||||
last_sector = (i_size_read(bdev->bd_inode)>>SECTOR_SHIFT) - 1;
|
||||
bio->bi_iter.bi_sector = last_sector;
|
||||
}
|
||||
bio->bi_vcnt = 1;
|
||||
bio->bi_iter.bi_idx = 0;
|
||||
bio->bi_iter.bi_size = 512;
|
||||
bio->bi_iter.bi_bvec_done = 0;
|
||||
bio->bi_rw = rw;
|
||||
bio->bi_io_vec[0].bv_page = page;
|
||||
bio->bi_io_vec[0].bv_len = 512;
|
||||
bio->bi_io_vec[0].bv_offset = 0;
|
||||
if (!bio_add_page(bio, page, PAGE_SIZE, 0)) {
|
||||
DMERR("invalidate_vbmeta_submit: bio_add_page error");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
submit_bio(rw, bio);
|
||||
/* Wait up to 2 seconds for completion or fail. */
|
||||
|
|
@ -65,6 +67,9 @@ static int invalidate_vbmeta(dev_t vbmeta_devt)
|
|||
int rw = REQ_SYNC | REQ_SOFTBARRIER | REQ_NOIDLE;
|
||||
int access_last_sector = 0;
|
||||
|
||||
DMINFO("invalidate_vbmeta: acting on device %d:%d",
|
||||
MAJOR(vbmeta_devt), MINOR(vbmeta_devt));
|
||||
|
||||
/* First we open the device for reading. */
|
||||
dev_mode = FMODE_READ | FMODE_EXCL;
|
||||
bdev = blkdev_get_by_dev(vbmeta_devt, dev_mode,
|
||||
|
|
@ -115,7 +120,7 @@ static int invalidate_vbmeta(dev_t vbmeta_devt)
|
|||
goto failed_to_submit_read;
|
||||
}
|
||||
if (memcmp("AVBf", page_address(page) + offset, 4) != 0) {
|
||||
DMERR("invalidate_vbmeta called on non-vbmeta partition");
|
||||
DMERR("invalidate_vbmeta on non-vbmeta partition");
|
||||
ret = -EINVAL;
|
||||
goto invalid_header;
|
||||
}
|
||||
|
|
@ -175,6 +180,11 @@ void dm_verity_avb_error_handler(void)
|
|||
|
||||
DMINFO("AVB error handler called for %s", avb_vbmeta_device);
|
||||
|
||||
if (strcmp(avb_invalidate_on_error, "yes") != 0) {
|
||||
DMINFO("Not configured to invalidate");
|
||||
return;
|
||||
}
|
||||
|
||||
if (avb_vbmeta_device[0] == '\0') {
|
||||
DMERR("avb_vbmeta_device parameter not set");
|
||||
goto fail_no_dev;
|
||||
|
|
@ -215,3 +225,5 @@ MODULE_LICENSE("GPL");
|
|||
#undef MODULE_PARAM_PREFIX
|
||||
#define MODULE_PARAM_PREFIX "androidboot.vbmeta."
|
||||
module_param_string(device, avb_vbmeta_device, sizeof(avb_vbmeta_device), 0);
|
||||
module_param_string(invalidate_on_error, avb_invalidate_on_error,
|
||||
sizeof(avb_invalidate_on_error), 0);
|
||||
|
|
|
|||
|
|
@ -887,8 +887,12 @@ static int find_key(struct ro_spine *s, dm_block_t block, bool find_highest,
|
|||
else
|
||||
*result_key = le64_to_cpu(ro_node(s)->keys[0]);
|
||||
|
||||
if (next_block || flags & INTERNAL_NODE)
|
||||
block = value64(ro_node(s), i);
|
||||
if (next_block || flags & INTERNAL_NODE) {
|
||||
if (find_highest)
|
||||
block = value64(ro_node(s), i);
|
||||
else
|
||||
block = value64(ro_node(s), 0);
|
||||
}
|
||||
|
||||
} while (flags & INTERNAL_NODE);
|
||||
|
||||
|
|
|
|||
|
|
@ -142,10 +142,23 @@ static int sm_disk_inc_block(struct dm_space_map *sm, dm_block_t b)
|
|||
|
||||
static int sm_disk_dec_block(struct dm_space_map *sm, dm_block_t b)
|
||||
{
|
||||
int r;
|
||||
uint32_t old_count;
|
||||
enum allocation_event ev;
|
||||
struct sm_disk *smd = container_of(sm, struct sm_disk, sm);
|
||||
|
||||
return sm_ll_dec(&smd->ll, b, &ev);
|
||||
r = sm_ll_dec(&smd->ll, b, &ev);
|
||||
if (!r && (ev == SM_FREE)) {
|
||||
/*
|
||||
* It's only free if it's also free in the last
|
||||
* transaction.
|
||||
*/
|
||||
r = sm_ll_lookup(&smd->old_ll, b, &old_count);
|
||||
if (!r && !old_count)
|
||||
smd->nr_allocated_this_transaction--;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int sm_disk_new_block(struct dm_space_map *sm, dm_block_t *b)
|
||||
|
|
|
|||
|
|
@ -2232,6 +2232,10 @@ static int resize_stripes(struct r5conf *conf, int newsize)
|
|||
err = -ENOMEM;
|
||||
|
||||
mutex_unlock(&conf->cache_size_mutex);
|
||||
|
||||
conf->slab_cache = sc;
|
||||
conf->active_name = 1-conf->active_name;
|
||||
|
||||
/* Step 4, return new stripes to service */
|
||||
while(!list_empty(&newstripes)) {
|
||||
nsh = list_entry(newstripes.next, struct stripe_head, lru);
|
||||
|
|
@ -2249,8 +2253,6 @@ static int resize_stripes(struct r5conf *conf, int newsize)
|
|||
}
|
||||
/* critical section pass, GFP_NOIO no longer needed */
|
||||
|
||||
conf->slab_cache = sc;
|
||||
conf->active_name = 1-conf->active_name;
|
||||
if (!err)
|
||||
conf->pool_size = newsize;
|
||||
return err;
|
||||
|
|
|
|||
|
|
@ -2678,7 +2678,9 @@ static struct dvb_frontend_ops cxd2841er_dvbt_t2_ops = {
|
|||
FE_CAN_MUTE_TS |
|
||||
FE_CAN_2G_MODULATION,
|
||||
.frequency_min = 42000000,
|
||||
.frequency_max = 1002000000
|
||||
.frequency_max = 1002000000,
|
||||
.symbol_rate_min = 870000,
|
||||
.symbol_rate_max = 11700000
|
||||
},
|
||||
.init = cxd2841er_init_tc,
|
||||
.sleep = cxd2841er_sleep_tc,
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user