Merge tag 'v6.6-rc3' into android-mainline
Linux 6.6-rc3 Change-Id: I19580d450ccd09fa0685b8e3283de3c2ec09fd78 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -175,6 +175,8 @@ infrastructure:
|
||||
+------------------------------+---------+---------+
|
||||
| Name | bits | visible |
|
||||
+------------------------------+---------+---------+
|
||||
| SME | [27-24] | y |
|
||||
+------------------------------+---------+---------+
|
||||
| MTE | [11-8] | y |
|
||||
+------------------------------+---------+---------+
|
||||
| SSBS | [7-4] | y |
|
||||
@@ -288,8 +290,18 @@ infrastructure:
|
||||
+------------------------------+---------+---------+
|
||||
| Name | bits | visible |
|
||||
+------------------------------+---------+---------+
|
||||
| CSSC | [55-52] | y |
|
||||
+------------------------------+---------+---------+
|
||||
| RPRFM | [51-48] | y |
|
||||
+------------------------------+---------+---------+
|
||||
| BC | [23-20] | y |
|
||||
+------------------------------+---------+---------+
|
||||
| MOPS | [19-16] | y |
|
||||
+------------------------------+---------+---------+
|
||||
| APA3 | [15-12] | y |
|
||||
+------------------------------+---------+---------+
|
||||
| GPA3 | [11-8] | y |
|
||||
+------------------------------+---------+---------+
|
||||
| RPRES | [7-4] | y |
|
||||
+------------------------------+---------+---------+
|
||||
| WFXT | [3-0] | y |
|
||||
|
||||
@@ -305,6 +305,9 @@ HWCAP2_SMEF16F16
|
||||
HWCAP2_MOPS
|
||||
Functionality implied by ID_AA64ISAR2_EL1.MOPS == 0b0001.
|
||||
|
||||
HWCAP2_HBC
|
||||
Functionality implied by ID_AA64ISAR2_EL1.BC == 0b0001.
|
||||
|
||||
4. Unused AT_HWCAP bits
|
||||
-----------------------
|
||||
|
||||
|
||||
@@ -381,9 +381,9 @@ Documentation of LoongArch ISA:
|
||||
|
||||
Documentation of LoongArch ELF psABI:
|
||||
|
||||
https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-ELF-ABI-v2.00-CN.pdf (in Chinese)
|
||||
https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-ELF-ABI-v2.01-CN.pdf (in Chinese)
|
||||
|
||||
https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-ELF-ABI-v2.00-EN.pdf (in English)
|
||||
https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-ELF-ABI-v2.01-EN.pdf (in English)
|
||||
|
||||
Linux kernel repository of Loongson and LoongArch:
|
||||
|
||||
|
||||
@@ -7,9 +7,9 @@ AX.25
|
||||
To use the amateur radio protocols within Linux you will need to get a
|
||||
suitable copy of the AX.25 Utilities. More detailed information about
|
||||
AX.25, NET/ROM and ROSE, associated programs and utilities can be
|
||||
found on http://www.linux-ax25.org.
|
||||
found on https://linux-ax25.in-berlin.de.
|
||||
|
||||
There is an active mailing list for discussing Linux amateur radio matters
|
||||
There is a mailing list for discussing Linux amateur radio matters
|
||||
called linux-hams@vger.kernel.org. To subscribe to it, send a message to
|
||||
majordomo@vger.kernel.org with the words "subscribe linux-hams" in the body
|
||||
of the message, the subject field is ignored. You don't need to be
|
||||
|
||||
@@ -74,8 +74,8 @@ topology based on those information. When the device is older and
|
||||
doesn't respond to the new UMP inquiries, the driver falls back and
|
||||
builds the topology based on Group Terminal Block (GTB) information
|
||||
from the USB descriptor. Some device might be screwed up by the
|
||||
unexpected UMP command; in such a case, pass `midi2_probe=0` option to
|
||||
snd-usb-audio driver for skipping the UMP v1.1 inquiries.
|
||||
unexpected UMP command; in such a case, pass `midi2_ump_probe=0`
|
||||
option to snd-usb-audio driver for skipping the UMP v1.1 inquiries.
|
||||
|
||||
When the MIDI 2.0 device is probed, the kernel creates a rawmidi
|
||||
device for each UMP Endpoint of the device. Its device name is
|
||||
|
||||
@@ -344,9 +344,9 @@ LoongArch指令集架构的文档:
|
||||
|
||||
LoongArch的ELF psABI文档:
|
||||
|
||||
https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-ELF-ABI-v2.00-CN.pdf (中文版)
|
||||
https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-ELF-ABI-v2.01-CN.pdf (中文版)
|
||||
|
||||
https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-ELF-ABI-v2.00-EN.pdf (英文版)
|
||||
https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-ELF-ABI-v2.01-EN.pdf (英文版)
|
||||
|
||||
Loongson与LoongArch的Linux内核源码仓库:
|
||||
|
||||
|
||||
+9
-6
@@ -1662,7 +1662,7 @@ F: arch/arm*/include/asm/perf_event.h
|
||||
F: arch/arm*/kernel/hw_breakpoint.c
|
||||
F: arch/arm*/kernel/perf_*
|
||||
F: drivers/perf/
|
||||
F: include/linux/perf/arm_pmu.h
|
||||
F: include/linux/perf/arm_pmu*.h
|
||||
|
||||
ARM PORT
|
||||
M: Russell King <linux@armlinux.org.uk>
|
||||
@@ -3344,7 +3344,7 @@ AX.25 NETWORK LAYER
|
||||
M: Ralf Baechle <ralf@linux-mips.org>
|
||||
L: linux-hams@vger.kernel.org
|
||||
S: Maintained
|
||||
W: http://www.linux-ax25.org/
|
||||
W: https://linux-ax25.in-berlin.de
|
||||
F: include/net/ax25.h
|
||||
F: include/uapi/linux/ax25.h
|
||||
F: net/ax25/
|
||||
@@ -6645,7 +6645,6 @@ F: Documentation/devicetree/bindings/display/panel/novatek,nt36672a.yaml
|
||||
F: drivers/gpu/drm/panel/panel-novatek-nt36672a.c
|
||||
|
||||
DRM DRIVER FOR NVIDIA GEFORCE/QUADRO GPUS
|
||||
M: Ben Skeggs <bskeggs@redhat.com>
|
||||
M: Karol Herbst <kherbst@redhat.com>
|
||||
M: Lyude Paul <lyude@redhat.com>
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
@@ -8874,7 +8873,7 @@ F: drivers/gpio/gpio-mockup.c
|
||||
F: tools/testing/selftests/gpio/
|
||||
|
||||
GPIO REGMAP
|
||||
R: Michael Walle <michael@walle.cc>
|
||||
M: Michael Walle <michael@walle.cc>
|
||||
S: Maintained
|
||||
F: drivers/gpio/gpio-regmap.c
|
||||
F: include/linux/gpio/regmap.h
|
||||
@@ -13623,6 +13622,7 @@ F: drivers/net/ethernet/mellanox/mlxfw/
|
||||
|
||||
MELLANOX HARDWARE PLATFORM SUPPORT
|
||||
M: Hans de Goede <hdegoede@redhat.com>
|
||||
M: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
|
||||
M: Mark Gross <markgross@kernel.org>
|
||||
M: Vadim Pasternak <vadimp@nvidia.com>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
@@ -14217,6 +14217,7 @@ F: drivers/platform/surface/surface_gpe.c
|
||||
|
||||
MICROSOFT SURFACE HARDWARE PLATFORM SUPPORT
|
||||
M: Hans de Goede <hdegoede@redhat.com>
|
||||
M: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
|
||||
M: Mark Gross <markgross@kernel.org>
|
||||
M: Maximilian Luz <luzmaximilian@gmail.com>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
@@ -14763,7 +14764,7 @@ NETROM NETWORK LAYER
|
||||
M: Ralf Baechle <ralf@linux-mips.org>
|
||||
L: linux-hams@vger.kernel.org
|
||||
S: Maintained
|
||||
W: http://www.linux-ax25.org/
|
||||
W: https://linux-ax25.in-berlin.de
|
||||
F: include/net/netrom.h
|
||||
F: include/uapi/linux/netrom.h
|
||||
F: net/netrom/
|
||||
@@ -18614,7 +18615,7 @@ ROSE NETWORK LAYER
|
||||
M: Ralf Baechle <ralf@linux-mips.org>
|
||||
L: linux-hams@vger.kernel.org
|
||||
S: Maintained
|
||||
W: http://www.linux-ax25.org/
|
||||
W: https://linux-ax25.in-berlin.de
|
||||
F: include/net/rose.h
|
||||
F: include/uapi/linux/rose.h
|
||||
F: net/rose/
|
||||
@@ -23430,9 +23431,11 @@ F: drivers/platform/x86/x86-android-tablets/
|
||||
|
||||
X86 PLATFORM DRIVERS
|
||||
M: Hans de Goede <hdegoede@redhat.com>
|
||||
M: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
|
||||
M: Mark Gross <markgross@kernel.org>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
S: Maintained
|
||||
Q: https://patchwork.kernel.org/project/platform-driver-x86/list/
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git
|
||||
F: drivers/platform/olpc/
|
||||
F: drivers/platform/x86/
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
VERSION = 6
|
||||
PATCHLEVEL = 6
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc2
|
||||
EXTRAVERSION = -rc3
|
||||
NAME = Hurr durr I'ma ninja sloth
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
||||
@@ -207,7 +207,7 @@ static void xen_power_off(void)
|
||||
|
||||
static irqreturn_t xen_arm_callback(int irq, void *arg)
|
||||
{
|
||||
xen_hvm_evtchn_do_upcall();
|
||||
xen_evtchn_do_upcall();
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
||||
@@ -663,7 +663,7 @@ static inline bool supports_clearbhb(int scope)
|
||||
isar2 = read_sanitised_ftr_reg(SYS_ID_AA64ISAR2_EL1);
|
||||
|
||||
return cpuid_feature_extract_unsigned_field(isar2,
|
||||
ID_AA64ISAR2_EL1_BC_SHIFT);
|
||||
ID_AA64ISAR2_EL1_CLRBHB_SHIFT);
|
||||
}
|
||||
|
||||
const struct cpumask *system_32bit_el0_cpumask(void);
|
||||
|
||||
@@ -118,7 +118,7 @@ void deactivate_traps_vhe_put(struct kvm_vcpu *vcpu);
|
||||
|
||||
u64 __guest_enter(struct kvm_vcpu *vcpu);
|
||||
|
||||
bool kvm_host_psci_handler(struct kvm_cpu_context *host_ctxt);
|
||||
bool kvm_host_psci_handler(struct kvm_cpu_context *host_ctxt, u32 func_id);
|
||||
|
||||
#ifdef __KVM_NVHE_HYPERVISOR__
|
||||
void __noreturn __hyp_do_panic(struct kvm_cpu_context *host_ctxt, u64 spsr,
|
||||
|
||||
@@ -222,7 +222,8 @@ static const struct arm64_ftr_bits ftr_id_aa64isar1[] = {
|
||||
static const struct arm64_ftr_bits ftr_id_aa64isar2[] = {
|
||||
ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_CSSC_SHIFT, 4, 0),
|
||||
ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_RPRFM_SHIFT, 4, 0),
|
||||
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_HIGHER_SAFE, ID_AA64ISAR2_EL1_BC_SHIFT, 4, 0),
|
||||
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_CLRBHB_SHIFT, 4, 0),
|
||||
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_BC_SHIFT, 4, 0),
|
||||
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_MOPS_SHIFT, 4, 0),
|
||||
ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_PTR_AUTH),
|
||||
FTR_STRICT, FTR_EXACT, ID_AA64ISAR2_EL1_APA3_SHIFT, 4, 0),
|
||||
|
||||
@@ -12,6 +12,6 @@
|
||||
#define FFA_MAX_FUNC_NUM 0x7F
|
||||
|
||||
int hyp_ffa_init(void *pages);
|
||||
bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt);
|
||||
bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id);
|
||||
|
||||
#endif /* __KVM_HYP_FFA_H */
|
||||
|
||||
@@ -634,9 +634,8 @@ out_handled:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt)
|
||||
bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
|
||||
{
|
||||
DECLARE_REG(u64, func_id, host_ctxt, 0);
|
||||
struct arm_smccc_res res;
|
||||
|
||||
/*
|
||||
|
||||
@@ -57,6 +57,7 @@ __do_hyp_init:
|
||||
cmp x0, #HVC_STUB_HCALL_NR
|
||||
b.lo __kvm_handle_stub_hvc
|
||||
|
||||
bic x0, x0, #ARM_SMCCC_CALL_HINTS
|
||||
mov x3, #KVM_HOST_SMCCC_FUNC(__kvm_hyp_init)
|
||||
cmp x0, x3
|
||||
b.eq 1f
|
||||
|
||||
@@ -368,6 +368,7 @@ static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
|
||||
if (static_branch_unlikely(&kvm_protected_mode_initialized))
|
||||
hcall_min = __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize;
|
||||
|
||||
id &= ~ARM_SMCCC_CALL_HINTS;
|
||||
id -= KVM_HOST_SMCCC_ID(0);
|
||||
|
||||
if (unlikely(id < hcall_min || id >= ARRAY_SIZE(host_hcall)))
|
||||
@@ -392,11 +393,14 @@ static void default_host_smc_handler(struct kvm_cpu_context *host_ctxt)
|
||||
|
||||
static void handle_host_smc(struct kvm_cpu_context *host_ctxt)
|
||||
{
|
||||
DECLARE_REG(u64, func_id, host_ctxt, 0);
|
||||
bool handled;
|
||||
|
||||
handled = kvm_host_psci_handler(host_ctxt);
|
||||
func_id &= ~ARM_SMCCC_CALL_HINTS;
|
||||
|
||||
handled = kvm_host_psci_handler(host_ctxt, func_id);
|
||||
if (!handled)
|
||||
handled = kvm_host_ffa_handler(host_ctxt);
|
||||
handled = kvm_host_ffa_handler(host_ctxt, func_id);
|
||||
if (!handled)
|
||||
default_host_smc_handler(host_ctxt);
|
||||
|
||||
|
||||
@@ -273,9 +273,8 @@ static unsigned long psci_1_0_handler(u64 func_id, struct kvm_cpu_context *host_
|
||||
}
|
||||
}
|
||||
|
||||
bool kvm_host_psci_handler(struct kvm_cpu_context *host_ctxt)
|
||||
bool kvm_host_psci_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
|
||||
{
|
||||
DECLARE_REG(u64, func_id, host_ctxt, 0);
|
||||
unsigned long ret;
|
||||
|
||||
switch (kvm_host_psci_config.version) {
|
||||
|
||||
@@ -652,6 +652,9 @@ int hyp_alloc_private_va_range(size_t size, unsigned long *haddr)
|
||||
|
||||
mutex_unlock(&kvm_hyp_pgd_mutex);
|
||||
|
||||
if (!ret)
|
||||
*haddr = base;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -1347,7 +1347,11 @@ UnsignedEnum 51:48 RPRFM
|
||||
0b0000 NI
|
||||
0b0001 IMP
|
||||
EndEnum
|
||||
Res0 47:28
|
||||
Res0 47:32
|
||||
UnsignedEnum 31:28 CLRBHB
|
||||
0b0000 NI
|
||||
0b0001 IMP
|
||||
EndEnum
|
||||
UnsignedEnum 27:24 PAC_frac
|
||||
0b0000 NI
|
||||
0b0001 IMP
|
||||
|
||||
@@ -907,3 +907,7 @@ EXPORT_SYMBOL(acpi_unregister_ioapic);
|
||||
* TBD when IA64 starts to support suspend...
|
||||
*/
|
||||
int acpi_suspend_lowlevel(void) { return 0; }
|
||||
|
||||
void acpi_proc_quirk_mwait_check(void)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
*/
|
||||
#ifndef __ASSEMBLY__
|
||||
#ifndef PHYS_OFFSET
|
||||
#define PHYS_OFFSET _AC(0, UL)
|
||||
#define PHYS_OFFSET _UL(0)
|
||||
#endif
|
||||
extern unsigned long vm_map_base;
|
||||
#endif /* __ASSEMBLY__ */
|
||||
@@ -43,7 +43,7 @@ extern unsigned long vm_map_base;
|
||||
* Memory above this physical address will be considered highmem.
|
||||
*/
|
||||
#ifndef HIGHMEM_START
|
||||
#define HIGHMEM_START (_AC(1, UL) << _AC(DMW_PABITS, UL))
|
||||
#define HIGHMEM_START (_UL(1) << _UL(DMW_PABITS))
|
||||
#endif
|
||||
|
||||
#define TO_PHYS(x) ( ((x) & TO_PHYS_MASK))
|
||||
@@ -65,16 +65,16 @@ extern unsigned long vm_map_base;
|
||||
#define _ATYPE_
|
||||
#define _ATYPE32_
|
||||
#define _ATYPE64_
|
||||
#define _CONST64_(x) x
|
||||
#else
|
||||
#define _ATYPE_ __PTRDIFF_TYPE__
|
||||
#define _ATYPE32_ int
|
||||
#define _ATYPE64_ __s64
|
||||
#ifdef CONFIG_64BIT
|
||||
#define _CONST64_(x) x ## UL
|
||||
#else
|
||||
#define _CONST64_(x) x ## ULL
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
#define _CONST64_(x) _UL(x)
|
||||
#else
|
||||
#define _CONST64_(x) _ULL(x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef __ASM_EXCEPTION_H
|
||||
#define __ASM_EXCEPTION_H
|
||||
|
||||
#include <asm/ptrace.h>
|
||||
#include <linux/kprobes.h>
|
||||
|
||||
void show_registers(struct pt_regs *regs);
|
||||
|
||||
asmlinkage void cache_parity_error(void);
|
||||
asmlinkage void noinstr do_ade(struct pt_regs *regs);
|
||||
asmlinkage void noinstr do_ale(struct pt_regs *regs);
|
||||
asmlinkage void noinstr do_bce(struct pt_regs *regs);
|
||||
asmlinkage void noinstr do_bp(struct pt_regs *regs);
|
||||
asmlinkage void noinstr do_ri(struct pt_regs *regs);
|
||||
asmlinkage void noinstr do_fpu(struct pt_regs *regs);
|
||||
asmlinkage void noinstr do_fpe(struct pt_regs *regs, unsigned long fcsr);
|
||||
asmlinkage void noinstr do_lsx(struct pt_regs *regs);
|
||||
asmlinkage void noinstr do_lasx(struct pt_regs *regs);
|
||||
asmlinkage void noinstr do_lbt(struct pt_regs *regs);
|
||||
asmlinkage void noinstr do_watch(struct pt_regs *regs);
|
||||
asmlinkage void noinstr do_syscall(struct pt_regs *regs);
|
||||
asmlinkage void noinstr do_reserved(struct pt_regs *regs);
|
||||
asmlinkage void noinstr do_vint(struct pt_regs *regs, unsigned long sp);
|
||||
asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
|
||||
unsigned long write, unsigned long address);
|
||||
|
||||
asmlinkage void handle_ade(void);
|
||||
asmlinkage void handle_ale(void);
|
||||
asmlinkage void handle_bce(void);
|
||||
asmlinkage void handle_sys(void);
|
||||
asmlinkage void handle_bp(void);
|
||||
asmlinkage void handle_ri(void);
|
||||
asmlinkage void handle_fpu(void);
|
||||
asmlinkage void handle_fpe(void);
|
||||
asmlinkage void handle_lsx(void);
|
||||
asmlinkage void handle_lasx(void);
|
||||
asmlinkage void handle_lbt(void);
|
||||
asmlinkage void handle_watch(void);
|
||||
asmlinkage void handle_reserved(void);
|
||||
asmlinkage void handle_vint(void);
|
||||
asmlinkage void noinstr handle_loongarch_irq(struct pt_regs *regs);
|
||||
|
||||
#endif /* __ASM_EXCEPTION_H */
|
||||
@@ -10,8 +10,6 @@
|
||||
#include <asm/io.h>
|
||||
#include <asm/pgtable.h>
|
||||
|
||||
#define __HAVE_ARCH_SHADOW_MAP
|
||||
|
||||
#define KASAN_SHADOW_SCALE_SHIFT 3
|
||||
#define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL)
|
||||
|
||||
@@ -62,61 +60,22 @@
|
||||
extern bool kasan_early_stage;
|
||||
extern unsigned char kasan_early_shadow_page[PAGE_SIZE];
|
||||
|
||||
#define kasan_mem_to_shadow kasan_mem_to_shadow
|
||||
void *kasan_mem_to_shadow(const void *addr);
|
||||
|
||||
#define kasan_shadow_to_mem kasan_shadow_to_mem
|
||||
const void *kasan_shadow_to_mem(const void *shadow_addr);
|
||||
|
||||
#define kasan_arch_is_ready kasan_arch_is_ready
|
||||
static __always_inline bool kasan_arch_is_ready(void)
|
||||
{
|
||||
return !kasan_early_stage;
|
||||
}
|
||||
|
||||
static inline void *kasan_mem_to_shadow(const void *addr)
|
||||
#define addr_has_metadata addr_has_metadata
|
||||
static __always_inline bool addr_has_metadata(const void *addr)
|
||||
{
|
||||
if (!kasan_arch_is_ready()) {
|
||||
return (void *)(kasan_early_shadow_page);
|
||||
} else {
|
||||
unsigned long maddr = (unsigned long)addr;
|
||||
unsigned long xrange = (maddr >> XRANGE_SHIFT) & 0xffff;
|
||||
unsigned long offset = 0;
|
||||
|
||||
maddr &= XRANGE_SHADOW_MASK;
|
||||
switch (xrange) {
|
||||
case XKPRANGE_CC_SEG:
|
||||
offset = XKPRANGE_CC_SHADOW_OFFSET;
|
||||
break;
|
||||
case XKPRANGE_UC_SEG:
|
||||
offset = XKPRANGE_UC_SHADOW_OFFSET;
|
||||
break;
|
||||
case XKVRANGE_VC_SEG:
|
||||
offset = XKVRANGE_VC_SHADOW_OFFSET;
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (void *)((maddr >> KASAN_SHADOW_SCALE_SHIFT) + offset);
|
||||
}
|
||||
}
|
||||
|
||||
static inline const void *kasan_shadow_to_mem(const void *shadow_addr)
|
||||
{
|
||||
unsigned long addr = (unsigned long)shadow_addr;
|
||||
|
||||
if (unlikely(addr > KASAN_SHADOW_END) ||
|
||||
unlikely(addr < KASAN_SHADOW_START)) {
|
||||
WARN_ON(1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (addr >= XKVRANGE_VC_SHADOW_OFFSET)
|
||||
return (void *)(((addr - XKVRANGE_VC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKVRANGE_VC_START);
|
||||
else if (addr >= XKPRANGE_UC_SHADOW_OFFSET)
|
||||
return (void *)(((addr - XKPRANGE_UC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKPRANGE_UC_START);
|
||||
else if (addr >= XKPRANGE_CC_SHADOW_OFFSET)
|
||||
return (void *)(((addr - XKPRANGE_CC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKPRANGE_CC_START);
|
||||
else {
|
||||
WARN_ON(1);
|
||||
return NULL;
|
||||
}
|
||||
return (kasan_mem_to_shadow((void *)addr) != NULL);
|
||||
}
|
||||
|
||||
void kasan_init(void);
|
||||
|
||||
@@ -70,6 +70,7 @@ struct secondary_data {
|
||||
extern struct secondary_data cpuboot_data;
|
||||
|
||||
extern asmlinkage void smpboot_entry(void);
|
||||
extern asmlinkage void start_secondary(void);
|
||||
|
||||
extern void calculate_cpu_foreign_map(void);
|
||||
|
||||
|
||||
@@ -19,6 +19,10 @@ obj-$(CONFIG_CPU_HAS_LBT) += lbt.o
|
||||
|
||||
obj-$(CONFIG_ARCH_STRICT_ALIGN) += unaligned.o
|
||||
|
||||
CFLAGS_module.o += $(call cc-option,-Wno-override-init,)
|
||||
CFLAGS_syscall.o += $(call cc-option,-Wno-override-init,)
|
||||
CFLAGS_perf_event.o += $(call cc-option,-Wno-override-init,)
|
||||
|
||||
ifdef CONFIG_FUNCTION_TRACER
|
||||
ifndef CONFIG_DYNAMIC_FTRACE
|
||||
obj-y += mcount.o ftrace.o
|
||||
|
||||
@@ -281,7 +281,6 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
|
||||
pr_info("SRAT: PXM %u -> CPU 0x%02x -> Node %u\n", pxm, pa->apic_id, node);
|
||||
}
|
||||
|
||||
void __init acpi_numa_arch_fixup(void) {}
|
||||
#endif
|
||||
|
||||
void __init arch_reserve_mem_area(acpi_physical_address addr, size_t size)
|
||||
|
||||
@@ -50,7 +50,6 @@ void __init memblock_init(void)
|
||||
}
|
||||
|
||||
memblock_set_current_limit(PFN_PHYS(max_low_pfn));
|
||||
memblock_set_node(0, PHYS_ADDR_MAX, &memblock.memory, 0);
|
||||
|
||||
/* Reserve the first 2MB */
|
||||
memblock_reserve(PHYS_OFFSET, 0x200000);
|
||||
@@ -58,4 +57,7 @@ void __init memblock_init(void)
|
||||
/* Reserve the kernel text/data/bss */
|
||||
memblock_reserve(__pa_symbol(&_text),
|
||||
__pa_symbol(&_end) - __pa_symbol(&_text));
|
||||
|
||||
memblock_set_node(0, PHYS_ADDR_MAX, &memblock.memory, 0);
|
||||
memblock_set_node(0, PHYS_ADDR_MAX, &memblock.reserved, 0);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <linux/elf.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleloader.h>
|
||||
#include <linux/ftrace.h>
|
||||
|
||||
Elf_Addr module_emit_got_entry(struct module *mod, Elf_Shdr *sechdrs, Elf_Addr val)
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/elf.h>
|
||||
#include <asm/exec.h>
|
||||
#include <asm/fpu.h>
|
||||
#include <asm/lbt.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
@@ -72,7 +72,6 @@ copy_word:
|
||||
LONG_ADDI s5, s5, -1
|
||||
beqz s5, process_entry
|
||||
b copy_word
|
||||
b process_entry
|
||||
|
||||
done:
|
||||
ibar 0
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <linux/audit.h>
|
||||
#include <linux/cache.h>
|
||||
#include <linux/context_tracking.h>
|
||||
#include <linux/entry-common.h>
|
||||
#include <linux/irqflags.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mm.h>
|
||||
@@ -891,8 +892,8 @@ static unsigned long setup_extcontext(struct extctx_layout *extctx, unsigned lon
|
||||
return new_sp;
|
||||
}
|
||||
|
||||
void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
|
||||
struct extctx_layout *extctx)
|
||||
static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
|
||||
struct extctx_layout *extctx)
|
||||
{
|
||||
unsigned long sp;
|
||||
|
||||
@@ -922,7 +923,7 @@ void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
|
||||
* Atomically swap in the new signal mask, and wait for a signal.
|
||||
*/
|
||||
|
||||
asmlinkage long sys_rt_sigreturn(void)
|
||||
SYSCALL_DEFINE0(rt_sigreturn)
|
||||
{
|
||||
int sig;
|
||||
sigset_t set;
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/profile.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/threads.h>
|
||||
@@ -556,10 +557,12 @@ void smp_send_stop(void)
|
||||
smp_call_function(stop_this_cpu, NULL, 0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PROFILING
|
||||
int setup_profiling_timer(unsigned int multiplier)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void flush_tlb_all_ipi(void *info)
|
||||
{
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <linux/unistd.h>
|
||||
|
||||
#include <asm/asm.h>
|
||||
#include <asm/exception.h>
|
||||
#include <asm/signal.h>
|
||||
#include <asm/switch_to.h>
|
||||
#include <asm-generic/syscalls.h>
|
||||
|
||||
@@ -29,7 +29,7 @@ static void constant_event_handler(struct clock_event_device *dev)
|
||||
{
|
||||
}
|
||||
|
||||
irqreturn_t constant_timer_interrupt(int irq, void *data)
|
||||
static irqreturn_t constant_timer_interrupt(int irq, void *data)
|
||||
{
|
||||
int cpu = smp_processor_id();
|
||||
struct clock_event_device *cd;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/init.h>
|
||||
@@ -7,6 +8,8 @@
|
||||
#include <linux/percpu.h>
|
||||
#include <asm/bootinfo.h>
|
||||
|
||||
#include <acpi/processor.h>
|
||||
|
||||
static DEFINE_PER_CPU(struct cpu, cpu_devices);
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/kgdb.h>
|
||||
#include <linux/kdebug.h>
|
||||
#include <linux/kprobes.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/perf_event.h>
|
||||
@@ -35,6 +34,7 @@
|
||||
#include <asm/branch.h>
|
||||
#include <asm/break.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/exception.h>
|
||||
#include <asm/fpu.h>
|
||||
#include <asm/lbt.h>
|
||||
#include <asm/inst.h>
|
||||
@@ -53,21 +53,6 @@
|
||||
|
||||
#include "access-helper.h"
|
||||
|
||||
extern asmlinkage void handle_ade(void);
|
||||
extern asmlinkage void handle_ale(void);
|
||||
extern asmlinkage void handle_bce(void);
|
||||
extern asmlinkage void handle_sys(void);
|
||||
extern asmlinkage void handle_bp(void);
|
||||
extern asmlinkage void handle_ri(void);
|
||||
extern asmlinkage void handle_fpu(void);
|
||||
extern asmlinkage void handle_fpe(void);
|
||||
extern asmlinkage void handle_lbt(void);
|
||||
extern asmlinkage void handle_lsx(void);
|
||||
extern asmlinkage void handle_lasx(void);
|
||||
extern asmlinkage void handle_reserved(void);
|
||||
extern asmlinkage void handle_watch(void);
|
||||
extern asmlinkage void handle_vint(void);
|
||||
|
||||
static void show_backtrace(struct task_struct *task, const struct pt_regs *regs,
|
||||
const char *loglvl, bool user)
|
||||
{
|
||||
@@ -439,8 +424,8 @@ static inline void setup_vint_size(unsigned int size)
|
||||
* happen together with Overflow or Underflow, and `ptrace' can set
|
||||
* any bits.
|
||||
*/
|
||||
void force_fcsr_sig(unsigned long fcsr, void __user *fault_addr,
|
||||
struct task_struct *tsk)
|
||||
static void force_fcsr_sig(unsigned long fcsr,
|
||||
void __user *fault_addr, struct task_struct *tsk)
|
||||
{
|
||||
int si_code = FPE_FLTUNK;
|
||||
|
||||
@@ -458,7 +443,7 @@ void force_fcsr_sig(unsigned long fcsr, void __user *fault_addr,
|
||||
force_sig_fault(SIGFPE, si_code, fault_addr);
|
||||
}
|
||||
|
||||
int process_fpemu_return(int sig, void __user *fault_addr, unsigned long fcsr)
|
||||
static int process_fpemu_return(int sig, void __user *fault_addr, unsigned long fcsr)
|
||||
{
|
||||
int si_code;
|
||||
|
||||
@@ -824,7 +809,7 @@ out:
|
||||
asmlinkage void noinstr do_ri(struct pt_regs *regs)
|
||||
{
|
||||
int status = SIGILL;
|
||||
unsigned int opcode = 0;
|
||||
unsigned int __maybe_unused opcode;
|
||||
unsigned int __user *era = (unsigned int __user *)exception_era(regs);
|
||||
irqentry_state_t state = irqentry_enter(regs);
|
||||
|
||||
|
||||
@@ -53,33 +53,6 @@ SECTIONS
|
||||
. = ALIGN(PECOFF_SEGMENT_ALIGN);
|
||||
_etext = .;
|
||||
|
||||
/*
|
||||
* struct alt_inst entries. From the header (alternative.h):
|
||||
* "Alternative instructions for different CPU types or capabilities"
|
||||
* Think locking instructions on spinlocks.
|
||||
*/
|
||||
. = ALIGN(4);
|
||||
.altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
|
||||
__alt_instructions = .;
|
||||
*(.altinstructions)
|
||||
__alt_instructions_end = .;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_RELOCATABLE
|
||||
. = ALIGN(8);
|
||||
.la_abs : AT(ADDR(.la_abs) - LOAD_OFFSET) {
|
||||
__la_abs_begin = .;
|
||||
*(.la_abs)
|
||||
__la_abs_end = .;
|
||||
}
|
||||
#endif
|
||||
|
||||
.got : ALIGN(16) { *(.got) }
|
||||
.plt : ALIGN(16) { *(.plt) }
|
||||
.got.plt : ALIGN(16) { *(.got.plt) }
|
||||
|
||||
.data.rel : { *(.data.rel*) }
|
||||
|
||||
. = ALIGN(PECOFF_SEGMENT_ALIGN);
|
||||
__init_begin = .;
|
||||
__inittext_begin = .;
|
||||
@@ -94,6 +67,18 @@ SECTIONS
|
||||
|
||||
__initdata_begin = .;
|
||||
|
||||
/*
|
||||
* struct alt_inst entries. From the header (alternative.h):
|
||||
* "Alternative instructions for different CPU types or capabilities"
|
||||
* Think locking instructions on spinlocks.
|
||||
*/
|
||||
. = ALIGN(4);
|
||||
.altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
|
||||
__alt_instructions = .;
|
||||
*(.altinstructions)
|
||||
__alt_instructions_end = .;
|
||||
}
|
||||
|
||||
INIT_DATA_SECTION(16)
|
||||
.exit.data : {
|
||||
EXIT_DATA
|
||||
@@ -113,6 +98,11 @@ SECTIONS
|
||||
|
||||
_sdata = .;
|
||||
RO_DATA(4096)
|
||||
|
||||
.got : ALIGN(16) { *(.got) }
|
||||
.plt : ALIGN(16) { *(.plt) }
|
||||
.got.plt : ALIGN(16) { *(.got.plt) }
|
||||
|
||||
RW_DATA(1 << CONFIG_L1_CACHE_SHIFT, PAGE_SIZE, THREAD_SIZE)
|
||||
|
||||
.rela.dyn : ALIGN(8) {
|
||||
@@ -121,6 +111,17 @@ SECTIONS
|
||||
__rela_dyn_end = .;
|
||||
}
|
||||
|
||||
.data.rel : { *(.data.rel*) }
|
||||
|
||||
#ifdef CONFIG_RELOCATABLE
|
||||
. = ALIGN(8);
|
||||
.la_abs : AT(ADDR(.la_abs) - LOAD_OFFSET) {
|
||||
__la_abs_begin = .;
|
||||
*(.la_abs)
|
||||
__la_abs_end = .;
|
||||
}
|
||||
#endif
|
||||
|
||||
.sdata : {
|
||||
*(.sdata)
|
||||
}
|
||||
|
||||
@@ -20,12 +20,12 @@
|
||||
#include <linux/mm.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/kdebug.h>
|
||||
#include <linux/kprobes.h>
|
||||
#include <linux/perf_event.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/kfence.h>
|
||||
|
||||
#include <asm/branch.h>
|
||||
#include <asm/exception.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
|
||||
@@ -50,18 +50,6 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr,
|
||||
return (pte_t *) pmd;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function checks for proper alignment of input addr and len parameters.
|
||||
*/
|
||||
int is_aligned_hugepage_range(unsigned long addr, unsigned long len)
|
||||
{
|
||||
if (len & ~HPAGE_MASK)
|
||||
return -EINVAL;
|
||||
if (addr & ~HPAGE_MASK)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pmd_huge(pmd_t pmd)
|
||||
{
|
||||
return (pmd_val(pmd) & _PAGE_HUGE) != 0;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
*/
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm-generic/early_ioremap.h>
|
||||
|
||||
void __init __iomem *early_ioremap(u64 phys_addr, unsigned long size)
|
||||
{
|
||||
|
||||
@@ -35,6 +35,57 @@ static pgd_t kasan_pg_dir[PTRS_PER_PGD] __initdata __aligned(PAGE_SIZE);
|
||||
|
||||
bool kasan_early_stage = true;
|
||||
|
||||
void *kasan_mem_to_shadow(const void *addr)
|
||||
{
|
||||
if (!kasan_arch_is_ready()) {
|
||||
return (void *)(kasan_early_shadow_page);
|
||||
} else {
|
||||
unsigned long maddr = (unsigned long)addr;
|
||||
unsigned long xrange = (maddr >> XRANGE_SHIFT) & 0xffff;
|
||||
unsigned long offset = 0;
|
||||
|
||||
maddr &= XRANGE_SHADOW_MASK;
|
||||
switch (xrange) {
|
||||
case XKPRANGE_CC_SEG:
|
||||
offset = XKPRANGE_CC_SHADOW_OFFSET;
|
||||
break;
|
||||
case XKPRANGE_UC_SEG:
|
||||
offset = XKPRANGE_UC_SHADOW_OFFSET;
|
||||
break;
|
||||
case XKVRANGE_VC_SEG:
|
||||
offset = XKVRANGE_VC_SHADOW_OFFSET;
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (void *)((maddr >> KASAN_SHADOW_SCALE_SHIFT) + offset);
|
||||
}
|
||||
}
|
||||
|
||||
const void *kasan_shadow_to_mem(const void *shadow_addr)
|
||||
{
|
||||
unsigned long addr = (unsigned long)shadow_addr;
|
||||
|
||||
if (unlikely(addr > KASAN_SHADOW_END) ||
|
||||
unlikely(addr < KASAN_SHADOW_START)) {
|
||||
WARN_ON(1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (addr >= XKVRANGE_VC_SHADOW_OFFSET)
|
||||
return (void *)(((addr - XKVRANGE_VC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKVRANGE_VC_START);
|
||||
else if (addr >= XKPRANGE_UC_SHADOW_OFFSET)
|
||||
return (void *)(((addr - XKPRANGE_UC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKPRANGE_UC_START);
|
||||
else if (addr >= XKPRANGE_CC_SHADOW_OFFSET)
|
||||
return (void *)(((addr - XKPRANGE_CC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKPRANGE_CC_START);
|
||||
else {
|
||||
WARN_ON(1);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Alloc memory for shadow memory page table.
|
||||
*/
|
||||
|
||||
@@ -261,7 +261,7 @@ unsigned long pcpu_handlers[NR_CPUS];
|
||||
#endif
|
||||
extern long exception_handlers[VECSIZE * 128 / sizeof(long)];
|
||||
|
||||
void setup_tlb_handler(int cpu)
|
||||
static void setup_tlb_handler(int cpu)
|
||||
{
|
||||
setup_ptwalker();
|
||||
local_flush_tlb_all();
|
||||
|
||||
@@ -255,7 +255,7 @@ config PPC
|
||||
select HAVE_KPROBES
|
||||
select HAVE_KPROBES_ON_FTRACE
|
||||
select HAVE_KRETPROBES
|
||||
select HAVE_LD_DEAD_CODE_DATA_ELIMINATION if HAVE_OBJTOOL_MCOUNT
|
||||
select HAVE_LD_DEAD_CODE_DATA_ELIMINATION if HAVE_OBJTOOL_MCOUNT && (!ARCH_USING_PATCHABLE_FUNCTION_ENTRY || (!CC_IS_GCC || GCC_VERSION >= 110100))
|
||||
select HAVE_LIVEPATCH if HAVE_DYNAMIC_FTRACE_WITH_REGS
|
||||
select HAVE_MOD_ARCH_SPECIFIC
|
||||
select HAVE_NMI if PERF_EVENTS || (PPC64 && PPC_BOOK3S)
|
||||
|
||||
@@ -230,13 +230,15 @@ void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs)
|
||||
struct arch_hw_breakpoint *info;
|
||||
int i;
|
||||
|
||||
preempt_disable();
|
||||
|
||||
for (i = 0; i < nr_wp_slots(); i++) {
|
||||
struct perf_event *bp = __this_cpu_read(bp_per_reg[i]);
|
||||
|
||||
if (unlikely(bp && counter_arch_bp(bp)->perf_single_step))
|
||||
goto reset;
|
||||
}
|
||||
return;
|
||||
goto out;
|
||||
|
||||
reset:
|
||||
regs_set_return_msr(regs, regs->msr & ~MSR_SE);
|
||||
@@ -245,6 +247,9 @@ reset:
|
||||
__set_breakpoint(i, info);
|
||||
info->perf_single_step = false;
|
||||
}
|
||||
|
||||
out:
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
static bool is_larx_stcx_instr(int type)
|
||||
@@ -363,6 +368,11 @@ static void handle_p10dd1_spurious_exception(struct perf_event **bp,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle a DABR or DAWR exception.
|
||||
*
|
||||
* Called in atomic context.
|
||||
*/
|
||||
int hw_breakpoint_handler(struct die_args *args)
|
||||
{
|
||||
bool err = false;
|
||||
@@ -490,6 +500,8 @@ NOKPROBE_SYMBOL(hw_breakpoint_handler);
|
||||
|
||||
/*
|
||||
* Handle single-step exceptions following a DABR hit.
|
||||
*
|
||||
* Called in atomic context.
|
||||
*/
|
||||
static int single_step_dabr_instruction(struct die_args *args)
|
||||
{
|
||||
@@ -541,6 +553,8 @@ NOKPROBE_SYMBOL(single_step_dabr_instruction);
|
||||
|
||||
/*
|
||||
* Handle debug exception notifications.
|
||||
*
|
||||
* Called in atomic context.
|
||||
*/
|
||||
int hw_breakpoint_exceptions_notify(
|
||||
struct notifier_block *unused, unsigned long val, void *data)
|
||||
|
||||
@@ -131,8 +131,13 @@ void wp_get_instr_detail(struct pt_regs *regs, ppc_inst_t *instr,
|
||||
int *type, int *size, unsigned long *ea)
|
||||
{
|
||||
struct instruction_op op;
|
||||
int err;
|
||||
|
||||
if (__get_user_instr(*instr, (void __user *)regs->nip))
|
||||
pagefault_disable();
|
||||
err = __get_user_instr(*instr, (void __user *)regs->nip);
|
||||
pagefault_enable();
|
||||
|
||||
if (err)
|
||||
return;
|
||||
|
||||
analyse_instr(&op, regs, *instr);
|
||||
|
||||
+36
-20
@@ -1512,23 +1512,11 @@ static void do_program_check(struct pt_regs *regs)
|
||||
return;
|
||||
}
|
||||
|
||||
if (cpu_has_feature(CPU_FTR_DEXCR_NPHIE) && user_mode(regs)) {
|
||||
ppc_inst_t insn;
|
||||
|
||||
if (get_user_instr(insn, (void __user *)regs->nip)) {
|
||||
_exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ppc_inst_primary_opcode(insn) == 31 &&
|
||||
get_xop(ppc_inst_val(insn)) == OP_31_XOP_HASHCHK) {
|
||||
_exception(SIGILL, regs, ILL_ILLOPN, regs->nip);
|
||||
return;
|
||||
}
|
||||
/* User mode considers other cases after enabling IRQs */
|
||||
if (!user_mode(regs)) {
|
||||
_exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
|
||||
return;
|
||||
}
|
||||
|
||||
_exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
|
||||
return;
|
||||
}
|
||||
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
||||
if (reason & REASON_TM) {
|
||||
@@ -1561,16 +1549,44 @@ static void do_program_check(struct pt_regs *regs)
|
||||
|
||||
/*
|
||||
* If we took the program check in the kernel skip down to sending a
|
||||
* SIGILL. The subsequent cases all relate to emulating instructions
|
||||
* which we should only do for userspace. We also do not want to enable
|
||||
* interrupts for kernel faults because that might lead to further
|
||||
* faults, and loose the context of the original exception.
|
||||
* SIGILL. The subsequent cases all relate to user space, such as
|
||||
* emulating instructions which we should only do for user space. We
|
||||
* also do not want to enable interrupts for kernel faults because that
|
||||
* might lead to further faults, and loose the context of the original
|
||||
* exception.
|
||||
*/
|
||||
if (!user_mode(regs))
|
||||
goto sigill;
|
||||
|
||||
interrupt_cond_local_irq_enable(regs);
|
||||
|
||||
/*
|
||||
* (reason & REASON_TRAP) is mostly handled before enabling IRQs,
|
||||
* except get_user_instr() can sleep so we cannot reliably inspect the
|
||||
* current instruction in that context. Now that we know we are
|
||||
* handling a user space trap and can sleep, we can check if the trap
|
||||
* was a hashchk failure.
|
||||
*/
|
||||
if (reason & REASON_TRAP) {
|
||||
if (cpu_has_feature(CPU_FTR_DEXCR_NPHIE)) {
|
||||
ppc_inst_t insn;
|
||||
|
||||
if (get_user_instr(insn, (void __user *)regs->nip)) {
|
||||
_exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ppc_inst_primary_opcode(insn) == 31 &&
|
||||
get_xop(ppc_inst_val(insn)) == OP_31_XOP_HASHCHK) {
|
||||
_exception(SIGILL, regs, ILL_ILLOPN, regs->nip);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
|
||||
return;
|
||||
}
|
||||
|
||||
/* (reason & REASON_ILLEGAL) would be the obvious thing here,
|
||||
* but there seems to be a hardware bug on the 405GP (RevD)
|
||||
* that means ESR is sometimes set incorrectly - either to
|
||||
|
||||
@@ -1418,7 +1418,7 @@ static int h_24x7_event_init(struct perf_event *event)
|
||||
}
|
||||
|
||||
domain = event_get_domain(event);
|
||||
if (domain >= HV_PERF_DOMAIN_MAX) {
|
||||
if (domain == 0 || domain >= HV_PERF_DOMAIN_MAX) {
|
||||
pr_devel("invalid domain %d\n", domain);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
menuconfig PPC_82xx
|
||||
bool "82xx-based boards (PQ II)"
|
||||
depends on PPC_BOOK3S_32
|
||||
select FSL_SOC
|
||||
|
||||
if PPC_82xx
|
||||
|
||||
@@ -9,7 +10,6 @@ config EP8248E
|
||||
bool "Embedded Planet EP8248E (a.k.a. CWH-PPC-8248N-VE)"
|
||||
select CPM2
|
||||
select PPC_INDIRECT_PCI if PCI
|
||||
select FSL_SOC
|
||||
select PHYLIB if NETDEVICES
|
||||
select MDIO_BITBANG if PHYLIB
|
||||
help
|
||||
@@ -22,7 +22,6 @@ config MGCOGE
|
||||
bool "Keymile MGCOGE"
|
||||
select CPM2
|
||||
select PPC_INDIRECT_PCI if PCI
|
||||
select FSL_SOC
|
||||
help
|
||||
This enables support for the Keymile MGCOGE board.
|
||||
|
||||
|
||||
@@ -460,8 +460,11 @@ static int riscv_vcpu_get_isa_ext_single(struct kvm_vcpu *vcpu,
|
||||
reg_num >= ARRAY_SIZE(kvm_isa_ext_arr))
|
||||
return -ENOENT;
|
||||
|
||||
*reg_val = 0;
|
||||
host_isa_ext = kvm_isa_ext_arr[reg_num];
|
||||
if (!__riscv_isa_extension_available(NULL, host_isa_ext))
|
||||
return -ENOENT;
|
||||
|
||||
*reg_val = 0;
|
||||
if (__riscv_isa_extension_available(vcpu->arch.isa, host_isa_ext))
|
||||
*reg_val = 1; /* Mark the given extension as available */
|
||||
|
||||
@@ -842,7 +845,7 @@ static int copy_isa_ext_reg_indices(const struct kvm_vcpu *vcpu,
|
||||
u64 reg = KVM_REG_RISCV | size | KVM_REG_RISCV_ISA_EXT | i;
|
||||
|
||||
isa_ext = kvm_isa_ext_arr[i];
|
||||
if (!__riscv_isa_extension_available(vcpu->arch.isa, isa_ext))
|
||||
if (!__riscv_isa_extension_available(NULL, isa_ext))
|
||||
continue;
|
||||
|
||||
if (uindices) {
|
||||
|
||||
@@ -40,23 +40,25 @@ CONFIG_SCHED_AUTOGROUP=y
|
||||
CONFIG_EXPERT=y
|
||||
# CONFIG_SYSFS_SYSCALL is not set
|
||||
CONFIG_PROFILING=y
|
||||
CONFIG_KEXEC_FILE=y
|
||||
CONFIG_KEXEC_SIG=y
|
||||
CONFIG_CRASH_DUMP=y
|
||||
CONFIG_LIVEPATCH=y
|
||||
CONFIG_MARCH_ZEC12=y
|
||||
CONFIG_TUNE_ZEC12=y
|
||||
CONFIG_NR_CPUS=512
|
||||
CONFIG_NUMA=y
|
||||
CONFIG_HZ_100=y
|
||||
CONFIG_KEXEC_FILE=y
|
||||
CONFIG_KEXEC_SIG=y
|
||||
CONFIG_CERT_STORE=y
|
||||
CONFIG_EXPOLINE=y
|
||||
CONFIG_EXPOLINE_AUTO=y
|
||||
CONFIG_CHSC_SCH=y
|
||||
CONFIG_VFIO_CCW=m
|
||||
CONFIG_VFIO_AP=m
|
||||
CONFIG_CRASH_DUMP=y
|
||||
CONFIG_PROTECTED_VIRTUALIZATION_GUEST=y
|
||||
CONFIG_CMM=m
|
||||
CONFIG_APPLDATA_BASE=y
|
||||
CONFIG_S390_HYPFS_FS=y
|
||||
CONFIG_KVM=m
|
||||
CONFIG_S390_UNWIND_SELFTEST=m
|
||||
CONFIG_S390_KPROBES_SANITY_TEST=m
|
||||
@@ -434,6 +436,7 @@ CONFIG_SCSI_DH_EMC=m
|
||||
CONFIG_SCSI_DH_ALUA=m
|
||||
CONFIG_MD=y
|
||||
CONFIG_BLK_DEV_MD=y
|
||||
# CONFIG_MD_BITMAP_FILE is not set
|
||||
CONFIG_MD_LINEAR=m
|
||||
CONFIG_MD_MULTIPATH=m
|
||||
CONFIG_MD_FAULTY=m
|
||||
@@ -577,6 +580,7 @@ CONFIG_SOFT_WATCHDOG=m
|
||||
CONFIG_DIAG288_WATCHDOG=m
|
||||
# CONFIG_DRM_DEBUG_MODESET_LOCK is not set
|
||||
CONFIG_FB=y
|
||||
# CONFIG_FB_DEVICE is not set
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
|
||||
# CONFIG_HID_SUPPORT is not set
|
||||
@@ -647,6 +651,7 @@ CONFIG_PROC_KCORE=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
CONFIG_TMPFS_INODE64=y
|
||||
CONFIG_TMPFS_QUOTA=y
|
||||
CONFIG_HUGETLBFS=y
|
||||
CONFIG_ECRYPT_FS=m
|
||||
CONFIG_CRAMFS=m
|
||||
@@ -703,6 +708,7 @@ CONFIG_IMA_WRITE_POLICY=y
|
||||
CONFIG_IMA_APPRAISE=y
|
||||
CONFIG_LSM="yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor"
|
||||
CONFIG_INIT_STACK_NONE=y
|
||||
CONFIG_BUG_ON_DATA_CORRUPTION=y
|
||||
CONFIG_CRYPTO_USER=m
|
||||
# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
|
||||
CONFIG_CRYPTO_PCRYPT=m
|
||||
@@ -825,9 +831,9 @@ CONFIG_LOCK_STAT=y
|
||||
CONFIG_DEBUG_ATOMIC_SLEEP=y
|
||||
CONFIG_DEBUG_LOCKING_API_SELFTESTS=y
|
||||
CONFIG_DEBUG_IRQFLAGS=y
|
||||
CONFIG_DEBUG_LIST=y
|
||||
CONFIG_DEBUG_SG=y
|
||||
CONFIG_DEBUG_NOTIFIERS=y
|
||||
CONFIG_BUG_ON_DATA_CORRUPTION=y
|
||||
CONFIG_DEBUG_CREDENTIALS=y
|
||||
CONFIG_RCU_TORTURE_TEST=m
|
||||
CONFIG_RCU_REF_SCALE_TEST=m
|
||||
|
||||
@@ -38,23 +38,25 @@ CONFIG_SCHED_AUTOGROUP=y
|
||||
CONFIG_EXPERT=y
|
||||
# CONFIG_SYSFS_SYSCALL is not set
|
||||
CONFIG_PROFILING=y
|
||||
CONFIG_KEXEC_FILE=y
|
||||
CONFIG_KEXEC_SIG=y
|
||||
CONFIG_CRASH_DUMP=y
|
||||
CONFIG_LIVEPATCH=y
|
||||
CONFIG_MARCH_ZEC12=y
|
||||
CONFIG_TUNE_ZEC12=y
|
||||
CONFIG_NR_CPUS=512
|
||||
CONFIG_NUMA=y
|
||||
CONFIG_HZ_100=y
|
||||
CONFIG_KEXEC_FILE=y
|
||||
CONFIG_KEXEC_SIG=y
|
||||
CONFIG_CERT_STORE=y
|
||||
CONFIG_EXPOLINE=y
|
||||
CONFIG_EXPOLINE_AUTO=y
|
||||
CONFIG_CHSC_SCH=y
|
||||
CONFIG_VFIO_CCW=m
|
||||
CONFIG_VFIO_AP=m
|
||||
CONFIG_CRASH_DUMP=y
|
||||
CONFIG_PROTECTED_VIRTUALIZATION_GUEST=y
|
||||
CONFIG_CMM=m
|
||||
CONFIG_APPLDATA_BASE=y
|
||||
CONFIG_S390_HYPFS_FS=y
|
||||
CONFIG_KVM=m
|
||||
CONFIG_S390_UNWIND_SELFTEST=m
|
||||
CONFIG_S390_KPROBES_SANITY_TEST=m
|
||||
@@ -424,6 +426,7 @@ CONFIG_SCSI_DH_EMC=m
|
||||
CONFIG_SCSI_DH_ALUA=m
|
||||
CONFIG_MD=y
|
||||
CONFIG_BLK_DEV_MD=y
|
||||
# CONFIG_MD_BITMAP_FILE is not set
|
||||
CONFIG_MD_LINEAR=m
|
||||
CONFIG_MD_MULTIPATH=m
|
||||
CONFIG_MD_FAULTY=m
|
||||
@@ -566,6 +569,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y
|
||||
CONFIG_SOFT_WATCHDOG=m
|
||||
CONFIG_DIAG288_WATCHDOG=m
|
||||
CONFIG_FB=y
|
||||
# CONFIG_FB_DEVICE is not set
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
|
||||
# CONFIG_HID_SUPPORT is not set
|
||||
@@ -632,6 +636,7 @@ CONFIG_PROC_KCORE=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
CONFIG_TMPFS_INODE64=y
|
||||
CONFIG_TMPFS_QUOTA=y
|
||||
CONFIG_HUGETLBFS=y
|
||||
CONFIG_CONFIGFS_FS=m
|
||||
CONFIG_ECRYPT_FS=m
|
||||
@@ -687,6 +692,7 @@ CONFIG_IMA_WRITE_POLICY=y
|
||||
CONFIG_IMA_APPRAISE=y
|
||||
CONFIG_LSM="yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor"
|
||||
CONFIG_INIT_STACK_NONE=y
|
||||
CONFIG_BUG_ON_DATA_CORRUPTION=y
|
||||
CONFIG_CRYPTO_FIPS=y
|
||||
CONFIG_CRYPTO_USER=m
|
||||
# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
|
||||
@@ -781,7 +787,6 @@ CONFIG_PTDUMP_DEBUGFS=y
|
||||
CONFIG_DEBUG_MEMORY_INIT=y
|
||||
CONFIG_PANIC_ON_OOPS=y
|
||||
CONFIG_TEST_LOCKUP=m
|
||||
CONFIG_BUG_ON_DATA_CORRUPTION=y
|
||||
CONFIG_RCU_TORTURE_TEST=m
|
||||
CONFIG_RCU_REF_SCALE_TEST=m
|
||||
CONFIG_RCU_CPU_STALL_TIMEOUT=60
|
||||
|
||||
@@ -8,6 +8,7 @@ CONFIG_BPF_SYSCALL=y
|
||||
# CONFIG_NET_NS is not set
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
|
||||
CONFIG_CRASH_DUMP=y
|
||||
CONFIG_MARCH_ZEC12=y
|
||||
CONFIG_TUNE_ZEC12=y
|
||||
# CONFIG_COMPAT is not set
|
||||
@@ -15,9 +16,8 @@ CONFIG_NR_CPUS=2
|
||||
CONFIG_HZ_100=y
|
||||
# CONFIG_CHSC_SCH is not set
|
||||
# CONFIG_SCM_BUS is not set
|
||||
CONFIG_CRASH_DUMP=y
|
||||
# CONFIG_PFAULT is not set
|
||||
# CONFIG_S390_HYPFS_FS is not set
|
||||
# CONFIG_S390_HYPFS is not set
|
||||
# CONFIG_VIRTUALIZATION is not set
|
||||
# CONFIG_S390_GUEST is not set
|
||||
# CONFIG_SECCOMP is not set
|
||||
|
||||
@@ -432,15 +432,16 @@ static char *get_key_description(struct vcssb *vcssb, const struct vce *vce)
|
||||
char *desc;
|
||||
|
||||
cs_token = vcssb->cs_token;
|
||||
/* Description string contains "%64s:%04u:%08u\0". */
|
||||
/* Description string contains "%64s:%05u:%010u\0". */
|
||||
name_len = sizeof(vce->vce_hdr.vc_name);
|
||||
len = name_len + 1 + 4 + 1 + 8 + 1;
|
||||
len = name_len + 1 + 5 + 1 + 10 + 1;
|
||||
desc = kmalloc(len, GFP_KERNEL);
|
||||
if (!desc)
|
||||
return NULL;
|
||||
|
||||
memcpy(desc, vce->vce_hdr.vc_name, name_len);
|
||||
sprintf(desc + name_len, ":%04u:%08u", vce->vce_hdr.vc_index, cs_token);
|
||||
snprintf(desc + name_len, len - name_len, ":%05u:%010u",
|
||||
vce->vce_hdr.vc_index, cs_token);
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
@@ -72,8 +72,8 @@ __ioremap_29bit(phys_addr_t offset, unsigned long size, pgprot_t prot)
|
||||
#define __ioremap_29bit(offset, size, prot) NULL
|
||||
#endif /* CONFIG_29BIT */
|
||||
|
||||
void __iomem *ioremap_prot(phys_addr_t phys_addr, size_t size,
|
||||
unsigned long prot)
|
||||
void __iomem __ref *ioremap_prot(phys_addr_t phys_addr, size_t size,
|
||||
unsigned long prot)
|
||||
{
|
||||
void __iomem *mapped;
|
||||
pgprot_t pgprot = __pgprot(prot);
|
||||
|
||||
@@ -294,7 +294,7 @@ static void __xen_pv_evtchn_do_upcall(struct pt_regs *regs)
|
||||
|
||||
inc_irq_stat(irq_hv_callback_count);
|
||||
|
||||
xen_hvm_evtchn_do_upcall();
|
||||
xen_evtchn_do_upcall();
|
||||
|
||||
set_irq_regs(old_regs);
|
||||
}
|
||||
|
||||
@@ -1419,7 +1419,6 @@ struct kvm_arch {
|
||||
* the thread holds the MMU lock in write mode.
|
||||
*/
|
||||
spinlock_t tdp_mmu_pages_lock;
|
||||
struct workqueue_struct *tdp_mmu_zap_wq;
|
||||
#endif /* CONFIG_X86_64 */
|
||||
|
||||
/*
|
||||
@@ -1835,7 +1834,7 @@ void kvm_mmu_vendor_module_exit(void);
|
||||
|
||||
void kvm_mmu_destroy(struct kvm_vcpu *vcpu);
|
||||
int kvm_mmu_create(struct kvm_vcpu *vcpu);
|
||||
int kvm_mmu_init_vm(struct kvm *kvm);
|
||||
void kvm_mmu_init_vm(struct kvm *kvm);
|
||||
void kvm_mmu_uninit_vm(struct kvm *kvm);
|
||||
|
||||
void kvm_mmu_after_set_cpuid(struct kvm_vcpu *vcpu);
|
||||
|
||||
@@ -105,6 +105,13 @@
|
||||
CFI_POST_PADDING \
|
||||
SYM_FUNC_END(__cfi_##name)
|
||||
|
||||
/* UML needs to be able to override memcpy() and friends for KASAN. */
|
||||
#ifdef CONFIG_UML
|
||||
# define SYM_FUNC_ALIAS_MEMFUNC SYM_FUNC_ALIAS_WEAK
|
||||
#else
|
||||
# define SYM_FUNC_ALIAS_MEMFUNC SYM_FUNC_ALIAS
|
||||
#endif
|
||||
|
||||
/* SYM_TYPED_FUNC_START -- use for indirectly called globals, w/ CFI type */
|
||||
#define SYM_TYPED_FUNC_START(name) \
|
||||
SYM_TYPED_START(name, SYM_L_GLOBAL, SYM_F_ALIGN) \
|
||||
|
||||
@@ -186,8 +186,7 @@ do { \
|
||||
#else
|
||||
#define deactivate_mm(tsk, mm) \
|
||||
do { \
|
||||
if (!tsk->vfork_done) \
|
||||
shstk_free(tsk); \
|
||||
shstk_free(tsk); \
|
||||
load_gs_index(0); \
|
||||
loadsegment(fs, 0); \
|
||||
} while (0)
|
||||
|
||||
@@ -9,13 +9,6 @@ struct paravirt_patch_site {
|
||||
u8 type; /* type of this instruction */
|
||||
u8 len; /* length of original instruction */
|
||||
};
|
||||
|
||||
/* Lazy mode for batching updates / context switch */
|
||||
enum paravirt_lazy_mode {
|
||||
PARAVIRT_LAZY_NONE,
|
||||
PARAVIRT_LAZY_MMU,
|
||||
PARAVIRT_LAZY_CPU,
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PARAVIRT
|
||||
@@ -549,14 +542,6 @@ int paravirt_disable_iospace(void);
|
||||
__PVOP_VCALL(op, PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2), \
|
||||
PVOP_CALL_ARG3(arg3), PVOP_CALL_ARG4(arg4))
|
||||
|
||||
enum paravirt_lazy_mode paravirt_get_lazy_mode(void);
|
||||
void paravirt_start_context_switch(struct task_struct *prev);
|
||||
void paravirt_end_context_switch(struct task_struct *next);
|
||||
|
||||
void paravirt_enter_lazy_mmu(void);
|
||||
void paravirt_leave_lazy_mmu(void);
|
||||
void paravirt_flush_lazy_mmu(void);
|
||||
|
||||
void _paravirt_nop(void);
|
||||
void paravirt_BUG(void);
|
||||
unsigned long paravirt_ret0(void);
|
||||
|
||||
@@ -683,13 +683,11 @@ extern u16 get_llc_id(unsigned int cpu);
|
||||
#ifdef CONFIG_CPU_SUP_AMD
|
||||
extern u32 amd_get_nodes_per_socket(void);
|
||||
extern u32 amd_get_highest_perf(void);
|
||||
extern bool cpu_has_ibpb_brtype_microcode(void);
|
||||
extern void amd_clear_divider(void);
|
||||
extern void amd_check_microcode(void);
|
||||
#else
|
||||
static inline u32 amd_get_nodes_per_socket(void) { return 0; }
|
||||
static inline u32 amd_get_highest_perf(void) { return 0; }
|
||||
static inline bool cpu_has_ibpb_brtype_microcode(void) { return false; }
|
||||
static inline void amd_clear_divider(void) { }
|
||||
static inline void amd_check_microcode(void) { }
|
||||
#endif
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
extern struct shared_info *HYPERVISOR_shared_info;
|
||||
extern struct start_info *xen_start_info;
|
||||
|
||||
#include <asm/bug.h>
|
||||
#include <asm/processor.h>
|
||||
|
||||
#define XEN_SIGNATURE "XenVMMXenVMM"
|
||||
@@ -63,4 +64,40 @@ void __init xen_pvh_init(struct boot_params *boot_params);
|
||||
void __init mem_map_via_hcall(struct boot_params *boot_params_p);
|
||||
#endif
|
||||
|
||||
/* Lazy mode for batching updates / context switch */
|
||||
enum xen_lazy_mode {
|
||||
XEN_LAZY_NONE,
|
||||
XEN_LAZY_MMU,
|
||||
XEN_LAZY_CPU,
|
||||
};
|
||||
|
||||
DECLARE_PER_CPU(enum xen_lazy_mode, xen_lazy_mode);
|
||||
DECLARE_PER_CPU(unsigned int, xen_lazy_nesting);
|
||||
|
||||
static inline void enter_lazy(enum xen_lazy_mode mode)
|
||||
{
|
||||
enum xen_lazy_mode old_mode = this_cpu_read(xen_lazy_mode);
|
||||
|
||||
if (mode == old_mode) {
|
||||
this_cpu_inc(xen_lazy_nesting);
|
||||
return;
|
||||
}
|
||||
|
||||
BUG_ON(old_mode != XEN_LAZY_NONE);
|
||||
|
||||
this_cpu_write(xen_lazy_mode, mode);
|
||||
}
|
||||
|
||||
static inline void leave_lazy(enum xen_lazy_mode mode)
|
||||
{
|
||||
BUG_ON(this_cpu_read(xen_lazy_mode) != mode);
|
||||
|
||||
if (this_cpu_read(xen_lazy_nesting) == 0)
|
||||
this_cpu_write(xen_lazy_mode, XEN_LAZY_NONE);
|
||||
else
|
||||
this_cpu_dec(xen_lazy_nesting);
|
||||
}
|
||||
|
||||
enum xen_lazy_mode xen_get_lazy_mode(void);
|
||||
|
||||
#endif /* _ASM_X86_XEN_HYPERVISOR_H */
|
||||
|
||||
@@ -720,13 +720,8 @@ void __init_or_module noinline apply_returns(s32 *start, s32 *end)
|
||||
{
|
||||
s32 *s;
|
||||
|
||||
/*
|
||||
* Do not patch out the default return thunks if those needed are the
|
||||
* ones generated by the compiler.
|
||||
*/
|
||||
if (cpu_feature_enabled(X86_FEATURE_RETHUNK) &&
|
||||
(x86_return_thunk == __x86_return_thunk))
|
||||
return;
|
||||
if (cpu_feature_enabled(X86_FEATURE_RETHUNK))
|
||||
static_call_force_reinit();
|
||||
|
||||
for (s = start; s < end; s++) {
|
||||
void *dest = NULL, *addr = (void *)s + *s;
|
||||
|
||||
@@ -272,7 +272,6 @@ void __init callthunks_patch_builtin_calls(void)
|
||||
pr_info("Setting up call depth tracking\n");
|
||||
mutex_lock(&text_mutex);
|
||||
callthunks_setup(&cs, &builtin_coretext);
|
||||
static_call_force_reinit();
|
||||
thunks_initialized = true;
|
||||
mutex_unlock(&text_mutex);
|
||||
}
|
||||
|
||||
@@ -766,6 +766,15 @@ static void early_init_amd(struct cpuinfo_x86 *c)
|
||||
|
||||
if (cpu_has(c, X86_FEATURE_TOPOEXT))
|
||||
smp_num_siblings = ((cpuid_ebx(0x8000001e) >> 8) & 0xff) + 1;
|
||||
|
||||
if (!cpu_has(c, X86_FEATURE_HYPERVISOR) && !cpu_has(c, X86_FEATURE_IBPB_BRTYPE)) {
|
||||
if (c->x86 == 0x17 && boot_cpu_has(X86_FEATURE_AMD_IBPB))
|
||||
setup_force_cpu_cap(X86_FEATURE_IBPB_BRTYPE);
|
||||
else if (c->x86 >= 0x19 && !wrmsrl_safe(MSR_IA32_PRED_CMD, PRED_CMD_SBPB)) {
|
||||
setup_force_cpu_cap(X86_FEATURE_IBPB_BRTYPE);
|
||||
setup_force_cpu_cap(X86_FEATURE_SBPB);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void init_amd_k8(struct cpuinfo_x86 *c)
|
||||
@@ -1301,25 +1310,6 @@ void amd_check_microcode(void)
|
||||
on_each_cpu(zenbleed_check_cpu, NULL, 1);
|
||||
}
|
||||
|
||||
bool cpu_has_ibpb_brtype_microcode(void)
|
||||
{
|
||||
switch (boot_cpu_data.x86) {
|
||||
/* Zen1/2 IBPB flushes branch type predictions too. */
|
||||
case 0x17:
|
||||
return boot_cpu_has(X86_FEATURE_AMD_IBPB);
|
||||
case 0x19:
|
||||
/* Poke the MSR bit on Zen3/4 to check its presence. */
|
||||
if (!wrmsrl_safe(MSR_IA32_PRED_CMD, PRED_CMD_SBPB)) {
|
||||
setup_force_cpu_cap(X86_FEATURE_SBPB);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Issue a DIV 0/1 insn to clear any division data from previous DIV
|
||||
* operations.
|
||||
|
||||
@@ -2404,26 +2404,15 @@ early_param("spec_rstack_overflow", srso_parse_cmdline);
|
||||
|
||||
static void __init srso_select_mitigation(void)
|
||||
{
|
||||
bool has_microcode;
|
||||
bool has_microcode = boot_cpu_has(X86_FEATURE_IBPB_BRTYPE);
|
||||
|
||||
if (!boot_cpu_has_bug(X86_BUG_SRSO) || cpu_mitigations_off())
|
||||
goto pred_cmd;
|
||||
|
||||
/*
|
||||
* The first check is for the kernel running as a guest in order
|
||||
* for guests to verify whether IBPB is a viable mitigation.
|
||||
*/
|
||||
has_microcode = boot_cpu_has(X86_FEATURE_IBPB_BRTYPE) || cpu_has_ibpb_brtype_microcode();
|
||||
if (!has_microcode) {
|
||||
pr_warn("IBPB-extending microcode not applied!\n");
|
||||
pr_warn(SRSO_NOTICE);
|
||||
} else {
|
||||
/*
|
||||
* Enable the synthetic (even if in a real CPUID leaf)
|
||||
* flags for guests.
|
||||
*/
|
||||
setup_force_cpu_cap(X86_FEATURE_IBPB_BRTYPE);
|
||||
|
||||
/*
|
||||
* Zen1/2 with SMT off aren't vulnerable after the right
|
||||
* IBPB microcode has been applied.
|
||||
@@ -2444,7 +2433,7 @@ static void __init srso_select_mitigation(void)
|
||||
|
||||
switch (srso_cmd) {
|
||||
case SRSO_CMD_OFF:
|
||||
return;
|
||||
goto pred_cmd;
|
||||
|
||||
case SRSO_CMD_MICROCODE:
|
||||
if (has_microcode) {
|
||||
@@ -2717,7 +2706,7 @@ static ssize_t srso_show_state(char *buf)
|
||||
|
||||
return sysfs_emit(buf, "%s%s\n",
|
||||
srso_strings[srso_mitigation],
|
||||
(cpu_has_ibpb_brtype_microcode() ? "" : ", no microcode"));
|
||||
boot_cpu_has(X86_FEATURE_IBPB_BRTYPE) ? "" : ", no microcode");
|
||||
}
|
||||
|
||||
static ssize_t gds_show_state(char *buf)
|
||||
|
||||
@@ -143,66 +143,7 @@ int paravirt_disable_iospace(void)
|
||||
return request_resource(&ioport_resource, &reserve_ioports);
|
||||
}
|
||||
|
||||
static DEFINE_PER_CPU(enum paravirt_lazy_mode, paravirt_lazy_mode) = PARAVIRT_LAZY_NONE;
|
||||
|
||||
static inline void enter_lazy(enum paravirt_lazy_mode mode)
|
||||
{
|
||||
BUG_ON(this_cpu_read(paravirt_lazy_mode) != PARAVIRT_LAZY_NONE);
|
||||
|
||||
this_cpu_write(paravirt_lazy_mode, mode);
|
||||
}
|
||||
|
||||
static void leave_lazy(enum paravirt_lazy_mode mode)
|
||||
{
|
||||
BUG_ON(this_cpu_read(paravirt_lazy_mode) != mode);
|
||||
|
||||
this_cpu_write(paravirt_lazy_mode, PARAVIRT_LAZY_NONE);
|
||||
}
|
||||
|
||||
void paravirt_enter_lazy_mmu(void)
|
||||
{
|
||||
enter_lazy(PARAVIRT_LAZY_MMU);
|
||||
}
|
||||
|
||||
void paravirt_leave_lazy_mmu(void)
|
||||
{
|
||||
leave_lazy(PARAVIRT_LAZY_MMU);
|
||||
}
|
||||
|
||||
void paravirt_flush_lazy_mmu(void)
|
||||
{
|
||||
preempt_disable();
|
||||
|
||||
if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) {
|
||||
arch_leave_lazy_mmu_mode();
|
||||
arch_enter_lazy_mmu_mode();
|
||||
}
|
||||
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PARAVIRT_XXL
|
||||
void paravirt_start_context_switch(struct task_struct *prev)
|
||||
{
|
||||
BUG_ON(preemptible());
|
||||
|
||||
if (this_cpu_read(paravirt_lazy_mode) == PARAVIRT_LAZY_MMU) {
|
||||
arch_leave_lazy_mmu_mode();
|
||||
set_ti_thread_flag(task_thread_info(prev), TIF_LAZY_MMU_UPDATES);
|
||||
}
|
||||
enter_lazy(PARAVIRT_LAZY_CPU);
|
||||
}
|
||||
|
||||
void paravirt_end_context_switch(struct task_struct *next)
|
||||
{
|
||||
BUG_ON(preemptible());
|
||||
|
||||
leave_lazy(PARAVIRT_LAZY_CPU);
|
||||
|
||||
if (test_and_clear_ti_thread_flag(task_thread_info(next), TIF_LAZY_MMU_UPDATES))
|
||||
arch_enter_lazy_mmu_mode();
|
||||
}
|
||||
|
||||
static noinstr void pv_native_write_cr2(unsigned long val)
|
||||
{
|
||||
native_write_cr2(val);
|
||||
@@ -229,14 +170,6 @@ static noinstr void pv_native_safe_halt(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
enum paravirt_lazy_mode paravirt_get_lazy_mode(void)
|
||||
{
|
||||
if (in_interrupt())
|
||||
return PARAVIRT_LAZY_NONE;
|
||||
|
||||
return this_cpu_read(paravirt_lazy_mode);
|
||||
}
|
||||
|
||||
struct pv_info pv_info = {
|
||||
.name = "bare hardware",
|
||||
#ifdef CONFIG_PARAVIRT_XXL
|
||||
|
||||
@@ -257,13 +257,6 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
|
||||
if (!ret && unlikely(test_tsk_thread_flag(current, TIF_IO_BITMAP)))
|
||||
io_bitmap_share(p);
|
||||
|
||||
/*
|
||||
* If copy_thread() if failing, don't leak the shadow stack possibly
|
||||
* allocated in shstk_alloc_thread_stack() above.
|
||||
*/
|
||||
if (ret)
|
||||
shstk_free(p);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -358,15 +358,11 @@ static void __init add_early_ima_buffer(u64 phys_addr)
|
||||
#if defined(CONFIG_HAVE_IMA_KEXEC) && !defined(CONFIG_OF_FLATTREE)
|
||||
int __init ima_free_kexec_buffer(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (!ima_kexec_buffer_size)
|
||||
return -ENOENT;
|
||||
|
||||
rc = memblock_phys_free(ima_kexec_buffer_phys,
|
||||
ima_kexec_buffer_size);
|
||||
if (rc)
|
||||
return rc;
|
||||
memblock_free_late(ima_kexec_buffer_phys,
|
||||
ima_kexec_buffer_size);
|
||||
|
||||
ima_kexec_buffer_phys = 0;
|
||||
ima_kexec_buffer_size = 0;
|
||||
|
||||
+31
-2
@@ -205,10 +205,21 @@ unsigned long shstk_alloc_thread_stack(struct task_struct *tsk, unsigned long cl
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* For CLONE_VM, except vfork, the child needs a separate shadow
|
||||
* For CLONE_VFORK the child will share the parents shadow stack.
|
||||
* Make sure to clear the internal tracking of the thread shadow
|
||||
* stack so the freeing logic run for child knows to leave it alone.
|
||||
*/
|
||||
if (clone_flags & CLONE_VFORK) {
|
||||
shstk->base = 0;
|
||||
shstk->size = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* For !CLONE_VM the child will use a copy of the parents shadow
|
||||
* stack.
|
||||
*/
|
||||
if ((clone_flags & (CLONE_VFORK | CLONE_VM)) != CLONE_VM)
|
||||
if (!(clone_flags & CLONE_VM))
|
||||
return 0;
|
||||
|
||||
size = adjust_shstk_size(stack_size);
|
||||
@@ -408,7 +419,25 @@ void shstk_free(struct task_struct *tsk)
|
||||
if (!tsk->mm || tsk->mm != current->mm)
|
||||
return;
|
||||
|
||||
/*
|
||||
* If shstk->base is NULL, then this task is not managing its
|
||||
* own shadow stack (CLONE_VFORK). So skip freeing it.
|
||||
*/
|
||||
if (!shstk->base)
|
||||
return;
|
||||
|
||||
/*
|
||||
* shstk->base is NULL for CLONE_VFORK child tasks, and so is
|
||||
* normal. But size = 0 on a shstk->base is not normal and
|
||||
* indicated an attempt to free the thread shadow stack twice.
|
||||
* Warn about it.
|
||||
*/
|
||||
if (WARN_ON(!shstk->size))
|
||||
return;
|
||||
|
||||
unmap_shadow_stack(shstk->base, shstk->size);
|
||||
|
||||
shstk->size = 0;
|
||||
}
|
||||
|
||||
static int wrss_control(bool enable)
|
||||
|
||||
+5
-16
@@ -6167,20 +6167,15 @@ static bool kvm_has_zapped_obsolete_pages(struct kvm *kvm)
|
||||
return unlikely(!list_empty_careful(&kvm->arch.zapped_obsolete_pages));
|
||||
}
|
||||
|
||||
int kvm_mmu_init_vm(struct kvm *kvm)
|
||||
void kvm_mmu_init_vm(struct kvm *kvm)
|
||||
{
|
||||
int r;
|
||||
|
||||
INIT_LIST_HEAD(&kvm->arch.active_mmu_pages);
|
||||
INIT_LIST_HEAD(&kvm->arch.zapped_obsolete_pages);
|
||||
INIT_LIST_HEAD(&kvm->arch.possible_nx_huge_pages);
|
||||
spin_lock_init(&kvm->arch.mmu_unsync_pages_lock);
|
||||
|
||||
if (tdp_mmu_enabled) {
|
||||
r = kvm_mmu_init_tdp_mmu(kvm);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
if (tdp_mmu_enabled)
|
||||
kvm_mmu_init_tdp_mmu(kvm);
|
||||
|
||||
kvm->arch.split_page_header_cache.kmem_cache = mmu_page_header_cache;
|
||||
kvm->arch.split_page_header_cache.gfp_zero = __GFP_ZERO;
|
||||
@@ -6189,8 +6184,6 @@ int kvm_mmu_init_vm(struct kvm *kvm)
|
||||
|
||||
kvm->arch.split_desc_cache.kmem_cache = pte_list_desc_cache;
|
||||
kvm->arch.split_desc_cache.gfp_zero = __GFP_ZERO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mmu_free_vm_memory_caches(struct kvm *kvm)
|
||||
@@ -6246,7 +6239,6 @@ static bool kvm_rmap_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_e
|
||||
void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end)
|
||||
{
|
||||
bool flush;
|
||||
int i;
|
||||
|
||||
if (WARN_ON_ONCE(gfn_end <= gfn_start))
|
||||
return;
|
||||
@@ -6257,11 +6249,8 @@ void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end)
|
||||
|
||||
flush = kvm_rmap_zap_gfn_range(kvm, gfn_start, gfn_end);
|
||||
|
||||
if (tdp_mmu_enabled) {
|
||||
for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++)
|
||||
flush = kvm_tdp_mmu_zap_leafs(kvm, i, gfn_start,
|
||||
gfn_end, true, flush);
|
||||
}
|
||||
if (tdp_mmu_enabled)
|
||||
flush = kvm_tdp_mmu_zap_leafs(kvm, gfn_start, gfn_end, flush);
|
||||
|
||||
if (flush)
|
||||
kvm_flush_remote_tlbs_range(kvm, gfn_start, gfn_end - gfn_start);
|
||||
|
||||
@@ -58,7 +58,12 @@ struct kvm_mmu_page {
|
||||
|
||||
bool tdp_mmu_page;
|
||||
bool unsync;
|
||||
u8 mmu_valid_gen;
|
||||
union {
|
||||
u8 mmu_valid_gen;
|
||||
|
||||
/* Only accessed under slots_lock. */
|
||||
bool tdp_mmu_scheduled_root_to_zap;
|
||||
};
|
||||
|
||||
/*
|
||||
* The shadow page can't be replaced by an equivalent huge page
|
||||
@@ -100,13 +105,7 @@ struct kvm_mmu_page {
|
||||
struct kvm_rmap_head parent_ptes; /* rmap pointers to parent sptes */
|
||||
tdp_ptep_t ptep;
|
||||
};
|
||||
union {
|
||||
DECLARE_BITMAP(unsync_child_bitmap, 512);
|
||||
struct {
|
||||
struct work_struct tdp_mmu_async_work;
|
||||
void *tdp_mmu_async_data;
|
||||
};
|
||||
};
|
||||
DECLARE_BITMAP(unsync_child_bitmap, 512);
|
||||
|
||||
/*
|
||||
* Tracks shadow pages that, if zapped, would allow KVM to create an NX
|
||||
|
||||
+67
-85
@@ -12,18 +12,10 @@
|
||||
#include <trace/events/kvm.h>
|
||||
|
||||
/* Initializes the TDP MMU for the VM, if enabled. */
|
||||
int kvm_mmu_init_tdp_mmu(struct kvm *kvm)
|
||||
void kvm_mmu_init_tdp_mmu(struct kvm *kvm)
|
||||
{
|
||||
struct workqueue_struct *wq;
|
||||
|
||||
wq = alloc_workqueue("kvm", WQ_UNBOUND|WQ_MEM_RECLAIM|WQ_CPU_INTENSIVE, 0);
|
||||
if (!wq)
|
||||
return -ENOMEM;
|
||||
|
||||
INIT_LIST_HEAD(&kvm->arch.tdp_mmu_roots);
|
||||
spin_lock_init(&kvm->arch.tdp_mmu_pages_lock);
|
||||
kvm->arch.tdp_mmu_zap_wq = wq;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Arbitrarily returns true so that this may be used in if statements. */
|
||||
@@ -46,20 +38,15 @@ void kvm_mmu_uninit_tdp_mmu(struct kvm *kvm)
|
||||
* ultimately frees all roots.
|
||||
*/
|
||||
kvm_tdp_mmu_invalidate_all_roots(kvm);
|
||||
|
||||
/*
|
||||
* Destroying a workqueue also first flushes the workqueue, i.e. no
|
||||
* need to invoke kvm_tdp_mmu_zap_invalidated_roots().
|
||||
*/
|
||||
destroy_workqueue(kvm->arch.tdp_mmu_zap_wq);
|
||||
kvm_tdp_mmu_zap_invalidated_roots(kvm);
|
||||
|
||||
WARN_ON(atomic64_read(&kvm->arch.tdp_mmu_pages));
|
||||
WARN_ON(!list_empty(&kvm->arch.tdp_mmu_roots));
|
||||
|
||||
/*
|
||||
* Ensure that all the outstanding RCU callbacks to free shadow pages
|
||||
* can run before the VM is torn down. Work items on tdp_mmu_zap_wq
|
||||
* can call kvm_tdp_mmu_put_root and create new callbacks.
|
||||
* can run before the VM is torn down. Putting the last reference to
|
||||
* zapped roots will create new callbacks.
|
||||
*/
|
||||
rcu_barrier();
|
||||
}
|
||||
@@ -86,46 +73,6 @@ static void tdp_mmu_free_sp_rcu_callback(struct rcu_head *head)
|
||||
tdp_mmu_free_sp(sp);
|
||||
}
|
||||
|
||||
static void tdp_mmu_zap_root(struct kvm *kvm, struct kvm_mmu_page *root,
|
||||
bool shared);
|
||||
|
||||
static void tdp_mmu_zap_root_work(struct work_struct *work)
|
||||
{
|
||||
struct kvm_mmu_page *root = container_of(work, struct kvm_mmu_page,
|
||||
tdp_mmu_async_work);
|
||||
struct kvm *kvm = root->tdp_mmu_async_data;
|
||||
|
||||
read_lock(&kvm->mmu_lock);
|
||||
|
||||
/*
|
||||
* A TLB flush is not necessary as KVM performs a local TLB flush when
|
||||
* allocating a new root (see kvm_mmu_load()), and when migrating vCPU
|
||||
* to a different pCPU. Note, the local TLB flush on reuse also
|
||||
* invalidates any paging-structure-cache entries, i.e. TLB entries for
|
||||
* intermediate paging structures, that may be zapped, as such entries
|
||||
* are associated with the ASID on both VMX and SVM.
|
||||
*/
|
||||
tdp_mmu_zap_root(kvm, root, true);
|
||||
|
||||
/*
|
||||
* Drop the refcount using kvm_tdp_mmu_put_root() to test its logic for
|
||||
* avoiding an infinite loop. By design, the root is reachable while
|
||||
* it's being asynchronously zapped, thus a different task can put its
|
||||
* last reference, i.e. flowing through kvm_tdp_mmu_put_root() for an
|
||||
* asynchronously zapped root is unavoidable.
|
||||
*/
|
||||
kvm_tdp_mmu_put_root(kvm, root, true);
|
||||
|
||||
read_unlock(&kvm->mmu_lock);
|
||||
}
|
||||
|
||||
static void tdp_mmu_schedule_zap_root(struct kvm *kvm, struct kvm_mmu_page *root)
|
||||
{
|
||||
root->tdp_mmu_async_data = kvm;
|
||||
INIT_WORK(&root->tdp_mmu_async_work, tdp_mmu_zap_root_work);
|
||||
queue_work(kvm->arch.tdp_mmu_zap_wq, &root->tdp_mmu_async_work);
|
||||
}
|
||||
|
||||
void kvm_tdp_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *root,
|
||||
bool shared)
|
||||
{
|
||||
@@ -211,8 +158,12 @@ static struct kvm_mmu_page *tdp_mmu_next_root(struct kvm *kvm,
|
||||
#define for_each_valid_tdp_mmu_root_yield_safe(_kvm, _root, _as_id, _shared) \
|
||||
__for_each_tdp_mmu_root_yield_safe(_kvm, _root, _as_id, _shared, true)
|
||||
|
||||
#define for_each_tdp_mmu_root_yield_safe(_kvm, _root, _as_id) \
|
||||
__for_each_tdp_mmu_root_yield_safe(_kvm, _root, _as_id, false, false)
|
||||
#define for_each_tdp_mmu_root_yield_safe(_kvm, _root, _shared) \
|
||||
for (_root = tdp_mmu_next_root(_kvm, NULL, _shared, false); \
|
||||
_root; \
|
||||
_root = tdp_mmu_next_root(_kvm, _root, _shared, false)) \
|
||||
if (!kvm_lockdep_assert_mmu_lock_held(_kvm, _shared)) { \
|
||||
} else
|
||||
|
||||
/*
|
||||
* Iterate over all TDP MMU roots. Requires that mmu_lock be held for write,
|
||||
@@ -292,7 +243,7 @@ hpa_t kvm_tdp_mmu_get_vcpu_root_hpa(struct kvm_vcpu *vcpu)
|
||||
* by a memslot update or by the destruction of the VM. Initialize the
|
||||
* refcount to two; one reference for the vCPU, and one reference for
|
||||
* the TDP MMU itself, which is held until the root is invalidated and
|
||||
* is ultimately put by tdp_mmu_zap_root_work().
|
||||
* is ultimately put by kvm_tdp_mmu_zap_invalidated_roots().
|
||||
*/
|
||||
refcount_set(&root->tdp_mmu_root_count, 2);
|
||||
|
||||
@@ -877,13 +828,12 @@ static bool tdp_mmu_zap_leafs(struct kvm *kvm, struct kvm_mmu_page *root,
|
||||
* true if a TLB flush is needed before releasing the MMU lock, i.e. if one or
|
||||
* more SPTEs were zapped since the MMU lock was last acquired.
|
||||
*/
|
||||
bool kvm_tdp_mmu_zap_leafs(struct kvm *kvm, int as_id, gfn_t start, gfn_t end,
|
||||
bool can_yield, bool flush)
|
||||
bool kvm_tdp_mmu_zap_leafs(struct kvm *kvm, gfn_t start, gfn_t end, bool flush)
|
||||
{
|
||||
struct kvm_mmu_page *root;
|
||||
|
||||
for_each_tdp_mmu_root_yield_safe(kvm, root, as_id)
|
||||
flush = tdp_mmu_zap_leafs(kvm, root, start, end, can_yield, flush);
|
||||
for_each_tdp_mmu_root_yield_safe(kvm, root, false)
|
||||
flush = tdp_mmu_zap_leafs(kvm, root, start, end, true, flush);
|
||||
|
||||
return flush;
|
||||
}
|
||||
@@ -891,7 +841,6 @@ bool kvm_tdp_mmu_zap_leafs(struct kvm *kvm, int as_id, gfn_t start, gfn_t end,
|
||||
void kvm_tdp_mmu_zap_all(struct kvm *kvm)
|
||||
{
|
||||
struct kvm_mmu_page *root;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Zap all roots, including invalid roots, as all SPTEs must be dropped
|
||||
@@ -905,10 +854,8 @@ void kvm_tdp_mmu_zap_all(struct kvm *kvm)
|
||||
* is being destroyed or the userspace VMM has exited. In both cases,
|
||||
* KVM_RUN is unreachable, i.e. no vCPUs will ever service the request.
|
||||
*/
|
||||
for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) {
|
||||
for_each_tdp_mmu_root_yield_safe(kvm, root, i)
|
||||
tdp_mmu_zap_root(kvm, root, false);
|
||||
}
|
||||
for_each_tdp_mmu_root_yield_safe(kvm, root, false)
|
||||
tdp_mmu_zap_root(kvm, root, false);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -917,18 +864,47 @@ void kvm_tdp_mmu_zap_all(struct kvm *kvm)
|
||||
*/
|
||||
void kvm_tdp_mmu_zap_invalidated_roots(struct kvm *kvm)
|
||||
{
|
||||
flush_workqueue(kvm->arch.tdp_mmu_zap_wq);
|
||||
struct kvm_mmu_page *root;
|
||||
|
||||
read_lock(&kvm->mmu_lock);
|
||||
|
||||
for_each_tdp_mmu_root_yield_safe(kvm, root, true) {
|
||||
if (!root->tdp_mmu_scheduled_root_to_zap)
|
||||
continue;
|
||||
|
||||
root->tdp_mmu_scheduled_root_to_zap = false;
|
||||
KVM_BUG_ON(!root->role.invalid, kvm);
|
||||
|
||||
/*
|
||||
* A TLB flush is not necessary as KVM performs a local TLB
|
||||
* flush when allocating a new root (see kvm_mmu_load()), and
|
||||
* when migrating a vCPU to a different pCPU. Note, the local
|
||||
* TLB flush on reuse also invalidates paging-structure-cache
|
||||
* entries, i.e. TLB entries for intermediate paging structures,
|
||||
* that may be zapped, as such entries are associated with the
|
||||
* ASID on both VMX and SVM.
|
||||
*/
|
||||
tdp_mmu_zap_root(kvm, root, true);
|
||||
|
||||
/*
|
||||
* The referenced needs to be put *after* zapping the root, as
|
||||
* the root must be reachable by mmu_notifiers while it's being
|
||||
* zapped
|
||||
*/
|
||||
kvm_tdp_mmu_put_root(kvm, root, true);
|
||||
}
|
||||
|
||||
read_unlock(&kvm->mmu_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark each TDP MMU root as invalid to prevent vCPUs from reusing a root that
|
||||
* is about to be zapped, e.g. in response to a memslots update. The actual
|
||||
* zapping is performed asynchronously. Using a separate workqueue makes it
|
||||
* easy to ensure that the destruction is performed before the "fast zap"
|
||||
* completes, without keeping a separate list of invalidated roots; the list is
|
||||
* effectively the list of work items in the workqueue.
|
||||
* zapping is done separately so that it happens with mmu_lock with read,
|
||||
* whereas invalidating roots must be done with mmu_lock held for write (unless
|
||||
* the VM is being destroyed).
|
||||
*
|
||||
* Note, the asynchronous worker is gifted the TDP MMU's reference.
|
||||
* Note, kvm_tdp_mmu_zap_invalidated_roots() is gifted the TDP MMU's reference.
|
||||
* See kvm_tdp_mmu_get_vcpu_root_hpa().
|
||||
*/
|
||||
void kvm_tdp_mmu_invalidate_all_roots(struct kvm *kvm)
|
||||
@@ -953,19 +929,20 @@ void kvm_tdp_mmu_invalidate_all_roots(struct kvm *kvm)
|
||||
/*
|
||||
* As above, mmu_lock isn't held when destroying the VM! There can't
|
||||
* be other references to @kvm, i.e. nothing else can invalidate roots
|
||||
* or be consuming roots, but walking the list of roots does need to be
|
||||
* guarded against roots being deleted by the asynchronous zap worker.
|
||||
* or get/put references to roots.
|
||||
*/
|
||||
rcu_read_lock();
|
||||
|
||||
list_for_each_entry_rcu(root, &kvm->arch.tdp_mmu_roots, link) {
|
||||
list_for_each_entry(root, &kvm->arch.tdp_mmu_roots, link) {
|
||||
/*
|
||||
* Note, invalid roots can outlive a memslot update! Invalid
|
||||
* roots must be *zapped* before the memslot update completes,
|
||||
* but a different task can acquire a reference and keep the
|
||||
* root alive after its been zapped.
|
||||
*/
|
||||
if (!root->role.invalid) {
|
||||
root->tdp_mmu_scheduled_root_to_zap = true;
|
||||
root->role.invalid = true;
|
||||
tdp_mmu_schedule_zap_root(kvm, root);
|
||||
}
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1146,8 +1123,13 @@ retry:
|
||||
bool kvm_tdp_mmu_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range,
|
||||
bool flush)
|
||||
{
|
||||
return kvm_tdp_mmu_zap_leafs(kvm, range->slot->as_id, range->start,
|
||||
range->end, range->may_block, flush);
|
||||
struct kvm_mmu_page *root;
|
||||
|
||||
__for_each_tdp_mmu_root_yield_safe(kvm, root, range->slot->as_id, false, false)
|
||||
flush = tdp_mmu_zap_leafs(kvm, root, range->start, range->end,
|
||||
range->may_block, flush);
|
||||
|
||||
return flush;
|
||||
}
|
||||
|
||||
typedef bool (*tdp_handler_t)(struct kvm *kvm, struct tdp_iter *iter,
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include "spte.h"
|
||||
|
||||
int kvm_mmu_init_tdp_mmu(struct kvm *kvm);
|
||||
void kvm_mmu_init_tdp_mmu(struct kvm *kvm);
|
||||
void kvm_mmu_uninit_tdp_mmu(struct kvm *kvm);
|
||||
|
||||
hpa_t kvm_tdp_mmu_get_vcpu_root_hpa(struct kvm_vcpu *vcpu);
|
||||
@@ -20,8 +20,7 @@ __must_check static inline bool kvm_tdp_mmu_get_root(struct kvm_mmu_page *root)
|
||||
void kvm_tdp_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *root,
|
||||
bool shared);
|
||||
|
||||
bool kvm_tdp_mmu_zap_leafs(struct kvm *kvm, int as_id, gfn_t start,
|
||||
gfn_t end, bool can_yield, bool flush);
|
||||
bool kvm_tdp_mmu_zap_leafs(struct kvm *kvm, gfn_t start, gfn_t end, bool flush);
|
||||
bool kvm_tdp_mmu_zap_sp(struct kvm *kvm, struct kvm_mmu_page *sp);
|
||||
void kvm_tdp_mmu_zap_all(struct kvm *kvm);
|
||||
void kvm_tdp_mmu_invalidate_all_roots(struct kvm *kvm);
|
||||
|
||||
+26
-8
@@ -2962,6 +2962,32 @@ int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in)
|
||||
count, in);
|
||||
}
|
||||
|
||||
static void sev_es_vcpu_after_set_cpuid(struct vcpu_svm *svm)
|
||||
{
|
||||
struct kvm_vcpu *vcpu = &svm->vcpu;
|
||||
|
||||
if (boot_cpu_has(X86_FEATURE_V_TSC_AUX)) {
|
||||
bool v_tsc_aux = guest_cpuid_has(vcpu, X86_FEATURE_RDTSCP) ||
|
||||
guest_cpuid_has(vcpu, X86_FEATURE_RDPID);
|
||||
|
||||
set_msr_interception(vcpu, svm->msrpm, MSR_TSC_AUX, v_tsc_aux, v_tsc_aux);
|
||||
}
|
||||
}
|
||||
|
||||
void sev_vcpu_after_set_cpuid(struct vcpu_svm *svm)
|
||||
{
|
||||
struct kvm_vcpu *vcpu = &svm->vcpu;
|
||||
struct kvm_cpuid_entry2 *best;
|
||||
|
||||
/* For sev guests, the memory encryption bit is not reserved in CR3. */
|
||||
best = kvm_find_cpuid_entry(vcpu, 0x8000001F);
|
||||
if (best)
|
||||
vcpu->arch.reserved_gpa_bits &= ~(1UL << (best->ebx & 0x3f));
|
||||
|
||||
if (sev_es_guest(svm->vcpu.kvm))
|
||||
sev_es_vcpu_after_set_cpuid(svm);
|
||||
}
|
||||
|
||||
static void sev_es_init_vmcb(struct vcpu_svm *svm)
|
||||
{
|
||||
struct vmcb *vmcb = svm->vmcb01.ptr;
|
||||
@@ -3024,14 +3050,6 @@ static void sev_es_init_vmcb(struct vcpu_svm *svm)
|
||||
set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHTOIP, 1, 1);
|
||||
set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTFROMIP, 1, 1);
|
||||
set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTTOIP, 1, 1);
|
||||
|
||||
if (boot_cpu_has(X86_FEATURE_V_TSC_AUX) &&
|
||||
(guest_cpuid_has(&svm->vcpu, X86_FEATURE_RDTSCP) ||
|
||||
guest_cpuid_has(&svm->vcpu, X86_FEATURE_RDPID))) {
|
||||
set_msr_interception(vcpu, svm->msrpm, MSR_TSC_AUX, 1, 1);
|
||||
if (guest_cpuid_has(&svm->vcpu, X86_FEATURE_RDTSCP))
|
||||
svm_clr_intercept(svm, INTERCEPT_RDTSCP);
|
||||
}
|
||||
}
|
||||
|
||||
void sev_init_vmcb(struct vcpu_svm *svm)
|
||||
|
||||
+35
-8
@@ -683,6 +683,21 @@ static int svm_hardware_enable(void)
|
||||
|
||||
amd_pmu_enable_virt();
|
||||
|
||||
/*
|
||||
* If TSC_AUX virtualization is supported, TSC_AUX becomes a swap type
|
||||
* "B" field (see sev_es_prepare_switch_to_guest()) for SEV-ES guests.
|
||||
* Since Linux does not change the value of TSC_AUX once set, prime the
|
||||
* TSC_AUX field now to avoid a RDMSR on every vCPU run.
|
||||
*/
|
||||
if (boot_cpu_has(X86_FEATURE_V_TSC_AUX)) {
|
||||
struct sev_es_save_area *hostsa;
|
||||
u32 msr_hi;
|
||||
|
||||
hostsa = (struct sev_es_save_area *)(page_address(sd->save_area) + 0x400);
|
||||
|
||||
rdmsr(MSR_TSC_AUX, hostsa->tsc_aux, msr_hi);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1532,7 +1547,14 @@ static void svm_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
|
||||
if (tsc_scaling)
|
||||
__svm_write_tsc_multiplier(vcpu->arch.tsc_scaling_ratio);
|
||||
|
||||
if (likely(tsc_aux_uret_slot >= 0))
|
||||
/*
|
||||
* TSC_AUX is always virtualized for SEV-ES guests when the feature is
|
||||
* available. The user return MSR support is not required in this case
|
||||
* because TSC_AUX is restored on #VMEXIT from the host save area
|
||||
* (which has been initialized in svm_hardware_enable()).
|
||||
*/
|
||||
if (likely(tsc_aux_uret_slot >= 0) &&
|
||||
(!boot_cpu_has(X86_FEATURE_V_TSC_AUX) || !sev_es_guest(vcpu->kvm)))
|
||||
kvm_set_user_return_msr(tsc_aux_uret_slot, svm->tsc_aux, -1ull);
|
||||
|
||||
svm->guest_state_loaded = true;
|
||||
@@ -3086,6 +3108,16 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
|
||||
svm->sysenter_esp_hi = guest_cpuid_is_intel(vcpu) ? (data >> 32) : 0;
|
||||
break;
|
||||
case MSR_TSC_AUX:
|
||||
/*
|
||||
* TSC_AUX is always virtualized for SEV-ES guests when the
|
||||
* feature is available. The user return MSR support is not
|
||||
* required in this case because TSC_AUX is restored on #VMEXIT
|
||||
* from the host save area (which has been initialized in
|
||||
* svm_hardware_enable()).
|
||||
*/
|
||||
if (boot_cpu_has(X86_FEATURE_V_TSC_AUX) && sev_es_guest(vcpu->kvm))
|
||||
break;
|
||||
|
||||
/*
|
||||
* TSC_AUX is usually changed only during boot and never read
|
||||
* directly. Intercept TSC_AUX instead of exposing it to the
|
||||
@@ -4284,7 +4316,6 @@ static bool svm_has_emulated_msr(struct kvm *kvm, u32 index)
|
||||
static void svm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct vcpu_svm *svm = to_svm(vcpu);
|
||||
struct kvm_cpuid_entry2 *best;
|
||||
|
||||
/*
|
||||
* SVM doesn't provide a way to disable just XSAVES in the guest, KVM
|
||||
@@ -4328,12 +4359,8 @@ static void svm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
|
||||
set_msr_interception(vcpu, svm->msrpm, MSR_IA32_FLUSH_CMD, 0,
|
||||
!!guest_cpuid_has(vcpu, X86_FEATURE_FLUSH_L1D));
|
||||
|
||||
/* For sev guests, the memory encryption bit is not reserved in CR3. */
|
||||
if (sev_guest(vcpu->kvm)) {
|
||||
best = kvm_find_cpuid_entry(vcpu, 0x8000001F);
|
||||
if (best)
|
||||
vcpu->arch.reserved_gpa_bits &= ~(1UL << (best->ebx & 0x3f));
|
||||
}
|
||||
if (sev_guest(vcpu->kvm))
|
||||
sev_vcpu_after_set_cpuid(svm);
|
||||
|
||||
init_vmcb_after_set_cpuid(vcpu);
|
||||
}
|
||||
|
||||
@@ -684,6 +684,7 @@ void __init sev_hardware_setup(void);
|
||||
void sev_hardware_unsetup(void);
|
||||
int sev_cpu_init(struct svm_cpu_data *sd);
|
||||
void sev_init_vmcb(struct vcpu_svm *svm);
|
||||
void sev_vcpu_after_set_cpuid(struct vcpu_svm *svm);
|
||||
void sev_free_vcpu(struct kvm_vcpu *vcpu);
|
||||
int sev_handle_vmgexit(struct kvm_vcpu *vcpu);
|
||||
int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in);
|
||||
|
||||
+1
-4
@@ -12308,9 +12308,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = kvm_mmu_init_vm(kvm);
|
||||
if (ret)
|
||||
goto out_page_track;
|
||||
kvm_mmu_init_vm(kvm);
|
||||
|
||||
ret = static_call(kvm_x86_vm_init)(kvm);
|
||||
if (ret)
|
||||
@@ -12355,7 +12353,6 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
|
||||
|
||||
out_uninit_mmu:
|
||||
kvm_mmu_uninit_vm(kvm);
|
||||
out_page_track:
|
||||
kvm_page_track_cleanup(kvm);
|
||||
out:
|
||||
return ret;
|
||||
|
||||
@@ -40,7 +40,7 @@ SYM_TYPED_FUNC_START(__memcpy)
|
||||
SYM_FUNC_END(__memcpy)
|
||||
EXPORT_SYMBOL(__memcpy)
|
||||
|
||||
SYM_FUNC_ALIAS(memcpy, __memcpy)
|
||||
SYM_FUNC_ALIAS_MEMFUNC(memcpy, __memcpy)
|
||||
EXPORT_SYMBOL(memcpy)
|
||||
|
||||
SYM_FUNC_START_LOCAL(memcpy_orig)
|
||||
|
||||
@@ -212,5 +212,5 @@ SYM_FUNC_START(__memmove)
|
||||
SYM_FUNC_END(__memmove)
|
||||
EXPORT_SYMBOL(__memmove)
|
||||
|
||||
SYM_FUNC_ALIAS(memmove, __memmove)
|
||||
SYM_FUNC_ALIAS_MEMFUNC(memmove, __memmove)
|
||||
EXPORT_SYMBOL(memmove)
|
||||
|
||||
@@ -40,7 +40,7 @@ SYM_FUNC_START(__memset)
|
||||
SYM_FUNC_END(__memset)
|
||||
EXPORT_SYMBOL(__memset)
|
||||
|
||||
SYM_FUNC_ALIAS(memset, __memset)
|
||||
SYM_FUNC_ALIAS_MEMFUNC(memset, __memset)
|
||||
EXPORT_SYMBOL(memset)
|
||||
|
||||
SYM_FUNC_START_LOCAL(memset_orig)
|
||||
|
||||
+1
-1
@@ -138,7 +138,7 @@ void __init xen_efi_init(struct boot_params *boot_params)
|
||||
if (efi_systab_xen == NULL)
|
||||
return;
|
||||
|
||||
strncpy((char *)&boot_params->efi_info.efi_loader_signature, "Xen",
|
||||
strscpy((char *)&boot_params->efi_info.efi_loader_signature, "Xen",
|
||||
sizeof(boot_params->efi_info.efi_loader_signature));
|
||||
boot_params->efi_info.efi_systab = (__u32)__pa(efi_systab_xen);
|
||||
boot_params->efi_info.efi_systab_hi = (__u32)(__pa(efi_systab_xen) >> 32);
|
||||
|
||||
@@ -32,7 +32,7 @@ EXPORT_SYMBOL_GPL(hypercall_page);
|
||||
* &HYPERVISOR_shared_info->vcpu_info[cpu]. See xen_hvm_init_shared_info
|
||||
* and xen_vcpu_setup for details. By default it points to share_info->vcpu_info
|
||||
* but during boot it is switched to point to xen_vcpu_info.
|
||||
* The pointer is used in __xen_evtchn_do_upcall to acknowledge pending events.
|
||||
* The pointer is used in xen_evtchn_do_upcall to acknowledge pending events.
|
||||
*/
|
||||
DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu);
|
||||
DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info);
|
||||
|
||||
@@ -136,7 +136,7 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_xen_hvm_callback)
|
||||
|
||||
inc_irq_stat(irq_hv_callback_count);
|
||||
|
||||
xen_hvm_evtchn_do_upcall();
|
||||
xen_evtchn_do_upcall();
|
||||
|
||||
set_irq_regs(old_regs);
|
||||
}
|
||||
|
||||
@@ -101,6 +101,17 @@ struct tls_descs {
|
||||
struct desc_struct desc[3];
|
||||
};
|
||||
|
||||
DEFINE_PER_CPU(enum xen_lazy_mode, xen_lazy_mode) = XEN_LAZY_NONE;
|
||||
DEFINE_PER_CPU(unsigned int, xen_lazy_nesting);
|
||||
|
||||
enum xen_lazy_mode xen_get_lazy_mode(void)
|
||||
{
|
||||
if (in_interrupt())
|
||||
return XEN_LAZY_NONE;
|
||||
|
||||
return this_cpu_read(xen_lazy_mode);
|
||||
}
|
||||
|
||||
/*
|
||||
* Updating the 3 TLS descriptors in the GDT on every task switch is
|
||||
* surprisingly expensive so we avoid updating them if they haven't
|
||||
@@ -362,10 +373,25 @@ static noinstr unsigned long xen_get_debugreg(int reg)
|
||||
return HYPERVISOR_get_debugreg(reg);
|
||||
}
|
||||
|
||||
static void xen_start_context_switch(struct task_struct *prev)
|
||||
{
|
||||
BUG_ON(preemptible());
|
||||
|
||||
if (this_cpu_read(xen_lazy_mode) == XEN_LAZY_MMU) {
|
||||
arch_leave_lazy_mmu_mode();
|
||||
set_ti_thread_flag(task_thread_info(prev), TIF_LAZY_MMU_UPDATES);
|
||||
}
|
||||
enter_lazy(XEN_LAZY_CPU);
|
||||
}
|
||||
|
||||
static void xen_end_context_switch(struct task_struct *next)
|
||||
{
|
||||
BUG_ON(preemptible());
|
||||
|
||||
xen_mc_flush();
|
||||
paravirt_end_context_switch(next);
|
||||
leave_lazy(XEN_LAZY_CPU);
|
||||
if (test_and_clear_ti_thread_flag(task_thread_info(next), TIF_LAZY_MMU_UPDATES))
|
||||
arch_enter_lazy_mmu_mode();
|
||||
}
|
||||
|
||||
static unsigned long xen_store_tr(void)
|
||||
@@ -472,7 +498,7 @@ static void xen_set_ldt(const void *addr, unsigned entries)
|
||||
|
||||
MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
|
||||
|
||||
xen_mc_issue(PARAVIRT_LAZY_CPU);
|
||||
xen_mc_issue(XEN_LAZY_CPU);
|
||||
}
|
||||
|
||||
static void xen_load_gdt(const struct desc_ptr *dtr)
|
||||
@@ -568,7 +594,7 @@ static void xen_load_tls(struct thread_struct *t, unsigned int cpu)
|
||||
* exception between the new %fs descriptor being loaded and
|
||||
* %fs being effectively cleared at __switch_to().
|
||||
*/
|
||||
if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU)
|
||||
if (xen_get_lazy_mode() == XEN_LAZY_CPU)
|
||||
loadsegment(fs, 0);
|
||||
|
||||
xen_mc_batch();
|
||||
@@ -577,7 +603,7 @@ static void xen_load_tls(struct thread_struct *t, unsigned int cpu)
|
||||
load_TLS_descriptor(t, cpu, 1);
|
||||
load_TLS_descriptor(t, cpu, 2);
|
||||
|
||||
xen_mc_issue(PARAVIRT_LAZY_CPU);
|
||||
xen_mc_issue(XEN_LAZY_CPU);
|
||||
}
|
||||
|
||||
static void xen_load_gs_index(unsigned int idx)
|
||||
@@ -909,7 +935,7 @@ static void xen_load_sp0(unsigned long sp0)
|
||||
|
||||
mcs = xen_mc_entry(0);
|
||||
MULTI_stack_switch(mcs.mc, __KERNEL_DS, sp0);
|
||||
xen_mc_issue(PARAVIRT_LAZY_CPU);
|
||||
xen_mc_issue(XEN_LAZY_CPU);
|
||||
this_cpu_write(cpu_tss_rw.x86_tss.sp0, sp0);
|
||||
}
|
||||
|
||||
@@ -973,7 +999,7 @@ static void xen_write_cr0(unsigned long cr0)
|
||||
|
||||
MULTI_fpu_taskswitch(mcs.mc, (cr0 & X86_CR0_TS) != 0);
|
||||
|
||||
xen_mc_issue(PARAVIRT_LAZY_CPU);
|
||||
xen_mc_issue(XEN_LAZY_CPU);
|
||||
}
|
||||
|
||||
static void xen_write_cr4(unsigned long cr4)
|
||||
@@ -1156,7 +1182,7 @@ static const typeof(pv_ops) xen_cpu_ops __initconst = {
|
||||
#endif
|
||||
.io_delay = xen_io_delay,
|
||||
|
||||
.start_context_switch = paravirt_start_context_switch,
|
||||
.start_context_switch = xen_start_context_switch,
|
||||
.end_context_switch = xen_end_context_switch,
|
||||
},
|
||||
};
|
||||
|
||||
+36
-19
@@ -236,7 +236,7 @@ static void xen_set_pmd_hyper(pmd_t *ptr, pmd_t val)
|
||||
u.val = pmd_val_ma(val);
|
||||
xen_extend_mmu_update(&u);
|
||||
|
||||
xen_mc_issue(PARAVIRT_LAZY_MMU);
|
||||
xen_mc_issue(XEN_LAZY_MMU);
|
||||
|
||||
preempt_enable();
|
||||
}
|
||||
@@ -270,7 +270,7 @@ static bool xen_batched_set_pte(pte_t *ptep, pte_t pteval)
|
||||
{
|
||||
struct mmu_update u;
|
||||
|
||||
if (paravirt_get_lazy_mode() != PARAVIRT_LAZY_MMU)
|
||||
if (xen_get_lazy_mode() != XEN_LAZY_MMU)
|
||||
return false;
|
||||
|
||||
xen_mc_batch();
|
||||
@@ -279,7 +279,7 @@ static bool xen_batched_set_pte(pte_t *ptep, pte_t pteval)
|
||||
u.val = pte_val_ma(pteval);
|
||||
xen_extend_mmu_update(&u);
|
||||
|
||||
xen_mc_issue(PARAVIRT_LAZY_MMU);
|
||||
xen_mc_issue(XEN_LAZY_MMU);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -325,7 +325,7 @@ void xen_ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr,
|
||||
u.val = pte_val_ma(pte);
|
||||
xen_extend_mmu_update(&u);
|
||||
|
||||
xen_mc_issue(PARAVIRT_LAZY_MMU);
|
||||
xen_mc_issue(XEN_LAZY_MMU);
|
||||
}
|
||||
|
||||
/* Assume pteval_t is equivalent to all the other *val_t types. */
|
||||
@@ -419,7 +419,7 @@ static void xen_set_pud_hyper(pud_t *ptr, pud_t val)
|
||||
u.val = pud_val_ma(val);
|
||||
xen_extend_mmu_update(&u);
|
||||
|
||||
xen_mc_issue(PARAVIRT_LAZY_MMU);
|
||||
xen_mc_issue(XEN_LAZY_MMU);
|
||||
|
||||
preempt_enable();
|
||||
}
|
||||
@@ -499,7 +499,7 @@ static void __init xen_set_p4d_hyper(p4d_t *ptr, p4d_t val)
|
||||
|
||||
__xen_set_p4d_hyper(ptr, val);
|
||||
|
||||
xen_mc_issue(PARAVIRT_LAZY_MMU);
|
||||
xen_mc_issue(XEN_LAZY_MMU);
|
||||
|
||||
preempt_enable();
|
||||
}
|
||||
@@ -531,7 +531,7 @@ static void xen_set_p4d(p4d_t *ptr, p4d_t val)
|
||||
if (user_ptr)
|
||||
__xen_set_p4d_hyper((p4d_t *)user_ptr, val);
|
||||
|
||||
xen_mc_issue(PARAVIRT_LAZY_MMU);
|
||||
xen_mc_issue(XEN_LAZY_MMU);
|
||||
}
|
||||
|
||||
#if CONFIG_PGTABLE_LEVELS >= 5
|
||||
@@ -1245,7 +1245,7 @@ static noinline void xen_flush_tlb(void)
|
||||
op->cmd = MMUEXT_TLB_FLUSH_LOCAL;
|
||||
MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
|
||||
|
||||
xen_mc_issue(PARAVIRT_LAZY_MMU);
|
||||
xen_mc_issue(XEN_LAZY_MMU);
|
||||
|
||||
preempt_enable();
|
||||
}
|
||||
@@ -1265,7 +1265,7 @@ static void xen_flush_tlb_one_user(unsigned long addr)
|
||||
op->arg1.linear_addr = addr & PAGE_MASK;
|
||||
MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
|
||||
|
||||
xen_mc_issue(PARAVIRT_LAZY_MMU);
|
||||
xen_mc_issue(XEN_LAZY_MMU);
|
||||
|
||||
preempt_enable();
|
||||
}
|
||||
@@ -1302,7 +1302,7 @@ static void xen_flush_tlb_multi(const struct cpumask *cpus,
|
||||
|
||||
MULTI_mmuext_op(mcs.mc, &args->op, 1, NULL, DOMID_SELF);
|
||||
|
||||
xen_mc_issue(PARAVIRT_LAZY_MMU);
|
||||
xen_mc_issue(XEN_LAZY_MMU);
|
||||
}
|
||||
|
||||
static unsigned long xen_read_cr3(void)
|
||||
@@ -1361,7 +1361,7 @@ static void xen_write_cr3(unsigned long cr3)
|
||||
else
|
||||
__xen_write_cr3(false, 0);
|
||||
|
||||
xen_mc_issue(PARAVIRT_LAZY_CPU); /* interrupts restored */
|
||||
xen_mc_issue(XEN_LAZY_CPU); /* interrupts restored */
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1396,7 +1396,7 @@ static void __init xen_write_cr3_init(unsigned long cr3)
|
||||
|
||||
__xen_write_cr3(true, cr3);
|
||||
|
||||
xen_mc_issue(PARAVIRT_LAZY_CPU); /* interrupts restored */
|
||||
xen_mc_issue(XEN_LAZY_CPU); /* interrupts restored */
|
||||
}
|
||||
|
||||
static int xen_pgd_alloc(struct mm_struct *mm)
|
||||
@@ -1557,7 +1557,7 @@ static inline void xen_alloc_ptpage(struct mm_struct *mm, unsigned long pfn,
|
||||
if (level == PT_PTE && USE_SPLIT_PTE_PTLOCKS && !pinned)
|
||||
__pin_pagetable_pfn(MMUEXT_PIN_L1_TABLE, pfn);
|
||||
|
||||
xen_mc_issue(PARAVIRT_LAZY_MMU);
|
||||
xen_mc_issue(XEN_LAZY_MMU);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1587,7 +1587,7 @@ static inline void xen_release_ptpage(unsigned long pfn, unsigned level)
|
||||
|
||||
__set_pfn_prot(pfn, PAGE_KERNEL);
|
||||
|
||||
xen_mc_issue(PARAVIRT_LAZY_MMU);
|
||||
xen_mc_issue(XEN_LAZY_MMU);
|
||||
|
||||
ClearPagePinned(page);
|
||||
}
|
||||
@@ -1804,7 +1804,7 @@ void __init xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn)
|
||||
*/
|
||||
xen_mc_batch();
|
||||
__xen_write_cr3(true, __pa(init_top_pgt));
|
||||
xen_mc_issue(PARAVIRT_LAZY_CPU);
|
||||
xen_mc_issue(XEN_LAZY_CPU);
|
||||
|
||||
/* We can't that easily rip out L3 and L2, as the Xen pagetables are
|
||||
* set out this way: [L4], [L1], [L2], [L3], [L1], [L1] ... for
|
||||
@@ -2083,6 +2083,23 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void xen_enter_lazy_mmu(void)
|
||||
{
|
||||
enter_lazy(XEN_LAZY_MMU);
|
||||
}
|
||||
|
||||
static void xen_flush_lazy_mmu(void)
|
||||
{
|
||||
preempt_disable();
|
||||
|
||||
if (xen_get_lazy_mode() == XEN_LAZY_MMU) {
|
||||
arch_leave_lazy_mmu_mode();
|
||||
arch_enter_lazy_mmu_mode();
|
||||
}
|
||||
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
static void __init xen_post_allocator_init(void)
|
||||
{
|
||||
pv_ops.mmu.set_pte = xen_set_pte;
|
||||
@@ -2107,7 +2124,7 @@ static void xen_leave_lazy_mmu(void)
|
||||
{
|
||||
preempt_disable();
|
||||
xen_mc_flush();
|
||||
paravirt_leave_lazy_mmu();
|
||||
leave_lazy(XEN_LAZY_MMU);
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
@@ -2166,9 +2183,9 @@ static const typeof(pv_ops) xen_mmu_ops __initconst = {
|
||||
.exit_mmap = xen_exit_mmap,
|
||||
|
||||
.lazy_mode = {
|
||||
.enter = paravirt_enter_lazy_mmu,
|
||||
.enter = xen_enter_lazy_mmu,
|
||||
.leave = xen_leave_lazy_mmu,
|
||||
.flush = paravirt_flush_lazy_mmu,
|
||||
.flush = xen_flush_lazy_mmu,
|
||||
},
|
||||
|
||||
.set_fixmap = xen_set_fixmap,
|
||||
@@ -2385,7 +2402,7 @@ static noinline void xen_flush_tlb_all(void)
|
||||
op->cmd = MMUEXT_TLB_FLUSH_ALL;
|
||||
MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
|
||||
|
||||
xen_mc_issue(PARAVIRT_LAZY_MMU);
|
||||
xen_mc_issue(XEN_LAZY_MMU);
|
||||
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ static inline void xen_mc_batch(void)
|
||||
|
||||
/* need to disable interrupts until this entry is complete */
|
||||
local_irq_save(flags);
|
||||
trace_xen_mc_batch(paravirt_get_lazy_mode());
|
||||
trace_xen_mc_batch(xen_get_lazy_mode());
|
||||
__this_cpu_write(xen_mc_irq_flags, flags);
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ static inline void xen_mc_issue(unsigned mode)
|
||||
{
|
||||
trace_xen_mc_issue(mode);
|
||||
|
||||
if ((paravirt_get_lazy_mode() & mode) == 0)
|
||||
if ((xen_get_lazy_mode() & mode) == 0)
|
||||
xen_mc_flush();
|
||||
|
||||
/* restore flags saved in xen_mc_batch */
|
||||
|
||||
+5
-1
@@ -278,10 +278,14 @@ int sm2_compute_z_digest(struct shash_desc *desc,
|
||||
if (!ec)
|
||||
return -ENOMEM;
|
||||
|
||||
err = __sm2_set_pub_key(ec, key, keylen);
|
||||
err = sm2_ec_ctx_init(ec);
|
||||
if (err)
|
||||
goto out_free_ec;
|
||||
|
||||
err = __sm2_set_pub_key(ec, key, keylen);
|
||||
if (err)
|
||||
goto out_deinit_ec;
|
||||
|
||||
bits_len = SM2_DEFAULT_USERID_LEN * 8;
|
||||
entl[0] = bits_len >> 8;
|
||||
entl[1] = bits_len & 0xff;
|
||||
|
||||
@@ -1046,7 +1046,8 @@ static irqreturn_t ivpu_hw_40xx_irqb_handler(struct ivpu_device *vdev, int irq)
|
||||
if (status == 0)
|
||||
return IRQ_NONE;
|
||||
|
||||
REGB_WR32(VPU_40XX_BUTTRESS_INTERRUPT_STAT, status);
|
||||
/* Disable global interrupt before handling local buttress interrupts */
|
||||
REGB_WR32(VPU_40XX_BUTTRESS_GLOBAL_INT_MASK, 0x1);
|
||||
|
||||
if (REG_TEST_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, FREQ_CHANGE, status))
|
||||
ivpu_dbg(vdev, IRQ, "FREQ_CHANGE");
|
||||
@@ -1092,6 +1093,12 @@ static irqreturn_t ivpu_hw_40xx_irqb_handler(struct ivpu_device *vdev, int irq)
|
||||
schedule_recovery = true;
|
||||
}
|
||||
|
||||
/* This must be done after interrupts are cleared at the source. */
|
||||
REGB_WR32(VPU_40XX_BUTTRESS_INTERRUPT_STAT, status);
|
||||
|
||||
/* Re-enable global interrupt */
|
||||
REGB_WR32(VPU_40XX_BUTTRESS_GLOBAL_INT_MASK, 0x0);
|
||||
|
||||
if (schedule_recovery)
|
||||
ivpu_pm_schedule_recovery(vdev);
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ static void acpi_set_pdc_bits(u32 *buf)
|
||||
{
|
||||
buf[0] = ACPI_PDC_REVISION_ID;
|
||||
buf[1] = 1;
|
||||
buf[2] = 0;
|
||||
|
||||
/* Twiddle arch-specific bits needed for _PDC */
|
||||
arch_acpi_set_proc_cap_bits(&buf[2]);
|
||||
|
||||
+2
-2
@@ -14,7 +14,7 @@
|
||||
|
||||
struct cxl_cxims_data {
|
||||
int nr_maps;
|
||||
u64 xormaps[];
|
||||
u64 xormaps[] __counted_by(nr_maps);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -112,9 +112,9 @@ static int cxl_parse_cxims(union acpi_subtable_headers *header, void *arg,
|
||||
GFP_KERNEL);
|
||||
if (!cximsd)
|
||||
return -ENOMEM;
|
||||
cximsd->nr_maps = nr_maps;
|
||||
memcpy(cximsd->xormaps, cxims->xormap_list,
|
||||
nr_maps * sizeof(*cximsd->xormaps));
|
||||
cximsd->nr_maps = nr_maps;
|
||||
cxlrd->platform_data = cximsd;
|
||||
|
||||
return 0;
|
||||
|
||||
+12
-11
@@ -715,24 +715,25 @@ static void cxl_walk_cel(struct cxl_memdev_state *mds, size_t size, u8 *cel)
|
||||
for (i = 0; i < cel_entries; i++) {
|
||||
u16 opcode = le16_to_cpu(cel_entry[i].opcode);
|
||||
struct cxl_mem_command *cmd = cxl_mem_find_command(opcode);
|
||||
int enabled = 0;
|
||||
|
||||
if (!cmd && (!cxl_is_poison_command(opcode) ||
|
||||
!cxl_is_security_command(opcode))) {
|
||||
dev_dbg(dev,
|
||||
"Opcode 0x%04x unsupported by driver\n", opcode);
|
||||
continue;
|
||||
if (cmd) {
|
||||
set_bit(cmd->info.id, mds->enabled_cmds);
|
||||
enabled++;
|
||||
}
|
||||
|
||||
if (cmd)
|
||||
set_bit(cmd->info.id, mds->enabled_cmds);
|
||||
|
||||
if (cxl_is_poison_command(opcode))
|
||||
if (cxl_is_poison_command(opcode)) {
|
||||
cxl_set_poison_cmd_enabled(&mds->poison, opcode);
|
||||
enabled++;
|
||||
}
|
||||
|
||||
if (cxl_is_security_command(opcode))
|
||||
if (cxl_is_security_command(opcode)) {
|
||||
cxl_set_security_cmd_enabled(&mds->security, opcode);
|
||||
enabled++;
|
||||
}
|
||||
|
||||
dev_dbg(dev, "Opcode 0x%04x enabled\n", opcode);
|
||||
dev_dbg(dev, "Opcode 0x%04x %s\n", opcode,
|
||||
enabled ? "enabled" : "unsupported by driver");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/memregion.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/debugfs.h>
|
||||
@@ -706,16 +707,20 @@ static int cxl_setup_comp_regs(struct device *dev, struct cxl_register_map *map,
|
||||
return cxl_setup_regs(map);
|
||||
}
|
||||
|
||||
static inline int cxl_port_setup_regs(struct cxl_port *port,
|
||||
resource_size_t component_reg_phys)
|
||||
static int cxl_port_setup_regs(struct cxl_port *port,
|
||||
resource_size_t component_reg_phys)
|
||||
{
|
||||
if (dev_is_platform(port->uport_dev))
|
||||
return 0;
|
||||
return cxl_setup_comp_regs(&port->dev, &port->comp_map,
|
||||
component_reg_phys);
|
||||
}
|
||||
|
||||
static inline int cxl_dport_setup_regs(struct cxl_dport *dport,
|
||||
resource_size_t component_reg_phys)
|
||||
static int cxl_dport_setup_regs(struct cxl_dport *dport,
|
||||
resource_size_t component_reg_phys)
|
||||
{
|
||||
if (dev_is_platform(dport->dport_dev))
|
||||
return 0;
|
||||
return cxl_setup_comp_regs(dport->dport_dev, &dport->comp_map,
|
||||
component_reg_phys);
|
||||
}
|
||||
|
||||
+31
-10
@@ -717,13 +717,35 @@ static int match_free_decoder(struct device *dev, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int match_auto_decoder(struct device *dev, void *data)
|
||||
{
|
||||
struct cxl_region_params *p = data;
|
||||
struct cxl_decoder *cxld;
|
||||
struct range *r;
|
||||
|
||||
if (!is_switch_decoder(dev))
|
||||
return 0;
|
||||
|
||||
cxld = to_cxl_decoder(dev);
|
||||
r = &cxld->hpa_range;
|
||||
|
||||
if (p->res && p->res->start == r->start && p->res->end == r->end)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cxl_decoder *cxl_region_find_decoder(struct cxl_port *port,
|
||||
struct cxl_region *cxlr)
|
||||
{
|
||||
struct device *dev;
|
||||
int id = 0;
|
||||
|
||||
dev = device_find_child(&port->dev, &id, match_free_decoder);
|
||||
if (test_bit(CXL_REGION_F_AUTO, &cxlr->flags))
|
||||
dev = device_find_child(&port->dev, &cxlr->params,
|
||||
match_auto_decoder);
|
||||
else
|
||||
dev = device_find_child(&port->dev, &id, match_free_decoder);
|
||||
if (!dev)
|
||||
return NULL;
|
||||
/*
|
||||
@@ -1154,16 +1176,15 @@ static int cxl_port_setup_targets(struct cxl_port *port,
|
||||
}
|
||||
|
||||
/*
|
||||
* If @parent_port is masking address bits, pick the next unused address
|
||||
* bit to route @port's targets.
|
||||
* Interleave granularity is a multiple of @parent_port granularity.
|
||||
* Multiplier is the parent port interleave ways.
|
||||
*/
|
||||
if (parent_iw > 1 && cxl_rr->nr_targets > 1) {
|
||||
u32 address_bit = max(peig + peiw, eiw + peig);
|
||||
|
||||
eig = address_bit - eiw + 1;
|
||||
} else {
|
||||
eiw = peiw;
|
||||
eig = peig;
|
||||
rc = granularity_to_eig(parent_ig * parent_iw, &eig);
|
||||
if (rc) {
|
||||
dev_dbg(&cxlr->dev,
|
||||
"%s: invalid granularity calculation (%d * %d)\n",
|
||||
dev_name(&parent_port->dev), parent_ig, parent_iw);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = eig_to_granularity(eig, &ig);
|
||||
|
||||
+3
-4
@@ -529,7 +529,6 @@ static int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
|
||||
|
||||
static int cxl_pci_ras_unmask(struct pci_dev *pdev)
|
||||
{
|
||||
struct pci_host_bridge *host_bridge = pci_find_host_bridge(pdev->bus);
|
||||
struct cxl_dev_state *cxlds = pci_get_drvdata(pdev);
|
||||
void __iomem *addr;
|
||||
u32 orig_val, val, mask;
|
||||
@@ -541,9 +540,9 @@ static int cxl_pci_ras_unmask(struct pci_dev *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* BIOS has CXL error control */
|
||||
if (!host_bridge->native_cxl_error)
|
||||
return -ENXIO;
|
||||
/* BIOS has PCIe AER error control */
|
||||
if (!pcie_aer_is_native(pdev))
|
||||
return 0;
|
||||
|
||||
rc = pcie_capability_read_word(pdev, PCI_EXP_DEVCTL, &cap);
|
||||
if (rc)
|
||||
|
||||
@@ -1863,15 +1863,15 @@ static int cs_dsp_adsp2_setup_algs(struct cs_dsp *dsp)
|
||||
return PTR_ERR(adsp2_alg);
|
||||
|
||||
for (i = 0; i < n_algs; i++) {
|
||||
cs_dsp_info(dsp,
|
||||
"%d: ID %x v%d.%d.%d XM@%x YM@%x ZM@%x\n",
|
||||
i, be32_to_cpu(adsp2_alg[i].alg.id),
|
||||
(be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff0000) >> 16,
|
||||
(be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff00) >> 8,
|
||||
be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff,
|
||||
be32_to_cpu(adsp2_alg[i].xm),
|
||||
be32_to_cpu(adsp2_alg[i].ym),
|
||||
be32_to_cpu(adsp2_alg[i].zm));
|
||||
cs_dsp_dbg(dsp,
|
||||
"%d: ID %x v%d.%d.%d XM@%x YM@%x ZM@%x\n",
|
||||
i, be32_to_cpu(adsp2_alg[i].alg.id),
|
||||
(be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff0000) >> 16,
|
||||
(be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff00) >> 8,
|
||||
be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff,
|
||||
be32_to_cpu(adsp2_alg[i].xm),
|
||||
be32_to_cpu(adsp2_alg[i].ym),
|
||||
be32_to_cpu(adsp2_alg[i].zm));
|
||||
|
||||
alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_XM,
|
||||
adsp2_alg[i].alg.id,
|
||||
@@ -1996,14 +1996,14 @@ static int cs_dsp_halo_setup_algs(struct cs_dsp *dsp)
|
||||
return PTR_ERR(halo_alg);
|
||||
|
||||
for (i = 0; i < n_algs; i++) {
|
||||
cs_dsp_info(dsp,
|
||||
"%d: ID %x v%d.%d.%d XM@%x YM@%x\n",
|
||||
i, be32_to_cpu(halo_alg[i].alg.id),
|
||||
(be32_to_cpu(halo_alg[i].alg.ver) & 0xff0000) >> 16,
|
||||
(be32_to_cpu(halo_alg[i].alg.ver) & 0xff00) >> 8,
|
||||
be32_to_cpu(halo_alg[i].alg.ver) & 0xff,
|
||||
be32_to_cpu(halo_alg[i].xm_base),
|
||||
be32_to_cpu(halo_alg[i].ym_base));
|
||||
cs_dsp_dbg(dsp,
|
||||
"%d: ID %x v%d.%d.%d XM@%x YM@%x\n",
|
||||
i, be32_to_cpu(halo_alg[i].alg.id),
|
||||
(be32_to_cpu(halo_alg[i].alg.ver) & 0xff0000) >> 16,
|
||||
(be32_to_cpu(halo_alg[i].alg.ver) & 0xff00) >> 8,
|
||||
be32_to_cpu(halo_alg[i].alg.ver) & 0xff,
|
||||
be32_to_cpu(halo_alg[i].xm_base),
|
||||
be32_to_cpu(halo_alg[i].ym_base));
|
||||
|
||||
ret = cs_dsp_halo_create_regions(dsp, halo_alg[i].alg.id,
|
||||
halo_alg[i].alg.ver,
|
||||
|
||||
@@ -623,6 +623,34 @@ static __init int match_config_table(const efi_guid_t *guid,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* reserve_unaccepted - Map and reserve unaccepted configuration table
|
||||
* @unaccepted: Pointer to unaccepted memory table
|
||||
*
|
||||
* memblock_add() makes sure that the table is mapped in direct mapping. During
|
||||
* normal boot it happens automatically because the table is allocated from
|
||||
* usable memory. But during crashkernel boot only memory specifically reserved
|
||||
* for crash scenario is mapped. memblock_add() forces the table to be mapped
|
||||
* in crashkernel case.
|
||||
*
|
||||
* Align the range to the nearest page borders. Ranges smaller than page size
|
||||
* are not going to be mapped.
|
||||
*
|
||||
* memblock_reserve() makes sure that future allocations will not touch the
|
||||
* table.
|
||||
*/
|
||||
|
||||
static __init void reserve_unaccepted(struct efi_unaccepted_memory *unaccepted)
|
||||
{
|
||||
phys_addr_t start, size;
|
||||
|
||||
start = PAGE_ALIGN_DOWN(efi.unaccepted);
|
||||
size = PAGE_ALIGN(sizeof(*unaccepted) + unaccepted->size);
|
||||
|
||||
memblock_add(start, size);
|
||||
memblock_reserve(start, size);
|
||||
}
|
||||
|
||||
int __init efi_config_parse_tables(const efi_config_table_t *config_tables,
|
||||
int count,
|
||||
const efi_config_table_type_t *arch_tables)
|
||||
@@ -751,11 +779,9 @@ int __init efi_config_parse_tables(const efi_config_table_t *config_tables,
|
||||
|
||||
unaccepted = early_memremap(efi.unaccepted, sizeof(*unaccepted));
|
||||
if (unaccepted) {
|
||||
unsigned long size;
|
||||
|
||||
if (unaccepted->version == 1) {
|
||||
size = sizeof(*unaccepted) + unaccepted->size;
|
||||
memblock_reserve(efi.unaccepted, size);
|
||||
reserve_unaccepted(unaccepted);
|
||||
} else {
|
||||
efi.unaccepted = EFI_INVALID_TABLE_ADDR;
|
||||
}
|
||||
|
||||
+23
-37
@@ -19,6 +19,7 @@
|
||||
#include <linux/irq.h>
|
||||
#include <linux/irq_sim.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/minmax.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
@@ -685,52 +686,32 @@ gpio_sim_device_config_live_show(struct config_item *item, char *page)
|
||||
return sprintf(page, "%c\n", live ? '1' : '0');
|
||||
}
|
||||
|
||||
static char **gpio_sim_make_line_names(struct gpio_sim_bank *bank,
|
||||
unsigned int *line_names_size)
|
||||
static unsigned int gpio_sim_get_line_names_size(struct gpio_sim_bank *bank)
|
||||
{
|
||||
unsigned int max_offset = 0;
|
||||
bool has_line_names = false;
|
||||
struct gpio_sim_line *line;
|
||||
char **line_names;
|
||||
unsigned int size = 0;
|
||||
|
||||
list_for_each_entry(line, &bank->line_list, siblings) {
|
||||
if (line->offset >= bank->num_lines)
|
||||
if (!line->name || (line->offset >= bank->num_lines))
|
||||
continue;
|
||||
|
||||
if (line->name) {
|
||||
if (line->offset > max_offset)
|
||||
max_offset = line->offset;
|
||||
|
||||
/*
|
||||
* max_offset can stay at 0 so it's not an indicator
|
||||
* of whether line names were configured at all.
|
||||
*/
|
||||
has_line_names = true;
|
||||
}
|
||||
size = max(size, line->offset + 1);
|
||||
}
|
||||
|
||||
if (!has_line_names)
|
||||
/*
|
||||
* This is not an error - NULL means, there are no line
|
||||
* names configured.
|
||||
*/
|
||||
return NULL;
|
||||
return size;
|
||||
}
|
||||
|
||||
*line_names_size = max_offset + 1;
|
||||
|
||||
line_names = kcalloc(*line_names_size, sizeof(*line_names), GFP_KERNEL);
|
||||
if (!line_names)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
static void
|
||||
gpio_sim_set_line_names(struct gpio_sim_bank *bank, char **line_names)
|
||||
{
|
||||
struct gpio_sim_line *line;
|
||||
|
||||
list_for_each_entry(line, &bank->line_list, siblings) {
|
||||
if (line->offset >= bank->num_lines)
|
||||
if (!line->name || (line->offset >= bank->num_lines))
|
||||
continue;
|
||||
|
||||
if (line->name && (line->offset <= max_offset))
|
||||
line_names[line->offset] = line->name;
|
||||
line_names[line->offset] = line->name;
|
||||
}
|
||||
|
||||
return line_names;
|
||||
}
|
||||
|
||||
static void gpio_sim_remove_hogs(struct gpio_sim_device *dev)
|
||||
@@ -834,7 +815,7 @@ gpio_sim_make_bank_swnode(struct gpio_sim_bank *bank,
|
||||
struct fwnode_handle *parent)
|
||||
{
|
||||
struct property_entry properties[GPIO_SIM_PROP_MAX];
|
||||
unsigned int prop_idx = 0, line_names_size = 0;
|
||||
unsigned int prop_idx = 0, line_names_size;
|
||||
char **line_names __free(kfree) = NULL;
|
||||
|
||||
memset(properties, 0, sizeof(properties));
|
||||
@@ -845,14 +826,19 @@ gpio_sim_make_bank_swnode(struct gpio_sim_bank *bank,
|
||||
properties[prop_idx++] = PROPERTY_ENTRY_STRING("gpio-sim,label",
|
||||
bank->label);
|
||||
|
||||
line_names = gpio_sim_make_line_names(bank, &line_names_size);
|
||||
if (IS_ERR(line_names))
|
||||
return ERR_CAST(line_names);
|
||||
line_names_size = gpio_sim_get_line_names_size(bank);
|
||||
if (line_names_size) {
|
||||
line_names = kcalloc(line_names_size, sizeof(*line_names),
|
||||
GFP_KERNEL);
|
||||
if (!line_names)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
gpio_sim_set_line_names(bank, line_names);
|
||||
|
||||
if (line_names)
|
||||
properties[prop_idx++] = PROPERTY_ENTRY_STRING_ARRAY_LEN(
|
||||
"gpio-line-names",
|
||||
line_names, line_names_size);
|
||||
}
|
||||
|
||||
return fwnode_create_software_node(properties, parent);
|
||||
}
|
||||
|
||||
@@ -195,7 +195,7 @@ static int tb10x_gpio_probe(struct platform_device *pdev)
|
||||
handle_edge_irq, IRQ_NOREQUEST, IRQ_NOPROBE,
|
||||
IRQ_GC_INIT_MASK_CACHE);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_remove_domain;
|
||||
|
||||
gc = tb10x_gpio->domain->gc->gc[0];
|
||||
gc->reg_base = tb10x_gpio->base;
|
||||
@@ -209,6 +209,10 @@ static int tb10x_gpio_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_remove_domain:
|
||||
irq_domain_remove(tb10x_gpio->domain);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tb10x_gpio_remove(struct platform_device *pdev)
|
||||
|
||||
@@ -136,7 +136,7 @@ config DRM_FBDEV_EMULATION
|
||||
bool "Enable legacy fbdev support for your modesetting driver"
|
||||
depends on DRM
|
||||
select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE
|
||||
default y
|
||||
default FB
|
||||
help
|
||||
Choose this option if you have a need for the legacy fbdev
|
||||
support. Note that this support also provides the linux console
|
||||
|
||||
@@ -1776,7 +1776,7 @@ static ssize_t amdgpu_atombios_get_vbios_version(struct device *dev,
|
||||
struct amdgpu_device *adev = drm_to_adev(ddev);
|
||||
struct atom_context *ctx = adev->mode_info.atom_context;
|
||||
|
||||
return sysfs_emit(buf, "%s\n", ctx->vbios_ver_str);
|
||||
return sysfs_emit(buf, "%s\n", ctx->vbios_pn);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(vbios_version, 0444, amdgpu_atombios_get_vbios_version,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user