Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
Pull powerpc LE updates from Ben Herrenschmidt: "With my previous pull request I mentioned some remaining Little Endian patches, notably support for our new ABI, which I was sitting on making sure it was all finalized. The toolchain folks confirmed it now, the new ABI is stable and merged with gcc, so we are all good. Oh and we actually missed the actual Kconfig switch for LE so here it is, along with a couple more bug fixes. I have more fixes but not related to LE so I'll send them as a separate pull request tomorrow, let's get this one out of the way. Note that this supports running user space binaries using the new ABI, but the kernel itself still needs to be built with the old one. We'll bring fixes for that after -rc1. Here's Anton log that goes with this series: This patch series adds support for the new ABI, LPAR support for H_SET_MODE and finally adds a kconfig option and defconfig. ABIv2 support was recently committed to binutils and gcc, and should be merged into glibc soon. There are a number of very nice improvements including the removal of function descriptors. Rusty's kernel patches allow binaries of either ABI to work, easing the transition" * 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: powerpc: Wrong DWARF CFI in the kernel vdso for little-endian / ELFv2 powerpc: Add pseries_le_defconfig powerpc: Add CONFIG_CPU_LITTLE_ENDIAN kernel config option. powerpc: Don't use ELFv2 ABI to build the kernel powerpc: ELF2 binaries signal handling powerpc: ELF2 binaries launched directly. powerpc: Set eflags correctly for ELF ABIv2 core dumps. powerpc: Add TIF_ELF2ABI flag. pseries: Add H_SET_MODE to change exception endianness powerpc/pseries: Fix endian issues in pseries EEH code
This commit is contained in:
Коммит
527d151131
|
@ -111,6 +111,7 @@ endif
|
|||
endif
|
||||
|
||||
CFLAGS-$(CONFIG_PPC64) := -mtraceback=no -mcall-aixdesc
|
||||
CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mabi=elfv1)
|
||||
CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mcmodel=medium,-mminimal-toc)
|
||||
CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mno-pointers-to-nested-functions)
|
||||
CFLAGS-$(CONFIG_PPC32) := -ffixed-r2 $(MULTIPLEWORD)
|
||||
|
|
|
@ -0,0 +1,352 @@
|
|||
CONFIG_PPC64=y
|
||||
CONFIG_ALTIVEC=y
|
||||
CONFIG_VSX=y
|
||||
CONFIG_SMP=y
|
||||
CONFIG_NR_CPUS=2048
|
||||
CONFIG_CPU_LITTLE_ENDIAN=y
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_POSIX_MQUEUE=y
|
||||
CONFIG_AUDIT=y
|
||||
CONFIG_AUDITSYSCALL=y
|
||||
CONFIG_IRQ_DOMAIN_DEBUG=y
|
||||
CONFIG_NO_HZ=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_TASKSTATS=y
|
||||
CONFIG_TASK_DELAY_ACCT=y
|
||||
CONFIG_TASK_XACCT=y
|
||||
CONFIG_TASK_IO_ACCOUNTING=y
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_CGROUPS=y
|
||||
CONFIG_CGROUP_FREEZER=y
|
||||
CONFIG_CGROUP_DEVICE=y
|
||||
CONFIG_CPUSETS=y
|
||||
CONFIG_CGROUP_CPUACCT=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
CONFIG_PROFILING=y
|
||||
CONFIG_OPROFILE=y
|
||||
CONFIG_KPROBES=y
|
||||
CONFIG_JUMP_LABEL=y
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
CONFIG_MODVERSIONS=y
|
||||
CONFIG_MODULE_SRCVERSION_ALL=y
|
||||
CONFIG_PARTITION_ADVANCED=y
|
||||
CONFIG_PPC_SPLPAR=y
|
||||
CONFIG_SCANLOG=m
|
||||
CONFIG_PPC_SMLPAR=y
|
||||
CONFIG_DTL=y
|
||||
# CONFIG_PPC_PMAC is not set
|
||||
CONFIG_RTAS_FLASH=m
|
||||
CONFIG_IBMEBUS=y
|
||||
CONFIG_HZ_100=y
|
||||
CONFIG_BINFMT_MISC=m
|
||||
CONFIG_PPC_TRANSACTIONAL_MEM=y
|
||||
CONFIG_KEXEC=y
|
||||
CONFIG_IRQ_ALL_CPUS=y
|
||||
CONFIG_MEMORY_HOTPLUG=y
|
||||
CONFIG_MEMORY_HOTREMOVE=y
|
||||
CONFIG_CMA=y
|
||||
CONFIG_PPC_64K_PAGES=y
|
||||
CONFIG_PPC_SUBPAGE_PROT=y
|
||||
CONFIG_SCHED_SMT=y
|
||||
CONFIG_HOTPLUG_PCI=y
|
||||
CONFIG_HOTPLUG_PCI_RPA=m
|
||||
CONFIG_HOTPLUG_PCI_RPA_DLPAR=m
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_XFRM_USER=m
|
||||
CONFIG_NET_KEY=m
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
CONFIG_NET_IPIP=y
|
||||
CONFIG_SYN_COOKIES=y
|
||||
CONFIG_INET_AH=m
|
||||
CONFIG_INET_ESP=m
|
||||
CONFIG_INET_IPCOMP=m
|
||||
# CONFIG_IPV6 is not set
|
||||
CONFIG_NETFILTER=y
|
||||
CONFIG_NF_CONNTRACK=m
|
||||
CONFIG_NF_CONNTRACK_EVENTS=y
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=m
|
||||
CONFIG_NF_CONNTRACK_FTP=m
|
||||
CONFIG_NF_CONNTRACK_IRC=m
|
||||
CONFIG_NF_CONNTRACK_TFTP=m
|
||||
CONFIG_NF_CT_NETLINK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
|
||||
CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
|
||||
CONFIG_NETFILTER_XT_MATCH_COMMENT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
|
||||
CONFIG_NETFILTER_XT_MATCH_DCCP=m
|
||||
CONFIG_NETFILTER_XT_MATCH_DSCP=m
|
||||
CONFIG_NETFILTER_XT_MATCH_ESP=m
|
||||
CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_HELPER=m
|
||||
CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
|
||||
CONFIG_NETFILTER_XT_MATCH_LENGTH=m
|
||||
CONFIG_NETFILTER_XT_MATCH_LIMIT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_MAC=m
|
||||
CONFIG_NETFILTER_XT_MATCH_MARK=m
|
||||
CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_OWNER=m
|
||||
CONFIG_NETFILTER_XT_MATCH_POLICY=m
|
||||
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
|
||||
CONFIG_NETFILTER_XT_MATCH_QUOTA=m
|
||||
CONFIG_NETFILTER_XT_MATCH_RATEEST=m
|
||||
CONFIG_NETFILTER_XT_MATCH_REALM=m
|
||||
CONFIG_NETFILTER_XT_MATCH_RECENT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_SCTP=m
|
||||
CONFIG_NETFILTER_XT_MATCH_STATE=m
|
||||
CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
|
||||
CONFIG_NETFILTER_XT_MATCH_STRING=m
|
||||
CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
|
||||
CONFIG_NETFILTER_XT_MATCH_TIME=m
|
||||
CONFIG_NETFILTER_XT_MATCH_U32=m
|
||||
CONFIG_NF_CONNTRACK_IPV4=m
|
||||
CONFIG_IP_NF_IPTABLES=m
|
||||
CONFIG_IP_NF_MATCH_AH=m
|
||||
CONFIG_IP_NF_MATCH_ECN=m
|
||||
CONFIG_IP_NF_MATCH_TTL=m
|
||||
CONFIG_IP_NF_FILTER=m
|
||||
CONFIG_IP_NF_TARGET_REJECT=m
|
||||
CONFIG_IP_NF_TARGET_ULOG=m
|
||||
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_DEVTMPFS_MOUNT=y
|
||||
CONFIG_PROC_DEVICETREE=y
|
||||
CONFIG_PARPORT=m
|
||||
CONFIG_PARPORT_PC=m
|
||||
CONFIG_BLK_DEV_FD=m
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
CONFIG_BLK_DEV_NBD=m
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_BLK_DEV_RAM_SIZE=65536
|
||||
CONFIG_VIRTIO_BLK=m
|
||||
CONFIG_IDE=y
|
||||
CONFIG_BLK_DEV_IDECD=y
|
||||
CONFIG_BLK_DEV_GENERIC=y
|
||||
CONFIG_BLK_DEV_AMD74XX=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_CHR_DEV_ST=y
|
||||
CONFIG_BLK_DEV_SR=y
|
||||
CONFIG_BLK_DEV_SR_VENDOR=y
|
||||
CONFIG_CHR_DEV_SG=y
|
||||
CONFIG_SCSI_MULTI_LUN=y
|
||||
CONFIG_SCSI_CONSTANTS=y
|
||||
CONFIG_SCSI_FC_ATTRS=y
|
||||
CONFIG_SCSI_CXGB3_ISCSI=m
|
||||
CONFIG_SCSI_CXGB4_ISCSI=m
|
||||
CONFIG_SCSI_BNX2_ISCSI=m
|
||||
CONFIG_BE2ISCSI=m
|
||||
CONFIG_SCSI_MPT2SAS=m
|
||||
CONFIG_SCSI_IBMVSCSI=y
|
||||
CONFIG_SCSI_IBMVFC=m
|
||||
CONFIG_SCSI_SYM53C8XX_2=y
|
||||
CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
|
||||
CONFIG_SCSI_IPR=y
|
||||
CONFIG_SCSI_QLA_FC=m
|
||||
CONFIG_SCSI_QLA_ISCSI=m
|
||||
CONFIG_SCSI_LPFC=m
|
||||
CONFIG_SCSI_VIRTIO=m
|
||||
CONFIG_SCSI_DH=m
|
||||
CONFIG_SCSI_DH_RDAC=m
|
||||
CONFIG_SCSI_DH_ALUA=m
|
||||
CONFIG_ATA=y
|
||||
# CONFIG_ATA_SFF is not set
|
||||
CONFIG_MD=y
|
||||
CONFIG_BLK_DEV_MD=y
|
||||
CONFIG_MD_LINEAR=y
|
||||
CONFIG_MD_RAID0=y
|
||||
CONFIG_MD_RAID1=y
|
||||
CONFIG_MD_RAID10=m
|
||||
CONFIG_MD_RAID456=m
|
||||
CONFIG_MD_MULTIPATH=m
|
||||
CONFIG_MD_FAULTY=m
|
||||
CONFIG_BLK_DEV_DM=y
|
||||
CONFIG_DM_CRYPT=m
|
||||
CONFIG_DM_SNAPSHOT=m
|
||||
CONFIG_DM_MIRROR=m
|
||||
CONFIG_DM_ZERO=m
|
||||
CONFIG_DM_MULTIPATH=m
|
||||
CONFIG_DM_MULTIPATH_QL=m
|
||||
CONFIG_DM_MULTIPATH_ST=m
|
||||
CONFIG_DM_UEVENT=y
|
||||
CONFIG_BONDING=m
|
||||
CONFIG_DUMMY=m
|
||||
CONFIG_NETCONSOLE=y
|
||||
CONFIG_NETPOLL_TRAP=y
|
||||
CONFIG_TUN=m
|
||||
CONFIG_VIRTIO_NET=m
|
||||
CONFIG_VORTEX=y
|
||||
CONFIG_ACENIC=m
|
||||
CONFIG_ACENIC_OMIT_TIGON_I=y
|
||||
CONFIG_PCNET32=y
|
||||
CONFIG_TIGON3=y
|
||||
CONFIG_CHELSIO_T1=m
|
||||
CONFIG_BE2NET=m
|
||||
CONFIG_S2IO=m
|
||||
CONFIG_IBMVETH=y
|
||||
CONFIG_EHEA=y
|
||||
CONFIG_E100=y
|
||||
CONFIG_E1000=y
|
||||
CONFIG_E1000E=y
|
||||
CONFIG_IXGB=m
|
||||
CONFIG_IXGBE=m
|
||||
CONFIG_MLX4_EN=m
|
||||
CONFIG_MYRI10GE=m
|
||||
CONFIG_QLGE=m
|
||||
CONFIG_NETXEN_NIC=m
|
||||
CONFIG_PPP=m
|
||||
CONFIG_PPP_BSDCOMP=m
|
||||
CONFIG_PPP_DEFLATE=m
|
||||
CONFIG_PPPOE=m
|
||||
CONFIG_PPP_ASYNC=m
|
||||
CONFIG_PPP_SYNC_TTY=m
|
||||
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
|
||||
CONFIG_INPUT_EVDEV=m
|
||||
CONFIG_INPUT_MISC=y
|
||||
CONFIG_INPUT_PCSPKR=m
|
||||
# CONFIG_SERIO_SERPORT is not set
|
||||
CONFIG_SERIAL_8250=y
|
||||
CONFIG_SERIAL_8250_CONSOLE=y
|
||||
CONFIG_SERIAL_ICOM=m
|
||||
CONFIG_SERIAL_JSM=m
|
||||
CONFIG_HVC_CONSOLE=y
|
||||
CONFIG_HVC_RTAS=y
|
||||
CONFIG_HVCS=m
|
||||
CONFIG_VIRTIO_CONSOLE=m
|
||||
CONFIG_IBM_BSR=m
|
||||
CONFIG_GEN_RTC=y
|
||||
CONFIG_RAW_DRIVER=y
|
||||
CONFIG_MAX_RAW_DEVS=1024
|
||||
CONFIG_FB=y
|
||||
CONFIG_FIRMWARE_EDID=y
|
||||
CONFIG_FB_OF=y
|
||||
CONFIG_FB_MATROX=y
|
||||
CONFIG_FB_MATROX_MILLENIUM=y
|
||||
CONFIG_FB_MATROX_MYSTIQUE=y
|
||||
CONFIG_FB_MATROX_G=y
|
||||
CONFIG_FB_RADEON=y
|
||||
CONFIG_FB_IBM_GXT4500=y
|
||||
CONFIG_LCD_PLATFORM=m
|
||||
# CONFIG_VGA_CONSOLE is not set
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
CONFIG_LOGO=y
|
||||
CONFIG_HID_GYRATION=y
|
||||
CONFIG_HID_PANTHERLORD=y
|
||||
CONFIG_HID_PETALYNX=y
|
||||
CONFIG_HID_SAMSUNG=y
|
||||
CONFIG_HID_SUNPLUS=y
|
||||
CONFIG_USB_HIDDEV=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_MON=m
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
# CONFIG_USB_EHCI_HCD_PPC_OF is not set
|
||||
CONFIG_USB_OHCI_HCD=y
|
||||
CONFIG_USB_STORAGE=m
|
||||
CONFIG_INFINIBAND=m
|
||||
CONFIG_INFINIBAND_USER_MAD=m
|
||||
CONFIG_INFINIBAND_USER_ACCESS=m
|
||||
CONFIG_INFINIBAND_MTHCA=m
|
||||
CONFIG_INFINIBAND_EHCA=m
|
||||
CONFIG_INFINIBAND_CXGB3=m
|
||||
CONFIG_INFINIBAND_CXGB4=m
|
||||
CONFIG_MLX4_INFINIBAND=m
|
||||
CONFIG_INFINIBAND_IPOIB=m
|
||||
CONFIG_INFINIBAND_IPOIB_CM=y
|
||||
CONFIG_INFINIBAND_SRP=m
|
||||
CONFIG_INFINIBAND_ISER=m
|
||||
CONFIG_VIRTIO_PCI=m
|
||||
CONFIG_VIRTIO_BALLOON=m
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT2_FS_XATTR=y
|
||||
CONFIG_EXT2_FS_POSIX_ACL=y
|
||||
CONFIG_EXT2_FS_SECURITY=y
|
||||
CONFIG_EXT2_FS_XIP=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT3_FS_POSIX_ACL=y
|
||||
CONFIG_EXT3_FS_SECURITY=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
CONFIG_REISERFS_FS=y
|
||||
CONFIG_REISERFS_FS_XATTR=y
|
||||
CONFIG_REISERFS_FS_POSIX_ACL=y
|
||||
CONFIG_REISERFS_FS_SECURITY=y
|
||||
CONFIG_JFS_FS=m
|
||||
CONFIG_JFS_POSIX_ACL=y
|
||||
CONFIG_JFS_SECURITY=y
|
||||
CONFIG_XFS_FS=m
|
||||
CONFIG_XFS_POSIX_ACL=y
|
||||
CONFIG_BTRFS_FS=m
|
||||
CONFIG_BTRFS_FS_POSIX_ACL=y
|
||||
CONFIG_NILFS2_FS=m
|
||||
CONFIG_AUTOFS4_FS=m
|
||||
CONFIG_FUSE_FS=m
|
||||
CONFIG_ISO9660_FS=y
|
||||
CONFIG_UDF_FS=m
|
||||
CONFIG_MSDOS_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_PROC_KCORE=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
CONFIG_HUGETLBFS=y
|
||||
CONFIG_CRAMFS=m
|
||||
CONFIG_SQUASHFS=m
|
||||
CONFIG_SQUASHFS_XATTR=y
|
||||
CONFIG_SQUASHFS_LZO=y
|
||||
CONFIG_SQUASHFS_XZ=y
|
||||
CONFIG_PSTORE=y
|
||||
CONFIG_NFS_FS=y
|
||||
CONFIG_NFS_V3_ACL=y
|
||||
CONFIG_NFS_V4=y
|
||||
CONFIG_NFSD=m
|
||||
CONFIG_NFSD_V3_ACL=y
|
||||
CONFIG_NFSD_V4=y
|
||||
CONFIG_CIFS=m
|
||||
CONFIG_CIFS_XATTR=y
|
||||
CONFIG_CIFS_POSIX=y
|
||||
CONFIG_NLS_DEFAULT="utf8"
|
||||
CONFIG_NLS_CODEPAGE_437=y
|
||||
CONFIG_NLS_ASCII=y
|
||||
CONFIG_NLS_ISO8859_1=y
|
||||
CONFIG_NLS_UTF8=y
|
||||
CONFIG_CRC_T10DIF=y
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_DEBUG_KERNEL=y
|
||||
CONFIG_DEBUG_STACK_USAGE=y
|
||||
CONFIG_DEBUG_STACKOVERFLOW=y
|
||||
CONFIG_LOCKUP_DETECTOR=y
|
||||
CONFIG_LATENCYTOP=y
|
||||
CONFIG_SCHED_TRACER=y
|
||||
CONFIG_BLK_DEV_IO_TRACE=y
|
||||
CONFIG_CODE_PATCHING_SELFTEST=y
|
||||
CONFIG_FTR_FIXUP_SELFTEST=y
|
||||
CONFIG_MSI_BITMAP_SELFTEST=y
|
||||
CONFIG_XMON=y
|
||||
CONFIG_CRYPTO_TEST=m
|
||||
CONFIG_CRYPTO_PCBC=m
|
||||
CONFIG_CRYPTO_HMAC=y
|
||||
CONFIG_CRYPTO_MICHAEL_MIC=m
|
||||
CONFIG_CRYPTO_TGR192=m
|
||||
CONFIG_CRYPTO_WP512=m
|
||||
CONFIG_CRYPTO_ANUBIS=m
|
||||
CONFIG_CRYPTO_BLOWFISH=m
|
||||
CONFIG_CRYPTO_CAST6=m
|
||||
CONFIG_CRYPTO_KHAZAD=m
|
||||
CONFIG_CRYPTO_SALSA20=m
|
||||
CONFIG_CRYPTO_SERPENT=m
|
||||
CONFIG_CRYPTO_TEA=m
|
||||
CONFIG_CRYPTO_TWOFISH=m
|
||||
CONFIG_CRYPTO_LZO=m
|
||||
# CONFIG_CRYPTO_ANSI_CPRNG is not set
|
||||
CONFIG_CRYPTO_DEV_NX=y
|
||||
CONFIG_CRYPTO_DEV_NX_ENCRYPT=m
|
|
@ -31,6 +31,8 @@
|
|||
extern unsigned long randomize_et_dyn(unsigned long base);
|
||||
#define ELF_ET_DYN_BASE (randomize_et_dyn(0x20000000))
|
||||
|
||||
#define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0)
|
||||
|
||||
/*
|
||||
* Our registers are always unsigned longs, whether we're a 32 bit
|
||||
* process or 64 bit, on either a 64 bit or 32 bit kernel.
|
||||
|
@ -86,6 +88,8 @@ typedef elf_vrregset_t elf_fpxregset_t;
|
|||
#ifdef __powerpc64__
|
||||
# define SET_PERSONALITY(ex) \
|
||||
do { \
|
||||
if (((ex).e_flags & 0x3) == 2) \
|
||||
set_thread_flag(TIF_ELF2ABI); \
|
||||
if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
|
||||
set_thread_flag(TIF_32BIT); \
|
||||
else \
|
||||
|
|
|
@ -403,6 +403,8 @@ static inline unsigned long cmo_get_page_size(void)
|
|||
extern long pSeries_enable_reloc_on_exc(void);
|
||||
extern long pSeries_disable_reloc_on_exc(void);
|
||||
|
||||
extern long pseries_big_endian_exceptions(void);
|
||||
|
||||
#else
|
||||
|
||||
#define pSeries_enable_reloc_on_exc() do {} while (0)
|
||||
|
|
|
@ -287,6 +287,32 @@ static inline long disable_reloc_on_exceptions(void) {
|
|||
return plpar_set_mode(0, 3, 0, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Take exceptions in big endian mode on this partition
|
||||
*
|
||||
* Note: this call has a partition wide scope and can take a while to complete.
|
||||
* If it returns H_LONG_BUSY_* it should be retried periodically until it
|
||||
* returns H_SUCCESS.
|
||||
*/
|
||||
static inline long enable_big_endian_exceptions(void)
|
||||
{
|
||||
/* mflags = 0: big endian exceptions */
|
||||
return plpar_set_mode(0, 4, 0, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Take exceptions in little endian mode on this partition
|
||||
*
|
||||
* Note: this call has a partition wide scope and can take a while to complete.
|
||||
* If it returns H_LONG_BUSY_* it should be retried periodically until it
|
||||
* returns H_SUCCESS.
|
||||
*/
|
||||
static inline long enable_little_endian_exceptions(void)
|
||||
{
|
||||
/* mflags = 1: little endian exceptions */
|
||||
return plpar_set_mode(1, 4, 0, 0);
|
||||
}
|
||||
|
||||
static inline long plapr_set_ciabr(unsigned long ciabr)
|
||||
{
|
||||
return plpar_set_mode(0, 1, ciabr, 0);
|
||||
|
|
|
@ -105,6 +105,9 @@ static inline struct thread_info *current_thread_info(void)
|
|||
#define TIF_EMULATE_STACK_STORE 16 /* Is an instruction emulation
|
||||
for stack store? */
|
||||
#define TIF_MEMDIE 17 /* is terminating due to OOM killer */
|
||||
#if defined(CONFIG_PPC64)
|
||||
#define TIF_ELF2ABI 18 /* function descriptors must die! */
|
||||
#endif
|
||||
|
||||
/* as above, but as bit values */
|
||||
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
|
||||
|
@ -183,6 +186,12 @@ static inline bool test_thread_local_flags(unsigned int flags)
|
|||
#define is_32bit_task() (1)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_PPC64)
|
||||
#define is_elf2_task() (test_thread_flag(TIF_ELF2ABI))
|
||||
#else
|
||||
#define is_elf2_task() (0)
|
||||
#endif
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
|
|
@ -1086,12 +1086,31 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
|
|||
regs->msr = MSR_USER;
|
||||
#else
|
||||
if (!is_32bit_task()) {
|
||||
unsigned long entry, toc;
|
||||
unsigned long entry;
|
||||
|
||||
/* start is a relocated pointer to the function descriptor for
|
||||
* the elf _start routine. The first entry in the function
|
||||
* descriptor is the entry address of _start and the second
|
||||
* entry is the TOC value we need to use.
|
||||
if (is_elf2_task()) {
|
||||
/* Look ma, no function descriptors! */
|
||||
entry = start;
|
||||
|
||||
/*
|
||||
* Ulrich says:
|
||||
* The latest iteration of the ABI requires that when
|
||||
* calling a function (at its global entry point),
|
||||
* the caller must ensure r12 holds the entry point
|
||||
* address (so that the function can quickly
|
||||
* establish addressability).
|
||||
*/
|
||||
regs->gpr[12] = start;
|
||||
/* Make sure that's restored on entry to userspace. */
|
||||
set_thread_flag(TIF_RESTOREALL);
|
||||
} else {
|
||||
unsigned long toc;
|
||||
|
||||
/* start is a relocated pointer to the function
|
||||
* descriptor for the elf _start routine. The first
|
||||
* entry in the function descriptor is the entry
|
||||
* address of _start and the second entry is the TOC
|
||||
* value we need to use.
|
||||
*/
|
||||
__get_user(entry, (unsigned long __user *)start);
|
||||
__get_user(toc, (unsigned long __user *)start+1);
|
||||
|
@ -1103,8 +1122,9 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
|
|||
entry += load_addr;
|
||||
toc += load_addr;
|
||||
}
|
||||
regs->nip = entry;
|
||||
regs->gpr[2] = toc;
|
||||
}
|
||||
regs->nip = entry;
|
||||
regs->msr = MSR_USER64;
|
||||
} else {
|
||||
regs->nip = start;
|
||||
|
|
|
@ -701,12 +701,6 @@ badframe:
|
|||
int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
|
||||
sigset_t *set, struct pt_regs *regs)
|
||||
{
|
||||
/* Handler is *really* a pointer to the function descriptor for
|
||||
* the signal routine. The first entry in the function
|
||||
* descriptor is the entry address of signal and the second
|
||||
* entry is the TOC value we need to use.
|
||||
*/
|
||||
func_descr_t __user *funct_desc_ptr;
|
||||
struct rt_sigframe __user *frame;
|
||||
unsigned long newsp = 0;
|
||||
long err = 0;
|
||||
|
@ -766,19 +760,32 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
|
|||
goto badframe;
|
||||
regs->link = (unsigned long) &frame->tramp[0];
|
||||
}
|
||||
funct_desc_ptr = (func_descr_t __user *) ka->sa.sa_handler;
|
||||
|
||||
/* Allocate a dummy caller frame for the signal handler. */
|
||||
newsp = ((unsigned long)frame) - __SIGNAL_FRAMESIZE;
|
||||
err |= put_user(regs->gpr[1], (unsigned long __user *)newsp);
|
||||
|
||||
/* Set up "regs" so we "return" to the signal handler. */
|
||||
if (is_elf2_task()) {
|
||||
regs->nip = (unsigned long) ka->sa.sa_handler;
|
||||
regs->gpr[12] = regs->nip;
|
||||
} else {
|
||||
/* Handler is *really* a pointer to the function descriptor for
|
||||
* the signal routine. The first entry in the function
|
||||
* descriptor is the entry address of signal and the second
|
||||
* entry is the TOC value we need to use.
|
||||
*/
|
||||
func_descr_t __user *funct_desc_ptr =
|
||||
(func_descr_t __user *) ka->sa.sa_handler;
|
||||
|
||||
err |= get_user(regs->nip, &funct_desc_ptr->entry);
|
||||
err |= get_user(regs->gpr[2], &funct_desc_ptr->toc);
|
||||
}
|
||||
|
||||
/* enter the signal handler in native-endian mode */
|
||||
regs->msr &= ~MSR_LE;
|
||||
regs->msr |= (MSR_KERNEL & MSR_LE);
|
||||
regs->gpr[1] = newsp;
|
||||
err |= get_user(regs->gpr[2], &funct_desc_ptr->toc);
|
||||
regs->gpr[3] = signr;
|
||||
regs->result = 0;
|
||||
if (ka->sa.sa_flags & SA_SIGINFO) {
|
||||
|
|
|
@ -142,6 +142,13 @@ V_FUNCTION_END(__kernel_sigtramp_rt64)
|
|||
/* Size of CR reg in DWARF unwind info. */
|
||||
#define CRSIZE 4
|
||||
|
||||
/* Offset of CR reg within a full word. */
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
#define CROFF 0
|
||||
#else
|
||||
#define CROFF (RSIZE - CRSIZE)
|
||||
#endif
|
||||
|
||||
/* This is the offset of the VMX reg pointer. */
|
||||
#define VREGS 48*RSIZE+33*8
|
||||
|
||||
|
@ -181,7 +188,14 @@ V_FUNCTION_END(__kernel_sigtramp_rt64)
|
|||
rsave (31, 31*RSIZE); \
|
||||
rsave (67, 32*RSIZE); /* ap, used as temp for nip */ \
|
||||
rsave (65, 36*RSIZE); /* lr */ \
|
||||
rsave (70, 38*RSIZE + (RSIZE - CRSIZE)) /* cr */
|
||||
rsave (68, 38*RSIZE + CROFF); /* cr fields */ \
|
||||
rsave (69, 38*RSIZE + CROFF); \
|
||||
rsave (70, 38*RSIZE + CROFF); \
|
||||
rsave (71, 38*RSIZE + CROFF); \
|
||||
rsave (72, 38*RSIZE + CROFF); \
|
||||
rsave (73, 38*RSIZE + CROFF); \
|
||||
rsave (74, 38*RSIZE + CROFF); \
|
||||
rsave (75, 38*RSIZE + CROFF)
|
||||
|
||||
/* Describe where the FP regs are saved. */
|
||||
#define EH_FRAME_FP \
|
||||
|
|
|
@ -403,3 +403,14 @@ config PPC_DOORBELL
|
|||
default n
|
||||
|
||||
endmenu
|
||||
|
||||
config CPU_LITTLE_ENDIAN
|
||||
bool "Build little endian kernel"
|
||||
default n
|
||||
help
|
||||
This option selects whether a big endian or little endian kernel will
|
||||
be built.
|
||||
|
||||
Note that if cross compiling a little endian kernel,
|
||||
CROSS_COMPILE must point to a toolchain capable of targeting
|
||||
little endian powerpc.
|
||||
|
|
|
@ -189,8 +189,9 @@ static void *pseries_eeh_of_probe(struct device_node *dn, void *flag)
|
|||
struct eeh_dev *edev;
|
||||
struct eeh_pe pe;
|
||||
struct pci_dn *pdn = PCI_DN(dn);
|
||||
const u32 *class_code, *vendor_id, *device_id;
|
||||
const u32 *regs;
|
||||
const __be32 *classp, *vendorp, *devicep;
|
||||
u32 class_code;
|
||||
const __be32 *regs;
|
||||
u32 pcie_flags;
|
||||
int enable = 0;
|
||||
int ret;
|
||||
|
@ -201,22 +202,24 @@ static void *pseries_eeh_of_probe(struct device_node *dn, void *flag)
|
|||
return NULL;
|
||||
|
||||
/* Retrieve class/vendor/device IDs */
|
||||
class_code = of_get_property(dn, "class-code", NULL);
|
||||
vendor_id = of_get_property(dn, "vendor-id", NULL);
|
||||
device_id = of_get_property(dn, "device-id", NULL);
|
||||
classp = of_get_property(dn, "class-code", NULL);
|
||||
vendorp = of_get_property(dn, "vendor-id", NULL);
|
||||
devicep = of_get_property(dn, "device-id", NULL);
|
||||
|
||||
/* Skip for bad OF node or PCI-ISA bridge */
|
||||
if (!class_code || !vendor_id || !device_id)
|
||||
if (!classp || !vendorp || !devicep)
|
||||
return NULL;
|
||||
if (dn->type && !strcmp(dn->type, "isa"))
|
||||
return NULL;
|
||||
|
||||
class_code = of_read_number(classp, 1);
|
||||
|
||||
/*
|
||||
* Update class code and mode of eeh device. We need
|
||||
* correctly reflects that current device is root port
|
||||
* or PCIe switch downstream port.
|
||||
*/
|
||||
edev->class_code = *class_code;
|
||||
edev->class_code = class_code;
|
||||
edev->pcie_cap = pseries_eeh_find_cap(dn, PCI_CAP_ID_EXP);
|
||||
edev->mode &= 0xFFFFFF00;
|
||||
if ((edev->class_code >> 8) == PCI_CLASS_BRIDGE_PCI) {
|
||||
|
@ -243,12 +246,12 @@ static void *pseries_eeh_of_probe(struct device_node *dn, void *flag)
|
|||
/* Initialize the fake PE */
|
||||
memset(&pe, 0, sizeof(struct eeh_pe));
|
||||
pe.phb = edev->phb;
|
||||
pe.config_addr = regs[0];
|
||||
pe.config_addr = of_read_number(regs, 1);
|
||||
|
||||
/* Enable EEH on the device */
|
||||
ret = eeh_ops->set_option(&pe, EEH_OPT_ENABLE);
|
||||
if (!ret) {
|
||||
edev->config_addr = regs[0];
|
||||
edev->config_addr = of_read_number(regs, 1);
|
||||
/* Retrieve PE address */
|
||||
edev->pe_config_addr = eeh_ops->get_pe_addr(&pe);
|
||||
pe.addr = edev->pe_config_addr;
|
||||
|
|
|
@ -245,6 +245,23 @@ static void pSeries_lpar_hptab_clear(void)
|
|||
&(ptes[j].pteh), &(ptes[j].ptel));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
/* Reset exceptions to big endian */
|
||||
if (firmware_has_feature(FW_FEATURE_SET_MODE)) {
|
||||
long rc;
|
||||
|
||||
rc = pseries_big_endian_exceptions();
|
||||
/*
|
||||
* At this point it is unlikely panic() will get anything
|
||||
* out to the user, but at least this will stop us from
|
||||
* continuing on further and creating an even more
|
||||
* difficult to debug situation.
|
||||
*/
|
||||
if (rc)
|
||||
panic("Could not enable big endian exceptions");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -442,6 +442,32 @@ static void pSeries_machine_kexec(struct kimage *image)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
long pseries_big_endian_exceptions(void)
|
||||
{
|
||||
long rc;
|
||||
|
||||
while (1) {
|
||||
rc = enable_big_endian_exceptions();
|
||||
if (!H_IS_LONG_BUSY(rc))
|
||||
return rc;
|
||||
mdelay(get_longbusy_msecs(rc));
|
||||
}
|
||||
}
|
||||
|
||||
static long pseries_little_endian_exceptions(void)
|
||||
{
|
||||
long rc;
|
||||
|
||||
while (1) {
|
||||
rc = enable_little_endian_exceptions();
|
||||
if (!H_IS_LONG_BUSY(rc))
|
||||
return rc;
|
||||
mdelay(get_longbusy_msecs(rc));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void __init pSeries_setup_arch(void)
|
||||
{
|
||||
panic_timeout = 10;
|
||||
|
@ -698,6 +724,22 @@ static int __init pSeries_probe(void)
|
|||
/* Now try to figure out if we are running on LPAR */
|
||||
of_scan_flat_dt(pseries_probe_fw_features, NULL);
|
||||
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
if (firmware_has_feature(FW_FEATURE_SET_MODE)) {
|
||||
long rc;
|
||||
/*
|
||||
* Tell the hypervisor that we want our exceptions to
|
||||
* be taken in little endian mode. If this fails we don't
|
||||
* want to use BUG() because it will trigger an exception.
|
||||
*/
|
||||
rc = pseries_little_endian_exceptions();
|
||||
if (rc) {
|
||||
ppc_md.progress("H_SET_MODE LE exception fail", 0);
|
||||
panic("Could not enable little endian exceptions");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (firmware_has_feature(FW_FEATURE_LPAR))
|
||||
hpte_init_lpar();
|
||||
else
|
||||
|
|
Загрузка…
Ссылка в новой задаче