mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 14:11:52 +00:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
tools/testing/selftests/net/ioam6.sh7b1700e009
("selftests: net: modify IOAM tests for undef bits")bf77b1400a
("selftests: net: Test for the IOAM encapsulation with IPv6") Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
e15f5972b8
@ -1226,7 +1226,7 @@ PAGE_SIZE multiple when read back.
|
||||
|
||||
Note that all fields in this file are hierarchical and the
|
||||
file modified event can be generated due to an event down the
|
||||
hierarchy. For for the local events at the cgroup level see
|
||||
hierarchy. For the local events at the cgroup level see
|
||||
memory.events.local.
|
||||
|
||||
low
|
||||
@ -2170,19 +2170,19 @@ existing device files.
|
||||
|
||||
Cgroup v2 device controller has no interface files and is implemented
|
||||
on top of cgroup BPF. To control access to device files, a user may
|
||||
create bpf programs of the BPF_CGROUP_DEVICE type and attach them
|
||||
to cgroups. On an attempt to access a device file, corresponding
|
||||
BPF programs will be executed, and depending on the return value
|
||||
the attempt will succeed or fail with -EPERM.
|
||||
create bpf programs of type BPF_PROG_TYPE_CGROUP_DEVICE and attach
|
||||
them to cgroups with BPF_CGROUP_DEVICE flag. On an attempt to access a
|
||||
device file, corresponding BPF programs will be executed, and depending
|
||||
on the return value the attempt will succeed or fail with -EPERM.
|
||||
|
||||
A BPF_CGROUP_DEVICE program takes a pointer to the bpf_cgroup_dev_ctx
|
||||
structure, which describes the device access attempt: access type
|
||||
(mknod/read/write) and device (type, major and minor numbers).
|
||||
If the program returns 0, the attempt fails with -EPERM, otherwise
|
||||
it succeeds.
|
||||
A BPF_PROG_TYPE_CGROUP_DEVICE program takes a pointer to the
|
||||
bpf_cgroup_dev_ctx structure, which describes the device access attempt:
|
||||
access type (mknod/read/write) and device (type, major and minor numbers).
|
||||
If the program returns 0, the attempt fails with -EPERM, otherwise it
|
||||
succeeds.
|
||||
|
||||
An example of BPF_CGROUP_DEVICE program may be found in the kernel
|
||||
source tree in the tools/testing/selftests/bpf/progs/dev_cgroup.c file.
|
||||
An example of BPF_PROG_TYPE_CGROUP_DEVICE program may be found in
|
||||
tools/testing/selftests/bpf/progs/dev_cgroup.c in the kernel source tree.
|
||||
|
||||
|
||||
RDMA
|
||||
|
@ -1266,7 +1266,7 @@
|
||||
The VGA and EFI output is eventually overwritten by
|
||||
the real console.
|
||||
|
||||
The xen output can only be used by Xen PV guests.
|
||||
The xen option can only be used in Xen domains.
|
||||
|
||||
The sclp output can only be used on s390.
|
||||
|
||||
|
@ -22,7 +22,7 @@ properties:
|
||||
items:
|
||||
- enum:
|
||||
# ili9341 240*320 Color on stm32f429-disco board
|
||||
- st,sf-tc240t-9370-t
|
||||
- st,sf-tc240t-9370-t
|
||||
- const: ilitek,ili9341
|
||||
|
||||
reg: true
|
||||
|
@ -21,6 +21,7 @@ select:
|
||||
contains:
|
||||
enum:
|
||||
- snps,dwmac
|
||||
- snps,dwmac-3.40a
|
||||
- snps,dwmac-3.50a
|
||||
- snps,dwmac-3.610
|
||||
- snps,dwmac-3.70a
|
||||
@ -76,6 +77,7 @@ properties:
|
||||
- rockchip,rk3399-gmac
|
||||
- rockchip,rv1108-gmac
|
||||
- snps,dwmac
|
||||
- snps,dwmac-3.40a
|
||||
- snps,dwmac-3.50a
|
||||
- snps,dwmac-3.610
|
||||
- snps,dwmac-3.70a
|
||||
|
@ -300,8 +300,8 @@ pcie_replay_count
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
|
||||
:doc: pcie_replay_count
|
||||
|
||||
+GPU SmartShift Information
|
||||
============================
|
||||
GPU SmartShift Information
|
||||
==========================
|
||||
|
||||
GPU SmartShift information via sysfs
|
||||
|
||||
|
@ -111,15 +111,6 @@ Component Helper Usage
|
||||
.. kernel-doc:: drivers/gpu/drm/drm_drv.c
|
||||
:doc: component helper usage recommendations
|
||||
|
||||
IRQ Helper Library
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/drm_irq.c
|
||||
:doc: irq helpers
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/drm_irq.c
|
||||
:export:
|
||||
|
||||
Memory Manager Initialization
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
@ -7440,7 +7440,7 @@ FREESCALE IMX / MXC FEC DRIVER
|
||||
M: Joakim Zhang <qiangqing.zhang@nxp.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/net/fsl-fec.txt
|
||||
F: Documentation/devicetree/bindings/net/fsl,fec.yaml
|
||||
F: drivers/net/ethernet/freescale/fec.h
|
||||
F: drivers/net/ethernet/freescale/fec_main.c
|
||||
F: drivers/net/ethernet/freescale/fec_ptp.c
|
||||
@ -9307,7 +9307,7 @@ S: Maintained
|
||||
F: drivers/platform/x86/intel/atomisp2/led.c
|
||||
|
||||
INTEL BIOS SAR INT1092 DRIVER
|
||||
M: Shravan S <s.shravan@intel.com>
|
||||
M: Shravan Sudhakar <s.shravan@intel.com>
|
||||
M: Intel Corporation <linuxwwan@intel.com>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
S: Maintained
|
||||
@ -9629,7 +9629,7 @@ F: include/uapi/linux/isst_if.h
|
||||
F: tools/power/x86/intel-speed-select/
|
||||
|
||||
INTEL STRATIX10 FIRMWARE DRIVERS
|
||||
M: Richard Gong <richard.gong@linux.intel.com>
|
||||
M: Dinh Nguyen <dinguyen@kernel.org>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/ABI/testing/sysfs-devices-platform-stratix10-rsu
|
||||
@ -11153,6 +11153,7 @@ S: Maintained
|
||||
F: Documentation/devicetree/bindings/net/dsa/marvell.txt
|
||||
F: Documentation/networking/devlink/mv88e6xxx.rst
|
||||
F: drivers/net/dsa/mv88e6xxx/
|
||||
F: include/linux/dsa/mv88e6xxx.h
|
||||
F: include/linux/platform_data/mv88e6xxx.h
|
||||
|
||||
MARVELL ARMADA 3700 PHY DRIVERS
|
||||
|
2
Makefile
2
Makefile
@ -2,7 +2,7 @@
|
||||
VERSION = 5
|
||||
PATCHLEVEL = 15
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc4
|
||||
EXTRAVERSION = -rc5
|
||||
NAME = Opossums on Parade
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
@ -1989,8 +1989,6 @@ config ARCH_HIBERNATION_POSSIBLE
|
||||
|
||||
endmenu
|
||||
|
||||
source "drivers/firmware/Kconfig"
|
||||
|
||||
if CRYPTO
|
||||
source "arch/arm/crypto/Kconfig"
|
||||
endif
|
||||
|
@ -47,7 +47,7 @@
|
||||
};
|
||||
|
||||
gmac: eth@e0800000 {
|
||||
compatible = "st,spear600-gmac";
|
||||
compatible = "snps,dwmac-3.40a";
|
||||
reg = <0xe0800000 0x8000>;
|
||||
interrupts = <23 22>;
|
||||
interrupt-names = "macirq", "eth_wake_irq";
|
||||
|
@ -1931,8 +1931,6 @@ source "drivers/cpufreq/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
||||
source "drivers/firmware/Kconfig"
|
||||
|
||||
source "drivers/acpi/Kconfig"
|
||||
|
||||
source "arch/arm64/kvm/Kconfig"
|
||||
|
@ -43,7 +43,7 @@ void __init arm64_hugetlb_cma_reserve(void)
|
||||
#ifdef CONFIG_ARM64_4K_PAGES
|
||||
order = PUD_SHIFT - PAGE_SHIFT;
|
||||
#else
|
||||
order = CONT_PMD_SHIFT + PMD_SHIFT - PAGE_SHIFT;
|
||||
order = CONT_PMD_SHIFT - PAGE_SHIFT;
|
||||
#endif
|
||||
/*
|
||||
* HugeTLB CMA reservation is required for gigantic
|
||||
|
@ -388,8 +388,6 @@ config CRASH_DUMP
|
||||
help
|
||||
Generate crash dump after being started by kexec.
|
||||
|
||||
source "drivers/firmware/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Power management and ACPI options"
|
||||
|
@ -3316,8 +3316,6 @@ source "drivers/cpuidle/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
||||
source "drivers/firmware/Kconfig"
|
||||
|
||||
source "arch/mips/kvm/Kconfig"
|
||||
|
||||
source "arch/mips/vdso/Kconfig"
|
||||
|
@ -384,6 +384,4 @@ config KEXEC_FILE
|
||||
|
||||
endmenu
|
||||
|
||||
source "drivers/firmware/Kconfig"
|
||||
|
||||
source "drivers/parisc/Kconfig"
|
||||
|
@ -136,6 +136,14 @@ static inline void kuap_kernel_restore(struct pt_regs *regs, unsigned long kuap)
|
||||
if (kuap_is_disabled())
|
||||
return;
|
||||
|
||||
if (unlikely(kuap != KUAP_NONE)) {
|
||||
current->thread.kuap = KUAP_NONE;
|
||||
kuap_lock(kuap, false);
|
||||
}
|
||||
|
||||
if (likely(regs->kuap == KUAP_NONE))
|
||||
return;
|
||||
|
||||
current->thread.kuap = regs->kuap;
|
||||
|
||||
kuap_unlock(regs->kuap, false);
|
||||
|
@ -23,6 +23,7 @@
|
||||
#define BRANCH_ABSOLUTE 0x2
|
||||
|
||||
bool is_offset_in_branch_range(long offset);
|
||||
bool is_offset_in_cond_branch_range(long offset);
|
||||
int create_branch(struct ppc_inst *instr, const u32 *addr,
|
||||
unsigned long target, int flags);
|
||||
int create_cond_branch(struct ppc_inst *instr, const u32 *addr,
|
||||
|
@ -265,13 +265,16 @@ static inline void interrupt_nmi_enter_prepare(struct pt_regs *regs, struct inte
|
||||
local_paca->irq_soft_mask = IRQS_ALL_DISABLED;
|
||||
local_paca->irq_happened |= PACA_IRQ_HARD_DIS;
|
||||
|
||||
if (is_implicit_soft_masked(regs)) {
|
||||
// Adjust regs->softe soft implicit soft-mask, so
|
||||
// arch_irq_disabled_regs(regs) behaves as expected.
|
||||
if (!(regs->msr & MSR_EE) || is_implicit_soft_masked(regs)) {
|
||||
/*
|
||||
* Adjust regs->softe to be soft-masked if it had not been
|
||||
* reconcied (e.g., interrupt entry with MSR[EE]=0 but softe
|
||||
* not yet set disabled), or if it was in an implicit soft
|
||||
* masked state. This makes arch_irq_disabled_regs(regs)
|
||||
* behave as expected.
|
||||
*/
|
||||
regs->softe = IRQS_ALL_DISABLED;
|
||||
}
|
||||
if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG))
|
||||
BUG_ON(!arch_irq_disabled_regs(regs) && !(regs->msr & MSR_EE));
|
||||
|
||||
/* Don't do any per-CPU operations until interrupt state is fixed */
|
||||
|
||||
@ -525,10 +528,9 @@ static __always_inline long ____##func(struct pt_regs *regs)
|
||||
/* kernel/traps.c */
|
||||
DECLARE_INTERRUPT_HANDLER_NMI(system_reset_exception);
|
||||
#ifdef CONFIG_PPC_BOOK3S_64
|
||||
DECLARE_INTERRUPT_HANDLER_ASYNC(machine_check_exception);
|
||||
#else
|
||||
DECLARE_INTERRUPT_HANDLER_NMI(machine_check_exception);
|
||||
DECLARE_INTERRUPT_HANDLER_ASYNC(machine_check_exception_async);
|
||||
#endif
|
||||
DECLARE_INTERRUPT_HANDLER_NMI(machine_check_exception);
|
||||
DECLARE_INTERRUPT_HANDLER(SMIException);
|
||||
DECLARE_INTERRUPT_HANDLER(handle_hmi_exception);
|
||||
DECLARE_INTERRUPT_HANDLER(unknown_exception);
|
||||
|
@ -39,6 +39,11 @@ static inline bool security_ftr_enabled(u64 feature)
|
||||
return !!(powerpc_security_features & feature);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PPC_BOOK3S_64
|
||||
enum stf_barrier_type stf_barrier_type_get(void);
|
||||
#else
|
||||
static inline enum stf_barrier_type stf_barrier_type_get(void) { return STF_BARRIER_NONE; }
|
||||
#endif
|
||||
|
||||
// Features indicating support for Spectre/Meltdown mitigations
|
||||
|
||||
|
@ -184,6 +184,15 @@ u64 dma_iommu_get_required_mask(struct device *dev)
|
||||
struct iommu_table *tbl = get_iommu_table_base(dev);
|
||||
u64 mask;
|
||||
|
||||
if (dev_is_pci(dev)) {
|
||||
u64 bypass_mask = dma_direct_get_required_mask(dev);
|
||||
|
||||
if (dma_iommu_dma_supported(dev, bypass_mask)) {
|
||||
dev_info(dev, "%s: returning bypass mask 0x%llx\n", __func__, bypass_mask);
|
||||
return bypass_mask;
|
||||
}
|
||||
}
|
||||
|
||||
if (!tbl)
|
||||
return 0;
|
||||
|
||||
|
@ -1243,7 +1243,7 @@ EXC_COMMON_BEGIN(machine_check_common)
|
||||
li r10,MSR_RI
|
||||
mtmsrd r10,1
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl machine_check_exception
|
||||
bl machine_check_exception_async
|
||||
b interrupt_return_srr
|
||||
|
||||
|
||||
@ -1303,7 +1303,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
|
||||
subi r12,r12,1
|
||||
sth r12,PACA_IN_MCE(r13)
|
||||
|
||||
/* Invoke machine_check_exception to print MCE event and panic. */
|
||||
/*
|
||||
* Invoke machine_check_exception to print MCE event and panic.
|
||||
* This is the NMI version of the handler because we are called from
|
||||
* the early handler which is a true NMI.
|
||||
*/
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl machine_check_exception
|
||||
|
||||
@ -1665,27 +1669,30 @@ EXC_COMMON_BEGIN(program_check_common)
|
||||
*/
|
||||
|
||||
andi. r10,r12,MSR_PR
|
||||
bne 2f /* If userspace, go normal path */
|
||||
bne .Lnormal_stack /* If userspace, go normal path */
|
||||
|
||||
andis. r10,r12,(SRR1_PROGTM)@h
|
||||
bne 1f /* If TM, emergency */
|
||||
bne .Lemergency_stack /* If TM, emergency */
|
||||
|
||||
cmpdi r1,-INT_FRAME_SIZE /* check if r1 is in userspace */
|
||||
blt 2f /* normal path if not */
|
||||
blt .Lnormal_stack /* normal path if not */
|
||||
|
||||
/* Use the emergency stack */
|
||||
1: andi. r10,r12,MSR_PR /* Set CR0 correctly for label */
|
||||
.Lemergency_stack:
|
||||
andi. r10,r12,MSR_PR /* Set CR0 correctly for label */
|
||||
/* 3 in EXCEPTION_PROLOG_COMMON */
|
||||
mr r10,r1 /* Save r1 */
|
||||
ld r1,PACAEMERGSP(r13) /* Use emergency stack */
|
||||
subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */
|
||||
__ISTACK(program_check)=0
|
||||
__GEN_COMMON_BODY program_check
|
||||
b 3f
|
||||
2:
|
||||
b .Ldo_program_check
|
||||
|
||||
.Lnormal_stack:
|
||||
__ISTACK(program_check)=1
|
||||
__GEN_COMMON_BODY program_check
|
||||
3:
|
||||
|
||||
.Ldo_program_check:
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl program_check_exception
|
||||
REST_NVGPRS(r1) /* instruction emulation may change GPRs */
|
||||
|
@ -229,6 +229,9 @@ notrace void arch_local_irq_restore(unsigned long mask)
|
||||
return;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG))
|
||||
WARN_ON_ONCE(in_nmi() || in_hardirq());
|
||||
|
||||
/*
|
||||
* After the stb, interrupts are unmasked and there are no interrupts
|
||||
* pending replay. The restart sequence makes this atomic with
|
||||
@ -321,6 +324,9 @@ notrace void arch_local_irq_restore(unsigned long mask)
|
||||
if (mask)
|
||||
return;
|
||||
|
||||
if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG))
|
||||
WARN_ON_ONCE(in_nmi() || in_hardirq());
|
||||
|
||||
/*
|
||||
* From this point onward, we can take interrupts, preempt,
|
||||
* etc... unless we got hard-disabled. We check if an event
|
||||
|
@ -263,6 +263,11 @@ static int __init handle_no_stf_barrier(char *p)
|
||||
|
||||
early_param("no_stf_barrier", handle_no_stf_barrier);
|
||||
|
||||
enum stf_barrier_type stf_barrier_type_get(void)
|
||||
{
|
||||
return stf_enabled_flush_types;
|
||||
}
|
||||
|
||||
/* This is the generic flag used by other architectures */
|
||||
static int __init handle_ssbd(char *p)
|
||||
{
|
||||
|
@ -340,10 +340,16 @@ static bool exception_common(int signr, struct pt_regs *regs, int code,
|
||||
return false;
|
||||
}
|
||||
|
||||
show_signal_msg(signr, regs, code, addr);
|
||||
/*
|
||||
* Must not enable interrupts even for user-mode exception, because
|
||||
* this can be called from machine check, which may be a NMI or IRQ
|
||||
* which don't like interrupts being enabled. Could check for
|
||||
* in_hardirq || in_nmi perhaps, but there doesn't seem to be a good
|
||||
* reason why _exception() should enable irqs for an exception handler,
|
||||
* the handlers themselves do that directly.
|
||||
*/
|
||||
|
||||
if (arch_irqs_disabled())
|
||||
interrupt_cond_local_irq_enable(regs);
|
||||
show_signal_msg(signr, regs, code, addr);
|
||||
|
||||
current->thread.trap_nr = code;
|
||||
|
||||
@ -790,24 +796,22 @@ void die_mce(const char *str, struct pt_regs *regs, long err)
|
||||
* do_exit() checks for in_interrupt() and panics in that case, so
|
||||
* exit the irq/nmi before calling die.
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_PPC_BOOK3S_64))
|
||||
irq_exit();
|
||||
else
|
||||
if (in_nmi())
|
||||
nmi_exit();
|
||||
else
|
||||
irq_exit();
|
||||
die(str, regs, err);
|
||||
}
|
||||
|
||||
/*
|
||||
* BOOK3S_64 does not call this handler as a non-maskable interrupt
|
||||
* BOOK3S_64 does not usually call this handler as a non-maskable interrupt
|
||||
* (it uses its own early real-mode handler to handle the MCE proper
|
||||
* and then raises irq_work to call this handler when interrupts are
|
||||
* enabled).
|
||||
* enabled). The only time when this is not true is if the early handler
|
||||
* is unrecoverable, then it does call this directly to try to get a
|
||||
* message out.
|
||||
*/
|
||||
#ifdef CONFIG_PPC_BOOK3S_64
|
||||
DEFINE_INTERRUPT_HANDLER_ASYNC(machine_check_exception)
|
||||
#else
|
||||
DEFINE_INTERRUPT_HANDLER_NMI(machine_check_exception)
|
||||
#endif
|
||||
static void __machine_check_exception(struct pt_regs *regs)
|
||||
{
|
||||
int recover = 0;
|
||||
|
||||
@ -841,12 +845,19 @@ bail:
|
||||
/* Must die if the interrupt is not recoverable */
|
||||
if (regs_is_unrecoverable(regs))
|
||||
die_mce("Unrecoverable Machine check", regs, SIGBUS);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PPC_BOOK3S_64
|
||||
return;
|
||||
#else
|
||||
return 0;
|
||||
DEFINE_INTERRUPT_HANDLER_ASYNC(machine_check_exception_async)
|
||||
{
|
||||
__machine_check_exception(regs);
|
||||
}
|
||||
#endif
|
||||
DEFINE_INTERRUPT_HANDLER_NMI(machine_check_exception)
|
||||
{
|
||||
__machine_check_exception(regs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_INTERRUPT_HANDLER(SMIException) /* async? */
|
||||
|
@ -228,6 +228,11 @@ bool is_offset_in_branch_range(long offset)
|
||||
return (offset >= -0x2000000 && offset <= 0x1fffffc && !(offset & 0x3));
|
||||
}
|
||||
|
||||
bool is_offset_in_cond_branch_range(long offset)
|
||||
{
|
||||
return offset >= -0x8000 && offset <= 0x7fff && !(offset & 0x3);
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper to check if a given instruction is a conditional branch
|
||||
* Derived from the conditional checks in analyse_instr()
|
||||
@ -280,7 +285,7 @@ int create_cond_branch(struct ppc_inst *instr, const u32 *addr,
|
||||
offset = offset - (unsigned long)addr;
|
||||
|
||||
/* Check we can represent the target in the instruction format */
|
||||
if (offset < -0x8000 || offset > 0x7FFF || offset & 0x3)
|
||||
if (!is_offset_in_cond_branch_range(offset))
|
||||
return 1;
|
||||
|
||||
/* Mask out the flags and target, so they don't step on each other. */
|
||||
|
@ -24,16 +24,30 @@
|
||||
#define EMIT(instr) PLANT_INSTR(image, ctx->idx, instr)
|
||||
|
||||
/* Long jump; (unconditional 'branch') */
|
||||
#define PPC_JMP(dest) EMIT(PPC_INST_BRANCH | \
|
||||
(((dest) - (ctx->idx * 4)) & 0x03fffffc))
|
||||
#define PPC_JMP(dest) \
|
||||
do { \
|
||||
long offset = (long)(dest) - (ctx->idx * 4); \
|
||||
if (!is_offset_in_branch_range(offset)) { \
|
||||
pr_err_ratelimited("Branch offset 0x%lx (@%u) out of range\n", offset, ctx->idx); \
|
||||
return -ERANGE; \
|
||||
} \
|
||||
EMIT(PPC_INST_BRANCH | (offset & 0x03fffffc)); \
|
||||
} while (0)
|
||||
|
||||
/* blr; (unconditional 'branch' with link) to absolute address */
|
||||
#define PPC_BL_ABS(dest) EMIT(PPC_INST_BL | \
|
||||
(((dest) - (unsigned long)(image + ctx->idx)) & 0x03fffffc))
|
||||
/* "cond" here covers BO:BI fields. */
|
||||
#define PPC_BCC_SHORT(cond, dest) EMIT(PPC_INST_BRANCH_COND | \
|
||||
(((cond) & 0x3ff) << 16) | \
|
||||
(((dest) - (ctx->idx * 4)) & \
|
||||
0xfffc))
|
||||
#define PPC_BCC_SHORT(cond, dest) \
|
||||
do { \
|
||||
long offset = (long)(dest) - (ctx->idx * 4); \
|
||||
if (!is_offset_in_cond_branch_range(offset)) { \
|
||||
pr_err_ratelimited("Conditional branch offset 0x%lx (@%u) out of range\n", offset, ctx->idx); \
|
||||
return -ERANGE; \
|
||||
} \
|
||||
EMIT(PPC_INST_BRANCH_COND | (((cond) & 0x3ff) << 16) | (offset & 0xfffc)); \
|
||||
} while (0)
|
||||
|
||||
/* Sign-extended 32-bit immediate load */
|
||||
#define PPC_LI32(d, i) do { \
|
||||
if ((int)(uintptr_t)(i) >= -32768 && \
|
||||
@ -78,11 +92,6 @@
|
||||
#define PPC_FUNC_ADDR(d,i) do { PPC_LI32(d, i); } while(0)
|
||||
#endif
|
||||
|
||||
static inline bool is_nearbranch(int offset)
|
||||
{
|
||||
return (offset < 32768) && (offset >= -32768);
|
||||
}
|
||||
|
||||
/*
|
||||
* The fly in the ointment of code size changing from pass to pass is
|
||||
* avoided by padding the short branch case with a NOP. If code size differs
|
||||
@ -91,7 +100,7 @@ static inline bool is_nearbranch(int offset)
|
||||
* state.
|
||||
*/
|
||||
#define PPC_BCC(cond, dest) do { \
|
||||
if (is_nearbranch((dest) - (ctx->idx * 4))) { \
|
||||
if (is_offset_in_cond_branch_range((long)(dest) - (ctx->idx * 4))) { \
|
||||
PPC_BCC_SHORT(cond, dest); \
|
||||
EMIT(PPC_RAW_NOP()); \
|
||||
} else { \
|
||||
|
@ -16,18 +16,18 @@
|
||||
* with our redzone usage.
|
||||
*
|
||||
* [ prev sp ] <-------------
|
||||
* [ nv gpr save area ] 6*8 |
|
||||
* [ nv gpr save area ] 5*8 |
|
||||
* [ tail_call_cnt ] 8 |
|
||||
* [ local_tmp_var ] 8 |
|
||||
* [ local_tmp_var ] 16 |
|
||||
* fp (r31) --> [ ebpf stack space ] upto 512 |
|
||||
* [ frame header ] 32/112 |
|
||||
* sp (r1) ---> [ stack pointer ] --------------
|
||||
*/
|
||||
|
||||
/* for gpr non volatile registers BPG_REG_6 to 10 */
|
||||
#define BPF_PPC_STACK_SAVE (6*8)
|
||||
#define BPF_PPC_STACK_SAVE (5*8)
|
||||
/* for bpf JIT code internal usage */
|
||||
#define BPF_PPC_STACK_LOCALS 16
|
||||
#define BPF_PPC_STACK_LOCALS 24
|
||||
/* stack frame excluding BPF stack, ensure this is quadword aligned */
|
||||
#define BPF_PPC_STACKFRAME (STACK_FRAME_MIN_SIZE + \
|
||||
BPF_PPC_STACK_LOCALS + BPF_PPC_STACK_SAVE)
|
||||
|
@ -210,7 +210,11 @@ skip_init_ctx:
|
||||
/* Now build the prologue, body code & epilogue for real. */
|
||||
cgctx.idx = 0;
|
||||
bpf_jit_build_prologue(code_base, &cgctx);
|
||||
bpf_jit_build_body(fp, code_base, &cgctx, addrs, extra_pass);
|
||||
if (bpf_jit_build_body(fp, code_base, &cgctx, addrs, extra_pass)) {
|
||||
bpf_jit_binary_free(bpf_hdr);
|
||||
fp = org_fp;
|
||||
goto out_addrs;
|
||||
}
|
||||
bpf_jit_build_epilogue(code_base, &cgctx);
|
||||
|
||||
if (bpf_jit_enable > 1)
|
||||
|
@ -200,7 +200,7 @@ void bpf_jit_emit_func_call_rel(u32 *image, struct codegen_context *ctx, u64 fun
|
||||
}
|
||||
}
|
||||
|
||||
static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 out)
|
||||
static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 out)
|
||||
{
|
||||
/*
|
||||
* By now, the eBPF program has already setup parameters in r3-r6
|
||||
@ -261,7 +261,9 @@ static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32
|
||||
bpf_jit_emit_common_epilogue(image, ctx);
|
||||
|
||||
EMIT(PPC_RAW_BCTR());
|
||||
|
||||
/* out: */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Assemble the body code between the prologue & epilogue */
|
||||
@ -355,7 +357,7 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
|
||||
PPC_LI32(_R0, imm);
|
||||
EMIT(PPC_RAW_ADDC(dst_reg, dst_reg, _R0));
|
||||
}
|
||||
if (imm >= 0)
|
||||
if (imm >= 0 || (BPF_OP(code) == BPF_SUB && imm == 0x80000000))
|
||||
EMIT(PPC_RAW_ADDZE(dst_reg_h, dst_reg_h));
|
||||
else
|
||||
EMIT(PPC_RAW_ADDME(dst_reg_h, dst_reg_h));
|
||||
@ -623,7 +625,7 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
|
||||
EMIT(PPC_RAW_LI(dst_reg_h, 0));
|
||||
break;
|
||||
case BPF_ALU | BPF_ARSH | BPF_X: /* (s32) dst >>= src */
|
||||
EMIT(PPC_RAW_SRAW(dst_reg_h, dst_reg, src_reg));
|
||||
EMIT(PPC_RAW_SRAW(dst_reg, dst_reg, src_reg));
|
||||
break;
|
||||
case BPF_ALU64 | BPF_ARSH | BPF_X: /* (s64) dst >>= src */
|
||||
bpf_set_seen_register(ctx, tmp_reg);
|
||||
@ -1073,7 +1075,7 @@ cond_branch:
|
||||
break;
|
||||
case BPF_JMP32 | BPF_JSET | BPF_K:
|
||||
/* andi does not sign-extend the immediate */
|
||||
if (imm >= -32768 && imm < 32768) {
|
||||
if (imm >= 0 && imm < 32768) {
|
||||
/* PPC_ANDI is _only/always_ dot-form */
|
||||
EMIT(PPC_RAW_ANDI(_R0, dst_reg, imm));
|
||||
} else {
|
||||
@ -1090,7 +1092,9 @@ cond_branch:
|
||||
*/
|
||||
case BPF_JMP | BPF_TAIL_CALL:
|
||||
ctx->seen |= SEEN_TAILCALL;
|
||||
bpf_jit_emit_tail_call(image, ctx, addrs[i + 1]);
|
||||
ret = bpf_jit_emit_tail_call(image, ctx, addrs[i + 1]);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1103,7 +1107,7 @@ cond_branch:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
if (BPF_CLASS(code) == BPF_ALU && !fp->aux->verifier_zext &&
|
||||
!insn_is_zext(&insn[i + 1]))
|
||||
!insn_is_zext(&insn[i + 1]) && !(BPF_OP(code) == BPF_END && imm == 64))
|
||||
EMIT(PPC_RAW_LI(dst_reg_h, 0));
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <linux/if_vlan.h>
|
||||
#include <asm/kprobes.h>
|
||||
#include <linux/bpf.h>
|
||||
#include <asm/security_features.h>
|
||||
|
||||
#include "bpf_jit64.h"
|
||||
|
||||
@ -35,9 +36,9 @@ static inline bool bpf_has_stack_frame(struct codegen_context *ctx)
|
||||
* [ prev sp ] <-------------
|
||||
* [ ... ] |
|
||||
* sp (r1) ---> [ stack pointer ] --------------
|
||||
* [ nv gpr save area ] 6*8
|
||||
* [ nv gpr save area ] 5*8
|
||||
* [ tail_call_cnt ] 8
|
||||
* [ local_tmp_var ] 8
|
||||
* [ local_tmp_var ] 16
|
||||
* [ unused red zone ] 208 bytes protected
|
||||
*/
|
||||
static int bpf_jit_stack_local(struct codegen_context *ctx)
|
||||
@ -45,12 +46,12 @@ static int bpf_jit_stack_local(struct codegen_context *ctx)
|
||||
if (bpf_has_stack_frame(ctx))
|
||||
return STACK_FRAME_MIN_SIZE + ctx->stack_size;
|
||||
else
|
||||
return -(BPF_PPC_STACK_SAVE + 16);
|
||||
return -(BPF_PPC_STACK_SAVE + 24);
|
||||
}
|
||||
|
||||
static int bpf_jit_stack_tailcallcnt(struct codegen_context *ctx)
|
||||
{
|
||||
return bpf_jit_stack_local(ctx) + 8;
|
||||
return bpf_jit_stack_local(ctx) + 16;
|
||||
}
|
||||
|
||||
static int bpf_jit_stack_offsetof(struct codegen_context *ctx, int reg)
|
||||
@ -206,7 +207,7 @@ void bpf_jit_emit_func_call_rel(u32 *image, struct codegen_context *ctx, u64 fun
|
||||
EMIT(PPC_RAW_BCTRL());
|
||||
}
|
||||
|
||||
static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 out)
|
||||
static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 out)
|
||||
{
|
||||
/*
|
||||
* By now, the eBPF program has already setup parameters in r3, r4 and r5
|
||||
@ -267,13 +268,38 @@ static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32
|
||||
bpf_jit_emit_common_epilogue(image, ctx);
|
||||
|
||||
EMIT(PPC_RAW_BCTR());
|
||||
|
||||
/* out: */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* We spill into the redzone always, even if the bpf program has its own stackframe.
|
||||
* Offsets hardcoded based on BPF_PPC_STACK_SAVE -- see bpf_jit_stack_local()
|
||||
*/
|
||||
void bpf_stf_barrier(void);
|
||||
|
||||
asm (
|
||||
" .global bpf_stf_barrier ;"
|
||||
" bpf_stf_barrier: ;"
|
||||
" std 21,-64(1) ;"
|
||||
" std 22,-56(1) ;"
|
||||
" sync ;"
|
||||
" ld 21,-64(1) ;"
|
||||
" ld 22,-56(1) ;"
|
||||
" ori 31,31,0 ;"
|
||||
" .rept 14 ;"
|
||||
" b 1f ;"
|
||||
" 1: ;"
|
||||
" .endr ;"
|
||||
" blr ;"
|
||||
);
|
||||
|
||||
/* Assemble the body code between the prologue & epilogue */
|
||||
int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *ctx,
|
||||
u32 *addrs, bool extra_pass)
|
||||
{
|
||||
enum stf_barrier_type stf_barrier = stf_barrier_type_get();
|
||||
const struct bpf_insn *insn = fp->insnsi;
|
||||
int flen = fp->len;
|
||||
int i, ret;
|
||||
@ -328,18 +354,25 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
|
||||
EMIT(PPC_RAW_SUB(dst_reg, dst_reg, src_reg));
|
||||
goto bpf_alu32_trunc;
|
||||
case BPF_ALU | BPF_ADD | BPF_K: /* (u32) dst += (u32) imm */
|
||||
case BPF_ALU | BPF_SUB | BPF_K: /* (u32) dst -= (u32) imm */
|
||||
case BPF_ALU64 | BPF_ADD | BPF_K: /* dst += imm */
|
||||
if (!imm) {
|
||||
goto bpf_alu32_trunc;
|
||||
} else if (imm >= -32768 && imm < 32768) {
|
||||
EMIT(PPC_RAW_ADDI(dst_reg, dst_reg, IMM_L(imm)));
|
||||
} else {
|
||||
PPC_LI32(b2p[TMP_REG_1], imm);
|
||||
EMIT(PPC_RAW_ADD(dst_reg, dst_reg, b2p[TMP_REG_1]));
|
||||
}
|
||||
goto bpf_alu32_trunc;
|
||||
case BPF_ALU | BPF_SUB | BPF_K: /* (u32) dst -= (u32) imm */
|
||||
case BPF_ALU64 | BPF_SUB | BPF_K: /* dst -= imm */
|
||||
if (BPF_OP(code) == BPF_SUB)
|
||||
imm = -imm;
|
||||
if (imm) {
|
||||
if (imm >= -32768 && imm < 32768)
|
||||
EMIT(PPC_RAW_ADDI(dst_reg, dst_reg, IMM_L(imm)));
|
||||
else {
|
||||
PPC_LI32(b2p[TMP_REG_1], imm);
|
||||
EMIT(PPC_RAW_ADD(dst_reg, dst_reg, b2p[TMP_REG_1]));
|
||||
}
|
||||
if (!imm) {
|
||||
goto bpf_alu32_trunc;
|
||||
} else if (imm > -32768 && imm <= 32768) {
|
||||
EMIT(PPC_RAW_ADDI(dst_reg, dst_reg, IMM_L(-imm)));
|
||||
} else {
|
||||
PPC_LI32(b2p[TMP_REG_1], imm);
|
||||
EMIT(PPC_RAW_SUB(dst_reg, dst_reg, b2p[TMP_REG_1]));
|
||||
}
|
||||
goto bpf_alu32_trunc;
|
||||
case BPF_ALU | BPF_MUL | BPF_X: /* (u32) dst *= (u32) src */
|
||||
@ -389,8 +422,14 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
|
||||
case BPF_ALU64 | BPF_DIV | BPF_K: /* dst /= imm */
|
||||
if (imm == 0)
|
||||
return -EINVAL;
|
||||
else if (imm == 1)
|
||||
goto bpf_alu32_trunc;
|
||||
if (imm == 1) {
|
||||
if (BPF_OP(code) == BPF_DIV) {
|
||||
goto bpf_alu32_trunc;
|
||||
} else {
|
||||
EMIT(PPC_RAW_LI(dst_reg, 0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
PPC_LI32(b2p[TMP_REG_1], imm);
|
||||
switch (BPF_CLASS(code)) {
|
||||
@ -631,6 +670,29 @@ emit_clear:
|
||||
* BPF_ST NOSPEC (speculation barrier)
|
||||
*/
|
||||
case BPF_ST | BPF_NOSPEC:
|
||||
if (!security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) ||
|
||||
!security_ftr_enabled(SEC_FTR_STF_BARRIER))
|
||||
break;
|
||||
|
||||
switch (stf_barrier) {
|
||||
case STF_BARRIER_EIEIO:
|
||||
EMIT(PPC_RAW_EIEIO() | 0x02000000);
|
||||
break;
|
||||
case STF_BARRIER_SYNC_ORI:
|
||||
EMIT(PPC_RAW_SYNC());
|
||||
EMIT(PPC_RAW_LD(b2p[TMP_REG_1], _R13, 0));
|
||||
EMIT(PPC_RAW_ORI(_R31, _R31, 0));
|
||||
break;
|
||||
case STF_BARRIER_FALLBACK:
|
||||
EMIT(PPC_RAW_MFLR(b2p[TMP_REG_1]));
|
||||
PPC_LI64(12, dereference_kernel_function_descriptor(bpf_stf_barrier));
|
||||
EMIT(PPC_RAW_MTCTR(12));
|
||||
EMIT(PPC_RAW_BCTRL());
|
||||
EMIT(PPC_RAW_MTLR(b2p[TMP_REG_1]));
|
||||
break;
|
||||
case STF_BARRIER_NONE:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
@ -993,7 +1055,9 @@ cond_branch:
|
||||
*/
|
||||
case BPF_JMP | BPF_TAIL_CALL:
|
||||
ctx->seen |= SEEN_TAILCALL;
|
||||
bpf_jit_emit_tail_call(image, ctx, addrs[i + 1]);
|
||||
ret = bpf_jit_emit_tail_call(image, ctx, addrs[i + 1]);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -867,6 +867,10 @@ static int __init eeh_pseries_init(void)
|
||||
if (is_kdump_kernel() || reset_devices) {
|
||||
pr_info("Issue PHB reset ...\n");
|
||||
list_for_each_entry(phb, &hose_list, list_node) {
|
||||
// Skip if the slot is empty
|
||||
if (list_empty(&PCI_DN(phb->dn)->child_list))
|
||||
continue;
|
||||
|
||||
pdn = list_first_entry(&PCI_DN(phb->dn)->child_list, struct pci_dn, list);
|
||||
config_addr = pseries_eeh_get_pe_config_addr(pdn);
|
||||
|
||||
|
@ -507,12 +507,27 @@ static void pseries_msi_unmask(struct irq_data *d)
|
||||
irq_chip_unmask_parent(d);
|
||||
}
|
||||
|
||||
static void pseries_msi_write_msg(struct irq_data *data, struct msi_msg *msg)
|
||||
{
|
||||
struct msi_desc *entry = irq_data_get_msi_desc(data);
|
||||
|
||||
/*
|
||||
* Do not update the MSIx vector table. It's not strictly necessary
|
||||
* because the table is initialized by the underlying hypervisor, PowerVM
|
||||
* or QEMU/KVM. However, if the MSIx vector entry is cleared, any further
|
||||
* activation will fail. This can happen in some drivers (eg. IPR) which
|
||||
* deactivate an IRQ used for testing MSI support.
|
||||
*/
|
||||
entry->msg = *msg;
|
||||
}
|
||||
|
||||
static struct irq_chip pseries_pci_msi_irq_chip = {
|
||||
.name = "pSeries-PCI-MSI",
|
||||
.irq_shutdown = pseries_msi_shutdown,
|
||||
.irq_mask = pseries_msi_mask,
|
||||
.irq_unmask = pseries_msi_unmask,
|
||||
.irq_eoi = irq_chip_eoi_parent,
|
||||
.irq_write_msi_msg = pseries_msi_write_msg,
|
||||
};
|
||||
|
||||
static struct msi_domain_info pseries_msi_domain_info = {
|
||||
|
@ -561,5 +561,3 @@ menu "Power management options"
|
||||
source "kernel/power/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
||||
source "drivers/firmware/Kconfig"
|
||||
|
@ -82,4 +82,5 @@ static inline int syscall_get_arch(struct task_struct *task)
|
||||
#endif
|
||||
}
|
||||
|
||||
asmlinkage long sys_riscv_flush_icache(uintptr_t, uintptr_t, uintptr_t);
|
||||
#endif /* _ASM_RISCV_SYSCALL_H */
|
||||
|
@ -16,18 +16,24 @@
|
||||
#ifdef CONFIG_MMU
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <generated/vdso-offsets.h>
|
||||
/*
|
||||
* All systems with an MMU have a VDSO, but systems without an MMU don't
|
||||
* support shared libraries and therefor don't have one.
|
||||
*/
|
||||
#ifdef CONFIG_MMU
|
||||
|
||||
#ifndef CONFIG_GENERIC_TIME_VSYSCALL
|
||||
struct vdso_data {
|
||||
};
|
||||
#endif
|
||||
#define __VVAR_PAGES 1
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <generated/vdso-offsets.h>
|
||||
|
||||
#define VDSO_SYMBOL(base, name) \
|
||||
(void __user *)((unsigned long)(base) + __vdso_##name##_offset)
|
||||
|
||||
#endif /* CONFIG_MMU */
|
||||
|
||||
asmlinkage long sys_riscv_flush_icache(uintptr_t, uintptr_t, uintptr_t);
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* CONFIG_MMU */
|
||||
|
||||
#endif /* _ASM_RISCV_VDSO_H */
|
||||
|
@ -18,9 +18,10 @@
|
||||
#ifdef __LP64__
|
||||
#define __ARCH_WANT_NEW_STAT
|
||||
#define __ARCH_WANT_SET_GET_RLIMIT
|
||||
#define __ARCH_WANT_SYS_CLONE3
|
||||
#endif /* __LP64__ */
|
||||
|
||||
#define __ARCH_WANT_SYS_CLONE3
|
||||
|
||||
#include <asm-generic/unistd.h>
|
||||
|
||||
/*
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <asm-generic/syscalls.h>
|
||||
#include <asm/vdso.h>
|
||||
#include <asm/syscall.h>
|
||||
|
||||
#undef __SYSCALL
|
||||
|
@ -12,14 +12,24 @@
|
||||
#include <linux/binfmts.h>
|
||||
#include <linux/err.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/vdso.h>
|
||||
|
||||
#ifdef CONFIG_GENERIC_TIME_VSYSCALL
|
||||
#include <vdso/datapage.h>
|
||||
#else
|
||||
#include <asm/vdso.h>
|
||||
struct vdso_data {
|
||||
};
|
||||
#endif
|
||||
|
||||
extern char vdso_start[], vdso_end[];
|
||||
|
||||
enum vvar_pages {
|
||||
VVAR_DATA_PAGE_OFFSET,
|
||||
VVAR_NR_PAGES,
|
||||
};
|
||||
|
||||
#define VVAR_SIZE (VVAR_NR_PAGES << PAGE_SHIFT)
|
||||
|
||||
static unsigned int vdso_pages __ro_after_init;
|
||||
static struct page **vdso_pagelist __ro_after_init;
|
||||
|
||||
@ -38,7 +48,7 @@ static int __init vdso_init(void)
|
||||
|
||||
vdso_pages = (vdso_end - vdso_start) >> PAGE_SHIFT;
|
||||
vdso_pagelist =
|
||||
kcalloc(vdso_pages + 1, sizeof(struct page *), GFP_KERNEL);
|
||||
kcalloc(vdso_pages + VVAR_NR_PAGES, sizeof(struct page *), GFP_KERNEL);
|
||||
if (unlikely(vdso_pagelist == NULL)) {
|
||||
pr_err("vdso: pagelist allocation failed\n");
|
||||
return -ENOMEM;
|
||||
@ -63,38 +73,41 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
|
||||
unsigned long vdso_base, vdso_len;
|
||||
int ret;
|
||||
|
||||
vdso_len = (vdso_pages + 1) << PAGE_SHIFT;
|
||||
BUILD_BUG_ON(VVAR_NR_PAGES != __VVAR_PAGES);
|
||||
|
||||
vdso_len = (vdso_pages + VVAR_NR_PAGES) << PAGE_SHIFT;
|
||||
|
||||
if (mmap_write_lock_killable(mm))
|
||||
return -EINTR;
|
||||
|
||||
mmap_write_lock(mm);
|
||||
vdso_base = get_unmapped_area(NULL, 0, vdso_len, 0, 0);
|
||||
if (IS_ERR_VALUE(vdso_base)) {
|
||||
ret = vdso_base;
|
||||
goto end;
|
||||
}
|
||||
|
||||
mm->context.vdso = NULL;
|
||||
ret = install_special_mapping(mm, vdso_base, VVAR_SIZE,
|
||||
(VM_READ | VM_MAYREAD), &vdso_pagelist[vdso_pages]);
|
||||
if (unlikely(ret))
|
||||
goto end;
|
||||
|
||||
ret =
|
||||
install_special_mapping(mm, vdso_base + VVAR_SIZE,
|
||||
vdso_pages << PAGE_SHIFT,
|
||||
(VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC),
|
||||
vdso_pagelist);
|
||||
|
||||
if (unlikely(ret))
|
||||
goto end;
|
||||
|
||||
/*
|
||||
* Put vDSO base into mm struct. We need to do this before calling
|
||||
* install_special_mapping or the perf counter mmap tracking code
|
||||
* will fail to recognise it as a vDSO (since arch_vma_name fails).
|
||||
*/
|
||||
mm->context.vdso = (void *)vdso_base;
|
||||
mm->context.vdso = (void *)vdso_base + VVAR_SIZE;
|
||||
|
||||
ret =
|
||||
install_special_mapping(mm, vdso_base, vdso_pages << PAGE_SHIFT,
|
||||
(VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC),
|
||||
vdso_pagelist);
|
||||
|
||||
if (unlikely(ret)) {
|
||||
mm->context.vdso = NULL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
vdso_base += (vdso_pages << PAGE_SHIFT);
|
||||
ret = install_special_mapping(mm, vdso_base, PAGE_SIZE,
|
||||
(VM_READ | VM_MAYREAD), &vdso_pagelist[vdso_pages]);
|
||||
|
||||
if (unlikely(ret))
|
||||
mm->context.vdso = NULL;
|
||||
end:
|
||||
mmap_write_unlock(mm);
|
||||
return ret;
|
||||
@ -105,7 +118,7 @@ const char *arch_vma_name(struct vm_area_struct *vma)
|
||||
if (vma->vm_mm && (vma->vm_start == (long)vma->vm_mm->context.vdso))
|
||||
return "[vdso]";
|
||||
if (vma->vm_mm && (vma->vm_start ==
|
||||
(long)vma->vm_mm->context.vdso + PAGE_SIZE))
|
||||
(long)vma->vm_mm->context.vdso - VVAR_SIZE))
|
||||
return "[vdso_data]";
|
||||
return NULL;
|
||||
}
|
||||
|
@ -3,12 +3,13 @@
|
||||
* Copyright (C) 2012 Regents of the University of California
|
||||
*/
|
||||
#include <asm/page.h>
|
||||
#include <asm/vdso.h>
|
||||
|
||||
OUTPUT_ARCH(riscv)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
PROVIDE(_vdso_data = . + PAGE_SIZE);
|
||||
PROVIDE(_vdso_data = . - __VVAR_PAGES * PAGE_SIZE);
|
||||
. = SIZEOF_HEADERS;
|
||||
|
||||
.hash : { *(.hash) } :text
|
||||
|
@ -16,6 +16,8 @@ static void ipi_remote_fence_i(void *info)
|
||||
|
||||
void flush_icache_all(void)
|
||||
{
|
||||
local_flush_icache_all();
|
||||
|
||||
if (IS_ENABLED(CONFIG_RISCV_SBI))
|
||||
sbi_remote_fence_i(NULL);
|
||||
else
|
||||
|
@ -207,6 +207,8 @@ int zpci_enable_device(struct zpci_dev *);
|
||||
int zpci_disable_device(struct zpci_dev *);
|
||||
int zpci_scan_configured_device(struct zpci_dev *zdev, u32 fh);
|
||||
int zpci_deconfigure_device(struct zpci_dev *zdev);
|
||||
void zpci_device_reserved(struct zpci_dev *zdev);
|
||||
bool zpci_is_device_configured(struct zpci_dev *zdev);
|
||||
|
||||
int zpci_register_ioat(struct zpci_dev *, u8, u64, u64, u64);
|
||||
int zpci_unregister_ioat(struct zpci_dev *, u8);
|
||||
|
@ -1826,7 +1826,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
|
||||
jit.addrs = kvcalloc(fp->len + 1, sizeof(*jit.addrs), GFP_KERNEL);
|
||||
if (jit.addrs == NULL) {
|
||||
fp = orig_fp;
|
||||
goto out;
|
||||
goto free_addrs;
|
||||
}
|
||||
/*
|
||||
* Three initial passes:
|
||||
|
@ -92,7 +92,7 @@ void zpci_remove_reserved_devices(void)
|
||||
spin_unlock(&zpci_list_lock);
|
||||
|
||||
list_for_each_entry_safe(zdev, tmp, &remove, entry)
|
||||
zpci_zdev_put(zdev);
|
||||
zpci_device_reserved(zdev);
|
||||
}
|
||||
|
||||
int pci_domain_nr(struct pci_bus *bus)
|
||||
@ -751,6 +751,14 @@ error:
|
||||
return ERR_PTR(rc);
|
||||
}
|
||||
|
||||
bool zpci_is_device_configured(struct zpci_dev *zdev)
|
||||
{
|
||||
enum zpci_state state = zdev->state;
|
||||
|
||||
return state != ZPCI_FN_STATE_RESERVED &&
|
||||
state != ZPCI_FN_STATE_STANDBY;
|
||||
}
|
||||
|
||||
/**
|
||||
* zpci_scan_configured_device() - Scan a freshly configured zpci_dev
|
||||
* @zdev: The zpci_dev to be configured
|
||||
@ -822,6 +830,31 @@ int zpci_deconfigure_device(struct zpci_dev *zdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* zpci_device_reserved() - Mark device as resverved
|
||||
* @zdev: the zpci_dev that was reserved
|
||||
*
|
||||
* Handle the case that a given zPCI function was reserved by another system.
|
||||
* After a call to this function the zpci_dev can not be found via
|
||||
* get_zdev_by_fid() anymore but may still be accessible via existing
|
||||
* references though it will not be functional anymore.
|
||||
*/
|
||||
void zpci_device_reserved(struct zpci_dev *zdev)
|
||||
{
|
||||
if (zdev->has_hp_slot)
|
||||
zpci_exit_slot(zdev);
|
||||
/*
|
||||
* Remove device from zpci_list as it is going away. This also
|
||||
* makes sure we ignore subsequent zPCI events for this device.
|
||||
*/
|
||||
spin_lock(&zpci_list_lock);
|
||||
list_del(&zdev->entry);
|
||||
spin_unlock(&zpci_list_lock);
|
||||
zdev->state = ZPCI_FN_STATE_RESERVED;
|
||||
zpci_dbg(3, "rsv fid:%x\n", zdev->fid);
|
||||
zpci_zdev_put(zdev);
|
||||
}
|
||||
|
||||
void zpci_release_device(struct kref *kref)
|
||||
{
|
||||
struct zpci_dev *zdev = container_of(kref, struct zpci_dev, kref);
|
||||
@ -843,6 +876,12 @@ void zpci_release_device(struct kref *kref)
|
||||
case ZPCI_FN_STATE_STANDBY:
|
||||
if (zdev->has_hp_slot)
|
||||
zpci_exit_slot(zdev);
|
||||
spin_lock(&zpci_list_lock);
|
||||
list_del(&zdev->entry);
|
||||
spin_unlock(&zpci_list_lock);
|
||||
zpci_dbg(3, "rsv fid:%x\n", zdev->fid);
|
||||
fallthrough;
|
||||
case ZPCI_FN_STATE_RESERVED:
|
||||
if (zdev->has_resources)
|
||||
zpci_cleanup_bus_resources(zdev);
|
||||
zpci_bus_device_unregister(zdev);
|
||||
@ -851,10 +890,6 @@ void zpci_release_device(struct kref *kref)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
spin_lock(&zpci_list_lock);
|
||||
list_del(&zdev->entry);
|
||||
spin_unlock(&zpci_list_lock);
|
||||
zpci_dbg(3, "rem fid:%x\n", zdev->fid);
|
||||
kfree(zdev);
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
|
||||
/* The 0x0304 event may immediately reserve the device */
|
||||
if (!clp_get_state(zdev->fid, &state) &&
|
||||
state == ZPCI_FN_STATE_RESERVED) {
|
||||
zpci_zdev_put(zdev);
|
||||
zpci_device_reserved(zdev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -151,7 +151,7 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
|
||||
case 0x0308: /* Standby -> Reserved */
|
||||
if (!zdev)
|
||||
break;
|
||||
zpci_zdev_put(zdev);
|
||||
zpci_device_reserved(zdev);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -1405,7 +1405,7 @@ config HIGHMEM4G
|
||||
|
||||
config HIGHMEM64G
|
||||
bool "64GB"
|
||||
depends on !M486SX && !M486 && !M586 && !M586TSC && !M586MMX && !MGEODE_LX && !MGEODEGX1 && !MCYRIXIII && !MELAN && !MWINCHIPC6 && !WINCHIP3D && !MK6
|
||||
depends on !M486SX && !M486 && !M586 && !M586TSC && !M586MMX && !MGEODE_LX && !MGEODEGX1 && !MCYRIXIII && !MELAN && !MWINCHIPC6 && !MWINCHIP3D && !MK6
|
||||
select X86_PAE
|
||||
help
|
||||
Select this if you have a 32-bit processor and more than 4
|
||||
@ -2832,8 +2832,6 @@ config HAVE_ATOMIC_IOMAP
|
||||
def_bool y
|
||||
depends on X86_32
|
||||
|
||||
source "drivers/firmware/Kconfig"
|
||||
|
||||
source "arch/x86/kvm/Kconfig"
|
||||
|
||||
source "arch/x86/Kconfig.assembler"
|
||||
|
@ -25,7 +25,7 @@ static __always_inline void arch_check_user_regs(struct pt_regs *regs)
|
||||
* For !SMAP hardware we patch out CLAC on entry.
|
||||
*/
|
||||
if (boot_cpu_has(X86_FEATURE_SMAP) ||
|
||||
(IS_ENABLED(CONFIG_64_BIT) && boot_cpu_has(X86_FEATURE_XENPV)))
|
||||
(IS_ENABLED(CONFIG_64BIT) && boot_cpu_has(X86_FEATURE_XENPV)))
|
||||
mask |= X86_EFLAGS_AC;
|
||||
|
||||
WARN_ON_ONCE(flags & mask);
|
||||
|
@ -14,16 +14,19 @@ static inline int pci_xen_hvm_init(void)
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_XEN_DOM0)
|
||||
#ifdef CONFIG_XEN_PV_DOM0
|
||||
int __init pci_xen_initial_domain(void);
|
||||
int xen_find_device_domain_owner(struct pci_dev *dev);
|
||||
int xen_register_device_domain_owner(struct pci_dev *dev, uint16_t domain);
|
||||
int xen_unregister_device_domain_owner(struct pci_dev *dev);
|
||||
#else
|
||||
static inline int __init pci_xen_initial_domain(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_XEN_DOM0
|
||||
int xen_find_device_domain_owner(struct pci_dev *dev);
|
||||
int xen_register_device_domain_owner(struct pci_dev *dev, uint16_t domain);
|
||||
int xen_unregister_device_domain_owner(struct pci_dev *dev);
|
||||
#else
|
||||
static inline int xen_find_device_domain_owner(struct pci_dev *dev)
|
||||
{
|
||||
return -1;
|
||||
|
@ -326,6 +326,7 @@ static __always_inline void setup_smap(struct cpuinfo_x86 *c)
|
||||
#ifdef CONFIG_X86_SMAP
|
||||
cr4_set_bits(X86_CR4_SMAP);
|
||||
#else
|
||||
clear_cpu_cap(c, X86_FEATURE_SMAP);
|
||||
cr4_clear_bits(X86_CR4_SMAP);
|
||||
#endif
|
||||
}
|
||||
|
@ -527,12 +527,14 @@ static void domain_add_cpu(int cpu, struct rdt_resource *r)
|
||||
rdt_domain_reconfigure_cdp(r);
|
||||
|
||||
if (r->alloc_capable && domain_setup_ctrlval(r, d)) {
|
||||
kfree(d);
|
||||
kfree(hw_dom);
|
||||
return;
|
||||
}
|
||||
|
||||
if (r->mon_capable && domain_setup_mon_state(r, d)) {
|
||||
kfree(d);
|
||||
kfree(hw_dom->ctrl_val);
|
||||
kfree(hw_dom->mbps_val);
|
||||
kfree(hw_dom);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -714,12 +714,6 @@ static struct chipset early_qrk[] __initdata = {
|
||||
*/
|
||||
{ PCI_VENDOR_ID_INTEL, 0x0f00,
|
||||
PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet},
|
||||
{ PCI_VENDOR_ID_INTEL, 0x3e20,
|
||||
PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet},
|
||||
{ PCI_VENDOR_ID_INTEL, 0x3ec4,
|
||||
PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet},
|
||||
{ PCI_VENDOR_ID_INTEL, 0x8a12,
|
||||
PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet},
|
||||
{ PCI_VENDOR_ID_BROADCOM, 0x4331,
|
||||
PCI_CLASS_NETWORK_OTHER, PCI_ANY_ID, 0, apple_airport_reset},
|
||||
{}
|
||||
|
@ -379,9 +379,14 @@ static int __fpu_restore_sig(void __user *buf, void __user *buf_fx,
|
||||
sizeof(fpu->state.fxsave)))
|
||||
return -EFAULT;
|
||||
|
||||
/* Reject invalid MXCSR values. */
|
||||
if (fpu->state.fxsave.mxcsr & ~mxcsr_feature_mask)
|
||||
return -EINVAL;
|
||||
if (IS_ENABLED(CONFIG_X86_64)) {
|
||||
/* Reject invalid MXCSR values. */
|
||||
if (fpu->state.fxsave.mxcsr & ~mxcsr_feature_mask)
|
||||
return -EINVAL;
|
||||
} else {
|
||||
/* Mask invalid bits out for historical reasons (broken hardware). */
|
||||
fpu->state.fxsave.mxcsr &= ~mxcsr_feature_mask;
|
||||
}
|
||||
|
||||
/* Enforce XFEATURE_MASK_FPSSE when XSAVE is enabled */
|
||||
if (use_xsave())
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <asm/irq_remapping.h>
|
||||
#include <asm/hpet.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/mwait.h>
|
||||
|
||||
#undef pr_fmt
|
||||
#define pr_fmt(fmt) "hpet: " fmt
|
||||
@ -916,6 +917,83 @@ static bool __init hpet_counting(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool __init mwait_pc10_supported(void)
|
||||
{
|
||||
unsigned int eax, ebx, ecx, mwait_substates;
|
||||
|
||||
if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
|
||||
return false;
|
||||
|
||||
if (!cpu_feature_enabled(X86_FEATURE_MWAIT))
|
||||
return false;
|
||||
|
||||
if (boot_cpu_data.cpuid_level < CPUID_MWAIT_LEAF)
|
||||
return false;
|
||||
|
||||
cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &mwait_substates);
|
||||
|
||||
return (ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) &&
|
||||
(ecx & CPUID5_ECX_INTERRUPT_BREAK) &&
|
||||
(mwait_substates & (0xF << 28));
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether the system supports PC10. If so force disable HPET as that
|
||||
* stops counting in PC10. This check is overbroad as it does not take any
|
||||
* of the following into account:
|
||||
*
|
||||
* - ACPI tables
|
||||
* - Enablement of intel_idle
|
||||
* - Command line arguments which limit intel_idle C-state support
|
||||
*
|
||||
* That's perfectly fine. HPET is a piece of hardware designed by committee
|
||||
* and the only reasons why it is still in use on modern systems is the
|
||||
* fact that it is impossible to reliably query TSC and CPU frequency via
|
||||
* CPUID or firmware.
|
||||
*
|
||||
* If HPET is functional it is useful for calibrating TSC, but this can be
|
||||
* done via PMTIMER as well which seems to be the last remaining timer on
|
||||
* X86/INTEL platforms that has not been completely wreckaged by feature
|
||||
* creep.
|
||||
*
|
||||
* In theory HPET support should be removed altogether, but there are older
|
||||
* systems out there which depend on it because TSC and APIC timer are
|
||||
* dysfunctional in deeper C-states.
|
||||
*
|
||||
* It's only 20 years now that hardware people have been asked to provide
|
||||
* reliable and discoverable facilities which can be used for timekeeping
|
||||
* and per CPU timer interrupts.
|
||||
*
|
||||
* The probability that this problem is going to be solved in the
|
||||
* forseeable future is close to zero, so the kernel has to be cluttered
|
||||
* with heuristics to keep up with the ever growing amount of hardware and
|
||||
* firmware trainwrecks. Hopefully some day hardware people will understand
|
||||
* that the approach of "This can be fixed in software" is not sustainable.
|
||||
* Hope dies last...
|
||||
*/
|
||||
static bool __init hpet_is_pc10_damaged(void)
|
||||
{
|
||||
unsigned long long pcfg;
|
||||
|
||||
/* Check whether PC10 substates are supported */
|
||||
if (!mwait_pc10_supported())
|
||||
return false;
|
||||
|
||||
/* Check whether PC10 is enabled in PKG C-state limit */
|
||||
rdmsrl(MSR_PKG_CST_CONFIG_CONTROL, pcfg);
|
||||
if ((pcfg & 0xF) < 8)
|
||||
return false;
|
||||
|
||||
if (hpet_force_user) {
|
||||
pr_warn("HPET force enabled via command line, but dysfunctional in PC10.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
pr_info("HPET dysfunctional in PC10. Force disabled.\n");
|
||||
boot_hpet_disable = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* hpet_enable - Try to setup the HPET timer. Returns 1 on success.
|
||||
*/
|
||||
@ -929,6 +1007,9 @@ int __init hpet_enable(void)
|
||||
if (!is_hpet_capable())
|
||||
return 0;
|
||||
|
||||
if (hpet_is_pc10_damaged())
|
||||
return 0;
|
||||
|
||||
hpet_set_mapping();
|
||||
if (!hpet_virt_address)
|
||||
return 0;
|
||||
|
@ -130,6 +130,8 @@ static enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb,
|
||||
} else {
|
||||
ret = ES_VMM_ERROR;
|
||||
}
|
||||
} else if (ghcb->save.sw_exit_info_1 & 0xffffffff) {
|
||||
ret = ES_VMM_ERROR;
|
||||
} else {
|
||||
ret = ES_OK;
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ static int acpi_register_gsi_xen_hvm(struct device *dev, u32 gsi,
|
||||
false /* no mapping of GSI to PIRQ */);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_XEN_DOM0
|
||||
#ifdef CONFIG_XEN_PV_DOM0
|
||||
static int xen_register_gsi(u32 gsi, int triggering, int polarity)
|
||||
{
|
||||
int rc, irq;
|
||||
@ -261,7 +261,7 @@ error:
|
||||
return irq;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_XEN_DOM0
|
||||
#ifdef CONFIG_XEN_PV_DOM0
|
||||
static bool __read_mostly pci_seg_supported = true;
|
||||
|
||||
static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
|
||||
@ -375,10 +375,10 @@ static void xen_initdom_restore_msi_irqs(struct pci_dev *dev)
|
||||
WARN(ret && ret != -ENOSYS, "restore_msi -> %d\n", ret);
|
||||
}
|
||||
}
|
||||
#else /* CONFIG_XEN_DOM0 */
|
||||
#else /* CONFIG_XEN_PV_DOM0 */
|
||||
#define xen_initdom_setup_msi_irqs NULL
|
||||
#define xen_initdom_restore_msi_irqs NULL
|
||||
#endif /* !CONFIG_XEN_DOM0 */
|
||||
#endif /* !CONFIG_XEN_PV_DOM0 */
|
||||
|
||||
static void xen_teardown_msi_irqs(struct pci_dev *dev)
|
||||
{
|
||||
@ -555,7 +555,7 @@ int __init pci_xen_hvm_init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_XEN_DOM0
|
||||
#ifdef CONFIG_XEN_PV_DOM0
|
||||
int __init pci_xen_initial_domain(void)
|
||||
{
|
||||
int irq;
|
||||
@ -583,6 +583,9 @@ int __init pci_xen_initial_domain(void)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_XEN_DOM0
|
||||
|
||||
struct xen_device_domain_owner {
|
||||
domid_t domain;
|
||||
@ -656,4 +659,4 @@ int xen_unregister_device_domain_owner(struct pci_dev *dev)
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xen_unregister_device_domain_owner);
|
||||
#endif
|
||||
#endif /* CONFIG_XEN_DOM0 */
|
||||
|
@ -274,7 +274,7 @@ static struct olpc_ec_driver ec_xo1_driver = {
|
||||
|
||||
static struct olpc_ec_driver ec_xo1_5_driver = {
|
||||
.ec_cmd = olpc_xo1_ec_cmd,
|
||||
#ifdef CONFIG_OLPC_XO1_5_SCI
|
||||
#ifdef CONFIG_OLPC_XO15_SCI
|
||||
/*
|
||||
* XO-1.5 EC wakeups are available when olpc-xo15-sci driver is
|
||||
* compiled in
|
||||
|
@ -16,15 +16,15 @@
|
||||
/*
|
||||
* PVH variables.
|
||||
*
|
||||
* pvh_bootparams and pvh_start_info need to live in the data segment since
|
||||
* pvh_bootparams and pvh_start_info need to live in a data segment since
|
||||
* they are used after startup_{32|64}, which clear .bss, are invoked.
|
||||
*/
|
||||
struct boot_params pvh_bootparams __section(".data");
|
||||
struct hvm_start_info pvh_start_info __section(".data");
|
||||
struct boot_params __initdata pvh_bootparams;
|
||||
struct hvm_start_info __initdata pvh_start_info;
|
||||
|
||||
unsigned int pvh_start_info_sz = sizeof(pvh_start_info);
|
||||
const unsigned int __initconst pvh_start_info_sz = sizeof(pvh_start_info);
|
||||
|
||||
static u64 pvh_get_root_pointer(void)
|
||||
static u64 __init pvh_get_root_pointer(void)
|
||||
{
|
||||
return pvh_start_info.rsdp_paddr;
|
||||
}
|
||||
@ -107,7 +107,7 @@ void __init __weak xen_pvh_init(struct boot_params *boot_params)
|
||||
BUG();
|
||||
}
|
||||
|
||||
static void hypervisor_specific_init(bool xen_guest)
|
||||
static void __init hypervisor_specific_init(bool xen_guest)
|
||||
{
|
||||
if (xen_guest)
|
||||
xen_pvh_init(&pvh_bootparams);
|
||||
|
@ -43,13 +43,9 @@ config XEN_PV_SMP
|
||||
def_bool y
|
||||
depends on XEN_PV && SMP
|
||||
|
||||
config XEN_DOM0
|
||||
bool "Xen PV Dom0 support"
|
||||
default y
|
||||
depends on XEN_PV && PCI_XEN && SWIOTLB_XEN
|
||||
depends on X86_IO_APIC && ACPI && PCI
|
||||
help
|
||||
Support running as a Xen PV Dom0 guest.
|
||||
config XEN_PV_DOM0
|
||||
def_bool y
|
||||
depends on XEN_PV && XEN_DOM0
|
||||
|
||||
config XEN_PVHVM
|
||||
def_bool y
|
||||
@ -86,3 +82,12 @@ config XEN_PVH
|
||||
def_bool n
|
||||
help
|
||||
Support for running as a Xen PVH guest.
|
||||
|
||||
config XEN_DOM0
|
||||
bool "Xen Dom0 support"
|
||||
default XEN_PV
|
||||
depends on (XEN_PV && SWIOTLB_XEN) || (XEN_PVH && X86_64)
|
||||
depends on X86_IO_APIC && ACPI && PCI
|
||||
select X86_X2APIC if XEN_PVH && X86_64
|
||||
help
|
||||
Support running as a Xen Dom0 guest.
|
||||
|
@ -45,7 +45,7 @@ obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o
|
||||
|
||||
obj-$(CONFIG_XEN_DEBUG_FS) += debugfs.o
|
||||
|
||||
obj-$(CONFIG_XEN_DOM0) += vga.o
|
||||
obj-$(CONFIG_XEN_PV_DOM0) += vga.o
|
||||
|
||||
obj-$(CONFIG_SWIOTLB_XEN) += pci-swiotlb-xen.o
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
#ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG
|
||||
#include <linux/memblock.h>
|
||||
#endif
|
||||
#include <linux/console.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/kexec.h>
|
||||
#include <linux/slab.h>
|
||||
@ -10,12 +11,15 @@
|
||||
|
||||
#include <xen/xen.h>
|
||||
#include <xen/features.h>
|
||||
#include <xen/interface/sched.h>
|
||||
#include <xen/interface/version.h>
|
||||
#include <xen/page.h>
|
||||
|
||||
#include <asm/xen/hypercall.h>
|
||||
#include <asm/xen/hypervisor.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/e820/api.h>
|
||||
#include <asm/setup.h>
|
||||
|
||||
#include "xen-ops.h"
|
||||
#include "smp.h"
|
||||
@ -52,9 +56,6 @@ DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info);
|
||||
DEFINE_PER_CPU(uint32_t, xen_vcpu_id);
|
||||
EXPORT_PER_CPU_SYMBOL(xen_vcpu_id);
|
||||
|
||||
enum xen_domain_type xen_domain_type = XEN_NATIVE;
|
||||
EXPORT_SYMBOL_GPL(xen_domain_type);
|
||||
|
||||
unsigned long *machine_to_phys_mapping = (void *)MACH2PHYS_VIRT_START;
|
||||
EXPORT_SYMBOL(machine_to_phys_mapping);
|
||||
unsigned long machine_to_phys_nr;
|
||||
@ -69,10 +70,12 @@ __read_mostly int xen_have_vector_callback;
|
||||
EXPORT_SYMBOL_GPL(xen_have_vector_callback);
|
||||
|
||||
/*
|
||||
* NB: needs to live in .data because it's used by xen_prepare_pvh which runs
|
||||
* before clearing the bss.
|
||||
* NB: These need to live in .data or alike because they're used by
|
||||
* xen_prepare_pvh() which runs before clearing the bss.
|
||||
*/
|
||||
uint32_t xen_start_flags __section(".data") = 0;
|
||||
enum xen_domain_type __ro_after_init xen_domain_type = XEN_NATIVE;
|
||||
EXPORT_SYMBOL_GPL(xen_domain_type);
|
||||
uint32_t __ro_after_init xen_start_flags;
|
||||
EXPORT_SYMBOL(xen_start_flags);
|
||||
|
||||
/*
|
||||
@ -258,6 +261,45 @@ int xen_vcpu_setup(int cpu)
|
||||
return ((per_cpu(xen_vcpu, cpu) == NULL) ? -ENODEV : 0);
|
||||
}
|
||||
|
||||
void __init xen_banner(void)
|
||||
{
|
||||
unsigned version = HYPERVISOR_xen_version(XENVER_version, NULL);
|
||||
struct xen_extraversion extra;
|
||||
|
||||
HYPERVISOR_xen_version(XENVER_extraversion, &extra);
|
||||
|
||||
pr_info("Booting kernel on %s\n", pv_info.name);
|
||||
pr_info("Xen version: %u.%u%s%s\n",
|
||||
version >> 16, version & 0xffff, extra.extraversion,
|
||||
xen_feature(XENFEAT_mmu_pt_update_preserve_ad)
|
||||
? " (preserve-AD)" : "");
|
||||
}
|
||||
|
||||
/* Check if running on Xen version (major, minor) or later */
|
||||
bool xen_running_on_version_or_later(unsigned int major, unsigned int minor)
|
||||
{
|
||||
unsigned int version;
|
||||
|
||||
if (!xen_domain())
|
||||
return false;
|
||||
|
||||
version = HYPERVISOR_xen_version(XENVER_version, NULL);
|
||||
if ((((version >> 16) == major) && ((version & 0xffff) >= minor)) ||
|
||||
((version >> 16) > major))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void __init xen_add_preferred_consoles(void)
|
||||
{
|
||||
add_preferred_console("xenboot", 0, NULL);
|
||||
if (!boot_params.screen_info.orig_video_isVGA)
|
||||
add_preferred_console("tty", 0, NULL);
|
||||
add_preferred_console("hvc", 0, NULL);
|
||||
if (boot_params.screen_info.orig_video_isVGA)
|
||||
add_preferred_console("tty", 0, NULL);
|
||||
}
|
||||
|
||||
void xen_reboot(int reason)
|
||||
{
|
||||
struct sched_shutdown r = { .reason = reason };
|
||||
|
@ -28,7 +28,6 @@
|
||||
#include <linux/mm.h>
|
||||
#include <linux/page-flags.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/edd.h>
|
||||
@ -109,17 +108,6 @@ struct tls_descs {
|
||||
*/
|
||||
static DEFINE_PER_CPU(struct tls_descs, shadow_tls_desc);
|
||||
|
||||
static void __init xen_banner(void)
|
||||
{
|
||||
unsigned version = HYPERVISOR_xen_version(XENVER_version, NULL);
|
||||
struct xen_extraversion extra;
|
||||
HYPERVISOR_xen_version(XENVER_extraversion, &extra);
|
||||
|
||||
pr_info("Booting paravirtualized kernel on %s\n", pv_info.name);
|
||||
pr_info("Xen version: %d.%d%s (preserve-AD)\n",
|
||||
version >> 16, version & 0xffff, extra.extraversion);
|
||||
}
|
||||
|
||||
static void __init xen_pv_init_platform(void)
|
||||
{
|
||||
populate_extra_pte(fix_to_virt(FIX_PARAVIRT_BOOTMAP));
|
||||
@ -142,22 +130,6 @@ static void __init xen_pv_guest_late_init(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Check if running on Xen version (major, minor) or later */
|
||||
bool
|
||||
xen_running_on_version_or_later(unsigned int major, unsigned int minor)
|
||||
{
|
||||
unsigned int version;
|
||||
|
||||
if (!xen_domain())
|
||||
return false;
|
||||
|
||||
version = HYPERVISOR_xen_version(XENVER_version, NULL);
|
||||
if ((((version >> 16) == major) && ((version & 0xffff) >= minor)) ||
|
||||
((version >> 16) > major))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static __read_mostly unsigned int cpuid_leaf5_ecx_val;
|
||||
static __read_mostly unsigned int cpuid_leaf5_edx_val;
|
||||
|
||||
@ -1364,7 +1336,6 @@ asmlinkage __visible void __init xen_start_kernel(void)
|
||||
boot_params.hdr.hardware_subarch = X86_SUBARCH_XEN;
|
||||
|
||||
if (!xen_initial_domain()) {
|
||||
add_preferred_console("xenboot", 0, NULL);
|
||||
if (pci_xen)
|
||||
x86_init.pci.arch_init = pci_xen_init;
|
||||
x86_platform.set_legacy_features =
|
||||
@ -1409,11 +1380,7 @@ asmlinkage __visible void __init xen_start_kernel(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!boot_params.screen_info.orig_video_isVGA)
|
||||
add_preferred_console("tty", 0, NULL);
|
||||
add_preferred_console("hvc", 0, NULL);
|
||||
if (boot_params.screen_info.orig_video_isVGA)
|
||||
add_preferred_console("tty", 0, NULL);
|
||||
xen_add_preferred_consoles();
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
/* PCI BIOS service won't work from a PV guest. */
|
||||
|
@ -1,5 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/export.h>
|
||||
|
||||
#include <xen/hvc-console.h>
|
||||
|
||||
@ -18,10 +19,11 @@
|
||||
/*
|
||||
* PVH variables.
|
||||
*
|
||||
* The variable xen_pvh needs to live in the data segment since it is used
|
||||
* The variable xen_pvh needs to live in a data segment since it is used
|
||||
* after startup_{32|64} is invoked, which will clear the .bss segment.
|
||||
*/
|
||||
bool xen_pvh __section(".data") = 0;
|
||||
bool __ro_after_init xen_pvh;
|
||||
EXPORT_SYMBOL_GPL(xen_pvh);
|
||||
|
||||
void __init xen_pvh_init(struct boot_params *boot_params)
|
||||
{
|
||||
@ -36,6 +38,10 @@ void __init xen_pvh_init(struct boot_params *boot_params)
|
||||
pfn = __pa(hypercall_page);
|
||||
wrmsr_safe(msr, (u32)pfn, (u32)(pfn >> 32));
|
||||
|
||||
if (xen_initial_domain())
|
||||
x86_init.oem.arch_setup = xen_add_preferred_consoles;
|
||||
x86_init.oem.banner = xen_banner;
|
||||
|
||||
xen_efi_init(boot_params);
|
||||
}
|
||||
|
||||
|
@ -2398,7 +2398,7 @@ static int remap_area_pfn_pte_fn(pte_t *ptep, unsigned long addr, void *data)
|
||||
|
||||
int xen_remap_pfn(struct vm_area_struct *vma, unsigned long addr,
|
||||
xen_pfn_t *pfn, int nr, int *err_ptr, pgprot_t prot,
|
||||
unsigned int domid, bool no_translate, struct page **pages)
|
||||
unsigned int domid, bool no_translate)
|
||||
{
|
||||
int err = 0;
|
||||
struct remap_data rmd;
|
||||
|
@ -51,6 +51,7 @@ void __init xen_remap_memory(void);
|
||||
phys_addr_t __init xen_find_free_area(phys_addr_t size);
|
||||
char * __init xen_memory_setup(void);
|
||||
void __init xen_arch_setup(void);
|
||||
void xen_banner(void);
|
||||
void xen_enable_sysenter(void);
|
||||
void xen_enable_syscall(void);
|
||||
void xen_vcpu_restore(void);
|
||||
@ -109,7 +110,7 @@ static inline void xen_uninit_lock_cpu(int cpu)
|
||||
|
||||
struct dom0_vga_console_info;
|
||||
|
||||
#ifdef CONFIG_XEN_DOM0
|
||||
#ifdef CONFIG_XEN_PV_DOM0
|
||||
void __init xen_init_vga(const struct dom0_vga_console_info *, size_t size);
|
||||
#else
|
||||
static inline void __init xen_init_vga(const struct dom0_vga_console_info *info,
|
||||
@ -118,6 +119,8 @@ static inline void __init xen_init_vga(const struct dom0_vga_console_info *info,
|
||||
}
|
||||
#endif
|
||||
|
||||
void xen_add_preferred_consoles(void);
|
||||
|
||||
void __init xen_init_apic(void);
|
||||
|
||||
#ifdef CONFIG_XEN_EFI
|
||||
|
@ -78,7 +78,7 @@
|
||||
#endif
|
||||
#define XCHAL_KIO_SIZE 0x10000000
|
||||
|
||||
#if (!XCHAL_HAVE_PTP_MMU || XCHAL_HAVE_SPANNING_WAY) && defined(CONFIG_OF)
|
||||
#if (!XCHAL_HAVE_PTP_MMU || XCHAL_HAVE_SPANNING_WAY) && defined(CONFIG_USE_OF)
|
||||
#define XCHAL_KIO_PADDR xtensa_get_kio_paddr()
|
||||
#ifndef __ASSEMBLY__
|
||||
extern unsigned long xtensa_kio_paddr;
|
||||
|
@ -143,7 +143,7 @@ unsigned xtensa_get_ext_irq_no(unsigned irq)
|
||||
|
||||
void __init init_IRQ(void)
|
||||
{
|
||||
#ifdef CONFIG_OF
|
||||
#ifdef CONFIG_USE_OF
|
||||
irqchip_init();
|
||||
#else
|
||||
#ifdef CONFIG_HAVE_SMP
|
||||
|
@ -63,7 +63,7 @@ extern unsigned long initrd_end;
|
||||
extern int initrd_below_start_ok;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
#ifdef CONFIG_USE_OF
|
||||
void *dtb_start = __dtb_start;
|
||||
#endif
|
||||
|
||||
@ -125,7 +125,7 @@ __tagtable(BP_TAG_INITRD, parse_tag_initrd);
|
||||
|
||||
#endif /* CONFIG_BLK_DEV_INITRD */
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
#ifdef CONFIG_USE_OF
|
||||
|
||||
static int __init parse_tag_fdt(const bp_tag_t *tag)
|
||||
{
|
||||
@ -135,7 +135,7 @@ static int __init parse_tag_fdt(const bp_tag_t *tag)
|
||||
|
||||
__tagtable(BP_TAG_FDT, parse_tag_fdt);
|
||||
|
||||
#endif /* CONFIG_OF */
|
||||
#endif /* CONFIG_USE_OF */
|
||||
|
||||
static int __init parse_tag_cmdline(const bp_tag_t* tag)
|
||||
{
|
||||
@ -183,7 +183,7 @@ static int __init parse_bootparam(const bp_tag_t *tag)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
#ifdef CONFIG_USE_OF
|
||||
|
||||
#if !XCHAL_HAVE_PTP_MMU || XCHAL_HAVE_SPANNING_WAY
|
||||
unsigned long xtensa_kio_paddr = XCHAL_KIO_DEFAULT_PADDR;
|
||||
@ -232,7 +232,7 @@ void __init early_init_devtree(void *params)
|
||||
strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_OF */
|
||||
#endif /* CONFIG_USE_OF */
|
||||
|
||||
/*
|
||||
* Initialize architecture. (Early stage)
|
||||
@ -253,7 +253,7 @@ void __init init_arch(bp_tag_t *bp_start)
|
||||
if (bp_start)
|
||||
parse_bootparam(bp_start);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
#ifdef CONFIG_USE_OF
|
||||
early_init_devtree(dtb_start);
|
||||
#endif
|
||||
|
||||
|
@ -101,7 +101,7 @@ void init_mmu(void)
|
||||
|
||||
void init_kio(void)
|
||||
{
|
||||
#if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY && defined(CONFIG_OF)
|
||||
#if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY && defined(CONFIG_USE_OF)
|
||||
/*
|
||||
* Update the IO area mapping in case xtensa_kio_paddr has changed
|
||||
*/
|
||||
|
@ -51,8 +51,12 @@ void platform_power_off(void)
|
||||
|
||||
void platform_restart(void)
|
||||
{
|
||||
/* Flush and reset the mmu, simulate a processor reset, and
|
||||
* jump to the reset vector. */
|
||||
/* Try software reset first. */
|
||||
WRITE_ONCE(*(u32 *)XTFPGA_SWRST_VADDR, 0xdead);
|
||||
|
||||
/* If software reset did not work, flush and reset the mmu,
|
||||
* simulate a processor reset, and jump to the reset vector.
|
||||
*/
|
||||
cpu_reset();
|
||||
/* control never gets here */
|
||||
}
|
||||
@ -66,7 +70,7 @@ void __init platform_calibrate_ccount(void)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
#ifdef CONFIG_USE_OF
|
||||
|
||||
static void __init xtfpga_clk_setup(struct device_node *np)
|
||||
{
|
||||
@ -284,4 +288,4 @@ static int __init xtavnet_init(void)
|
||||
*/
|
||||
arch_initcall(xtavnet_init);
|
||||
|
||||
#endif /* CONFIG_OF */
|
||||
#endif /* CONFIG_USE_OF */
|
||||
|
@ -490,7 +490,6 @@ struct block_device *bdev_alloc(struct gendisk *disk, u8 partno)
|
||||
bdev = I_BDEV(inode);
|
||||
mutex_init(&bdev->bd_fsfreeze_mutex);
|
||||
spin_lock_init(&bdev->bd_size_lock);
|
||||
bdev->bd_disk = disk;
|
||||
bdev->bd_partno = partno;
|
||||
bdev->bd_inode = inode;
|
||||
bdev->bd_stats = alloc_percpu(struct disk_stats);
|
||||
@ -498,6 +497,7 @@ struct block_device *bdev_alloc(struct gendisk *disk, u8 partno)
|
||||
iput(inode);
|
||||
return NULL;
|
||||
}
|
||||
bdev->bd_disk = disk;
|
||||
return bdev;
|
||||
}
|
||||
|
||||
|
@ -129,6 +129,7 @@ static const char *const blk_queue_flag_name[] = {
|
||||
QUEUE_FLAG_NAME(PCI_P2PDMA),
|
||||
QUEUE_FLAG_NAME(ZONE_RESETALL),
|
||||
QUEUE_FLAG_NAME(RQ_ALLOC_TIME),
|
||||
QUEUE_FLAG_NAME(HCTX_ACTIVE),
|
||||
QUEUE_FLAG_NAME(NOWAIT),
|
||||
};
|
||||
#undef QUEUE_FLAG_NAME
|
||||
|
@ -1268,6 +1268,7 @@ struct gendisk *__alloc_disk_node(struct request_queue *q, int node_id,
|
||||
|
||||
out_destroy_part_tbl:
|
||||
xa_destroy(&disk->part_tbl);
|
||||
disk->part0->bd_disk = NULL;
|
||||
iput(disk->part0->bd_inode);
|
||||
out_free_bdi:
|
||||
bdi_put(disk->bdi);
|
||||
|
@ -17,6 +17,8 @@ source "drivers/bus/Kconfig"
|
||||
|
||||
source "drivers/connector/Kconfig"
|
||||
|
||||
source "drivers/firmware/Kconfig"
|
||||
|
||||
source "drivers/gnss/Kconfig"
|
||||
|
||||
source "drivers/mtd/Kconfig"
|
||||
|
@ -36,7 +36,7 @@ struct acpi_gtdt_descriptor {
|
||||
|
||||
static struct acpi_gtdt_descriptor acpi_gtdt_desc __initdata;
|
||||
|
||||
static inline void *next_platform_timer(void *platform_timer)
|
||||
static inline __init void *next_platform_timer(void *platform_timer)
|
||||
{
|
||||
struct acpi_gtdt_header *gh = platform_timer;
|
||||
|
||||
|
@ -2,4 +2,4 @@
|
||||
obj-$(CONFIG_TEST_ASYNC_DRIVER_PROBE) += test_async_driver_probe.o
|
||||
|
||||
obj-$(CONFIG_DRIVER_PE_KUNIT_TEST) += property-entry-test.o
|
||||
CFLAGS_REMOVE_property-entry-test.o += -fplugin-arg-structleak_plugin-byref -fplugin-arg-structleak_plugin-byref-all
|
||||
CFLAGS_property-entry-test.o += $(DISABLE_STRUCTLEAK_PLUGIN)
|
||||
|
@ -203,10 +203,7 @@ config INTEL_STRATIX10_RSU
|
||||
Say Y here if you want Intel RSU support.
|
||||
|
||||
config QCOM_SCM
|
||||
tristate "Qcom SCM driver"
|
||||
depends on ARCH_QCOM || COMPILE_TEST
|
||||
depends on HAVE_ARM_SMCCC
|
||||
select RESET_CONTROLLER
|
||||
tristate
|
||||
|
||||
config QCOM_SCM_DOWNLOAD_MODE_DEFAULT
|
||||
bool "Qualcomm download mode enabled by default"
|
||||
|
@ -1087,6 +1087,7 @@ struct amdgpu_device {
|
||||
|
||||
bool no_hw_access;
|
||||
struct pci_saved_state *pci_state;
|
||||
pci_channel_state_t pci_channel_state;
|
||||
|
||||
struct amdgpu_reset_control *reset_cntl;
|
||||
};
|
||||
|
@ -563,6 +563,7 @@ kfd_mem_dmaunmap_userptr(struct kgd_mem *mem,
|
||||
|
||||
dma_unmap_sgtable(adev->dev, ttm->sg, direction, 0);
|
||||
sg_free_table(ttm->sg);
|
||||
kfree(ttm->sg);
|
||||
ttm->sg = NULL;
|
||||
}
|
||||
|
||||
|
@ -2394,10 +2394,6 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
|
||||
if (r)
|
||||
goto init_failed;
|
||||
|
||||
r = amdgpu_amdkfd_resume_iommu(adev);
|
||||
if (r)
|
||||
goto init_failed;
|
||||
|
||||
r = amdgpu_device_ip_hw_init_phase1(adev);
|
||||
if (r)
|
||||
goto init_failed;
|
||||
@ -2436,6 +2432,10 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
|
||||
if (!adev->gmc.xgmi.pending_reset)
|
||||
amdgpu_amdkfd_device_init(adev);
|
||||
|
||||
r = amdgpu_amdkfd_resume_iommu(adev);
|
||||
if (r)
|
||||
goto init_failed;
|
||||
|
||||
amdgpu_fru_get_product_info(adev);
|
||||
|
||||
init_failed:
|
||||
@ -5399,6 +5399,8 @@ pci_ers_result_t amdgpu_pci_error_detected(struct pci_dev *pdev, pci_channel_sta
|
||||
return PCI_ERS_RESULT_DISCONNECT;
|
||||
}
|
||||
|
||||
adev->pci_channel_state = state;
|
||||
|
||||
switch (state) {
|
||||
case pci_channel_io_normal:
|
||||
return PCI_ERS_RESULT_CAN_RECOVER;
|
||||
@ -5541,6 +5543,10 @@ void amdgpu_pci_resume(struct pci_dev *pdev)
|
||||
|
||||
DRM_INFO("PCI error: resume callback!!\n");
|
||||
|
||||
/* Only continue execution for the case of pci_channel_io_frozen */
|
||||
if (adev->pci_channel_state != pci_channel_io_frozen)
|
||||
return;
|
||||
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
|
||||
struct amdgpu_ring *ring = adev->rings[i];
|
||||
|
||||
|
@ -31,6 +31,8 @@
|
||||
/* delay 0.1 second to enable gfx off feature */
|
||||
#define GFX_OFF_DELAY_ENABLE msecs_to_jiffies(100)
|
||||
|
||||
#define GFX_OFF_NO_DELAY 0
|
||||
|
||||
/*
|
||||
* GPU GFX IP block helpers function.
|
||||
*/
|
||||
@ -558,6 +560,8 @@ int amdgpu_gfx_enable_kcq(struct amdgpu_device *adev)
|
||||
|
||||
void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable)
|
||||
{
|
||||
unsigned long delay = GFX_OFF_DELAY_ENABLE;
|
||||
|
||||
if (!(adev->pm.pp_feature & PP_GFXOFF_MASK))
|
||||
return;
|
||||
|
||||
@ -573,8 +577,14 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable)
|
||||
|
||||
adev->gfx.gfx_off_req_count--;
|
||||
|
||||
if (adev->gfx.gfx_off_req_count == 0 && !adev->gfx.gfx_off_state)
|
||||
schedule_delayed_work(&adev->gfx.gfx_off_delay_work, GFX_OFF_DELAY_ENABLE);
|
||||
if (adev->gfx.gfx_off_req_count == 0 &&
|
||||
!adev->gfx.gfx_off_state) {
|
||||
/* If going to s2idle, no need to wait */
|
||||
if (adev->in_s0ix)
|
||||
delay = GFX_OFF_NO_DELAY;
|
||||
schedule_delayed_work(&adev->gfx.gfx_off_delay_work,
|
||||
delay);
|
||||
}
|
||||
} else {
|
||||
if (adev->gfx.gfx_off_req_count == 0) {
|
||||
cancel_delayed_work_sync(&adev->gfx.gfx_off_delay_work);
|
||||
|
@ -1085,18 +1085,12 @@ static int kfd_resume(struct kfd_dev *kfd)
|
||||
int err = 0;
|
||||
|
||||
err = kfd->dqm->ops.start(kfd->dqm);
|
||||
if (err) {
|
||||
if (err)
|
||||
dev_err(kfd_device,
|
||||
"Error starting queue manager for device %x:%x\n",
|
||||
kfd->pdev->vendor, kfd->pdev->device);
|
||||
goto dqm_start_error;
|
||||
}
|
||||
|
||||
return err;
|
||||
|
||||
dqm_start_error:
|
||||
kfd_iommu_suspend(kfd);
|
||||
return err;
|
||||
}
|
||||
|
||||
static inline void kfd_queue_work(struct workqueue_struct *wq,
|
||||
|
@ -25,6 +25,8 @@ config DRM_AMD_DC_HDCP
|
||||
|
||||
config DRM_AMD_DC_SI
|
||||
bool "AMD DC support for Southern Islands ASICs"
|
||||
depends on DRM_AMDGPU_SI
|
||||
depends on DRM_AMD_DC
|
||||
default n
|
||||
help
|
||||
Choose this option to enable new AMD DC support for SI asics
|
||||
|
@ -1306,12 +1306,6 @@ static void override_training_settings(
|
||||
{
|
||||
uint32_t lane;
|
||||
|
||||
/* Override link settings */
|
||||
if (link->preferred_link_setting.link_rate != LINK_RATE_UNKNOWN)
|
||||
lt_settings->link_settings.link_rate = link->preferred_link_setting.link_rate;
|
||||
if (link->preferred_link_setting.lane_count != LANE_COUNT_UNKNOWN)
|
||||
lt_settings->link_settings.lane_count = link->preferred_link_setting.lane_count;
|
||||
|
||||
/* Override link spread */
|
||||
if (!link->dp_ss_off && overrides->downspread != NULL)
|
||||
lt_settings->link_settings.link_spread = *overrides->downspread ?
|
||||
|
@ -118,6 +118,7 @@ struct dcn10_link_enc_registers {
|
||||
uint32_t RDPCSTX_PHY_CNTL4;
|
||||
uint32_t RDPCSTX_PHY_CNTL5;
|
||||
uint32_t RDPCSTX_PHY_CNTL6;
|
||||
uint32_t RDPCSPIPE_PHY_CNTL6;
|
||||
uint32_t RDPCSTX_PHY_CNTL7;
|
||||
uint32_t RDPCSTX_PHY_CNTL8;
|
||||
uint32_t RDPCSTX_PHY_CNTL9;
|
||||
|
@ -37,6 +37,7 @@
|
||||
|
||||
#include "link_enc_cfg.h"
|
||||
#include "dc_dmub_srv.h"
|
||||
#include "dal_asic_id.h"
|
||||
|
||||
#define CTX \
|
||||
enc10->base.ctx
|
||||
@ -62,6 +63,10 @@
|
||||
#define AUX_REG_WRITE(reg_name, val) \
|
||||
dm_write_reg(CTX, AUX_REG(reg_name), val)
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
|
||||
#endif
|
||||
|
||||
void dcn31_link_encoder_set_dio_phy_mux(
|
||||
struct link_encoder *enc,
|
||||
enum encoder_type_select sel,
|
||||
@ -215,8 +220,8 @@ static const struct link_encoder_funcs dcn31_link_enc_funcs = {
|
||||
.fec_is_active = enc2_fec_is_active,
|
||||
.get_dig_frontend = dcn10_get_dig_frontend,
|
||||
.get_dig_mode = dcn10_get_dig_mode,
|
||||
.is_in_alt_mode = dcn20_link_encoder_is_in_alt_mode,
|
||||
.get_max_link_cap = dcn20_link_encoder_get_max_link_cap,
|
||||
.is_in_alt_mode = dcn31_link_encoder_is_in_alt_mode,
|
||||
.get_max_link_cap = dcn31_link_encoder_get_max_link_cap,
|
||||
.set_dio_phy_mux = dcn31_link_encoder_set_dio_phy_mux,
|
||||
};
|
||||
|
||||
@ -404,3 +409,60 @@ void dcn31_link_encoder_disable_output(
|
||||
}
|
||||
}
|
||||
|
||||
bool dcn31_link_encoder_is_in_alt_mode(struct link_encoder *enc)
|
||||
{
|
||||
struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
|
||||
uint32_t dp_alt_mode_disable;
|
||||
bool is_usb_c_alt_mode = false;
|
||||
|
||||
if (enc->features.flags.bits.DP_IS_USB_C) {
|
||||
if (enc->ctx->asic_id.hw_internal_rev != YELLOW_CARP_B0) {
|
||||
// [Note] no need to check hw_internal_rev once phy mux selection is ready
|
||||
REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable);
|
||||
} else {
|
||||
/*
|
||||
* B0 phys use a new set of registers to check whether alt mode is disabled.
|
||||
* if value == 1 alt mode is disabled, otherwise it is enabled.
|
||||
*/
|
||||
if ((enc10->base.transmitter == TRANSMITTER_UNIPHY_A)
|
||||
|| (enc10->base.transmitter == TRANSMITTER_UNIPHY_B)
|
||||
|| (enc10->base.transmitter == TRANSMITTER_UNIPHY_E)) {
|
||||
REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable);
|
||||
} else {
|
||||
// [Note] need to change TRANSMITTER_UNIPHY_C/D to F/G once phy mux selection is ready
|
||||
REG_GET(RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable);
|
||||
}
|
||||
}
|
||||
|
||||
is_usb_c_alt_mode = (dp_alt_mode_disable == 0);
|
||||
}
|
||||
|
||||
return is_usb_c_alt_mode;
|
||||
}
|
||||
|
||||
void dcn31_link_encoder_get_max_link_cap(struct link_encoder *enc,
|
||||
struct dc_link_settings *link_settings)
|
||||
{
|
||||
struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
|
||||
uint32_t is_in_usb_c_dp4_mode = 0;
|
||||
|
||||
dcn10_link_encoder_get_max_link_cap(enc, link_settings);
|
||||
|
||||
/* in usb c dp2 mode, max lane count is 2 */
|
||||
if (enc->funcs->is_in_alt_mode && enc->funcs->is_in_alt_mode(enc)) {
|
||||
if (enc->ctx->asic_id.hw_internal_rev != YELLOW_CARP_B0) {
|
||||
// [Note] no need to check hw_internal_rev once phy mux selection is ready
|
||||
REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &is_in_usb_c_dp4_mode);
|
||||
} else {
|
||||
if ((enc10->base.transmitter == TRANSMITTER_UNIPHY_A)
|
||||
|| (enc10->base.transmitter == TRANSMITTER_UNIPHY_B)
|
||||
|| (enc10->base.transmitter == TRANSMITTER_UNIPHY_E)) {
|
||||
REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &is_in_usb_c_dp4_mode);
|
||||
} else {
|
||||
REG_GET(RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &is_in_usb_c_dp4_mode);
|
||||
}
|
||||
}
|
||||
if (!is_in_usb_c_dp4_mode)
|
||||
link_settings->lane_count = MIN(LANE_COUNT_TWO, link_settings->lane_count);
|
||||
}
|
||||
}
|
||||
|
@ -69,6 +69,7 @@
|
||||
SRI(RDPCSTX_PHY_CNTL4, RDPCSTX, id), \
|
||||
SRI(RDPCSTX_PHY_CNTL5, RDPCSTX, id), \
|
||||
SRI(RDPCSTX_PHY_CNTL6, RDPCSTX, id), \
|
||||
SRI(RDPCSPIPE_PHY_CNTL6, RDPCSPIPE, id), \
|
||||
SRI(RDPCSTX_PHY_CNTL7, RDPCSTX, id), \
|
||||
SRI(RDPCSTX_PHY_CNTL8, RDPCSTX, id), \
|
||||
SRI(RDPCSTX_PHY_CNTL9, RDPCSTX, id), \
|
||||
@ -115,7 +116,9 @@
|
||||
LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DP_TX2_MPLL_EN, mask_sh),\
|
||||
LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DP_TX3_MPLL_EN, mask_sh),\
|
||||
LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, mask_sh),\
|
||||
LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, mask_sh),\
|
||||
LE_SF(RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, mask_sh),\
|
||||
LE_SF(RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, mask_sh),\
|
||||
LE_SF(RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE_ACK, mask_sh),\
|
||||
LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL7, RDPCS_PHY_DP_MPLLB_FRACN_QUOT, mask_sh),\
|
||||
LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL7, RDPCS_PHY_DP_MPLLB_FRACN_DEN, mask_sh),\
|
||||
LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL8, RDPCS_PHY_DP_MPLLB_SSC_PEAK, mask_sh),\
|
||||
@ -243,4 +246,13 @@ void dcn31_link_encoder_disable_output(
|
||||
struct link_encoder *enc,
|
||||
enum signal_type signal);
|
||||
|
||||
/*
|
||||
* Check whether USB-C DP Alt mode is disabled
|
||||
*/
|
||||
bool dcn31_link_encoder_is_in_alt_mode(
|
||||
struct link_encoder *enc);
|
||||
|
||||
void dcn31_link_encoder_get_max_link_cap(struct link_encoder *enc,
|
||||
struct dc_link_settings *link_settings);
|
||||
|
||||
#endif /* __DC_LINK_ENCODER__DCN31_H__ */
|
||||
|
@ -928,7 +928,7 @@ static const struct dc_debug_options debug_defaults_drv = {
|
||||
.disable_dcc = DCC_ENABLE,
|
||||
.vsr_support = true,
|
||||
.performance_trace = false,
|
||||
.max_downscale_src_width = 7680,/*upto 8K*/
|
||||
.max_downscale_src_width = 3840,/*upto 4K*/
|
||||
.disable_pplib_wm_range = false,
|
||||
.scl_reset_length10 = true,
|
||||
.sanity_checks = false,
|
||||
@ -1284,6 +1284,12 @@ static struct stream_encoder *dcn31_stream_encoder_create(
|
||||
if (!enc1 || !vpg || !afmt)
|
||||
return NULL;
|
||||
|
||||
if (ctx->asic_id.chip_family == FAMILY_YELLOW_CARP &&
|
||||
ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) {
|
||||
if ((eng_id == ENGINE_ID_DIGC) || (eng_id == ENGINE_ID_DIGD))
|
||||
eng_id = eng_id + 3; // For B0 only. C->F, D->G.
|
||||
}
|
||||
|
||||
dcn30_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios,
|
||||
eng_id, vpg, afmt,
|
||||
&stream_enc_regs[eng_id],
|
||||
|
@ -227,7 +227,7 @@ enum {
|
||||
#define FAMILY_YELLOW_CARP 146
|
||||
|
||||
#define YELLOW_CARP_A0 0x01
|
||||
#define YELLOW_CARP_B0 0x02 // TODO: DCN31 - update with correct B0 ID
|
||||
#define YELLOW_CARP_B0 0x1A
|
||||
#define YELLOW_CARP_UNKNOWN 0xFF
|
||||
|
||||
#ifndef ASICREV_IS_YELLOW_CARP
|
||||
|
@ -11932,5 +11932,32 @@
|
||||
#define ixDPCSSYS_CR4_RAWLANEX_DIG_PCS_XF_RX_OVRD_OUT_2 0xe0c7
|
||||
#define ixDPCSSYS_CR4_RAWLANEX_DIG_PCS_XF_TX_OVRD_IN_2 0xe0c8
|
||||
|
||||
//RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6
|
||||
#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DP4__SHIFT 0x10
|
||||
#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE__SHIFT 0x11
|
||||
#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_ACK__SHIFT 0x12
|
||||
#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DP4_MASK 0x00010000L
|
||||
#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_MASK 0x00020000L
|
||||
#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_ACK_MASK 0x00040000L
|
||||
|
||||
//RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6
|
||||
#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DP4__SHIFT 0x10
|
||||
#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE__SHIFT 0x11
|
||||
#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_ACK__SHIFT 0x12
|
||||
#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DP4_MASK 0x00010000L
|
||||
#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_MASK 0x00020000L
|
||||
#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_ACK_MASK 0x00040000L
|
||||
|
||||
//[Note] Hack. RDPCSPIPE only has 2 instances.
|
||||
#define regRDPCSPIPE0_RDPCSPIPE_PHY_CNTL6 0x2d73
|
||||
#define regRDPCSPIPE0_RDPCSPIPE_PHY_CNTL6_BASE_IDX 2
|
||||
#define regRDPCSPIPE1_RDPCSPIPE_PHY_CNTL6 0x2e4b
|
||||
#define regRDPCSPIPE1_RDPCSPIPE_PHY_CNTL6_BASE_IDX 2
|
||||
#define regRDPCSPIPE2_RDPCSPIPE_PHY_CNTL6 0x2d73
|
||||
#define regRDPCSPIPE2_RDPCSPIPE_PHY_CNTL6_BASE_IDX 2
|
||||
#define regRDPCSPIPE3_RDPCSPIPE_PHY_CNTL6 0x2e4b
|
||||
#define regRDPCSPIPE3_RDPCSPIPE_PHY_CNTL6_BASE_IDX 2
|
||||
#define regRDPCSPIPE4_RDPCSPIPE_PHY_CNTL6 0x2d73
|
||||
#define regRDPCSPIPE4_RDPCSPIPE_PHY_CNTL6_BASE_IDX 2
|
||||
|
||||
#endif
|
||||
|
@ -1577,8 +1577,14 @@ static void gen11_dsi_sync_state(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
enum pipe pipe = intel_crtc->pipe;
|
||||
struct intel_crtc *intel_crtc;
|
||||
enum pipe pipe;
|
||||
|
||||
if (!crtc_state)
|
||||
return;
|
||||
|
||||
intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
pipe = intel_crtc->pipe;
|
||||
|
||||
/* wa verify 1409054076:icl,jsl,ehl */
|
||||
if (DISPLAY_VER(dev_priv) == 11 && pipe == PIPE_B &&
|
||||
|
@ -1308,8 +1308,9 @@ static void i915_audio_component_init(struct drm_i915_private *dev_priv)
|
||||
else
|
||||
aud_freq = aud_freq_init;
|
||||
|
||||
/* use BIOS provided value for TGL unless it is a known bad value */
|
||||
if (IS_TIGERLAKE(dev_priv) && aud_freq_init != AUD_FREQ_TGL_BROKEN)
|
||||
/* use BIOS provided value for TGL and RKL unless it is a known bad value */
|
||||
if ((IS_TIGERLAKE(dev_priv) || IS_ROCKETLAKE(dev_priv)) &&
|
||||
aud_freq_init != AUD_FREQ_TGL_BROKEN)
|
||||
aud_freq = aud_freq_init;
|
||||
|
||||
drm_dbg_kms(&dev_priv->drm, "use AUD_FREQ_CNTRL of 0x%x (init value 0x%x)\n",
|
||||
|
@ -451,13 +451,23 @@ parse_lfp_backlight(struct drm_i915_private *i915,
|
||||
}
|
||||
|
||||
i915->vbt.backlight.type = INTEL_BACKLIGHT_DISPLAY_DDI;
|
||||
if (bdb->version >= 191 &&
|
||||
get_blocksize(backlight_data) >= sizeof(*backlight_data)) {
|
||||
const struct lfp_backlight_control_method *method;
|
||||
if (bdb->version >= 191) {
|
||||
size_t exp_size;
|
||||
|
||||
method = &backlight_data->backlight_control[panel_type];
|
||||
i915->vbt.backlight.type = method->type;
|
||||
i915->vbt.backlight.controller = method->controller;
|
||||
if (bdb->version >= 236)
|
||||
exp_size = sizeof(struct bdb_lfp_backlight_data);
|
||||
else if (bdb->version >= 234)
|
||||
exp_size = EXP_BDB_LFP_BL_DATA_SIZE_REV_234;
|
||||
else
|
||||
exp_size = EXP_BDB_LFP_BL_DATA_SIZE_REV_191;
|
||||
|
||||
if (get_blocksize(backlight_data) >= exp_size) {
|
||||
const struct lfp_backlight_control_method *method;
|
||||
|
||||
method = &backlight_data->backlight_control[panel_type];
|
||||
i915->vbt.backlight.type = method->type;
|
||||
i915->vbt.backlight.controller = method->controller;
|
||||
}
|
||||
}
|
||||
|
||||
i915->vbt.backlight.pwm_freq_hz = entry->pwm_freq_hz;
|
||||
|
@ -3807,7 +3807,13 @@ void hsw_ddi_get_config(struct intel_encoder *encoder,
|
||||
static void intel_ddi_sync_state(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
if (intel_crtc_has_dp_encoder(crtc_state))
|
||||
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
|
||||
enum phy phy = intel_port_to_phy(i915, encoder->port);
|
||||
|
||||
if (intel_phy_is_tc(i915, phy))
|
||||
intel_tc_port_sanitize(enc_to_dig_port(encoder));
|
||||
|
||||
if (crtc_state && intel_crtc_has_dp_encoder(crtc_state))
|
||||
intel_dp_sync_state(encoder, crtc_state);
|
||||
}
|
||||
|
||||
|
@ -13082,18 +13082,16 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
|
||||
readout_plane_state(dev_priv);
|
||||
|
||||
for_each_intel_encoder(dev, encoder) {
|
||||
struct intel_crtc_state *crtc_state = NULL;
|
||||
|
||||
pipe = 0;
|
||||
|
||||
if (encoder->get_hw_state(encoder, &pipe)) {
|
||||
struct intel_crtc_state *crtc_state;
|
||||
|
||||
crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
|
||||
crtc_state = to_intel_crtc_state(crtc->base.state);
|
||||
|
||||
encoder->base.crtc = &crtc->base;
|
||||
intel_encoder_get_config(encoder, crtc_state);
|
||||
if (encoder->sync_state)
|
||||
encoder->sync_state(encoder, crtc_state);
|
||||
|
||||
/* read out to slave crtc as well for bigjoiner */
|
||||
if (crtc_state->bigjoiner) {
|
||||
@ -13108,6 +13106,9 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
|
||||
encoder->base.crtc = NULL;
|
||||
}
|
||||
|
||||
if (encoder->sync_state)
|
||||
encoder->sync_state(encoder, crtc_state);
|
||||
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"[ENCODER:%d:%s] hw state readout: %s, pipe %c\n",
|
||||
encoder->base.base.id, encoder->base.name,
|
||||
@ -13390,17 +13391,6 @@ intel_modeset_setup_hw_state(struct drm_device *dev,
|
||||
intel_modeset_readout_hw_state(dev);
|
||||
|
||||
/* HW state is read out, now we need to sanitize this mess. */
|
||||
|
||||
/* Sanitize the TypeC port mode upfront, encoders depend on this */
|
||||
for_each_intel_encoder(dev, encoder) {
|
||||
enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
|
||||
|
||||
/* We need to sanitize only the MST primary port. */
|
||||
if (encoder->type != INTEL_OUTPUT_DP_MST &&
|
||||
intel_phy_is_tc(dev_priv, phy))
|
||||
intel_tc_port_sanitize(enc_to_dig_port(encoder));
|
||||
}
|
||||
|
||||
get_encoder_power_domains(dev_priv);
|
||||
|
||||
if (HAS_PCH_IBX(dev_priv))
|
||||
|
@ -814,6 +814,11 @@ struct lfp_brightness_level {
|
||||
u16 reserved;
|
||||
} __packed;
|
||||
|
||||
#define EXP_BDB_LFP_BL_DATA_SIZE_REV_191 \
|
||||
offsetof(struct bdb_lfp_backlight_data, brightness_level)
|
||||
#define EXP_BDB_LFP_BL_DATA_SIZE_REV_234 \
|
||||
offsetof(struct bdb_lfp_backlight_data, brightness_precision_bits)
|
||||
|
||||
struct bdb_lfp_backlight_data {
|
||||
u8 entry_size;
|
||||
struct lfp_backlight_data_entry data[16];
|
||||
|
@ -118,7 +118,7 @@ i915_gem_shrink(struct i915_gem_ww_ctx *ww,
|
||||
intel_wakeref_t wakeref = 0;
|
||||
unsigned long count = 0;
|
||||
unsigned long scanned = 0;
|
||||
int err;
|
||||
int err = 0;
|
||||
|
||||
/* CHV + VTD workaround use stop_machine(); need to trylock vm->mutex */
|
||||
bool trylock_vm = !ww && intel_vm_no_concurrent_access_wa(i915);
|
||||
@ -242,12 +242,15 @@ skip:
|
||||
list_splice_tail(&still_in_list, phase->list);
|
||||
spin_unlock_irqrestore(&i915->mm.obj_lock, flags);
|
||||
if (err)
|
||||
return err;
|
||||
break;
|
||||
}
|
||||
|
||||
if (shrink & I915_SHRINK_BOUND)
|
||||
intel_runtime_pm_put(&i915->runtime_pm, wakeref);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (nr_scanned)
|
||||
*nr_scanned += scanned;
|
||||
return count;
|
||||
|
@ -8193,6 +8193,11 @@ enum {
|
||||
#define HSW_SPR_STRETCH_MAX_X1 REG_FIELD_PREP(HSW_SPR_STRETCH_MAX_MASK, 3)
|
||||
#define HSW_FBCQ_DIS (1 << 22)
|
||||
#define BDW_DPRS_MASK_VBLANK_SRD (1 << 0)
|
||||
#define SKL_PLANE1_STRETCH_MAX_MASK REG_GENMASK(1, 0)
|
||||
#define SKL_PLANE1_STRETCH_MAX_X8 REG_FIELD_PREP(SKL_PLANE1_STRETCH_MAX_MASK, 0)
|
||||
#define SKL_PLANE1_STRETCH_MAX_X4 REG_FIELD_PREP(SKL_PLANE1_STRETCH_MAX_MASK, 1)
|
||||
#define SKL_PLANE1_STRETCH_MAX_X2 REG_FIELD_PREP(SKL_PLANE1_STRETCH_MAX_MASK, 2)
|
||||
#define SKL_PLANE1_STRETCH_MAX_X1 REG_FIELD_PREP(SKL_PLANE1_STRETCH_MAX_MASK, 3)
|
||||
#define CHICKEN_PIPESL_1(pipe) _MMIO_PIPE(pipe, _CHICKEN_PIPESL_1_A, _CHICKEN_PIPESL_1_B)
|
||||
|
||||
#define _CHICKEN_TRANS_A 0x420c0
|
||||
|
@ -76,6 +76,8 @@ struct intel_wm_config {
|
||||
|
||||
static void gen9_init_clock_gating(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
enum pipe pipe;
|
||||
|
||||
if (HAS_LLC(dev_priv)) {
|
||||
/*
|
||||
* WaCompressedResourceDisplayNewHashMode:skl,kbl
|
||||
@ -89,6 +91,16 @@ static void gen9_init_clock_gating(struct drm_i915_private *dev_priv)
|
||||
SKL_DE_COMPRESSED_HASH_MODE);
|
||||
}
|
||||
|
||||
for_each_pipe(dev_priv, pipe) {
|
||||
/*
|
||||
* "Plane N strech max must be programmed to 11b (x1)
|
||||
* when Async flips are enabled on that plane."
|
||||
*/
|
||||
if (!IS_GEMINILAKE(dev_priv) && intel_vtd_active())
|
||||
intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PIPESL_1(pipe),
|
||||
SKL_PLANE1_STRETCH_MAX_MASK, SKL_PLANE1_STRETCH_MAX_X1);
|
||||
}
|
||||
|
||||
/* See Bspec note for PSR2_CTL bit 31, Wa#828:skl,bxt,kbl,cfl */
|
||||
intel_uncore_write(&dev_priv->uncore, CHICKEN_PAR1_1,
|
||||
intel_uncore_read(&dev_priv->uncore, CHICKEN_PAR1_1) | SKL_EDP_PSR_FIX_RDWRAP);
|
||||
|
@ -172,10 +172,10 @@ static int kmb_setup_mode_config(struct drm_device *drm)
|
||||
ret = drmm_mode_config_init(drm);
|
||||
if (ret)
|
||||
return ret;
|
||||
drm->mode_config.min_width = KMB_MIN_WIDTH;
|
||||
drm->mode_config.min_height = KMB_MIN_HEIGHT;
|
||||
drm->mode_config.max_width = KMB_MAX_WIDTH;
|
||||
drm->mode_config.max_height = KMB_MAX_HEIGHT;
|
||||
drm->mode_config.min_width = KMB_FB_MIN_WIDTH;
|
||||
drm->mode_config.min_height = KMB_FB_MIN_HEIGHT;
|
||||
drm->mode_config.max_width = KMB_FB_MAX_WIDTH;
|
||||
drm->mode_config.max_height = KMB_FB_MAX_HEIGHT;
|
||||
drm->mode_config.funcs = &kmb_mode_config_funcs;
|
||||
|
||||
ret = kmb_setup_crtc(drm);
|
||||
|
@ -20,6 +20,11 @@
|
||||
#define DRIVER_MAJOR 1
|
||||
#define DRIVER_MINOR 1
|
||||
|
||||
#define KMB_FB_MAX_WIDTH 1920
|
||||
#define KMB_FB_MAX_HEIGHT 1080
|
||||
#define KMB_FB_MIN_WIDTH 1
|
||||
#define KMB_FB_MIN_HEIGHT 1
|
||||
|
||||
#define KMB_LCD_DEFAULT_CLK 200000000
|
||||
#define KMB_SYS_CLK_MHZ 500
|
||||
|
||||
|
@ -94,9 +94,10 @@ static int kmb_plane_atomic_check(struct drm_plane *plane,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (new_plane_state->crtc_w > KMB_MAX_WIDTH || new_plane_state->crtc_h > KMB_MAX_HEIGHT)
|
||||
return -EINVAL;
|
||||
if (new_plane_state->crtc_w < KMB_MIN_WIDTH || new_plane_state->crtc_h < KMB_MIN_HEIGHT)
|
||||
if (new_plane_state->crtc_w > KMB_FB_MAX_WIDTH ||
|
||||
new_plane_state->crtc_h > KMB_FB_MAX_HEIGHT ||
|
||||
new_plane_state->crtc_w < KMB_FB_MIN_WIDTH ||
|
||||
new_plane_state->crtc_h < KMB_FB_MIN_HEIGHT)
|
||||
return -EINVAL;
|
||||
can_position = (plane->type == DRM_PLANE_TYPE_OVERLAY);
|
||||
crtc_state =
|
||||
@ -277,6 +278,44 @@ static void config_csc(struct kmb_drm_private *kmb, int plane_id)
|
||||
kmb_write_lcd(kmb, LCD_LAYERn_CSC_OFF3(plane_id), csc_coef_lcd[11]);
|
||||
}
|
||||
|
||||
static void kmb_plane_set_alpha(struct kmb_drm_private *kmb,
|
||||
const struct drm_plane_state *state,
|
||||
unsigned char plane_id,
|
||||
unsigned int *val)
|
||||
{
|
||||
u16 plane_alpha = state->alpha;
|
||||
u16 pixel_blend_mode = state->pixel_blend_mode;
|
||||
int has_alpha = state->fb->format->has_alpha;
|
||||
|
||||
if (plane_alpha != DRM_BLEND_ALPHA_OPAQUE)
|
||||
*val |= LCD_LAYER_ALPHA_STATIC;
|
||||
|
||||
if (has_alpha) {
|
||||
switch (pixel_blend_mode) {
|
||||
case DRM_MODE_BLEND_PIXEL_NONE:
|
||||
break;
|
||||
case DRM_MODE_BLEND_PREMULTI:
|
||||
*val |= LCD_LAYER_ALPHA_EMBED | LCD_LAYER_ALPHA_PREMULT;
|
||||
break;
|
||||
case DRM_MODE_BLEND_COVERAGE:
|
||||
*val |= LCD_LAYER_ALPHA_EMBED;
|
||||
break;
|
||||
default:
|
||||
DRM_DEBUG("Missing pixel blend mode case (%s == %ld)\n",
|
||||
__stringify(pixel_blend_mode),
|
||||
(long)pixel_blend_mode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (plane_alpha == DRM_BLEND_ALPHA_OPAQUE && !has_alpha) {
|
||||
*val &= LCD_LAYER_ALPHA_DISABLED;
|
||||
return;
|
||||
}
|
||||
|
||||
kmb_write_lcd(kmb, LCD_LAYERn_ALPHA(plane_id), plane_alpha);
|
||||
}
|
||||
|
||||
static void kmb_plane_atomic_update(struct drm_plane *plane,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
@ -303,11 +342,12 @@ static void kmb_plane_atomic_update(struct drm_plane *plane,
|
||||
fb = new_plane_state->fb;
|
||||
if (!fb)
|
||||
return;
|
||||
|
||||
num_planes = fb->format->num_planes;
|
||||
kmb_plane = to_kmb_plane(plane);
|
||||
plane_id = kmb_plane->id;
|
||||
|
||||
kmb = to_kmb(plane->dev);
|
||||
plane_id = kmb_plane->id;
|
||||
|
||||
spin_lock_irq(&kmb->irq_lock);
|
||||
if (kmb->kmb_under_flow || kmb->kmb_flush_done) {
|
||||
@ -400,20 +440,32 @@ static void kmb_plane_atomic_update(struct drm_plane *plane,
|
||||
config_csc(kmb, plane_id);
|
||||
}
|
||||
|
||||
kmb_plane_set_alpha(kmb, plane->state, plane_id, &val);
|
||||
|
||||
kmb_write_lcd(kmb, LCD_LAYERn_CFG(plane_id), val);
|
||||
|
||||
/* Configure LCD_CONTROL */
|
||||
ctrl = kmb_read_lcd(kmb, LCD_CONTROL);
|
||||
|
||||
/* Set layer blending config */
|
||||
ctrl &= ~LCD_CTRL_ALPHA_ALL;
|
||||
ctrl |= LCD_CTRL_ALPHA_BOTTOM_VL1 |
|
||||
LCD_CTRL_ALPHA_BLEND_VL2;
|
||||
|
||||
ctrl &= ~LCD_CTRL_ALPHA_BLEND_BKGND_DISABLE;
|
||||
|
||||
switch (plane_id) {
|
||||
case LAYER_0:
|
||||
ctrl = LCD_CTRL_VL1_ENABLE;
|
||||
ctrl |= LCD_CTRL_VL1_ENABLE;
|
||||
break;
|
||||
case LAYER_1:
|
||||
ctrl = LCD_CTRL_VL2_ENABLE;
|
||||
ctrl |= LCD_CTRL_VL2_ENABLE;
|
||||
break;
|
||||
case LAYER_2:
|
||||
ctrl = LCD_CTRL_GL1_ENABLE;
|
||||
ctrl |= LCD_CTRL_GL1_ENABLE;
|
||||
break;
|
||||
case LAYER_3:
|
||||
ctrl = LCD_CTRL_GL2_ENABLE;
|
||||
ctrl |= LCD_CTRL_GL2_ENABLE;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -425,7 +477,7 @@ static void kmb_plane_atomic_update(struct drm_plane *plane,
|
||||
*/
|
||||
ctrl |= LCD_CTRL_VHSYNC_IDLE_LVL;
|
||||
|
||||
kmb_set_bitmask_lcd(kmb, LCD_CONTROL, ctrl);
|
||||
kmb_write_lcd(kmb, LCD_CONTROL, ctrl);
|
||||
|
||||
/* Enable pipeline AXI read transactions for the DMA
|
||||
* after setting graphics layers. This must be done
|
||||
@ -490,6 +542,9 @@ struct kmb_plane *kmb_plane_init(struct drm_device *drm)
|
||||
enum drm_plane_type plane_type;
|
||||
const u32 *plane_formats;
|
||||
int num_plane_formats;
|
||||
unsigned int blend_caps = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
|
||||
BIT(DRM_MODE_BLEND_PREMULTI) |
|
||||
BIT(DRM_MODE_BLEND_COVERAGE);
|
||||
|
||||
for (i = 0; i < KMB_MAX_PLANES; i++) {
|
||||
plane = drmm_kzalloc(drm, sizeof(*plane), GFP_KERNEL);
|
||||
@ -521,8 +576,16 @@ struct kmb_plane *kmb_plane_init(struct drm_device *drm)
|
||||
drm_dbg(drm, "%s : %d i=%d type=%d",
|
||||
__func__, __LINE__,
|
||||
i, plane_type);
|
||||
drm_plane_create_alpha_property(&plane->base_plane);
|
||||
|
||||
drm_plane_create_blend_mode_property(&plane->base_plane,
|
||||
blend_caps);
|
||||
|
||||
drm_plane_create_zpos_immutable_property(&plane->base_plane, i);
|
||||
|
||||
drm_plane_helper_add(&plane->base_plane,
|
||||
&kmb_plane_helper_funcs);
|
||||
|
||||
if (plane_type == DRM_PLANE_TYPE_PRIMARY) {
|
||||
primary = plane;
|
||||
kmb->plane = plane;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user