Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4d4fb97a authored by Jiri Kosina's avatar Jiri Kosina
Browse files

Merge branch 'topic/livepatch' of...

Merge branch 'topic/livepatch' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux

 into for-4.7/livepatching-ppc64le

Pull livepatching support for ppc64 architecture from Michael Ellerman.

Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parents 61bf12d3 85baa095
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -94,6 +94,7 @@ config PPC
	select OF_RESERVED_MEM
	select HAVE_FTRACE_MCOUNT_RECORD
	select HAVE_DYNAMIC_FTRACE
	select HAVE_DYNAMIC_FTRACE_WITH_REGS if MPROFILE_KERNEL
	select HAVE_FUNCTION_TRACER
	select HAVE_FUNCTION_GRAPH_TRACER
	select SYSCTL_EXCEPTION_TRACE
@@ -158,6 +159,7 @@ config PPC
	select ARCH_HAS_DEVMEM_IS_ALLOWED
	select HAVE_ARCH_SECCOMP_FILTER
	select ARCH_HAS_UBSAN_SANITIZE_ALL
	select HAVE_LIVEPATCH if HAVE_DYNAMIC_FTRACE_WITH_REGS

config GENERIC_CSUM
	def_bool CPU_LITTLE_ENDIAN
@@ -373,6 +375,24 @@ config PPC_TRANSACTIONAL_MEM
       ---help---
         Support user-mode Transactional Memory on POWERPC.

config DISABLE_MPROFILE_KERNEL
	bool "Disable use of mprofile-kernel for kernel tracing"
	depends on PPC64 && CPU_LITTLE_ENDIAN
	default y
	help
	  Selecting this options disables use of the mprofile-kernel ABI for
	  kernel tracing. That will cause options such as live patching
	  (CONFIG_LIVEPATCH) which depend on CONFIG_DYNAMIC_FTRACE_WITH_REGS to
	  be disabled also.

	  If you have a toolchain which supports mprofile-kernel, then you can
	  enable this. Otherwise leave it disabled. If you're not sure, say
	  "N".

config MPROFILE_KERNEL
	depends on PPC64 && CPU_LITTLE_ENDIAN
	def_bool !DISABLE_MPROFILE_KERNEL

config IOMMU_HELPER
	def_bool PPC64

@@ -1087,3 +1107,5 @@ config PPC_LIB_RHEAP
	bool

source "arch/powerpc/kvm/Kconfig"

source "kernel/livepatch/Kconfig"
+15 −0
Original line number Diff line number Diff line
@@ -133,6 +133,21 @@ else
CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=powerpc64
endif

ifdef CONFIG_MPROFILE_KERNEL
    ifeq ($(shell $(srctree)/arch/powerpc/scripts/gcc-check-mprofile-kernel.sh $(CC) -I$(srctree)/include -D__KERNEL__),OK)
        CC_FLAGS_FTRACE := -pg -mprofile-kernel
        KBUILD_CPPFLAGS += -DCC_USING_MPROFILE_KERNEL
    else
        # If the user asked for mprofile-kernel but the toolchain doesn't
        # support it, emit a warning and deliberately break the build later
        # with mprofile-kernel-not-supported. We would prefer to make this an
        # error right here, but then the user would never be able to run
        # oldconfig to change their configuration.
        $(warning Compiler does not support mprofile-kernel, set CONFIG_DISABLE_MPROFILE_KERNEL)
        CC_FLAGS_FTRACE := -mprofile-kernel-not-supported
    endif
endif

CFLAGS-$(CONFIG_CELL_CPU) += $(call cc-option,-mcpu=cell)
CFLAGS-$(CONFIG_POWER4_CPU) += $(call cc-option,-mcpu=power4)
CFLAGS-$(CONFIG_POWER5_CPU) += $(call cc-option,-mcpu=power5)
+21 −0
Original line number Diff line number Diff line
@@ -99,4 +99,25 @@ static inline unsigned long ppc_global_function_entry(void *func)
#endif
}

#ifdef CONFIG_PPC64
/*
 * Some instruction encodings commonly used in dynamic ftracing
 * and function live patching.
 */

/* This must match the definition of STK_GOT in <asm/ppc_asm.h> */
#if defined(_CALL_ELF) && _CALL_ELF == 2
#define R2_STACK_OFFSET         24
#else
#define R2_STACK_OFFSET         40
#endif

#define PPC_INST_LD_TOC		(PPC_INST_LD  | ___PPC_RT(__REG_R2) | \
				 ___PPC_RA(__REG_R1) | R2_STACK_OFFSET)

/* usually preceded by a mflr r0 */
#define PPC_INST_STD_LR		(PPC_INST_STD | ___PPC_RS(__REG_R0) | \
				 ___PPC_RA(__REG_R1) | PPC_LR_STKOFF)
#endif /* CONFIG_PPC64 */

#endif /* _ASM_POWERPC_CODE_PATCHING_H */
+5 −0
Original line number Diff line number Diff line
@@ -46,6 +46,8 @@
extern void _mcount(void);

#ifdef CONFIG_DYNAMIC_FTRACE
# define FTRACE_ADDR ((unsigned long)ftrace_caller)
# define FTRACE_REGS_ADDR FTRACE_ADDR
static inline unsigned long ftrace_call_adjust(unsigned long addr)
{
       /* reloction of mcount call site is the same as the address */
@@ -58,6 +60,9 @@ struct dyn_arch_ftrace {
#endif /*  CONFIG_DYNAMIC_FTRACE */
#endif /* __ASSEMBLY__ */

#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
#define ARCH_SUPPORTS_FTRACE_OPS 1
#endif
#endif

#if defined(CONFIG_FTRACE_SYSCALLS) && defined(CONFIG_PPC64) && !defined(__ASSEMBLY__)
+62 −0
Original line number Diff line number Diff line
/*
 * livepatch.h - powerpc-specific Kernel Live Patching Core
 *
 * Copyright (C) 2015-2016, SUSE, IBM Corp.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
#ifndef _ASM_POWERPC_LIVEPATCH_H
#define _ASM_POWERPC_LIVEPATCH_H

#include <linux/module.h>
#include <linux/ftrace.h>

#ifdef CONFIG_LIVEPATCH
static inline int klp_check_compiler_support(void)
{
	return 0;
}

static inline int klp_write_module_reloc(struct module *mod, unsigned long
		type, unsigned long loc, unsigned long value)
{
	/* This requires infrastructure changes; we need the loadinfos. */
	return -ENOSYS;
}

static inline void klp_arch_set_pc(struct pt_regs *regs, unsigned long ip)
{
	regs->nip = ip;
}

#define klp_get_ftrace_location klp_get_ftrace_location
static inline unsigned long klp_get_ftrace_location(unsigned long faddr)
{
	/*
	 * Live patch works only with -mprofile-kernel on PPC. In this case,
	 * the ftrace location is always within the first 16 bytes.
	 */
	return ftrace_location_range(faddr, faddr + 16);
}

static inline void klp_init_thread_info(struct thread_info *ti)
{
	/* + 1 to account for STACK_END_MAGIC */
	ti->livepatch_sp = (unsigned long *)(ti + 1) + 1;
}
#else
static void klp_init_thread_info(struct thread_info *ti) { }
#endif /* CONFIG_LIVEPATCH */

#endif /* _ASM_POWERPC_LIVEPATCH_H */
Loading