mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-10-29 07:18:51 +01:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
9
arch/s390/Kbuild
Normal file
9
arch/s390/Kbuild
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
obj-y += kernel/
|
||||
obj-y += mm/
|
||||
obj-$(CONFIG_KVM) += kvm/
|
||||
obj-$(CONFIG_CRYPTO_HW) += crypto/
|
||||
obj-$(CONFIG_S390_HYPFS_FS) += hypfs/
|
||||
obj-$(CONFIG_APPLDATA_BASE) += appldata/
|
||||
obj-$(CONFIG_MATHEMU) += math-emu/
|
||||
obj-y += net/
|
||||
obj-$(CONFIG_PCI) += pci/
|
||||
798
arch/s390/Kconfig
Normal file
798
arch/s390/Kconfig
Normal file
|
|
@ -0,0 +1,798 @@
|
|||
config MMU
|
||||
def_bool y
|
||||
|
||||
config ZONE_DMA
|
||||
def_bool y
|
||||
|
||||
config LOCKDEP_SUPPORT
|
||||
def_bool y
|
||||
|
||||
config STACKTRACE_SUPPORT
|
||||
def_bool y
|
||||
|
||||
config HAVE_LATENCYTOP_SUPPORT
|
||||
def_bool y
|
||||
|
||||
config RWSEM_GENERIC_SPINLOCK
|
||||
bool
|
||||
|
||||
config RWSEM_XCHGADD_ALGORITHM
|
||||
def_bool y
|
||||
|
||||
config ARCH_HAS_ILOG2_U32
|
||||
def_bool n
|
||||
|
||||
config ARCH_HAS_ILOG2_U64
|
||||
def_bool n
|
||||
|
||||
config GENERIC_HWEIGHT
|
||||
def_bool y
|
||||
|
||||
config GENERIC_BUG
|
||||
def_bool y if BUG
|
||||
|
||||
config GENERIC_BUG_RELATIVE_POINTERS
|
||||
def_bool y
|
||||
|
||||
config ARCH_DMA_ADDR_T_64BIT
|
||||
def_bool 64BIT
|
||||
|
||||
config GENERIC_LOCKBREAK
|
||||
def_bool y if SMP && PREEMPT
|
||||
|
||||
config PGSTE
|
||||
def_bool y if KVM
|
||||
|
||||
config ARCH_SUPPORTS_DEBUG_PAGEALLOC
|
||||
def_bool y
|
||||
|
||||
config KEXEC
|
||||
def_bool y
|
||||
|
||||
config AUDIT_ARCH
|
||||
def_bool y
|
||||
|
||||
config NO_IOPORT_MAP
|
||||
def_bool y
|
||||
|
||||
config PCI_QUIRKS
|
||||
def_bool n
|
||||
|
||||
config ARCH_SUPPORTS_UPROBES
|
||||
def_bool 64BIT
|
||||
|
||||
config S390
|
||||
def_bool y
|
||||
select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
|
||||
select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS
|
||||
select ARCH_HAVE_NMI_SAFE_CMPXCHG
|
||||
select ARCH_INLINE_READ_LOCK
|
||||
select ARCH_INLINE_READ_LOCK_BH
|
||||
select ARCH_INLINE_READ_LOCK_IRQ
|
||||
select ARCH_INLINE_READ_LOCK_IRQSAVE
|
||||
select ARCH_INLINE_READ_TRYLOCK
|
||||
select ARCH_INLINE_READ_UNLOCK
|
||||
select ARCH_INLINE_READ_UNLOCK_BH
|
||||
select ARCH_INLINE_READ_UNLOCK_IRQ
|
||||
select ARCH_INLINE_READ_UNLOCK_IRQRESTORE
|
||||
select ARCH_INLINE_SPIN_LOCK
|
||||
select ARCH_INLINE_SPIN_LOCK_BH
|
||||
select ARCH_INLINE_SPIN_LOCK_IRQ
|
||||
select ARCH_INLINE_SPIN_LOCK_IRQSAVE
|
||||
select ARCH_INLINE_SPIN_TRYLOCK
|
||||
select ARCH_INLINE_SPIN_TRYLOCK_BH
|
||||
select ARCH_INLINE_SPIN_UNLOCK
|
||||
select ARCH_INLINE_SPIN_UNLOCK_BH
|
||||
select ARCH_INLINE_SPIN_UNLOCK_IRQ
|
||||
select ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE
|
||||
select ARCH_INLINE_WRITE_LOCK
|
||||
select ARCH_INLINE_WRITE_LOCK_BH
|
||||
select ARCH_INLINE_WRITE_LOCK_IRQ
|
||||
select ARCH_INLINE_WRITE_LOCK_IRQSAVE
|
||||
select ARCH_INLINE_WRITE_TRYLOCK
|
||||
select ARCH_INLINE_WRITE_UNLOCK
|
||||
select ARCH_INLINE_WRITE_UNLOCK_BH
|
||||
select ARCH_INLINE_WRITE_UNLOCK_IRQ
|
||||
select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE
|
||||
select ARCH_SAVE_PAGE_KEYS if HIBERNATION
|
||||
select ARCH_SUPPORTS_ATOMIC_RMW
|
||||
select ARCH_USE_CMPXCHG_LOCKREF
|
||||
select ARCH_WANT_IPC_PARSE_VERSION
|
||||
select BUILDTIME_EXTABLE_SORT
|
||||
select CLONE_BACKWARDS2
|
||||
select DYNAMIC_FTRACE if FUNCTION_TRACER
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select GENERIC_CPU_DEVICES if !SMP
|
||||
select GENERIC_FIND_FIRST_BIT
|
||||
select GENERIC_SMP_IDLE_THREAD
|
||||
select GENERIC_TIME_VSYSCALL
|
||||
select HAVE_ALIGNED_STRUCT_PAGE if SLUB
|
||||
select HAVE_ARCH_AUDITSYSCALL
|
||||
select HAVE_ARCH_JUMP_LABEL if !MARCH_G5
|
||||
select HAVE_ARCH_SECCOMP_FILTER
|
||||
select HAVE_ARCH_TRACEHOOK
|
||||
select HAVE_ARCH_TRANSPARENT_HUGEPAGE if 64BIT
|
||||
select HAVE_BPF_JIT if 64BIT && PACK_STACK
|
||||
select HAVE_CMPXCHG_DOUBLE
|
||||
select HAVE_CMPXCHG_LOCAL
|
||||
select HAVE_C_RECORDMCOUNT
|
||||
select HAVE_DEBUG_KMEMLEAK
|
||||
select HAVE_DYNAMIC_FTRACE if 64BIT
|
||||
select HAVE_DYNAMIC_FTRACE_WITH_REGS if 64BIT
|
||||
select HAVE_FTRACE_MCOUNT_RECORD
|
||||
select HAVE_FUNCTION_GRAPH_TRACER if 64BIT
|
||||
select HAVE_FUNCTION_TRACER if 64BIT
|
||||
select HAVE_FUTEX_CMPXCHG if FUTEX
|
||||
select HAVE_KERNEL_BZIP2
|
||||
select HAVE_KERNEL_GZIP
|
||||
select HAVE_KERNEL_LZ4
|
||||
select HAVE_KERNEL_LZMA
|
||||
select HAVE_KERNEL_LZO
|
||||
select HAVE_KERNEL_XZ
|
||||
select HAVE_KPROBES
|
||||
select HAVE_KRETPROBES
|
||||
select HAVE_KVM if 64BIT
|
||||
select HAVE_MEMBLOCK
|
||||
select HAVE_MEMBLOCK_NODE_MAP
|
||||
select HAVE_MEMBLOCK_PHYS_MAP
|
||||
select HAVE_MOD_ARCH_SPECIFIC
|
||||
select HAVE_OPROFILE
|
||||
select HAVE_PERF_EVENTS
|
||||
select HAVE_REGS_AND_STACK_ACCESS_API
|
||||
select HAVE_SYSCALL_TRACEPOINTS
|
||||
select HAVE_UID16 if 32BIT
|
||||
select HAVE_VIRT_CPU_ACCOUNTING
|
||||
select MODULES_USE_ELF_RELA
|
||||
select NO_BOOTMEM
|
||||
select OLD_SIGACTION
|
||||
select OLD_SIGSUSPEND3
|
||||
select SYSCTL_EXCEPTION_TRACE
|
||||
select TTY
|
||||
select VIRT_CPU_ACCOUNTING
|
||||
select VIRT_TO_BUS
|
||||
select ARCH_HAS_SG_CHAIN
|
||||
|
||||
config SCHED_OMIT_FRAME_POINTER
|
||||
def_bool y
|
||||
|
||||
source "init/Kconfig"
|
||||
|
||||
source "kernel/Kconfig.freezer"
|
||||
|
||||
menu "Processor type and features"
|
||||
|
||||
config HAVE_MARCH_Z900_FEATURES
|
||||
def_bool n
|
||||
|
||||
config HAVE_MARCH_Z990_FEATURES
|
||||
def_bool n
|
||||
select HAVE_MARCH_Z900_FEATURES
|
||||
|
||||
config HAVE_MARCH_Z9_109_FEATURES
|
||||
def_bool n
|
||||
select HAVE_MARCH_Z990_FEATURES
|
||||
|
||||
config HAVE_MARCH_Z10_FEATURES
|
||||
def_bool n
|
||||
select HAVE_MARCH_Z9_109_FEATURES
|
||||
|
||||
config HAVE_MARCH_Z196_FEATURES
|
||||
def_bool n
|
||||
select HAVE_MARCH_Z10_FEATURES
|
||||
|
||||
config HAVE_MARCH_ZEC12_FEATURES
|
||||
def_bool n
|
||||
select HAVE_MARCH_Z196_FEATURES
|
||||
|
||||
choice
|
||||
prompt "Processor type"
|
||||
default MARCH_G5
|
||||
|
||||
config MARCH_G5
|
||||
bool "System/390 model G5 and G6"
|
||||
depends on !64BIT
|
||||
help
|
||||
Select this to build a 31 bit kernel that works
|
||||
on all ESA/390 and z/Architecture machines.
|
||||
|
||||
config MARCH_Z900
|
||||
bool "IBM zSeries model z800 and z900"
|
||||
select HAVE_MARCH_Z900_FEATURES if 64BIT
|
||||
help
|
||||
Select this to enable optimizations for model z800/z900 (2064 and
|
||||
2066 series). This will enable some optimizations that are not
|
||||
available on older ESA/390 (31 Bit) only CPUs.
|
||||
|
||||
config MARCH_Z990
|
||||
bool "IBM zSeries model z890 and z990"
|
||||
select HAVE_MARCH_Z990_FEATURES if 64BIT
|
||||
help
|
||||
Select this to enable optimizations for model z890/z990 (2084 and
|
||||
2086 series). The kernel will be slightly faster but will not work
|
||||
on older machines.
|
||||
|
||||
config MARCH_Z9_109
|
||||
bool "IBM System z9"
|
||||
select HAVE_MARCH_Z9_109_FEATURES if 64BIT
|
||||
help
|
||||
Select this to enable optimizations for IBM System z9 (2094 and
|
||||
2096 series). The kernel will be slightly faster but will not work
|
||||
on older machines.
|
||||
|
||||
config MARCH_Z10
|
||||
bool "IBM System z10"
|
||||
select HAVE_MARCH_Z10_FEATURES if 64BIT
|
||||
help
|
||||
Select this to enable optimizations for IBM System z10 (2097 and
|
||||
2098 series). The kernel will be slightly faster but will not work
|
||||
on older machines.
|
||||
|
||||
config MARCH_Z196
|
||||
bool "IBM zEnterprise 114 and 196"
|
||||
select HAVE_MARCH_Z196_FEATURES if 64BIT
|
||||
help
|
||||
Select this to enable optimizations for IBM zEnterprise 114 and 196
|
||||
(2818 and 2817 series). The kernel will be slightly faster but will
|
||||
not work on older machines.
|
||||
|
||||
config MARCH_ZEC12
|
||||
bool "IBM zBC12 and zEC12"
|
||||
select HAVE_MARCH_ZEC12_FEATURES if 64BIT
|
||||
help
|
||||
Select this to enable optimizations for IBM zBC12 and zEC12 (2828 and
|
||||
2827 series). The kernel will be slightly faster but will not work on
|
||||
older machines.
|
||||
|
||||
endchoice
|
||||
|
||||
config MARCH_G5_TUNE
|
||||
def_bool TUNE_G5 || MARCH_G5 && TUNE_DEFAULT
|
||||
|
||||
config MARCH_Z900_TUNE
|
||||
def_bool TUNE_Z900 || MARCH_Z900 && TUNE_DEFAULT
|
||||
|
||||
config MARCH_Z990_TUNE
|
||||
def_bool TUNE_Z990 || MARCH_Z990 && TUNE_DEFAULT
|
||||
|
||||
config MARCH_Z9_109_TUNE
|
||||
def_bool TUNE_Z9_109 || MARCH_Z9_109 && TUNE_DEFAULT
|
||||
|
||||
config MARCH_Z10_TUNE
|
||||
def_bool TUNE_Z10 || MARCH_Z10 && TUNE_DEFAULT
|
||||
|
||||
config MARCH_Z196_TUNE
|
||||
def_bool TUNE_Z196 || MARCH_Z196 && TUNE_DEFAULT
|
||||
|
||||
config MARCH_ZEC12_TUNE
|
||||
def_bool TUNE_ZEC12 || MARCH_ZEC12 && TUNE_DEFAULT
|
||||
|
||||
choice
|
||||
prompt "Tune code generation"
|
||||
default TUNE_DEFAULT
|
||||
help
|
||||
Cause the compiler to tune (-mtune) the generated code for a machine.
|
||||
This will make the code run faster on the selected machine but
|
||||
somewhat slower on other machines.
|
||||
This option only changes how the compiler emits instructions, not the
|
||||
selection of instructions itself, so the resulting kernel will run on
|
||||
all other machines.
|
||||
|
||||
config TUNE_DEFAULT
|
||||
bool "Default"
|
||||
help
|
||||
Tune the generated code for the target processor for which the kernel
|
||||
will be compiled.
|
||||
|
||||
config TUNE_G5
|
||||
bool "System/390 model G5 and G6"
|
||||
|
||||
config TUNE_Z900
|
||||
bool "IBM zSeries model z800 and z900"
|
||||
|
||||
config TUNE_Z990
|
||||
bool "IBM zSeries model z890 and z990"
|
||||
|
||||
config TUNE_Z9_109
|
||||
bool "IBM System z9"
|
||||
|
||||
config TUNE_Z10
|
||||
bool "IBM System z10"
|
||||
|
||||
config TUNE_Z196
|
||||
bool "IBM zEnterprise 114 and 196"
|
||||
|
||||
config TUNE_ZEC12
|
||||
bool "IBM zBC12 and zEC12"
|
||||
|
||||
endchoice
|
||||
|
||||
config 64BIT
|
||||
def_bool y
|
||||
prompt "64 bit kernel"
|
||||
help
|
||||
Select this option if you have an IBM z/Architecture machine
|
||||
and want to use the 64 bit addressing mode.
|
||||
|
||||
config 32BIT
|
||||
def_bool y if !64BIT
|
||||
|
||||
config COMPAT
|
||||
def_bool y
|
||||
prompt "Kernel support for 31 bit emulation"
|
||||
depends on 64BIT
|
||||
select COMPAT_BINFMT_ELF if BINFMT_ELF
|
||||
select ARCH_WANT_OLD_COMPAT_IPC
|
||||
select COMPAT_OLD_SIGACTION
|
||||
help
|
||||
Select this option if you want to enable your system kernel to
|
||||
handle system-calls from ELF binaries for 31 bit ESA. This option
|
||||
(and some other stuff like libraries and such) is needed for
|
||||
executing 31 bit applications. It is safe to say "Y".
|
||||
|
||||
config SYSVIPC_COMPAT
|
||||
def_bool y if COMPAT && SYSVIPC
|
||||
|
||||
config KEYS_COMPAT
|
||||
def_bool y if COMPAT && KEYS
|
||||
|
||||
config SMP
|
||||
def_bool y
|
||||
prompt "Symmetric multi-processing support"
|
||||
---help---
|
||||
This enables support for systems with more than one CPU. If you have
|
||||
a system with only one CPU, like most personal computers, say N. If
|
||||
you have a system with more than one CPU, say Y.
|
||||
|
||||
If you say N here, the kernel will run on uni- and multiprocessor
|
||||
machines, but will use only one CPU of a multiprocessor machine. If
|
||||
you say Y here, the kernel will run on many, but not all,
|
||||
uniprocessor machines. On a uniprocessor machine, the kernel
|
||||
will run faster if you say N here.
|
||||
|
||||
See also the SMP-HOWTO available at
|
||||
<http://www.tldp.org/docs.html#howto>.
|
||||
|
||||
Even if you don't know what to do here, say Y.
|
||||
|
||||
config NR_CPUS
|
||||
int "Maximum number of CPUs (2-256)"
|
||||
range 2 256
|
||||
depends on SMP
|
||||
default "32" if !64BIT
|
||||
default "64" if 64BIT
|
||||
help
|
||||
This allows you to specify the maximum number of CPUs which this
|
||||
kernel will support. The maximum supported value is 256 and the
|
||||
minimum value which makes sense is 2.
|
||||
|
||||
This is purely to save memory - each supported CPU adds
|
||||
approximately sixteen kilobytes to the kernel image.
|
||||
|
||||
config HOTPLUG_CPU
|
||||
def_bool y
|
||||
prompt "Support for hot-pluggable CPUs"
|
||||
depends on SMP
|
||||
help
|
||||
Say Y here to be able to turn CPUs off and on. CPUs
|
||||
can be controlled through /sys/devices/system/cpu/cpu#.
|
||||
Say N if you want to disable CPU hotplug.
|
||||
|
||||
config SCHED_MC
|
||||
def_bool n
|
||||
|
||||
config SCHED_BOOK
|
||||
def_bool y
|
||||
prompt "Book scheduler support"
|
||||
depends on SMP
|
||||
select SCHED_MC
|
||||
help
|
||||
Book scheduler support improves the CPU scheduler's decision making
|
||||
when dealing with machines that have several books.
|
||||
|
||||
source kernel/Kconfig.preempt
|
||||
|
||||
config MATHEMU
|
||||
def_bool y
|
||||
prompt "IEEE FPU emulation"
|
||||
depends on MARCH_G5
|
||||
help
|
||||
This option is required for IEEE compliant floating point arithmetic
|
||||
on older ESA/390 machines. Say Y unless you know your machine doesn't
|
||||
need this.
|
||||
|
||||
source kernel/Kconfig.hz
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Memory setup"
|
||||
|
||||
config ARCH_SPARSEMEM_ENABLE
|
||||
def_bool y
|
||||
select SPARSEMEM_VMEMMAP_ENABLE
|
||||
select SPARSEMEM_VMEMMAP
|
||||
select SPARSEMEM_STATIC if !64BIT
|
||||
|
||||
config ARCH_SPARSEMEM_DEFAULT
|
||||
def_bool y
|
||||
|
||||
config ARCH_SELECT_MEMORY_MODEL
|
||||
def_bool y
|
||||
|
||||
config ARCH_ENABLE_MEMORY_HOTPLUG
|
||||
def_bool y if SPARSEMEM
|
||||
|
||||
config ARCH_ENABLE_MEMORY_HOTREMOVE
|
||||
def_bool y
|
||||
|
||||
config ARCH_ENABLE_SPLIT_PMD_PTLOCK
|
||||
def_bool y
|
||||
depends on 64BIT
|
||||
|
||||
config FORCE_MAX_ZONEORDER
|
||||
int
|
||||
default "9"
|
||||
|
||||
source "mm/Kconfig"
|
||||
|
||||
config PACK_STACK
|
||||
def_bool y
|
||||
prompt "Pack kernel stack"
|
||||
help
|
||||
This option enables the compiler option -mkernel-backchain if it
|
||||
is available. If the option is available the compiler supports
|
||||
the new stack layout which dramatically reduces the minimum stack
|
||||
frame size. With an old compiler a non-leaf function needs a
|
||||
minimum of 96 bytes on 31 bit and 160 bytes on 64 bit. With
|
||||
-mkernel-backchain the minimum size drops to 16 byte on 31 bit
|
||||
and 24 byte on 64 bit.
|
||||
|
||||
Say Y if you are unsure.
|
||||
|
||||
config CHECK_STACK
|
||||
def_bool y
|
||||
prompt "Detect kernel stack overflow"
|
||||
help
|
||||
This option enables the compiler option -mstack-guard and
|
||||
-mstack-size if they are available. If the compiler supports them
|
||||
it will emit additional code to each function prolog to trigger
|
||||
an illegal operation if the kernel stack is about to overflow.
|
||||
|
||||
Say N if you are unsure.
|
||||
|
||||
config STACK_GUARD
|
||||
int "Size of the guard area (128-1024)"
|
||||
range 128 1024
|
||||
depends on CHECK_STACK
|
||||
default "256"
|
||||
help
|
||||
This allows you to specify the size of the guard area at the lower
|
||||
end of the kernel stack. If the kernel stack points into the guard
|
||||
area on function entry an illegal operation is triggered. The size
|
||||
needs to be a power of 2. Please keep in mind that the size of an
|
||||
interrupt frame is 184 bytes for 31 bit and 328 bytes on 64 bit.
|
||||
The minimum size for the stack guard should be 256 for 31 bit and
|
||||
512 for 64 bit.
|
||||
|
||||
config WARN_DYNAMIC_STACK
|
||||
def_bool n
|
||||
prompt "Emit compiler warnings for function with dynamic stack usage"
|
||||
help
|
||||
This option enables the compiler option -mwarn-dynamicstack. If the
|
||||
compiler supports this options generates warnings for functions
|
||||
that dynamically allocate stack space using alloca.
|
||||
|
||||
Say N if you are unsure.
|
||||
|
||||
endmenu
|
||||
|
||||
menu "I/O subsystem"
|
||||
|
||||
config QDIO
|
||||
def_tristate y
|
||||
prompt "QDIO support"
|
||||
---help---
|
||||
This driver provides the Queued Direct I/O base support for
|
||||
IBM System z.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called qdio.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
menuconfig PCI
|
||||
bool "PCI support"
|
||||
depends on 64BIT
|
||||
select HAVE_DMA_ATTRS
|
||||
select PCI_MSI
|
||||
help
|
||||
Enable PCI support.
|
||||
|
||||
if PCI
|
||||
|
||||
config PCI_NR_FUNCTIONS
|
||||
int "Maximum number of PCI functions (1-4096)"
|
||||
range 1 4096
|
||||
default "64"
|
||||
help
|
||||
This allows you to specify the maximum number of PCI functions which
|
||||
this kernel will support.
|
||||
|
||||
config PCI_NR_MSI
|
||||
int "Maximum number of MSI interrupts (64-32768)"
|
||||
range 64 32768
|
||||
default "256"
|
||||
help
|
||||
This defines the number of virtual interrupts the kernel will
|
||||
provide for MSI interrupts. If you configure your system to have
|
||||
too few drivers will fail to allocate MSI interrupts for all
|
||||
PCI devices.
|
||||
|
||||
source "drivers/pci/Kconfig"
|
||||
source "drivers/pci/pcie/Kconfig"
|
||||
source "drivers/pci/hotplug/Kconfig"
|
||||
|
||||
endif # PCI
|
||||
|
||||
config PCI_DOMAINS
|
||||
def_bool PCI
|
||||
|
||||
config HAS_IOMEM
|
||||
def_bool PCI
|
||||
|
||||
config IOMMU_HELPER
|
||||
def_bool PCI
|
||||
|
||||
config HAS_DMA
|
||||
def_bool PCI
|
||||
select HAVE_DMA_API_DEBUG
|
||||
|
||||
config NEED_SG_DMA_LENGTH
|
||||
def_bool PCI
|
||||
|
||||
config NEED_DMA_MAP_STATE
|
||||
def_bool PCI
|
||||
|
||||
config CHSC_SCH
|
||||
def_tristate m
|
||||
prompt "Support for CHSC subchannels"
|
||||
help
|
||||
This driver allows usage of CHSC subchannels. A CHSC subchannel
|
||||
is usually present on LPAR only.
|
||||
The driver creates a device /dev/chsc, which may be used to
|
||||
obtain I/O configuration information about the machine and
|
||||
to issue asynchronous chsc commands (DANGEROUS).
|
||||
You will usually only want to use this interface on a special
|
||||
LPAR designated for system management.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called chsc_sch.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config SCM_BUS
|
||||
def_bool y
|
||||
depends on 64BIT
|
||||
prompt "SCM bus driver"
|
||||
help
|
||||
Bus driver for Storage Class Memory.
|
||||
|
||||
config EADM_SCH
|
||||
def_tristate m
|
||||
prompt "Support for EADM subchannels"
|
||||
depends on SCM_BUS
|
||||
help
|
||||
This driver allows usage of EADM subchannels. EADM subchannels act
|
||||
as a communication vehicle for SCM increments.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called eadm_sch.
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Dump support"
|
||||
|
||||
config CRASH_DUMP
|
||||
bool "kernel crash dumps"
|
||||
depends on 64BIT && SMP
|
||||
select KEXEC
|
||||
help
|
||||
Generate crash dump after being started by kexec.
|
||||
Crash dump kernels are loaded in the main kernel with kexec-tools
|
||||
into a specially reserved region and then later executed after
|
||||
a crash by kdump/kexec.
|
||||
Refer to <file:Documentation/s390/zfcpdump.txt> for more details on this.
|
||||
This option also enables s390 zfcpdump.
|
||||
See also <file:Documentation/s390/zfcpdump.txt>
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Executable file formats / Emulations"
|
||||
|
||||
source "fs/Kconfig.binfmt"
|
||||
|
||||
config SECCOMP
|
||||
def_bool y
|
||||
prompt "Enable seccomp to safely compute untrusted bytecode"
|
||||
depends on PROC_FS
|
||||
help
|
||||
This kernel feature is useful for number crunching applications
|
||||
that may need to compute untrusted bytecode during their
|
||||
execution. By using pipes or other transports made available to
|
||||
the process as file descriptors supporting the read/write
|
||||
syscalls, it's possible to isolate those applications in
|
||||
their own address space using seccomp. Once seccomp is
|
||||
enabled via /proc/<pid>/seccomp, it cannot be disabled
|
||||
and the task is only allowed to execute a few safe syscalls
|
||||
defined by each seccomp mode.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Power Management"
|
||||
|
||||
config ARCH_HIBERNATION_POSSIBLE
|
||||
def_bool y if 64BIT
|
||||
|
||||
source "kernel/power/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
||||
source "net/Kconfig"
|
||||
|
||||
config PCMCIA
|
||||
def_bool n
|
||||
|
||||
config CCW
|
||||
def_bool y
|
||||
|
||||
source "drivers/Kconfig"
|
||||
|
||||
source "fs/Kconfig"
|
||||
|
||||
source "arch/s390/Kconfig.debug"
|
||||
|
||||
source "security/Kconfig"
|
||||
|
||||
source "crypto/Kconfig"
|
||||
|
||||
source "lib/Kconfig"
|
||||
|
||||
menu "Virtualization"
|
||||
|
||||
config PFAULT
|
||||
def_bool y
|
||||
prompt "Pseudo page fault support"
|
||||
help
|
||||
Select this option, if you want to use PFAULT pseudo page fault
|
||||
handling under VM. If running native or in LPAR, this option
|
||||
has no effect. If your VM does not support PFAULT, PAGEEX
|
||||
pseudo page fault handling will be used.
|
||||
Note that VM 4.2 supports PFAULT but has a bug in its
|
||||
implementation that causes some problems.
|
||||
Everybody who wants to run Linux under VM != VM4.2 should select
|
||||
this option.
|
||||
|
||||
config SHARED_KERNEL
|
||||
bool "VM shared kernel support"
|
||||
depends on !JUMP_LABEL
|
||||
help
|
||||
Select this option, if you want to share the text segment of the
|
||||
Linux kernel between different VM guests. This reduces memory
|
||||
usage with lots of guests but greatly increases kernel size.
|
||||
Also if a kernel was IPL'ed from a shared segment the kexec system
|
||||
call will not work.
|
||||
You should only select this option if you know what you are
|
||||
doing and want to exploit this feature.
|
||||
|
||||
config CMM
|
||||
def_tristate n
|
||||
prompt "Cooperative memory management"
|
||||
help
|
||||
Select this option, if you want to enable the kernel interface
|
||||
to reduce the memory size of the system. This is accomplished
|
||||
by allocating pages of memory and put them "on hold". This only
|
||||
makes sense for a system running under VM where the unused pages
|
||||
will be reused by VM for other guest systems. The interface
|
||||
allows an external monitor to balance memory of many systems.
|
||||
Everybody who wants to run Linux under VM should select this
|
||||
option.
|
||||
|
||||
config CMM_IUCV
|
||||
def_bool y
|
||||
prompt "IUCV special message interface to cooperative memory management"
|
||||
depends on CMM && (SMSGIUCV=y || CMM=SMSGIUCV)
|
||||
help
|
||||
Select this option to enable the special message interface to
|
||||
the cooperative memory management.
|
||||
|
||||
config APPLDATA_BASE
|
||||
def_bool n
|
||||
prompt "Linux - VM Monitor Stream, base infrastructure"
|
||||
depends on PROC_FS
|
||||
help
|
||||
This provides a kernel interface for creating and updating z/VM APPLDATA
|
||||
monitor records. The monitor records are updated at certain time
|
||||
intervals, once the timer is started.
|
||||
Writing 1 or 0 to /proc/appldata/timer starts(1) or stops(0) the timer,
|
||||
i.e. enables or disables monitoring on the Linux side.
|
||||
A custom interval value (in seconds) can be written to
|
||||
/proc/appldata/interval.
|
||||
|
||||
Defaults are 60 seconds interval and timer off.
|
||||
The /proc entries can also be read from, showing the current settings.
|
||||
|
||||
config APPLDATA_MEM
|
||||
def_tristate m
|
||||
prompt "Monitor memory management statistics"
|
||||
depends on APPLDATA_BASE && VM_EVENT_COUNTERS
|
||||
help
|
||||
This provides memory management related data to the Linux - VM Monitor
|
||||
Stream, like paging/swapping rate, memory utilisation, etc.
|
||||
Writing 1 or 0 to /proc/appldata/memory creates(1) or removes(0) a z/VM
|
||||
APPLDATA monitor record, i.e. enables or disables monitoring this record
|
||||
on the z/VM side.
|
||||
|
||||
Default is disabled.
|
||||
The /proc entry can also be read from, showing the current settings.
|
||||
|
||||
This can also be compiled as a module, which will be called
|
||||
appldata_mem.o.
|
||||
|
||||
config APPLDATA_OS
|
||||
def_tristate m
|
||||
prompt "Monitor OS statistics"
|
||||
depends on APPLDATA_BASE
|
||||
help
|
||||
This provides OS related data to the Linux - VM Monitor Stream, like
|
||||
CPU utilisation, etc.
|
||||
Writing 1 or 0 to /proc/appldata/os creates(1) or removes(0) a z/VM
|
||||
APPLDATA monitor record, i.e. enables or disables monitoring this record
|
||||
on the z/VM side.
|
||||
|
||||
Default is disabled.
|
||||
This can also be compiled as a module, which will be called
|
||||
appldata_os.o.
|
||||
|
||||
config APPLDATA_NET_SUM
|
||||
def_tristate m
|
||||
prompt "Monitor overall network statistics"
|
||||
depends on APPLDATA_BASE && NET
|
||||
help
|
||||
This provides network related data to the Linux - VM Monitor Stream,
|
||||
currently there is only a total sum of network I/O statistics, no
|
||||
per-interface data.
|
||||
Writing 1 or 0 to /proc/appldata/net_sum creates(1) or removes(0) a z/VM
|
||||
APPLDATA monitor record, i.e. enables or disables monitoring this record
|
||||
on the z/VM side.
|
||||
|
||||
Default is disabled.
|
||||
This can also be compiled as a module, which will be called
|
||||
appldata_net_sum.o.
|
||||
|
||||
config S390_HYPFS_FS
|
||||
def_bool y
|
||||
prompt "s390 hypervisor file system support"
|
||||
select SYS_HYPERVISOR
|
||||
help
|
||||
This is a virtual file system intended to provide accounting
|
||||
information in an s390 hypervisor environment.
|
||||
|
||||
source "arch/s390/kvm/Kconfig"
|
||||
|
||||
config S390_GUEST
|
||||
def_bool y
|
||||
prompt "s390 support for virtio devices"
|
||||
depends on 64BIT
|
||||
select TTY
|
||||
select VIRTUALIZATION
|
||||
select VIRTIO
|
||||
select VIRTIO_CONSOLE
|
||||
help
|
||||
Enabling this option adds support for virtio based paravirtual device
|
||||
drivers on s390.
|
||||
|
||||
Select this option if you want to run the kernel as a guest under
|
||||
the KVM hypervisor.
|
||||
|
||||
endmenu
|
||||
35
arch/s390/Kconfig.debug
Normal file
35
arch/s390/Kconfig.debug
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
menu "Kernel hacking"
|
||||
|
||||
config TRACE_IRQFLAGS_SUPPORT
|
||||
def_bool y
|
||||
|
||||
source "lib/Kconfig.debug"
|
||||
|
||||
config STRICT_DEVMEM
|
||||
def_bool y
|
||||
prompt "Filter access to /dev/mem"
|
||||
---help---
|
||||
This option restricts access to /dev/mem. If this option is
|
||||
disabled, you allow userspace access to all memory, including
|
||||
kernel and userspace memory. Accidental memory access is likely
|
||||
to be disastrous.
|
||||
Memory access is required for experts who want to debug the kernel.
|
||||
|
||||
If you are unsure, say Y.
|
||||
|
||||
config S390_PTDUMP
|
||||
bool "Export kernel pagetable layout to userspace via debugfs"
|
||||
depends on DEBUG_KERNEL
|
||||
select DEBUG_FS
|
||||
---help---
|
||||
Say Y here if you want to show the kernel pagetable layout in a
|
||||
debugfs file. This information is only useful for kernel developers
|
||||
who are working in architecture specific areas of the kernel.
|
||||
It is probably not a good idea to enable this feature in a production
|
||||
kernel.
|
||||
If in doubt, say "N"
|
||||
|
||||
config DEBUG_SET_MODULE_RONX
|
||||
def_bool y
|
||||
depends on MODULES
|
||||
endmenu
|
||||
132
arch/s390/Makefile
Normal file
132
arch/s390/Makefile
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
#
|
||||
# s390/Makefile
|
||||
#
|
||||
# This file is included by the global makefile so that you can add your own
|
||||
# architecture-specific flags and dependencies. Remember to do have actions
|
||||
# for "archclean" and "archdep" for cleaning up and making dependencies for
|
||||
# this architecture
|
||||
#
|
||||
# This file is subject to the terms and conditions of the GNU General Public
|
||||
# License. See the file "COPYING" in the main directory of this archive
|
||||
# for more details.
|
||||
#
|
||||
# Copyright (C) 1994 by Linus Torvalds
|
||||
#
|
||||
|
||||
ifndef CONFIG_64BIT
|
||||
LD_BFD := elf32-s390
|
||||
LDFLAGS := -m elf_s390
|
||||
KBUILD_CFLAGS += -m31
|
||||
KBUILD_AFLAGS += -m31
|
||||
UTS_MACHINE := s390
|
||||
STACK_SIZE := 8192
|
||||
CHECKFLAGS += -D__s390__ -msize-long
|
||||
else
|
||||
LD_BFD := elf64-s390
|
||||
LDFLAGS := -m elf64_s390
|
||||
KBUILD_AFLAGS_MODULE += -fPIC
|
||||
KBUILD_CFLAGS_MODULE += -fPIC
|
||||
KBUILD_CFLAGS += -m64
|
||||
KBUILD_AFLAGS += -m64
|
||||
UTS_MACHINE := s390x
|
||||
STACK_SIZE := 16384
|
||||
CHECKFLAGS += -D__s390__ -D__s390x__
|
||||
endif
|
||||
|
||||
export LD_BFD
|
||||
|
||||
mflags-$(CONFIG_MARCH_G5) := -march=g5
|
||||
mflags-$(CONFIG_MARCH_Z900) := -march=z900
|
||||
mflags-$(CONFIG_MARCH_Z990) := -march=z990
|
||||
mflags-$(CONFIG_MARCH_Z9_109) := -march=z9-109
|
||||
mflags-$(CONFIG_MARCH_Z10) := -march=z10
|
||||
mflags-$(CONFIG_MARCH_Z196) := -march=z196
|
||||
mflags-$(CONFIG_MARCH_ZEC12) := -march=zEC12
|
||||
|
||||
aflags-y += $(mflags-y)
|
||||
cflags-y += $(mflags-y)
|
||||
|
||||
cflags-$(CONFIG_MARCH_G5_TUNE) += -mtune=g5
|
||||
cflags-$(CONFIG_MARCH_Z900_TUNE) += -mtune=z900
|
||||
cflags-$(CONFIG_MARCH_Z990_TUNE) += -mtune=z990
|
||||
cflags-$(CONFIG_MARCH_Z9_109_TUNE) += -mtune=z9-109
|
||||
cflags-$(CONFIG_MARCH_Z10_TUNE) += -mtune=z10
|
||||
cflags-$(CONFIG_MARCH_Z196_TUNE) += -mtune=z196
|
||||
cflags-$(CONFIG_MARCH_ZEC12_TUNE) += -mtune=zEC12
|
||||
|
||||
#KBUILD_IMAGE is necessary for make rpm
|
||||
KBUILD_IMAGE :=arch/s390/boot/image
|
||||
|
||||
#
|
||||
# Prevent tail-call optimizations, to get clearer backtraces:
|
||||
#
|
||||
cflags-$(CONFIG_FRAME_POINTER) += -fno-optimize-sibling-calls
|
||||
|
||||
# old style option for packed stacks
|
||||
ifeq ($(call cc-option-yn,-mkernel-backchain),y)
|
||||
cflags-$(CONFIG_PACK_STACK) += -mkernel-backchain -D__PACK_STACK
|
||||
aflags-$(CONFIG_PACK_STACK) += -D__PACK_STACK
|
||||
endif
|
||||
|
||||
# new style option for packed stacks
|
||||
ifeq ($(call cc-option-yn,-mpacked-stack),y)
|
||||
cflags-$(CONFIG_PACK_STACK) += -mpacked-stack -D__PACK_STACK
|
||||
aflags-$(CONFIG_PACK_STACK) += -D__PACK_STACK
|
||||
endif
|
||||
|
||||
ifeq ($(call cc-option-yn,-mstack-size=8192 -mstack-guard=128),y)
|
||||
cflags-$(CONFIG_CHECK_STACK) += -mstack-size=$(STACK_SIZE)
|
||||
ifneq ($(call cc-option-yn,-mstack-size=8192),y)
|
||||
cflags-$(CONFIG_CHECK_STACK) += -mstack-guard=$(CONFIG_STACK_GUARD)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(call cc-option-yn,-mwarn-dynamicstack),y)
|
||||
cflags-$(CONFIG_WARN_DYNAMIC_STACK) += -mwarn-dynamicstack
|
||||
endif
|
||||
|
||||
KBUILD_CFLAGS += -mbackchain -msoft-float $(cflags-y)
|
||||
KBUILD_CFLAGS += -pipe -fno-strength-reduce -Wno-sign-compare
|
||||
KBUILD_AFLAGS += $(aflags-y)
|
||||
|
||||
OBJCOPYFLAGS := -O binary
|
||||
|
||||
head-y := arch/s390/kernel/head.o
|
||||
head-y += arch/s390/kernel/$(if $(CONFIG_64BIT),head64.o,head31.o)
|
||||
|
||||
# See arch/s390/Kbuild for content of core part of the kernel
|
||||
core-y += arch/s390/
|
||||
|
||||
libs-y += arch/s390/lib/
|
||||
drivers-y += drivers/s390/
|
||||
|
||||
# must be linked after kernel
|
||||
drivers-$(CONFIG_OPROFILE) += arch/s390/oprofile/
|
||||
|
||||
boot := arch/s390/boot
|
||||
|
||||
all: image bzImage
|
||||
|
||||
install: vmlinux
|
||||
$(Q)$(MAKE) $(build)=$(boot) $@
|
||||
|
||||
image bzImage: vmlinux
|
||||
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
|
||||
|
||||
zfcpdump:
|
||||
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
|
||||
|
||||
vdso_install:
|
||||
ifeq ($(CONFIG_64BIT),y)
|
||||
$(Q)$(MAKE) $(build)=arch/$(ARCH)/kernel/vdso64 $@
|
||||
endif
|
||||
$(Q)$(MAKE) $(build)=arch/$(ARCH)/kernel/vdso32 $@
|
||||
|
||||
archclean:
|
||||
$(Q)$(MAKE) $(clean)=$(boot)
|
||||
|
||||
# Don't use tabs in echo arguments
|
||||
define archhelp
|
||||
echo '* image - Kernel image for IPL ($(boot)/image)'
|
||||
echo '* bzImage - Compressed kernel image for IPL ($(boot)/bzImage)'
|
||||
endef
|
||||
8
arch/s390/appldata/Makefile
Normal file
8
arch/s390/appldata/Makefile
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#
|
||||
# Makefile for the Linux - z/VM Monitor Stream.
|
||||
#
|
||||
|
||||
obj-$(CONFIG_APPLDATA_BASE) += appldata_base.o
|
||||
obj-$(CONFIG_APPLDATA_MEM) += appldata_mem.o
|
||||
obj-$(CONFIG_APPLDATA_OS) += appldata_os.o
|
||||
obj-$(CONFIG_APPLDATA_NET_SUM) += appldata_net_sum.o
|
||||
47
arch/s390/appldata/appldata.h
Normal file
47
arch/s390/appldata/appldata.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Definitions and interface for Linux - z/VM Monitor Stream.
|
||||
*
|
||||
* Copyright IBM Corp. 2003, 2008
|
||||
*
|
||||
* Author: Gerald Schaefer <gerald.schaefer@de.ibm.com>
|
||||
*/
|
||||
|
||||
#define APPLDATA_MAX_REC_SIZE 4024 /* Maximum size of the */
|
||||
/* data buffer */
|
||||
#define APPLDATA_MAX_PROCS 100
|
||||
|
||||
#define APPLDATA_PROC_NAME_LENGTH 16 /* Max. length of /proc name */
|
||||
|
||||
#define APPLDATA_RECORD_MEM_ID 0x01 /* IDs to identify the */
|
||||
#define APPLDATA_RECORD_OS_ID 0x02 /* individual records, */
|
||||
#define APPLDATA_RECORD_NET_SUM_ID 0x03 /* must be < 256 ! */
|
||||
#define APPLDATA_RECORD_PROC_ID 0x04
|
||||
|
||||
#define CTL_APPLDATA_TIMER 2121 /* sysctl IDs, must be unique */
|
||||
#define CTL_APPLDATA_INTERVAL 2122
|
||||
#define CTL_APPLDATA_MEM 2123
|
||||
#define CTL_APPLDATA_OS 2124
|
||||
#define CTL_APPLDATA_NET_SUM 2125
|
||||
#define CTL_APPLDATA_PROC 2126
|
||||
|
||||
struct appldata_ops {
|
||||
struct list_head list;
|
||||
struct ctl_table_header *sysctl_header;
|
||||
struct ctl_table *ctl_table;
|
||||
int active; /* monitoring status */
|
||||
|
||||
/* fill in from here */
|
||||
char name[APPLDATA_PROC_NAME_LENGTH]; /* name of /proc fs node */
|
||||
unsigned char record_nr; /* Record Nr. for Product ID */
|
||||
void (*callback)(void *data); /* callback function */
|
||||
void *data; /* record data */
|
||||
unsigned int size; /* size of record */
|
||||
struct module *owner; /* THIS_MODULE */
|
||||
char mod_lvl[2]; /* modification level, EBCDIC */
|
||||
};
|
||||
|
||||
extern int appldata_register_ops(struct appldata_ops *ops);
|
||||
extern void appldata_unregister_ops(struct appldata_ops *ops);
|
||||
extern int appldata_diag(char record_nr, u16 function, unsigned long buffer,
|
||||
u16 length, char *mod_lvl);
|
||||
|
||||
575
arch/s390/appldata/appldata_base.c
Normal file
575
arch/s390/appldata/appldata_base.c
Normal file
|
|
@ -0,0 +1,575 @@
|
|||
/*
|
||||
* Base infrastructure for Linux-z/VM Monitor Stream, Stage 1.
|
||||
* Exports appldata_register_ops() and appldata_unregister_ops() for the
|
||||
* data gathering modules.
|
||||
*
|
||||
* Copyright IBM Corp. 2003, 2009
|
||||
*
|
||||
* Author: Gerald Schaefer <gerald.schaefer@de.ibm.com>
|
||||
*/
|
||||
|
||||
#define KMSG_COMPONENT "appldata"
|
||||
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/swap.h>
|
||||
#include <linux/pagemap.h>
|
||||
#include <linux/sysctl.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <asm/appldata.h>
|
||||
#include <asm/vtimer.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/smp.h>
|
||||
|
||||
#include "appldata.h"
|
||||
|
||||
|
||||
#define APPLDATA_CPU_INTERVAL 10000 /* default (CPU) time for
|
||||
sampling interval in
|
||||
milliseconds */
|
||||
|
||||
#define TOD_MICRO 0x01000 /* nr. of TOD clock units
|
||||
for 1 microsecond */
|
||||
|
||||
static struct platform_device *appldata_pdev;
|
||||
|
||||
/*
|
||||
* /proc entries (sysctl)
|
||||
*/
|
||||
static const char appldata_proc_name[APPLDATA_PROC_NAME_LENGTH] = "appldata";
|
||||
static int appldata_timer_handler(struct ctl_table *ctl, int write,
|
||||
void __user *buffer, size_t *lenp, loff_t *ppos);
|
||||
static int appldata_interval_handler(struct ctl_table *ctl, int write,
|
||||
void __user *buffer,
|
||||
size_t *lenp, loff_t *ppos);
|
||||
|
||||
static struct ctl_table_header *appldata_sysctl_header;
|
||||
static struct ctl_table appldata_table[] = {
|
||||
{
|
||||
.procname = "timer",
|
||||
.mode = S_IRUGO | S_IWUSR,
|
||||
.proc_handler = appldata_timer_handler,
|
||||
},
|
||||
{
|
||||
.procname = "interval",
|
||||
.mode = S_IRUGO | S_IWUSR,
|
||||
.proc_handler = appldata_interval_handler,
|
||||
},
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct ctl_table appldata_dir_table[] = {
|
||||
{
|
||||
.procname = appldata_proc_name,
|
||||
.maxlen = 0,
|
||||
.mode = S_IRUGO | S_IXUGO,
|
||||
.child = appldata_table,
|
||||
},
|
||||
{ },
|
||||
};
|
||||
|
||||
/*
|
||||
* Timer
|
||||
*/
|
||||
static struct vtimer_list appldata_timer;
|
||||
|
||||
static DEFINE_SPINLOCK(appldata_timer_lock);
|
||||
static int appldata_interval = APPLDATA_CPU_INTERVAL;
|
||||
static int appldata_timer_active;
|
||||
static int appldata_timer_suspended = 0;
|
||||
|
||||
/*
|
||||
* Work queue
|
||||
*/
|
||||
static struct workqueue_struct *appldata_wq;
|
||||
static void appldata_work_fn(struct work_struct *work);
|
||||
static DECLARE_WORK(appldata_work, appldata_work_fn);
|
||||
|
||||
|
||||
/*
|
||||
* Ops list
|
||||
*/
|
||||
static DEFINE_MUTEX(appldata_ops_mutex);
|
||||
static LIST_HEAD(appldata_ops_list);
|
||||
|
||||
|
||||
/*************************** timer, work, DIAG *******************************/
|
||||
/*
|
||||
* appldata_timer_function()
|
||||
*
|
||||
* schedule work and reschedule timer
|
||||
*/
|
||||
static void appldata_timer_function(unsigned long data)
|
||||
{
|
||||
queue_work(appldata_wq, (struct work_struct *) data);
|
||||
}
|
||||
|
||||
/*
|
||||
* appldata_work_fn()
|
||||
*
|
||||
* call data gathering function for each (active) module
|
||||
*/
|
||||
static void appldata_work_fn(struct work_struct *work)
|
||||
{
|
||||
struct list_head *lh;
|
||||
struct appldata_ops *ops;
|
||||
|
||||
mutex_lock(&appldata_ops_mutex);
|
||||
list_for_each(lh, &appldata_ops_list) {
|
||||
ops = list_entry(lh, struct appldata_ops, list);
|
||||
if (ops->active == 1) {
|
||||
ops->callback(ops->data);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&appldata_ops_mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
* appldata_diag()
|
||||
*
|
||||
* prepare parameter list, issue DIAG 0xDC
|
||||
*/
|
||||
int appldata_diag(char record_nr, u16 function, unsigned long buffer,
|
||||
u16 length, char *mod_lvl)
|
||||
{
|
||||
struct appldata_product_id id = {
|
||||
.prod_nr = {0xD3, 0xC9, 0xD5, 0xE4,
|
||||
0xE7, 0xD2, 0xD9}, /* "LINUXKR" */
|
||||
.prod_fn = 0xD5D3, /* "NL" */
|
||||
.version_nr = 0xF2F6, /* "26" */
|
||||
.release_nr = 0xF0F1, /* "01" */
|
||||
};
|
||||
|
||||
id.record_nr = record_nr;
|
||||
id.mod_lvl = (mod_lvl[0]) << 8 | mod_lvl[1];
|
||||
return appldata_asm(&id, function, (void *) buffer, length);
|
||||
}
|
||||
/************************ timer, work, DIAG <END> ****************************/
|
||||
|
||||
|
||||
/****************************** /proc stuff **********************************/
|
||||
|
||||
#define APPLDATA_ADD_TIMER 0
|
||||
#define APPLDATA_DEL_TIMER 1
|
||||
#define APPLDATA_MOD_TIMER 2
|
||||
|
||||
/*
|
||||
* __appldata_vtimer_setup()
|
||||
*
|
||||
* Add, delete or modify virtual timers on all online cpus.
|
||||
* The caller needs to get the appldata_timer_lock spinlock.
|
||||
*/
|
||||
static void __appldata_vtimer_setup(int cmd)
|
||||
{
|
||||
u64 timer_interval = (u64) appldata_interval * 1000 * TOD_MICRO;
|
||||
|
||||
switch (cmd) {
|
||||
case APPLDATA_ADD_TIMER:
|
||||
if (appldata_timer_active)
|
||||
break;
|
||||
appldata_timer.expires = timer_interval;
|
||||
add_virt_timer_periodic(&appldata_timer);
|
||||
appldata_timer_active = 1;
|
||||
break;
|
||||
case APPLDATA_DEL_TIMER:
|
||||
del_virt_timer(&appldata_timer);
|
||||
if (!appldata_timer_active)
|
||||
break;
|
||||
appldata_timer_active = 0;
|
||||
break;
|
||||
case APPLDATA_MOD_TIMER:
|
||||
if (!appldata_timer_active)
|
||||
break;
|
||||
mod_virt_timer_periodic(&appldata_timer, timer_interval);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* appldata_timer_handler()
|
||||
*
|
||||
* Start/Stop timer, show status of timer (0 = not active, 1 = active)
|
||||
*/
|
||||
static int
|
||||
appldata_timer_handler(struct ctl_table *ctl, int write,
|
||||
void __user *buffer, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
unsigned int len;
|
||||
char buf[2];
|
||||
|
||||
if (!*lenp || *ppos) {
|
||||
*lenp = 0;
|
||||
return 0;
|
||||
}
|
||||
if (!write) {
|
||||
strncpy(buf, appldata_timer_active ? "1\n" : "0\n",
|
||||
ARRAY_SIZE(buf));
|
||||
len = strnlen(buf, ARRAY_SIZE(buf));
|
||||
if (len > *lenp)
|
||||
len = *lenp;
|
||||
if (copy_to_user(buffer, buf, len))
|
||||
return -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
len = *lenp;
|
||||
if (copy_from_user(buf, buffer, len > sizeof(buf) ? sizeof(buf) : len))
|
||||
return -EFAULT;
|
||||
spin_lock(&appldata_timer_lock);
|
||||
if (buf[0] == '1')
|
||||
__appldata_vtimer_setup(APPLDATA_ADD_TIMER);
|
||||
else if (buf[0] == '0')
|
||||
__appldata_vtimer_setup(APPLDATA_DEL_TIMER);
|
||||
spin_unlock(&appldata_timer_lock);
|
||||
out:
|
||||
*lenp = len;
|
||||
*ppos += len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* appldata_interval_handler()
|
||||
*
|
||||
* Set (CPU) timer interval for collection of data (in milliseconds), show
|
||||
* current timer interval.
|
||||
*/
|
||||
static int
|
||||
appldata_interval_handler(struct ctl_table *ctl, int write,
|
||||
void __user *buffer, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
unsigned int len;
|
||||
int interval;
|
||||
char buf[16];
|
||||
|
||||
if (!*lenp || *ppos) {
|
||||
*lenp = 0;
|
||||
return 0;
|
||||
}
|
||||
if (!write) {
|
||||
len = sprintf(buf, "%i\n", appldata_interval);
|
||||
if (len > *lenp)
|
||||
len = *lenp;
|
||||
if (copy_to_user(buffer, buf, len))
|
||||
return -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
len = *lenp;
|
||||
if (copy_from_user(buf, buffer, len > sizeof(buf) ? sizeof(buf) : len))
|
||||
return -EFAULT;
|
||||
interval = 0;
|
||||
sscanf(buf, "%i", &interval);
|
||||
if (interval <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock(&appldata_timer_lock);
|
||||
appldata_interval = interval;
|
||||
__appldata_vtimer_setup(APPLDATA_MOD_TIMER);
|
||||
spin_unlock(&appldata_timer_lock);
|
||||
out:
|
||||
*lenp = len;
|
||||
*ppos += len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* appldata_generic_handler()
|
||||
*
|
||||
* Generic start/stop monitoring and DIAG, show status of
|
||||
* monitoring (0 = not in process, 1 = in process)
|
||||
*/
|
||||
static int
|
||||
appldata_generic_handler(struct ctl_table *ctl, int write,
|
||||
void __user *buffer, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
struct appldata_ops *ops = NULL, *tmp_ops;
|
||||
unsigned int len;
|
||||
int rc, found;
|
||||
char buf[2];
|
||||
struct list_head *lh;
|
||||
|
||||
found = 0;
|
||||
mutex_lock(&appldata_ops_mutex);
|
||||
list_for_each(lh, &appldata_ops_list) {
|
||||
tmp_ops = list_entry(lh, struct appldata_ops, list);
|
||||
if (&tmp_ops->ctl_table[2] == ctl) {
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
mutex_unlock(&appldata_ops_mutex);
|
||||
return -ENODEV;
|
||||
}
|
||||
ops = ctl->data;
|
||||
if (!try_module_get(ops->owner)) { // protect this function
|
||||
mutex_unlock(&appldata_ops_mutex);
|
||||
return -ENODEV;
|
||||
}
|
||||
mutex_unlock(&appldata_ops_mutex);
|
||||
|
||||
if (!*lenp || *ppos) {
|
||||
*lenp = 0;
|
||||
module_put(ops->owner);
|
||||
return 0;
|
||||
}
|
||||
if (!write) {
|
||||
strncpy(buf, ops->active ? "1\n" : "0\n", ARRAY_SIZE(buf));
|
||||
len = strnlen(buf, ARRAY_SIZE(buf));
|
||||
if (len > *lenp)
|
||||
len = *lenp;
|
||||
if (copy_to_user(buffer, buf, len)) {
|
||||
module_put(ops->owner);
|
||||
return -EFAULT;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
len = *lenp;
|
||||
if (copy_from_user(buf, buffer,
|
||||
len > sizeof(buf) ? sizeof(buf) : len)) {
|
||||
module_put(ops->owner);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
mutex_lock(&appldata_ops_mutex);
|
||||
if ((buf[0] == '1') && (ops->active == 0)) {
|
||||
// protect work queue callback
|
||||
if (!try_module_get(ops->owner)) {
|
||||
mutex_unlock(&appldata_ops_mutex);
|
||||
module_put(ops->owner);
|
||||
return -ENODEV;
|
||||
}
|
||||
ops->callback(ops->data); // init record
|
||||
rc = appldata_diag(ops->record_nr,
|
||||
APPLDATA_START_INTERVAL_REC,
|
||||
(unsigned long) ops->data, ops->size,
|
||||
ops->mod_lvl);
|
||||
if (rc != 0) {
|
||||
pr_err("Starting the data collection for %s "
|
||||
"failed with rc=%d\n", ops->name, rc);
|
||||
module_put(ops->owner);
|
||||
} else
|
||||
ops->active = 1;
|
||||
} else if ((buf[0] == '0') && (ops->active == 1)) {
|
||||
ops->active = 0;
|
||||
rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC,
|
||||
(unsigned long) ops->data, ops->size,
|
||||
ops->mod_lvl);
|
||||
if (rc != 0)
|
||||
pr_err("Stopping the data collection for %s "
|
||||
"failed with rc=%d\n", ops->name, rc);
|
||||
module_put(ops->owner);
|
||||
}
|
||||
mutex_unlock(&appldata_ops_mutex);
|
||||
out:
|
||||
*lenp = len;
|
||||
*ppos += len;
|
||||
module_put(ops->owner);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*************************** /proc stuff <END> *******************************/
|
||||
|
||||
|
||||
/************************* module-ops management *****************************/
|
||||
/*
|
||||
* appldata_register_ops()
|
||||
*
|
||||
* update ops list, register /proc/sys entries
|
||||
*/
|
||||
int appldata_register_ops(struct appldata_ops *ops)
|
||||
{
|
||||
if (ops->size > APPLDATA_MAX_REC_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
ops->ctl_table = kzalloc(4 * sizeof(struct ctl_table), GFP_KERNEL);
|
||||
if (!ops->ctl_table)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_lock(&appldata_ops_mutex);
|
||||
list_add(&ops->list, &appldata_ops_list);
|
||||
mutex_unlock(&appldata_ops_mutex);
|
||||
|
||||
ops->ctl_table[0].procname = appldata_proc_name;
|
||||
ops->ctl_table[0].maxlen = 0;
|
||||
ops->ctl_table[0].mode = S_IRUGO | S_IXUGO;
|
||||
ops->ctl_table[0].child = &ops->ctl_table[2];
|
||||
|
||||
ops->ctl_table[2].procname = ops->name;
|
||||
ops->ctl_table[2].mode = S_IRUGO | S_IWUSR;
|
||||
ops->ctl_table[2].proc_handler = appldata_generic_handler;
|
||||
ops->ctl_table[2].data = ops;
|
||||
|
||||
ops->sysctl_header = register_sysctl_table(ops->ctl_table);
|
||||
if (!ops->sysctl_header)
|
||||
goto out;
|
||||
return 0;
|
||||
out:
|
||||
mutex_lock(&appldata_ops_mutex);
|
||||
list_del(&ops->list);
|
||||
mutex_unlock(&appldata_ops_mutex);
|
||||
kfree(ops->ctl_table);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/*
|
||||
* appldata_unregister_ops()
|
||||
*
|
||||
* update ops list, unregister /proc entries, stop DIAG if necessary
|
||||
*/
|
||||
void appldata_unregister_ops(struct appldata_ops *ops)
|
||||
{
|
||||
mutex_lock(&appldata_ops_mutex);
|
||||
list_del(&ops->list);
|
||||
mutex_unlock(&appldata_ops_mutex);
|
||||
unregister_sysctl_table(ops->sysctl_header);
|
||||
kfree(ops->ctl_table);
|
||||
}
|
||||
/********************** module-ops management <END> **************************/
|
||||
|
||||
|
||||
/**************************** suspend / resume *******************************/
|
||||
static int appldata_freeze(struct device *dev)
|
||||
{
|
||||
struct appldata_ops *ops;
|
||||
int rc;
|
||||
struct list_head *lh;
|
||||
|
||||
spin_lock(&appldata_timer_lock);
|
||||
if (appldata_timer_active) {
|
||||
__appldata_vtimer_setup(APPLDATA_DEL_TIMER);
|
||||
appldata_timer_suspended = 1;
|
||||
}
|
||||
spin_unlock(&appldata_timer_lock);
|
||||
|
||||
mutex_lock(&appldata_ops_mutex);
|
||||
list_for_each(lh, &appldata_ops_list) {
|
||||
ops = list_entry(lh, struct appldata_ops, list);
|
||||
if (ops->active == 1) {
|
||||
rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC,
|
||||
(unsigned long) ops->data, ops->size,
|
||||
ops->mod_lvl);
|
||||
if (rc != 0)
|
||||
pr_err("Stopping the data collection for %s "
|
||||
"failed with rc=%d\n", ops->name, rc);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&appldata_ops_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int appldata_restore(struct device *dev)
|
||||
{
|
||||
struct appldata_ops *ops;
|
||||
int rc;
|
||||
struct list_head *lh;
|
||||
|
||||
spin_lock(&appldata_timer_lock);
|
||||
if (appldata_timer_suspended) {
|
||||
__appldata_vtimer_setup(APPLDATA_ADD_TIMER);
|
||||
appldata_timer_suspended = 0;
|
||||
}
|
||||
spin_unlock(&appldata_timer_lock);
|
||||
|
||||
mutex_lock(&appldata_ops_mutex);
|
||||
list_for_each(lh, &appldata_ops_list) {
|
||||
ops = list_entry(lh, struct appldata_ops, list);
|
||||
if (ops->active == 1) {
|
||||
ops->callback(ops->data); // init record
|
||||
rc = appldata_diag(ops->record_nr,
|
||||
APPLDATA_START_INTERVAL_REC,
|
||||
(unsigned long) ops->data, ops->size,
|
||||
ops->mod_lvl);
|
||||
if (rc != 0) {
|
||||
pr_err("Starting the data collection for %s "
|
||||
"failed with rc=%d\n", ops->name, rc);
|
||||
}
|
||||
}
|
||||
}
|
||||
mutex_unlock(&appldata_ops_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int appldata_thaw(struct device *dev)
|
||||
{
|
||||
return appldata_restore(dev);
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops appldata_pm_ops = {
|
||||
.freeze = appldata_freeze,
|
||||
.thaw = appldata_thaw,
|
||||
.restore = appldata_restore,
|
||||
};
|
||||
|
||||
static struct platform_driver appldata_pdrv = {
|
||||
.driver = {
|
||||
.name = "appldata",
|
||||
.owner = THIS_MODULE,
|
||||
.pm = &appldata_pm_ops,
|
||||
},
|
||||
};
|
||||
/************************* suspend / resume <END> ****************************/
|
||||
|
||||
|
||||
/******************************* init / exit *********************************/
|
||||
|
||||
/*
|
||||
* appldata_init()
|
||||
*
|
||||
* init timer, register /proc entries
|
||||
*/
|
||||
static int __init appldata_init(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
init_virt_timer(&appldata_timer);
|
||||
appldata_timer.function = appldata_timer_function;
|
||||
appldata_timer.data = (unsigned long) &appldata_work;
|
||||
|
||||
rc = platform_driver_register(&appldata_pdrv);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
appldata_pdev = platform_device_register_simple("appldata", -1, NULL,
|
||||
0);
|
||||
if (IS_ERR(appldata_pdev)) {
|
||||
rc = PTR_ERR(appldata_pdev);
|
||||
goto out_driver;
|
||||
}
|
||||
appldata_wq = create_singlethread_workqueue("appldata");
|
||||
if (!appldata_wq) {
|
||||
rc = -ENOMEM;
|
||||
goto out_device;
|
||||
}
|
||||
|
||||
appldata_sysctl_header = register_sysctl_table(appldata_dir_table);
|
||||
return 0;
|
||||
|
||||
out_device:
|
||||
platform_device_unregister(appldata_pdev);
|
||||
out_driver:
|
||||
platform_driver_unregister(&appldata_pdrv);
|
||||
return rc;
|
||||
}
|
||||
|
||||
__initcall(appldata_init);
|
||||
|
||||
/**************************** init / exit <END> ******************************/
|
||||
|
||||
EXPORT_SYMBOL_GPL(appldata_register_ops);
|
||||
EXPORT_SYMBOL_GPL(appldata_unregister_ops);
|
||||
EXPORT_SYMBOL_GPL(appldata_diag);
|
||||
|
||||
#ifdef CONFIG_SWAP
|
||||
EXPORT_SYMBOL_GPL(si_swapinfo);
|
||||
#endif
|
||||
EXPORT_SYMBOL_GPL(nr_threads);
|
||||
EXPORT_SYMBOL_GPL(nr_running);
|
||||
EXPORT_SYMBOL_GPL(nr_iowait);
|
||||
164
arch/s390/appldata/appldata_mem.c
Normal file
164
arch/s390/appldata/appldata_mem.c
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
* Data gathering module for Linux-VM Monitor Stream, Stage 1.
|
||||
* Collects data related to memory management.
|
||||
*
|
||||
* Copyright IBM Corp. 2003, 2006
|
||||
*
|
||||
* Author: Gerald Schaefer <gerald.schaefer@de.ibm.com>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel_stat.h>
|
||||
#include <linux/pagemap.h>
|
||||
#include <linux/swap.h>
|
||||
#include <linux/slab.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include "appldata.h"
|
||||
|
||||
|
||||
#define P2K(x) ((x) << (PAGE_SHIFT - 10)) /* Converts #Pages to KB */
|
||||
|
||||
/*
|
||||
* Memory data
|
||||
*
|
||||
* This is accessed as binary data by z/VM. If changes to it can't be avoided,
|
||||
* the structure version (product ID, see appldata_base.c) needs to be changed
|
||||
* as well and all documentation and z/VM applications using it must be
|
||||
* updated.
|
||||
*
|
||||
* The record layout is documented in the Linux for zSeries Device Drivers
|
||||
* book:
|
||||
* http://oss.software.ibm.com/developerworks/opensource/linux390/index.shtml
|
||||
*/
|
||||
struct appldata_mem_data {
|
||||
u64 timestamp;
|
||||
u32 sync_count_1; /* after VM collected the record data, */
|
||||
u32 sync_count_2; /* sync_count_1 and sync_count_2 should be the
|
||||
same. If not, the record has been updated on
|
||||
the Linux side while VM was collecting the
|
||||
(possibly corrupt) data */
|
||||
|
||||
u64 pgpgin; /* data read from disk */
|
||||
u64 pgpgout; /* data written to disk */
|
||||
u64 pswpin; /* pages swapped in */
|
||||
u64 pswpout; /* pages swapped out */
|
||||
|
||||
u64 sharedram; /* sharedram is currently set to 0 */
|
||||
|
||||
u64 totalram; /* total main memory size */
|
||||
u64 freeram; /* free main memory size */
|
||||
u64 totalhigh; /* total high memory size */
|
||||
u64 freehigh; /* free high memory size */
|
||||
|
||||
u64 bufferram; /* memory reserved for buffers, free cache */
|
||||
u64 cached; /* size of (used) cache, w/o buffers */
|
||||
u64 totalswap; /* total swap space size */
|
||||
u64 freeswap; /* free swap space */
|
||||
|
||||
// New in 2.6 -->
|
||||
u64 pgalloc; /* page allocations */
|
||||
u64 pgfault; /* page faults (major+minor) */
|
||||
u64 pgmajfault; /* page faults (major only) */
|
||||
// <-- New in 2.6
|
||||
|
||||
} __packed;
|
||||
|
||||
|
||||
/*
|
||||
* appldata_get_mem_data()
|
||||
*
|
||||
* gather memory data
|
||||
*/
|
||||
static void appldata_get_mem_data(void *data)
|
||||
{
|
||||
/*
|
||||
* don't put large structures on the stack, we are
|
||||
* serialized through the appldata_ops_mutex and can use static
|
||||
*/
|
||||
static struct sysinfo val;
|
||||
unsigned long ev[NR_VM_EVENT_ITEMS];
|
||||
struct appldata_mem_data *mem_data;
|
||||
|
||||
mem_data = data;
|
||||
mem_data->sync_count_1++;
|
||||
|
||||
all_vm_events(ev);
|
||||
mem_data->pgpgin = ev[PGPGIN] >> 1;
|
||||
mem_data->pgpgout = ev[PGPGOUT] >> 1;
|
||||
mem_data->pswpin = ev[PSWPIN];
|
||||
mem_data->pswpout = ev[PSWPOUT];
|
||||
mem_data->pgalloc = ev[PGALLOC_NORMAL];
|
||||
mem_data->pgalloc += ev[PGALLOC_DMA];
|
||||
mem_data->pgfault = ev[PGFAULT];
|
||||
mem_data->pgmajfault = ev[PGMAJFAULT];
|
||||
|
||||
si_meminfo(&val);
|
||||
mem_data->sharedram = val.sharedram;
|
||||
mem_data->totalram = P2K(val.totalram);
|
||||
mem_data->freeram = P2K(val.freeram);
|
||||
mem_data->totalhigh = P2K(val.totalhigh);
|
||||
mem_data->freehigh = P2K(val.freehigh);
|
||||
mem_data->bufferram = P2K(val.bufferram);
|
||||
mem_data->cached = P2K(global_page_state(NR_FILE_PAGES)
|
||||
- val.bufferram);
|
||||
|
||||
si_swapinfo(&val);
|
||||
mem_data->totalswap = P2K(val.totalswap);
|
||||
mem_data->freeswap = P2K(val.freeswap);
|
||||
|
||||
mem_data->timestamp = get_tod_clock();
|
||||
mem_data->sync_count_2++;
|
||||
}
|
||||
|
||||
|
||||
static struct appldata_ops ops = {
|
||||
.name = "mem",
|
||||
.record_nr = APPLDATA_RECORD_MEM_ID,
|
||||
.size = sizeof(struct appldata_mem_data),
|
||||
.callback = &appldata_get_mem_data,
|
||||
.owner = THIS_MODULE,
|
||||
.mod_lvl = {0xF0, 0xF0}, /* EBCDIC "00" */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* appldata_mem_init()
|
||||
*
|
||||
* init_data, register ops
|
||||
*/
|
||||
static int __init appldata_mem_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ops.data = kzalloc(sizeof(struct appldata_mem_data), GFP_KERNEL);
|
||||
if (!ops.data)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = appldata_register_ops(&ops);
|
||||
if (ret)
|
||||
kfree(ops.data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* appldata_mem_exit()
|
||||
*
|
||||
* unregister ops
|
||||
*/
|
||||
static void __exit appldata_mem_exit(void)
|
||||
{
|
||||
appldata_unregister_ops(&ops);
|
||||
kfree(ops.data);
|
||||
}
|
||||
|
||||
|
||||
module_init(appldata_mem_init);
|
||||
module_exit(appldata_mem_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Gerald Schaefer");
|
||||
MODULE_DESCRIPTION("Linux-VM Monitor Stream, MEMORY statistics");
|
||||
166
arch/s390/appldata/appldata_net_sum.c
Normal file
166
arch/s390/appldata/appldata_net_sum.c
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* Data gathering module for Linux-VM Monitor Stream, Stage 1.
|
||||
* Collects accumulated network statistics (Packets received/transmitted,
|
||||
* dropped, errors, ...).
|
||||
*
|
||||
* Copyright IBM Corp. 2003, 2006
|
||||
*
|
||||
* Author: Gerald Schaefer <gerald.schaefer@de.ibm.com>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel_stat.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <net/net_namespace.h>
|
||||
|
||||
#include "appldata.h"
|
||||
|
||||
|
||||
/*
|
||||
* Network data
|
||||
*
|
||||
* This is accessed as binary data by z/VM. If changes to it can't be avoided,
|
||||
* the structure version (product ID, see appldata_base.c) needs to be changed
|
||||
* as well and all documentation and z/VM applications using it must be updated.
|
||||
*
|
||||
* The record layout is documented in the Linux for zSeries Device Drivers
|
||||
* book:
|
||||
* http://oss.software.ibm.com/developerworks/opensource/linux390/index.shtml
|
||||
*/
|
||||
struct appldata_net_sum_data {
|
||||
u64 timestamp;
|
||||
u32 sync_count_1; /* after VM collected the record data, */
|
||||
u32 sync_count_2; /* sync_count_1 and sync_count_2 should be the
|
||||
same. If not, the record has been updated on
|
||||
the Linux side while VM was collecting the
|
||||
(possibly corrupt) data */
|
||||
|
||||
u32 nr_interfaces; /* nr. of network interfaces being monitored */
|
||||
|
||||
u32 padding; /* next value is 64-bit aligned, so these */
|
||||
/* 4 byte would be padded out by compiler */
|
||||
|
||||
u64 rx_packets; /* total packets received */
|
||||
u64 tx_packets; /* total packets transmitted */
|
||||
u64 rx_bytes; /* total bytes received */
|
||||
u64 tx_bytes; /* total bytes transmitted */
|
||||
u64 rx_errors; /* bad packets received */
|
||||
u64 tx_errors; /* packet transmit problems */
|
||||
u64 rx_dropped; /* no space in linux buffers */
|
||||
u64 tx_dropped; /* no space available in linux */
|
||||
u64 collisions; /* collisions while transmitting */
|
||||
} __packed;
|
||||
|
||||
|
||||
/*
|
||||
* appldata_get_net_sum_data()
|
||||
*
|
||||
* gather accumulated network statistics
|
||||
*/
|
||||
static void appldata_get_net_sum_data(void *data)
|
||||
{
|
||||
int i;
|
||||
struct appldata_net_sum_data *net_data;
|
||||
struct net_device *dev;
|
||||
unsigned long rx_packets, tx_packets, rx_bytes, tx_bytes, rx_errors,
|
||||
tx_errors, rx_dropped, tx_dropped, collisions;
|
||||
|
||||
net_data = data;
|
||||
net_data->sync_count_1++;
|
||||
|
||||
i = 0;
|
||||
rx_packets = 0;
|
||||
tx_packets = 0;
|
||||
rx_bytes = 0;
|
||||
tx_bytes = 0;
|
||||
rx_errors = 0;
|
||||
tx_errors = 0;
|
||||
rx_dropped = 0;
|
||||
tx_dropped = 0;
|
||||
collisions = 0;
|
||||
|
||||
rcu_read_lock();
|
||||
for_each_netdev_rcu(&init_net, dev) {
|
||||
const struct rtnl_link_stats64 *stats;
|
||||
struct rtnl_link_stats64 temp;
|
||||
|
||||
stats = dev_get_stats(dev, &temp);
|
||||
rx_packets += stats->rx_packets;
|
||||
tx_packets += stats->tx_packets;
|
||||
rx_bytes += stats->rx_bytes;
|
||||
tx_bytes += stats->tx_bytes;
|
||||
rx_errors += stats->rx_errors;
|
||||
tx_errors += stats->tx_errors;
|
||||
rx_dropped += stats->rx_dropped;
|
||||
tx_dropped += stats->tx_dropped;
|
||||
collisions += stats->collisions;
|
||||
i++;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
net_data->nr_interfaces = i;
|
||||
net_data->rx_packets = rx_packets;
|
||||
net_data->tx_packets = tx_packets;
|
||||
net_data->rx_bytes = rx_bytes;
|
||||
net_data->tx_bytes = tx_bytes;
|
||||
net_data->rx_errors = rx_errors;
|
||||
net_data->tx_errors = tx_errors;
|
||||
net_data->rx_dropped = rx_dropped;
|
||||
net_data->tx_dropped = tx_dropped;
|
||||
net_data->collisions = collisions;
|
||||
|
||||
net_data->timestamp = get_tod_clock();
|
||||
net_data->sync_count_2++;
|
||||
}
|
||||
|
||||
|
||||
static struct appldata_ops ops = {
|
||||
.name = "net_sum",
|
||||
.record_nr = APPLDATA_RECORD_NET_SUM_ID,
|
||||
.size = sizeof(struct appldata_net_sum_data),
|
||||
.callback = &appldata_get_net_sum_data,
|
||||
.owner = THIS_MODULE,
|
||||
.mod_lvl = {0xF0, 0xF0}, /* EBCDIC "00" */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* appldata_net_init()
|
||||
*
|
||||
* init data, register ops
|
||||
*/
|
||||
static int __init appldata_net_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ops.data = kzalloc(sizeof(struct appldata_net_sum_data), GFP_KERNEL);
|
||||
if (!ops.data)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = appldata_register_ops(&ops);
|
||||
if (ret)
|
||||
kfree(ops.data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* appldata_net_exit()
|
||||
*
|
||||
* unregister ops
|
||||
*/
|
||||
static void __exit appldata_net_exit(void)
|
||||
{
|
||||
appldata_unregister_ops(&ops);
|
||||
kfree(ops.data);
|
||||
}
|
||||
|
||||
|
||||
module_init(appldata_net_init);
|
||||
module_exit(appldata_net_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Gerald Schaefer");
|
||||
MODULE_DESCRIPTION("Linux-VM Monitor Stream, accumulated network statistics");
|
||||
218
arch/s390/appldata/appldata_os.c
Normal file
218
arch/s390/appldata/appldata_os.c
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
/*
|
||||
* Data gathering module for Linux-VM Monitor Stream, Stage 1.
|
||||
* Collects misc. OS related data (CPU utilization, running processes).
|
||||
*
|
||||
* Copyright IBM Corp. 2003, 2006
|
||||
*
|
||||
* Author: Gerald Schaefer <gerald.schaefer@de.ibm.com>
|
||||
*/
|
||||
|
||||
#define KMSG_COMPONENT "appldata"
|
||||
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel_stat.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/sched.h>
|
||||
#include <asm/appldata.h>
|
||||
#include <asm/smp.h>
|
||||
|
||||
#include "appldata.h"
|
||||
|
||||
|
||||
#define LOAD_INT(x) ((x) >> FSHIFT)
|
||||
#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
|
||||
|
||||
/*
|
||||
* OS data
|
||||
*
|
||||
* This is accessed as binary data by z/VM. If changes to it can't be avoided,
|
||||
* the structure version (product ID, see appldata_base.c) needs to be changed
|
||||
* as well and all documentation and z/VM applications using it must be
|
||||
* updated.
|
||||
*
|
||||
* The record layout is documented in the Linux for zSeries Device Drivers
|
||||
* book:
|
||||
* http://oss.software.ibm.com/developerworks/opensource/linux390/index.shtml
|
||||
*/
|
||||
struct appldata_os_per_cpu {
|
||||
u32 per_cpu_user; /* timer ticks spent in user mode */
|
||||
u32 per_cpu_nice; /* ... spent with modified priority */
|
||||
u32 per_cpu_system; /* ... spent in kernel mode */
|
||||
u32 per_cpu_idle; /* ... spent in idle mode */
|
||||
|
||||
/* New in 2.6 */
|
||||
u32 per_cpu_irq; /* ... spent in interrupts */
|
||||
u32 per_cpu_softirq; /* ... spent in softirqs */
|
||||
u32 per_cpu_iowait; /* ... spent while waiting for I/O */
|
||||
|
||||
/* New in modification level 01 */
|
||||
u32 per_cpu_steal; /* ... stolen by hypervisor */
|
||||
u32 cpu_id; /* number of this CPU */
|
||||
} __attribute__((packed));
|
||||
|
||||
struct appldata_os_data {
|
||||
u64 timestamp;
|
||||
u32 sync_count_1; /* after VM collected the record data, */
|
||||
u32 sync_count_2; /* sync_count_1 and sync_count_2 should be the
|
||||
same. If not, the record has been updated on
|
||||
the Linux side while VM was collecting the
|
||||
(possibly corrupt) data */
|
||||
|
||||
u32 nr_cpus; /* number of (virtual) CPUs */
|
||||
u32 per_cpu_size; /* size of the per-cpu data struct */
|
||||
u32 cpu_offset; /* offset of the first per-cpu data struct */
|
||||
|
||||
u32 nr_running; /* number of runnable threads */
|
||||
u32 nr_threads; /* number of threads */
|
||||
u32 avenrun[3]; /* average nr. of running processes during */
|
||||
/* the last 1, 5 and 15 minutes */
|
||||
|
||||
/* New in 2.6 */
|
||||
u32 nr_iowait; /* number of blocked threads
|
||||
(waiting for I/O) */
|
||||
|
||||
/* per cpu data */
|
||||
struct appldata_os_per_cpu os_cpu[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
static struct appldata_os_data *appldata_os_data;
|
||||
|
||||
static struct appldata_ops ops = {
|
||||
.name = "os",
|
||||
.record_nr = APPLDATA_RECORD_OS_ID,
|
||||
.owner = THIS_MODULE,
|
||||
.mod_lvl = {0xF0, 0xF1}, /* EBCDIC "01" */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* appldata_get_os_data()
|
||||
*
|
||||
* gather OS data
|
||||
*/
|
||||
static void appldata_get_os_data(void *data)
|
||||
{
|
||||
int i, j, rc;
|
||||
struct appldata_os_data *os_data;
|
||||
unsigned int new_size;
|
||||
|
||||
os_data = data;
|
||||
os_data->sync_count_1++;
|
||||
|
||||
os_data->nr_threads = nr_threads;
|
||||
os_data->nr_running = nr_running();
|
||||
os_data->nr_iowait = nr_iowait();
|
||||
os_data->avenrun[0] = avenrun[0] + (FIXED_1/200);
|
||||
os_data->avenrun[1] = avenrun[1] + (FIXED_1/200);
|
||||
os_data->avenrun[2] = avenrun[2] + (FIXED_1/200);
|
||||
|
||||
j = 0;
|
||||
for_each_online_cpu(i) {
|
||||
os_data->os_cpu[j].per_cpu_user =
|
||||
cputime_to_jiffies(kcpustat_cpu(i).cpustat[CPUTIME_USER]);
|
||||
os_data->os_cpu[j].per_cpu_nice =
|
||||
cputime_to_jiffies(kcpustat_cpu(i).cpustat[CPUTIME_NICE]);
|
||||
os_data->os_cpu[j].per_cpu_system =
|
||||
cputime_to_jiffies(kcpustat_cpu(i).cpustat[CPUTIME_SYSTEM]);
|
||||
os_data->os_cpu[j].per_cpu_idle =
|
||||
cputime_to_jiffies(kcpustat_cpu(i).cpustat[CPUTIME_IDLE]);
|
||||
os_data->os_cpu[j].per_cpu_irq =
|
||||
cputime_to_jiffies(kcpustat_cpu(i).cpustat[CPUTIME_IRQ]);
|
||||
os_data->os_cpu[j].per_cpu_softirq =
|
||||
cputime_to_jiffies(kcpustat_cpu(i).cpustat[CPUTIME_SOFTIRQ]);
|
||||
os_data->os_cpu[j].per_cpu_iowait =
|
||||
cputime_to_jiffies(kcpustat_cpu(i).cpustat[CPUTIME_IOWAIT]);
|
||||
os_data->os_cpu[j].per_cpu_steal =
|
||||
cputime_to_jiffies(kcpustat_cpu(i).cpustat[CPUTIME_STEAL]);
|
||||
os_data->os_cpu[j].cpu_id = i;
|
||||
j++;
|
||||
}
|
||||
|
||||
os_data->nr_cpus = j;
|
||||
|
||||
new_size = sizeof(struct appldata_os_data) +
|
||||
(os_data->nr_cpus * sizeof(struct appldata_os_per_cpu));
|
||||
if (ops.size != new_size) {
|
||||
if (ops.active) {
|
||||
rc = appldata_diag(APPLDATA_RECORD_OS_ID,
|
||||
APPLDATA_START_INTERVAL_REC,
|
||||
(unsigned long) ops.data, new_size,
|
||||
ops.mod_lvl);
|
||||
if (rc != 0)
|
||||
pr_err("Starting a new OS data collection "
|
||||
"failed with rc=%d\n", rc);
|
||||
|
||||
rc = appldata_diag(APPLDATA_RECORD_OS_ID,
|
||||
APPLDATA_STOP_REC,
|
||||
(unsigned long) ops.data, ops.size,
|
||||
ops.mod_lvl);
|
||||
if (rc != 0)
|
||||
pr_err("Stopping a faulty OS data "
|
||||
"collection failed with rc=%d\n", rc);
|
||||
}
|
||||
ops.size = new_size;
|
||||
}
|
||||
os_data->timestamp = get_tod_clock();
|
||||
os_data->sync_count_2++;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* appldata_os_init()
|
||||
*
|
||||
* init data, register ops
|
||||
*/
|
||||
static int __init appldata_os_init(void)
|
||||
{
|
||||
int rc, max_size;
|
||||
|
||||
max_size = sizeof(struct appldata_os_data) +
|
||||
(num_possible_cpus() * sizeof(struct appldata_os_per_cpu));
|
||||
if (max_size > APPLDATA_MAX_REC_SIZE) {
|
||||
pr_err("Maximum OS record size %i exceeds the maximum "
|
||||
"record size %i\n", max_size, APPLDATA_MAX_REC_SIZE);
|
||||
rc = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
appldata_os_data = kzalloc(max_size, GFP_KERNEL | GFP_DMA);
|
||||
if (appldata_os_data == NULL) {
|
||||
rc = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
appldata_os_data->per_cpu_size = sizeof(struct appldata_os_per_cpu);
|
||||
appldata_os_data->cpu_offset = offsetof(struct appldata_os_data,
|
||||
os_cpu);
|
||||
|
||||
ops.data = appldata_os_data;
|
||||
ops.callback = &appldata_get_os_data;
|
||||
rc = appldata_register_ops(&ops);
|
||||
if (rc != 0)
|
||||
kfree(appldata_os_data);
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* appldata_os_exit()
|
||||
*
|
||||
* unregister ops
|
||||
*/
|
||||
static void __exit appldata_os_exit(void)
|
||||
{
|
||||
appldata_unregister_ops(&ops);
|
||||
kfree(appldata_os_data);
|
||||
}
|
||||
|
||||
|
||||
module_init(appldata_os_init);
|
||||
module_exit(appldata_os_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Gerald Schaefer");
|
||||
MODULE_DESCRIPTION("Linux-VM Monitor Stream, OS statistics");
|
||||
26
arch/s390/boot/Makefile
Normal file
26
arch/s390/boot/Makefile
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#
|
||||
# Makefile for the linux s390-specific parts of the memory manager.
|
||||
#
|
||||
|
||||
COMPILE_VERSION := __linux_compile_version_id__`hostname | \
|
||||
tr -c '[0-9A-Za-z]' '_'`__`date | \
|
||||
tr -c '[0-9A-Za-z]' '_'`_t
|
||||
|
||||
ccflags-y := -DCOMPILE_VERSION=$(COMPILE_VERSION) -gstabs -I.
|
||||
|
||||
targets := image
|
||||
targets += bzImage
|
||||
subdir- := compressed
|
||||
|
||||
$(obj)/image: vmlinux FORCE
|
||||
$(call if_changed,objcopy)
|
||||
|
||||
$(obj)/bzImage: $(obj)/compressed/vmlinux FORCE
|
||||
$(call if_changed,objcopy)
|
||||
|
||||
$(obj)/compressed/vmlinux: FORCE
|
||||
$(Q)$(MAKE) $(build)=$(obj)/compressed $@
|
||||
|
||||
install: $(CONFIGURE) $(obj)/bzImage
|
||||
sh -x $(srctree)/$(obj)/install.sh $(KERNELRELEASE) $(obj)/bzImage \
|
||||
System.map "$(INSTALL_PATH)"
|
||||
71
arch/s390/boot/compressed/Makefile
Normal file
71
arch/s390/boot/compressed/Makefile
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
#
|
||||
# linux/arch/s390/boot/compressed/Makefile
|
||||
#
|
||||
# create a compressed vmlinux image from the original vmlinux
|
||||
#
|
||||
|
||||
BITS := $(if $(CONFIG_64BIT),64,31)
|
||||
|
||||
targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2
|
||||
targets += vmlinux.bin.xz vmlinux.bin.lzma vmlinux.bin.lzo vmlinux.bin.lz4
|
||||
targets += misc.o piggy.o sizes.h head$(BITS).o
|
||||
|
||||
KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2
|
||||
KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
|
||||
KBUILD_CFLAGS += $(cflags-y) -fno-delete-null-pointer-checks
|
||||
KBUILD_CFLAGS += $(call cc-option,-mpacked-stack)
|
||||
KBUILD_CFLAGS += $(call cc-option,-ffreestanding)
|
||||
|
||||
GCOV_PROFILE := n
|
||||
|
||||
OBJECTS := $(addprefix $(objtree)/arch/s390/kernel/, head.o sclp.o ebcdic.o)
|
||||
OBJECTS += $(obj)/head$(BITS).o $(obj)/misc.o $(obj)/piggy.o
|
||||
|
||||
LDFLAGS_vmlinux := --oformat $(LD_BFD) -e startup -T
|
||||
$(obj)/vmlinux: $(obj)/vmlinux.lds $(OBJECTS)
|
||||
$(call if_changed,ld)
|
||||
@:
|
||||
|
||||
sed-sizes := -e 's/^\([0-9a-fA-F]*\) . \(__bss_start\|_end\)$$/\#define SZ\2 0x\1/p'
|
||||
|
||||
quiet_cmd_sizes = GEN $@
|
||||
cmd_sizes = $(NM) $< | sed -n $(sed-sizes) > $@
|
||||
|
||||
$(obj)/sizes.h: vmlinux
|
||||
$(call if_changed,sizes)
|
||||
|
||||
AFLAGS_head$(BITS).o += -I$(obj)
|
||||
$(obj)/head$(BITS).o: $(obj)/sizes.h
|
||||
|
||||
CFLAGS_misc.o += -I$(obj)
|
||||
$(obj)/misc.o: $(obj)/sizes.h
|
||||
|
||||
OBJCOPYFLAGS_vmlinux.bin := -R .comment -S
|
||||
$(obj)/vmlinux.bin: vmlinux
|
||||
$(call if_changed,objcopy)
|
||||
|
||||
vmlinux.bin.all-y := $(obj)/vmlinux.bin
|
||||
|
||||
suffix-$(CONFIG_KERNEL_GZIP) := gz
|
||||
suffix-$(CONFIG_KERNEL_BZIP2) := bz2
|
||||
suffix-$(CONFIG_KERNEL_LZ4) := lz4
|
||||
suffix-$(CONFIG_KERNEL_LZMA) := lzma
|
||||
suffix-$(CONFIG_KERNEL_LZO) := lzo
|
||||
suffix-$(CONFIG_KERNEL_XZ) := xz
|
||||
|
||||
$(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y)
|
||||
$(call if_changed,gzip)
|
||||
$(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y)
|
||||
$(call if_changed,bzip2)
|
||||
$(obj)/vmlinux.bin.lz4: $(vmlinux.bin.all-y)
|
||||
$(call if_changed,lz4)
|
||||
$(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y)
|
||||
$(call if_changed,lzma)
|
||||
$(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y)
|
||||
$(call if_changed,lzo)
|
||||
$(obj)/vmlinux.bin.xz: $(vmlinux.bin.all-y)
|
||||
$(call if_changed,xzkern)
|
||||
|
||||
LDFLAGS_piggy.o := -r --format binary --oformat $(LD_BFD) -T
|
||||
$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y)
|
||||
$(call if_changed,ld)
|
||||
51
arch/s390/boot/compressed/head31.S
Normal file
51
arch/s390/boot/compressed/head31.S
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Startup glue code to uncompress the kernel
|
||||
*
|
||||
* Copyright IBM Corp. 2010
|
||||
*
|
||||
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/thread_info.h>
|
||||
#include <asm/page.h>
|
||||
#include "sizes.h"
|
||||
|
||||
__HEAD
|
||||
ENTRY(startup_continue)
|
||||
basr %r13,0 # get base
|
||||
.LPG1:
|
||||
# setup stack
|
||||
l %r15,.Lstack-.LPG1(%r13)
|
||||
ahi %r15,-96
|
||||
l %r1,.Ldecompress-.LPG1(%r13)
|
||||
basr %r14,%r1
|
||||
# setup registers for memory mover & branch to target
|
||||
lr %r4,%r2
|
||||
l %r2,.Loffset-.LPG1(%r13)
|
||||
la %r4,0(%r2,%r4)
|
||||
l %r3,.Lmvsize-.LPG1(%r13)
|
||||
lr %r5,%r3
|
||||
# move the memory mover someplace safe
|
||||
la %r1,0x200
|
||||
mvc 0(mover_end-mover,%r1),mover-.LPG1(%r13)
|
||||
# decompress image is started at 0x11000
|
||||
lr %r6,%r2
|
||||
br %r1
|
||||
mover:
|
||||
mvcle %r2,%r4,0
|
||||
jo mover
|
||||
br %r6
|
||||
mover_end:
|
||||
|
||||
.align 8
|
||||
.Lstack:
|
||||
.long 0x8000 + (1<<(PAGE_SHIFT+THREAD_ORDER))
|
||||
.Ldecompress:
|
||||
.long decompress_kernel
|
||||
.Loffset:
|
||||
.long 0x11000
|
||||
.Lmvsize:
|
||||
.long SZ__bss_start
|
||||
48
arch/s390/boot/compressed/head64.S
Normal file
48
arch/s390/boot/compressed/head64.S
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Startup glue code to uncompress the kernel
|
||||
*
|
||||
* Copyright IBM Corp. 2010
|
||||
*
|
||||
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/thread_info.h>
|
||||
#include <asm/page.h>
|
||||
#include "sizes.h"
|
||||
|
||||
__HEAD
|
||||
ENTRY(startup_continue)
|
||||
basr %r13,0 # get base
|
||||
.LPG1:
|
||||
# setup stack
|
||||
lg %r15,.Lstack-.LPG1(%r13)
|
||||
aghi %r15,-160
|
||||
brasl %r14,decompress_kernel
|
||||
# setup registers for memory mover & branch to target
|
||||
lgr %r4,%r2
|
||||
lg %r2,.Loffset-.LPG1(%r13)
|
||||
la %r4,0(%r2,%r4)
|
||||
lg %r3,.Lmvsize-.LPG1(%r13)
|
||||
lgr %r5,%r3
|
||||
# move the memory mover someplace safe
|
||||
la %r1,0x200
|
||||
mvc 0(mover_end-mover,%r1),mover-.LPG1(%r13)
|
||||
# decompress image is started at 0x11000
|
||||
lgr %r6,%r2
|
||||
br %r1
|
||||
mover:
|
||||
mvcle %r2,%r4,0
|
||||
jo mover
|
||||
br %r6
|
||||
mover_end:
|
||||
|
||||
.align 8
|
||||
.Lstack:
|
||||
.quad 0x8000 + (1<<(PAGE_SHIFT+THREAD_ORDER))
|
||||
.Loffset:
|
||||
.quad 0x11000
|
||||
.Lmvsize:
|
||||
.quad SZ__bss_start
|
||||
175
arch/s390/boot/compressed/misc.c
Normal file
175
arch/s390/boot/compressed/misc.c
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* Definitions and wrapper functions for kernel decompressor
|
||||
*
|
||||
* Copyright IBM Corp. 2010
|
||||
*
|
||||
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
|
||||
*/
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/ipl.h>
|
||||
#include "sizes.h"
|
||||
|
||||
/*
|
||||
* gzip declarations
|
||||
*/
|
||||
#define STATIC static
|
||||
|
||||
#undef memset
|
||||
#undef memcpy
|
||||
#undef memmove
|
||||
#define memmove memmove
|
||||
#define memzero(s, n) memset((s), 0, (n))
|
||||
|
||||
/* Symbols defined by linker scripts */
|
||||
extern char input_data[];
|
||||
extern int input_len;
|
||||
extern char _text, _end;
|
||||
extern char _bss, _ebss;
|
||||
|
||||
static void error(char *m);
|
||||
|
||||
static unsigned long free_mem_ptr;
|
||||
static unsigned long free_mem_end_ptr;
|
||||
|
||||
#ifdef CONFIG_HAVE_KERNEL_BZIP2
|
||||
#define HEAP_SIZE 0x400000
|
||||
#else
|
||||
#define HEAP_SIZE 0x10000
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KERNEL_GZIP
|
||||
#include "../../../../lib/decompress_inflate.c"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KERNEL_BZIP2
|
||||
#include "../../../../lib/decompress_bunzip2.c"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KERNEL_LZ4
|
||||
#include "../../../../lib/decompress_unlz4.c"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KERNEL_LZMA
|
||||
#include "../../../../lib/decompress_unlzma.c"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KERNEL_LZO
|
||||
#include "../../../../lib/decompress_unlzo.c"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KERNEL_XZ
|
||||
#include "../../../../lib/decompress_unxz.c"
|
||||
#endif
|
||||
|
||||
extern _sclp_print_early(const char *);
|
||||
|
||||
static int puts(const char *s)
|
||||
{
|
||||
_sclp_print_early(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *memset(void *s, int c, size_t n)
|
||||
{
|
||||
char *xs;
|
||||
|
||||
xs = s;
|
||||
while (n--)
|
||||
*xs++ = c;
|
||||
return s;
|
||||
}
|
||||
|
||||
void *memcpy(void *dest, const void *src, size_t n)
|
||||
{
|
||||
const char *s = src;
|
||||
char *d = dest;
|
||||
|
||||
while (n--)
|
||||
*d++ = *s++;
|
||||
return dest;
|
||||
}
|
||||
|
||||
void *memmove(void *dest, const void *src, size_t n)
|
||||
{
|
||||
const char *s = src;
|
||||
char *d = dest;
|
||||
|
||||
if (d <= s) {
|
||||
while (n--)
|
||||
*d++ = *s++;
|
||||
} else {
|
||||
d += n;
|
||||
s += n;
|
||||
while (n--)
|
||||
*--d = *--s;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
static void error(char *x)
|
||||
{
|
||||
unsigned long long psw = 0x000a0000deadbeefULL;
|
||||
|
||||
puts("\n\n");
|
||||
puts(x);
|
||||
puts("\n\n -- System halted");
|
||||
|
||||
asm volatile("lpsw %0" : : "Q" (psw));
|
||||
}
|
||||
|
||||
/*
|
||||
* Safe guard the ipl parameter block against a memory area that will be
|
||||
* overwritten. The validity check for the ipl parameter block is complex
|
||||
* (see cio_get_iplinfo and ipl_save_parameters) but if the pointer to
|
||||
* the ipl parameter block intersects with the passed memory area we can
|
||||
* safely assume that we can read from that memory. In that case just copy
|
||||
* the memory to IPL_PARMBLOCK_ORIGIN even if there is no ipl parameter
|
||||
* block.
|
||||
*/
|
||||
static void check_ipl_parmblock(void *start, unsigned long size)
|
||||
{
|
||||
void *src, *dst;
|
||||
|
||||
src = (void *)(unsigned long) S390_lowcore.ipl_parmblock_ptr;
|
||||
if (src + PAGE_SIZE <= start || src >= start + size)
|
||||
return;
|
||||
dst = (void *) IPL_PARMBLOCK_ORIGIN;
|
||||
memmove(dst, src, PAGE_SIZE);
|
||||
S390_lowcore.ipl_parmblock_ptr = IPL_PARMBLOCK_ORIGIN;
|
||||
}
|
||||
|
||||
unsigned long decompress_kernel(void)
|
||||
{
|
||||
unsigned long output_addr;
|
||||
unsigned char *output;
|
||||
|
||||
output_addr = ((unsigned long) &_end + HEAP_SIZE + 4095UL) & -4096UL;
|
||||
check_ipl_parmblock((void *) 0, output_addr + SZ__bss_start);
|
||||
memset(&_bss, 0, &_ebss - &_bss);
|
||||
free_mem_ptr = (unsigned long)&_end;
|
||||
free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
|
||||
output = (unsigned char *) output_addr;
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
/*
|
||||
* Move the initrd right behind the end of the decompressed
|
||||
* kernel image.
|
||||
*/
|
||||
if (INITRD_START && INITRD_SIZE &&
|
||||
INITRD_START < (unsigned long) output + SZ__bss_start) {
|
||||
check_ipl_parmblock(output + SZ__bss_start,
|
||||
INITRD_START + INITRD_SIZE);
|
||||
memmove(output + SZ__bss_start,
|
||||
(void *) INITRD_START, INITRD_SIZE);
|
||||
INITRD_START = (unsigned long) output + SZ__bss_start;
|
||||
}
|
||||
#endif
|
||||
|
||||
puts("Uncompressing Linux... ");
|
||||
decompress(input_data, input_len, NULL, NULL, output, NULL, error);
|
||||
puts("Ok, booting the kernel.\n");
|
||||
return (unsigned long) output;
|
||||
}
|
||||
|
||||
55
arch/s390/boot/compressed/vmlinux.lds.S
Normal file
55
arch/s390/boot/compressed/vmlinux.lds.S
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
#include <asm-generic/vmlinux.lds.h>
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390")
|
||||
OUTPUT_ARCH(s390:64-bit)
|
||||
#else
|
||||
OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390")
|
||||
OUTPUT_ARCH(s390:31-bit)
|
||||
#endif
|
||||
|
||||
ENTRY(startup)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* Be careful parts of head_64.S assume startup_32 is at
|
||||
* address 0.
|
||||
*/
|
||||
. = 0;
|
||||
.head.text : {
|
||||
_head = . ;
|
||||
HEAD_TEXT
|
||||
_ehead = . ;
|
||||
}
|
||||
.rodata.compressed : {
|
||||
*(.rodata.compressed)
|
||||
}
|
||||
.text : {
|
||||
_text = .; /* Text */
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
_etext = . ;
|
||||
}
|
||||
.rodata : {
|
||||
_rodata = . ;
|
||||
*(.rodata) /* read-only data */
|
||||
*(.rodata.*)
|
||||
_erodata = . ;
|
||||
}
|
||||
.data : {
|
||||
_data = . ;
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
_edata = . ;
|
||||
}
|
||||
. = ALIGN(256);
|
||||
.bss : {
|
||||
_bss = . ;
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(COMMON)
|
||||
. = ALIGN(8); /* For convenience during zeroing */
|
||||
_ebss = .;
|
||||
}
|
||||
_end = .;
|
||||
}
|
||||
10
arch/s390/boot/compressed/vmlinux.scr
Normal file
10
arch/s390/boot/compressed/vmlinux.scr
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
SECTIONS
|
||||
{
|
||||
.rodata.compressed : {
|
||||
input_len = .;
|
||||
LONG(input_data_end - input_data) input_data = .;
|
||||
*(.data)
|
||||
output_len = . - 4;
|
||||
input_data_end = .;
|
||||
}
|
||||
}
|
||||
38
arch/s390/boot/install.sh
Normal file
38
arch/s390/boot/install.sh
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# arch/s390x/boot/install.sh
|
||||
#
|
||||
# This file is subject to the terms and conditions of the GNU General Public
|
||||
# License. See the file "COPYING" in the main directory of this archive
|
||||
# for more details.
|
||||
#
|
||||
# Copyright (C) 1995 by Linus Torvalds
|
||||
#
|
||||
# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
|
||||
#
|
||||
# "make install" script for s390 architecture
|
||||
#
|
||||
# Arguments:
|
||||
# $1 - kernel version
|
||||
# $2 - kernel image file
|
||||
# $3 - kernel map file
|
||||
# $4 - default install path (blank if root directory)
|
||||
#
|
||||
|
||||
# User may have a custom install script
|
||||
|
||||
if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi
|
||||
if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi
|
||||
|
||||
# Default install - same as make zlilo
|
||||
|
||||
if [ -f $4/vmlinuz ]; then
|
||||
mv $4/vmlinuz $4/vmlinuz.old
|
||||
fi
|
||||
|
||||
if [ -f $4/System.map ]; then
|
||||
mv $4/System.map $4/System.old
|
||||
fi
|
||||
|
||||
cat $2 > $4/vmlinuz
|
||||
cp $3 $4/System.map
|
||||
678
arch/s390/configs/default_defconfig
Normal file
678
arch/s390/configs/default_defconfig
Normal file
|
|
@ -0,0 +1,678 @@
|
|||
CONFIG_SYSVIPC=y
|
||||
CONFIG_POSIX_MQUEUE=y
|
||||
CONFIG_FHANDLE=y
|
||||
CONFIG_AUDIT=y
|
||||
CONFIG_NO_HZ=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_BSD_PROCESS_ACCT=y
|
||||
CONFIG_BSD_PROCESS_ACCT_V3=y
|
||||
CONFIG_TASKSTATS=y
|
||||
CONFIG_TASK_DELAY_ACCT=y
|
||||
CONFIG_TASK_XACCT=y
|
||||
CONFIG_TASK_IO_ACCOUNTING=y
|
||||
CONFIG_RCU_FAST_NO_HZ=y
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_CGROUP_FREEZER=y
|
||||
CONFIG_CGROUP_DEVICE=y
|
||||
CONFIG_CPUSETS=y
|
||||
CONFIG_CGROUP_CPUACCT=y
|
||||
CONFIG_RESOURCE_COUNTERS=y
|
||||
CONFIG_CGROUP_PERF=y
|
||||
CONFIG_CFS_BANDWIDTH=y
|
||||
CONFIG_RT_GROUP_SCHED=y
|
||||
CONFIG_BLK_CGROUP=y
|
||||
CONFIG_SCHED_AUTOGROUP=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
CONFIG_PROFILING=y
|
||||
CONFIG_OPROFILE=m
|
||||
CONFIG_KPROBES=y
|
||||
CONFIG_JUMP_LABEL=y
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_FORCE_LOAD=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
CONFIG_MODULE_FORCE_UNLOAD=y
|
||||
CONFIG_MODVERSIONS=y
|
||||
CONFIG_MODULE_SRCVERSION_ALL=y
|
||||
CONFIG_BLK_DEV_THROTTLING=y
|
||||
CONFIG_PARTITION_ADVANCED=y
|
||||
CONFIG_IBM_PARTITION=y
|
||||
CONFIG_BSD_DISKLABEL=y
|
||||
CONFIG_MINIX_SUBPARTITION=y
|
||||
CONFIG_SOLARIS_X86_PARTITION=y
|
||||
CONFIG_UNIXWARE_DISKLABEL=y
|
||||
CONFIG_CFQ_GROUP_IOSCHED=y
|
||||
CONFIG_DEFAULT_DEADLINE=y
|
||||
CONFIG_MARCH_Z196=y
|
||||
CONFIG_TUNE_ZEC12=y
|
||||
CONFIG_NR_CPUS=256
|
||||
CONFIG_PREEMPT=y
|
||||
CONFIG_HZ_100=y
|
||||
CONFIG_MEMORY_HOTPLUG=y
|
||||
CONFIG_MEMORY_HOTREMOVE=y
|
||||
CONFIG_KSM=y
|
||||
CONFIG_TRANSPARENT_HUGEPAGE=y
|
||||
CONFIG_PCI=y
|
||||
CONFIG_PCI_DEBUG=y
|
||||
CONFIG_HOTPLUG_PCI=y
|
||||
CONFIG_HOTPLUG_PCI_S390=y
|
||||
CONFIG_CHSC_SCH=y
|
||||
CONFIG_CRASH_DUMP=y
|
||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
|
||||
CONFIG_BINFMT_MISC=m
|
||||
CONFIG_HIBERNATION=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_PACKET_DIAG=m
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_UNIX_DIAG=m
|
||||
CONFIG_XFRM_USER=m
|
||||
CONFIG_NET_KEY=m
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
CONFIG_IP_ADVANCED_ROUTER=y
|
||||
CONFIG_IP_MULTIPLE_TABLES=y
|
||||
CONFIG_IP_ROUTE_MULTIPATH=y
|
||||
CONFIG_IP_ROUTE_VERBOSE=y
|
||||
CONFIG_NET_IPIP=m
|
||||
CONFIG_NET_IPGRE_DEMUX=m
|
||||
CONFIG_NET_IPGRE=m
|
||||
CONFIG_NET_IPGRE_BROADCAST=y
|
||||
CONFIG_IP_MROUTE=y
|
||||
CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
|
||||
CONFIG_IP_PIMSM_V1=y
|
||||
CONFIG_IP_PIMSM_V2=y
|
||||
CONFIG_SYN_COOKIES=y
|
||||
CONFIG_NET_IPVTI=m
|
||||
CONFIG_INET_AH=m
|
||||
CONFIG_INET_ESP=m
|
||||
CONFIG_INET_IPCOMP=m
|
||||
CONFIG_INET_XFRM_MODE_TRANSPORT=m
|
||||
CONFIG_INET_XFRM_MODE_TUNNEL=m
|
||||
CONFIG_INET_XFRM_MODE_BEET=m
|
||||
CONFIG_INET_DIAG=m
|
||||
CONFIG_INET_UDP_DIAG=m
|
||||
CONFIG_TCP_CONG_ADVANCED=y
|
||||
CONFIG_TCP_CONG_HSTCP=m
|
||||
CONFIG_TCP_CONG_HYBLA=m
|
||||
CONFIG_TCP_CONG_SCALABLE=m
|
||||
CONFIG_TCP_CONG_LP=m
|
||||
CONFIG_TCP_CONG_VENO=m
|
||||
CONFIG_TCP_CONG_YEAH=m
|
||||
CONFIG_TCP_CONG_ILLINOIS=m
|
||||
CONFIG_IPV6=y
|
||||
CONFIG_IPV6_ROUTER_PREF=y
|
||||
CONFIG_INET6_AH=m
|
||||
CONFIG_INET6_ESP=m
|
||||
CONFIG_INET6_IPCOMP=m
|
||||
CONFIG_IPV6_MIP6=m
|
||||
CONFIG_INET6_XFRM_MODE_TRANSPORT=m
|
||||
CONFIG_INET6_XFRM_MODE_TUNNEL=m
|
||||
CONFIG_INET6_XFRM_MODE_BEET=m
|
||||
CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
|
||||
CONFIG_IPV6_VTI=m
|
||||
CONFIG_IPV6_SIT=m
|
||||
CONFIG_IPV6_GRE=m
|
||||
CONFIG_IPV6_MULTIPLE_TABLES=y
|
||||
CONFIG_IPV6_SUBTREES=y
|
||||
CONFIG_NETFILTER=y
|
||||
CONFIG_NF_CONNTRACK=m
|
||||
CONFIG_NF_CONNTRACK_SECMARK=y
|
||||
CONFIG_NF_CONNTRACK_EVENTS=y
|
||||
CONFIG_NF_CONNTRACK_TIMEOUT=y
|
||||
CONFIG_NF_CONNTRACK_TIMESTAMP=y
|
||||
CONFIG_NF_CT_PROTO_DCCP=m
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=m
|
||||
CONFIG_NF_CONNTRACK_AMANDA=m
|
||||
CONFIG_NF_CONNTRACK_FTP=m
|
||||
CONFIG_NF_CONNTRACK_H323=m
|
||||
CONFIG_NF_CONNTRACK_IRC=m
|
||||
CONFIG_NF_CONNTRACK_NETBIOS_NS=m
|
||||
CONFIG_NF_CONNTRACK_SNMP=m
|
||||
CONFIG_NF_CONNTRACK_PPTP=m
|
||||
CONFIG_NF_CONNTRACK_SANE=m
|
||||
CONFIG_NF_CONNTRACK_SIP=m
|
||||
CONFIG_NF_CONNTRACK_TFTP=m
|
||||
CONFIG_NF_CT_NETLINK=m
|
||||
CONFIG_NF_CT_NETLINK_TIMEOUT=m
|
||||
CONFIG_NF_TABLES=m
|
||||
CONFIG_NFT_EXTHDR=m
|
||||
CONFIG_NFT_META=m
|
||||
CONFIG_NFT_CT=m
|
||||
CONFIG_NFT_RBTREE=m
|
||||
CONFIG_NFT_HASH=m
|
||||
CONFIG_NFT_COUNTER=m
|
||||
CONFIG_NFT_LOG=m
|
||||
CONFIG_NFT_LIMIT=m
|
||||
CONFIG_NFT_NAT=m
|
||||
CONFIG_NFT_COMPAT=m
|
||||
CONFIG_NETFILTER_XT_SET=m
|
||||
CONFIG_NETFILTER_XT_TARGET_AUDIT=m
|
||||
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
|
||||
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
|
||||
CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_CT=m
|
||||
CONFIG_NETFILTER_XT_TARGET_DSCP=m
|
||||
CONFIG_NETFILTER_XT_TARGET_HMARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
|
||||
CONFIG_NETFILTER_XT_TARGET_LOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TEE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TPROXY=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_SECMARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
|
||||
CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
|
||||
CONFIG_NETFILTER_XT_MATCH_BPF=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
|
||||
CONFIG_NETFILTER_XT_MATCH_COMMENT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CPU=m
|
||||
CONFIG_NETFILTER_XT_MATCH_DCCP=m
|
||||
CONFIG_NETFILTER_XT_MATCH_DEVGROUP=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_IPVS=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_NFACCT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_OSF=m
|
||||
CONFIG_NETFILTER_XT_MATCH_OWNER=m
|
||||
CONFIG_NETFILTER_XT_MATCH_POLICY=m
|
||||
CONFIG_NETFILTER_XT_MATCH_PHYSDEV=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_SOCKET=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_IP_SET=m
|
||||
CONFIG_IP_SET_BITMAP_IP=m
|
||||
CONFIG_IP_SET_BITMAP_IPMAC=m
|
||||
CONFIG_IP_SET_BITMAP_PORT=m
|
||||
CONFIG_IP_SET_HASH_IP=m
|
||||
CONFIG_IP_SET_HASH_IPPORT=m
|
||||
CONFIG_IP_SET_HASH_IPPORTIP=m
|
||||
CONFIG_IP_SET_HASH_IPPORTNET=m
|
||||
CONFIG_IP_SET_HASH_NETPORTNET=m
|
||||
CONFIG_IP_SET_HASH_NET=m
|
||||
CONFIG_IP_SET_HASH_NETNET=m
|
||||
CONFIG_IP_SET_HASH_NETPORT=m
|
||||
CONFIG_IP_SET_HASH_NETIFACE=m
|
||||
CONFIG_IP_SET_LIST_SET=m
|
||||
CONFIG_IP_VS=m
|
||||
CONFIG_IP_VS_PROTO_TCP=y
|
||||
CONFIG_IP_VS_PROTO_UDP=y
|
||||
CONFIG_IP_VS_PROTO_ESP=y
|
||||
CONFIG_IP_VS_PROTO_AH=y
|
||||
CONFIG_IP_VS_RR=m
|
||||
CONFIG_IP_VS_WRR=m
|
||||
CONFIG_IP_VS_LC=m
|
||||
CONFIG_IP_VS_WLC=m
|
||||
CONFIG_IP_VS_LBLC=m
|
||||
CONFIG_IP_VS_LBLCR=m
|
||||
CONFIG_IP_VS_DH=m
|
||||
CONFIG_IP_VS_SH=m
|
||||
CONFIG_IP_VS_SED=m
|
||||
CONFIG_IP_VS_NQ=m
|
||||
CONFIG_IP_VS_FTP=m
|
||||
CONFIG_IP_VS_PE_SIP=m
|
||||
CONFIG_NF_CONNTRACK_IPV4=m
|
||||
# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
|
||||
CONFIG_NF_TABLES_IPV4=m
|
||||
CONFIG_NFT_CHAIN_ROUTE_IPV4=m
|
||||
CONFIG_NFT_CHAIN_NAT_IPV4=m
|
||||
CONFIG_NF_TABLES_ARP=m
|
||||
CONFIG_NF_NAT_IPV4=m
|
||||
CONFIG_IP_NF_IPTABLES=m
|
||||
CONFIG_IP_NF_MATCH_AH=m
|
||||
CONFIG_IP_NF_MATCH_ECN=m
|
||||
CONFIG_IP_NF_MATCH_RPFILTER=m
|
||||
CONFIG_IP_NF_MATCH_TTL=m
|
||||
CONFIG_IP_NF_FILTER=m
|
||||
CONFIG_IP_NF_TARGET_REJECT=m
|
||||
CONFIG_IP_NF_MANGLE=m
|
||||
CONFIG_IP_NF_TARGET_CLUSTERIP=m
|
||||
CONFIG_IP_NF_TARGET_ECN=m
|
||||
CONFIG_IP_NF_TARGET_TTL=m
|
||||
CONFIG_IP_NF_RAW=m
|
||||
CONFIG_IP_NF_SECURITY=m
|
||||
CONFIG_IP_NF_ARPTABLES=m
|
||||
CONFIG_IP_NF_ARPFILTER=m
|
||||
CONFIG_IP_NF_ARP_MANGLE=m
|
||||
CONFIG_NF_CONNTRACK_IPV6=m
|
||||
CONFIG_NF_TABLES_IPV6=m
|
||||
CONFIG_NFT_CHAIN_ROUTE_IPV6=m
|
||||
CONFIG_NFT_CHAIN_NAT_IPV6=m
|
||||
CONFIG_NF_NAT_IPV6=m
|
||||
CONFIG_IP6_NF_IPTABLES=m
|
||||
CONFIG_IP6_NF_MATCH_AH=m
|
||||
CONFIG_IP6_NF_MATCH_EUI64=m
|
||||
CONFIG_IP6_NF_MATCH_FRAG=m
|
||||
CONFIG_IP6_NF_MATCH_OPTS=m
|
||||
CONFIG_IP6_NF_MATCH_HL=m
|
||||
CONFIG_IP6_NF_MATCH_IPV6HEADER=m
|
||||
CONFIG_IP6_NF_MATCH_MH=m
|
||||
CONFIG_IP6_NF_MATCH_RPFILTER=m
|
||||
CONFIG_IP6_NF_MATCH_RT=m
|
||||
CONFIG_IP6_NF_TARGET_HL=m
|
||||
CONFIG_IP6_NF_FILTER=m
|
||||
CONFIG_IP6_NF_TARGET_REJECT=m
|
||||
CONFIG_IP6_NF_MANGLE=m
|
||||
CONFIG_IP6_NF_RAW=m
|
||||
CONFIG_IP6_NF_SECURITY=m
|
||||
CONFIG_NF_TABLES_BRIDGE=m
|
||||
CONFIG_NET_SCTPPROBE=m
|
||||
CONFIG_RDS=m
|
||||
CONFIG_RDS_RDMA=m
|
||||
CONFIG_RDS_TCP=m
|
||||
CONFIG_RDS_DEBUG=y
|
||||
CONFIG_L2TP=m
|
||||
CONFIG_L2TP_DEBUGFS=m
|
||||
CONFIG_L2TP_V3=y
|
||||
CONFIG_L2TP_IP=m
|
||||
CONFIG_L2TP_ETH=m
|
||||
CONFIG_BRIDGE=m
|
||||
CONFIG_VLAN_8021Q=m
|
||||
CONFIG_VLAN_8021Q_GVRP=y
|
||||
CONFIG_NET_SCHED=y
|
||||
CONFIG_NET_SCH_CBQ=m
|
||||
CONFIG_NET_SCH_HTB=m
|
||||
CONFIG_NET_SCH_HFSC=m
|
||||
CONFIG_NET_SCH_PRIO=m
|
||||
CONFIG_NET_SCH_MULTIQ=m
|
||||
CONFIG_NET_SCH_RED=m
|
||||
CONFIG_NET_SCH_SFB=m
|
||||
CONFIG_NET_SCH_SFQ=m
|
||||
CONFIG_NET_SCH_TEQL=m
|
||||
CONFIG_NET_SCH_TBF=m
|
||||
CONFIG_NET_SCH_GRED=m
|
||||
CONFIG_NET_SCH_DSMARK=m
|
||||
CONFIG_NET_SCH_NETEM=m
|
||||
CONFIG_NET_SCH_DRR=m
|
||||
CONFIG_NET_SCH_MQPRIO=m
|
||||
CONFIG_NET_SCH_CHOKE=m
|
||||
CONFIG_NET_SCH_QFQ=m
|
||||
CONFIG_NET_SCH_CODEL=m
|
||||
CONFIG_NET_SCH_FQ_CODEL=m
|
||||
CONFIG_NET_SCH_INGRESS=m
|
||||
CONFIG_NET_SCH_PLUG=m
|
||||
CONFIG_NET_CLS_BASIC=m
|
||||
CONFIG_NET_CLS_TCINDEX=m
|
||||
CONFIG_NET_CLS_ROUTE4=m
|
||||
CONFIG_NET_CLS_FW=m
|
||||
CONFIG_NET_CLS_U32=m
|
||||
CONFIG_CLS_U32_PERF=y
|
||||
CONFIG_CLS_U32_MARK=y
|
||||
CONFIG_NET_CLS_RSVP=m
|
||||
CONFIG_NET_CLS_RSVP6=m
|
||||
CONFIG_NET_CLS_FLOW=m
|
||||
CONFIG_NET_CLS_CGROUP=y
|
||||
CONFIG_NET_CLS_BPF=m
|
||||
CONFIG_NET_CLS_ACT=y
|
||||
CONFIG_NET_ACT_POLICE=m
|
||||
CONFIG_NET_ACT_GACT=m
|
||||
CONFIG_GACT_PROB=y
|
||||
CONFIG_NET_ACT_MIRRED=m
|
||||
CONFIG_NET_ACT_IPT=m
|
||||
CONFIG_NET_ACT_NAT=m
|
||||
CONFIG_NET_ACT_PEDIT=m
|
||||
CONFIG_NET_ACT_SIMP=m
|
||||
CONFIG_NET_ACT_SKBEDIT=m
|
||||
CONFIG_NET_ACT_CSUM=m
|
||||
CONFIG_DNS_RESOLVER=y
|
||||
CONFIG_BPF_JIT=y
|
||||
CONFIG_NET_PKTGEN=m
|
||||
CONFIG_NET_TCPPROBE=m
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_CONNECTOR=y
|
||||
CONFIG_BLK_DEV_LOOP=m
|
||||
CONFIG_BLK_DEV_CRYPTOLOOP=m
|
||||
CONFIG_BLK_DEV_NBD=m
|
||||
CONFIG_BLK_DEV_OSD=m
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_BLK_DEV_RAM_SIZE=32768
|
||||
CONFIG_BLK_DEV_XIP=y
|
||||
CONFIG_CDROM_PKTCDVD=m
|
||||
CONFIG_ATA_OVER_ETH=m
|
||||
CONFIG_VIRTIO_BLK=y
|
||||
CONFIG_ENCLOSURE_SERVICES=m
|
||||
CONFIG_RAID_ATTRS=m
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_CHR_DEV_ST=m
|
||||
CONFIG_CHR_DEV_OSST=m
|
||||
CONFIG_BLK_DEV_SR=m
|
||||
CONFIG_CHR_DEV_SG=y
|
||||
CONFIG_CHR_DEV_SCH=m
|
||||
CONFIG_SCSI_ENCLOSURE=m
|
||||
CONFIG_SCSI_CONSTANTS=y
|
||||
CONFIG_SCSI_LOGGING=y
|
||||
CONFIG_SCSI_SPI_ATTRS=m
|
||||
CONFIG_SCSI_FC_ATTRS=y
|
||||
CONFIG_SCSI_SAS_LIBSAS=m
|
||||
CONFIG_SCSI_SRP_ATTRS=m
|
||||
CONFIG_ISCSI_TCP=m
|
||||
CONFIG_SCSI_DEBUG=m
|
||||
CONFIG_ZFCP=y
|
||||
CONFIG_SCSI_VIRTIO=m
|
||||
CONFIG_SCSI_DH=m
|
||||
CONFIG_SCSI_DH_RDAC=m
|
||||
CONFIG_SCSI_DH_HP_SW=m
|
||||
CONFIG_SCSI_DH_EMC=m
|
||||
CONFIG_SCSI_DH_ALUA=m
|
||||
CONFIG_SCSI_OSD_INITIATOR=m
|
||||
CONFIG_SCSI_OSD_ULD=m
|
||||
CONFIG_MD=y
|
||||
CONFIG_BLK_DEV_MD=y
|
||||
CONFIG_MD_LINEAR=m
|
||||
CONFIG_MD_RAID0=m
|
||||
CONFIG_MD_MULTIPATH=m
|
||||
CONFIG_MD_FAULTY=m
|
||||
CONFIG_BLK_DEV_DM=m
|
||||
CONFIG_DM_CRYPT=m
|
||||
CONFIG_DM_SNAPSHOT=m
|
||||
CONFIG_DM_MIRROR=m
|
||||
CONFIG_DM_LOG_USERSPACE=m
|
||||
CONFIG_DM_RAID=m
|
||||
CONFIG_DM_ZERO=m
|
||||
CONFIG_DM_MULTIPATH=m
|
||||
CONFIG_DM_MULTIPATH_QL=m
|
||||
CONFIG_DM_MULTIPATH_ST=m
|
||||
CONFIG_DM_DELAY=m
|
||||
CONFIG_DM_UEVENT=y
|
||||
CONFIG_DM_FLAKEY=m
|
||||
CONFIG_DM_VERITY=m
|
||||
CONFIG_DM_SWITCH=m
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_BONDING=m
|
||||
CONFIG_DUMMY=m
|
||||
CONFIG_EQUALIZER=m
|
||||
CONFIG_IFB=m
|
||||
CONFIG_MACVLAN=m
|
||||
CONFIG_MACVTAP=m
|
||||
CONFIG_VXLAN=m
|
||||
CONFIG_TUN=m
|
||||
CONFIG_VETH=m
|
||||
CONFIG_VIRTIO_NET=m
|
||||
CONFIG_NLMON=m
|
||||
CONFIG_VHOST_NET=m
|
||||
# CONFIG_NET_VENDOR_ARC is not set
|
||||
# CONFIG_NET_VENDOR_CHELSIO is not set
|
||||
# CONFIG_NET_VENDOR_INTEL is not set
|
||||
# CONFIG_NET_VENDOR_MARVELL is not set
|
||||
CONFIG_MLX4_EN=m
|
||||
# CONFIG_NET_VENDOR_NATSEMI is not set
|
||||
CONFIG_PPP=m
|
||||
CONFIG_PPP_BSDCOMP=m
|
||||
CONFIG_PPP_DEFLATE=m
|
||||
CONFIG_PPP_MPPE=m
|
||||
CONFIG_PPPOE=m
|
||||
CONFIG_PPTP=m
|
||||
CONFIG_PPPOL2TP=m
|
||||
CONFIG_PPP_ASYNC=m
|
||||
CONFIG_PPP_SYNC_TTY=m
|
||||
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
|
||||
# CONFIG_INPUT_KEYBOARD is not set
|
||||
# CONFIG_INPUT_MOUSE is not set
|
||||
# CONFIG_SERIO is not set
|
||||
CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
|
||||
CONFIG_LEGACY_PTY_COUNT=0
|
||||
CONFIG_HW_RANDOM_VIRTIO=m
|
||||
CONFIG_RAW_DRIVER=m
|
||||
CONFIG_HANGCHECK_TIMER=m
|
||||
CONFIG_TN3270_FS=y
|
||||
CONFIG_WATCHDOG=y
|
||||
CONFIG_WATCHDOG_NOWAYOUT=y
|
||||
CONFIG_SOFT_WATCHDOG=m
|
||||
CONFIG_DIAG288_WATCHDOG=m
|
||||
# CONFIG_HID is not set
|
||||
# CONFIG_USB_SUPPORT is not set
|
||||
CONFIG_INFINIBAND=m
|
||||
CONFIG_INFINIBAND_USER_ACCESS=m
|
||||
CONFIG_MLX4_INFINIBAND=m
|
||||
CONFIG_VIRTIO_BALLOON=m
|
||||
# CONFIG_IOMMU_SUPPORT is not set
|
||||
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_DEFAULTS_TO_ORDERED is not set
|
||||
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_JBD_DEBUG=y
|
||||
CONFIG_JBD2_DEBUG=y
|
||||
CONFIG_JFS_FS=m
|
||||
CONFIG_JFS_POSIX_ACL=y
|
||||
CONFIG_JFS_SECURITY=y
|
||||
CONFIG_JFS_STATISTICS=y
|
||||
CONFIG_XFS_FS=y
|
||||
CONFIG_XFS_QUOTA=y
|
||||
CONFIG_XFS_POSIX_ACL=y
|
||||
CONFIG_XFS_RT=y
|
||||
CONFIG_XFS_DEBUG=y
|
||||
CONFIG_GFS2_FS=m
|
||||
CONFIG_OCFS2_FS=m
|
||||
CONFIG_BTRFS_FS=y
|
||||
CONFIG_BTRFS_FS_POSIX_ACL=y
|
||||
CONFIG_NILFS2_FS=m
|
||||
CONFIG_FANOTIFY=y
|
||||
CONFIG_QUOTA_NETLINK_INTERFACE=y
|
||||
CONFIG_QFMT_V1=m
|
||||
CONFIG_QFMT_V2=m
|
||||
CONFIG_AUTOFS4_FS=m
|
||||
CONFIG_FUSE_FS=m
|
||||
CONFIG_CUSE=m
|
||||
CONFIG_FSCACHE=m
|
||||
CONFIG_CACHEFILES=m
|
||||
CONFIG_ISO9660_FS=y
|
||||
CONFIG_JOLIET=y
|
||||
CONFIG_ZISOFS=y
|
||||
CONFIG_UDF_FS=m
|
||||
CONFIG_MSDOS_FS=m
|
||||
CONFIG_VFAT_FS=m
|
||||
CONFIG_NTFS_FS=m
|
||||
CONFIG_NTFS_RW=y
|
||||
CONFIG_PROC_KCORE=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
CONFIG_HUGETLBFS=y
|
||||
CONFIG_CONFIGFS_FS=m
|
||||
CONFIG_ECRYPT_FS=m
|
||||
CONFIG_CRAMFS=m
|
||||
CONFIG_SQUASHFS=m
|
||||
CONFIG_SQUASHFS_XATTR=y
|
||||
CONFIG_SQUASHFS_LZO=y
|
||||
CONFIG_SQUASHFS_XZ=y
|
||||
CONFIG_ROMFS_FS=m
|
||||
CONFIG_NFS_FS=m
|
||||
CONFIG_NFS_V3_ACL=y
|
||||
CONFIG_NFS_V4=m
|
||||
CONFIG_NFS_SWAP=y
|
||||
CONFIG_NFSD=m
|
||||
CONFIG_NFSD_V3_ACL=y
|
||||
CONFIG_NFSD_V4=y
|
||||
CONFIG_NFSD_V4_SECURITY_LABEL=y
|
||||
CONFIG_CIFS=m
|
||||
CONFIG_CIFS_STATS=y
|
||||
CONFIG_CIFS_STATS2=y
|
||||
CONFIG_CIFS_WEAK_PW_HASH=y
|
||||
CONFIG_CIFS_UPCALL=y
|
||||
CONFIG_CIFS_XATTR=y
|
||||
CONFIG_CIFS_POSIX=y
|
||||
# CONFIG_CIFS_DEBUG is not set
|
||||
CONFIG_CIFS_DFS_UPCALL=y
|
||||
CONFIG_NLS_DEFAULT="utf8"
|
||||
CONFIG_NLS_CODEPAGE_437=m
|
||||
CONFIG_NLS_CODEPAGE_850=m
|
||||
CONFIG_NLS_ASCII=m
|
||||
CONFIG_NLS_ISO8859_1=m
|
||||
CONFIG_NLS_ISO8859_15=m
|
||||
CONFIG_NLS_UTF8=m
|
||||
CONFIG_DLM=m
|
||||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_DYNAMIC_DEBUG=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
# CONFIG_ENABLE_MUST_CHECK is not set
|
||||
CONFIG_FRAME_WARN=1024
|
||||
CONFIG_READABLE_ASM=y
|
||||
CONFIG_UNUSED_SYMBOLS=y
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_DEBUG_KERNEL=y
|
||||
CONFIG_DEBUG_PAGEALLOC=y
|
||||
CONFIG_DEBUG_OBJECTS=y
|
||||
CONFIG_DEBUG_OBJECTS_SELFTEST=y
|
||||
CONFIG_DEBUG_OBJECTS_FREE=y
|
||||
CONFIG_DEBUG_OBJECTS_TIMERS=y
|
||||
CONFIG_DEBUG_OBJECTS_WORK=y
|
||||
CONFIG_DEBUG_OBJECTS_RCU_HEAD=y
|
||||
CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y
|
||||
CONFIG_SLUB_DEBUG_ON=y
|
||||
CONFIG_SLUB_STATS=y
|
||||
CONFIG_DEBUG_KMEMLEAK=y
|
||||
CONFIG_DEBUG_STACK_USAGE=y
|
||||
CONFIG_DEBUG_VM=y
|
||||
CONFIG_DEBUG_VM_RB=y
|
||||
CONFIG_MEMORY_NOTIFIER_ERROR_INJECT=m
|
||||
CONFIG_DEBUG_PER_CPU_MAPS=y
|
||||
CONFIG_DEBUG_SHIRQ=y
|
||||
CONFIG_DETECT_HUNG_TASK=y
|
||||
CONFIG_TIMER_STATS=y
|
||||
CONFIG_DEBUG_RT_MUTEXES=y
|
||||
CONFIG_DEBUG_WW_MUTEX_SLOWPATH=y
|
||||
CONFIG_PROVE_LOCKING=y
|
||||
CONFIG_LOCK_STAT=y
|
||||
CONFIG_DEBUG_LOCKDEP=y
|
||||
CONFIG_DEBUG_ATOMIC_SLEEP=y
|
||||
CONFIG_DEBUG_LOCKING_API_SELFTESTS=y
|
||||
CONFIG_DEBUG_LIST=y
|
||||
CONFIG_DEBUG_SG=y
|
||||
CONFIG_DEBUG_NOTIFIERS=y
|
||||
CONFIG_DEBUG_CREDENTIALS=y
|
||||
CONFIG_PROVE_RCU=y
|
||||
CONFIG_RCU_TORTURE_TEST=m
|
||||
CONFIG_RCU_CPU_STALL_TIMEOUT=300
|
||||
CONFIG_NOTIFIER_ERROR_INJECTION=m
|
||||
CONFIG_CPU_NOTIFIER_ERROR_INJECT=m
|
||||
CONFIG_PM_NOTIFIER_ERROR_INJECT=m
|
||||
CONFIG_FAULT_INJECTION=y
|
||||
CONFIG_FAILSLAB=y
|
||||
CONFIG_FAIL_PAGE_ALLOC=y
|
||||
CONFIG_FAIL_MAKE_REQUEST=y
|
||||
CONFIG_FAIL_IO_TIMEOUT=y
|
||||
CONFIG_FAULT_INJECTION_DEBUG_FS=y
|
||||
CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
|
||||
CONFIG_LATENCYTOP=y
|
||||
CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y
|
||||
CONFIG_IRQSOFF_TRACER=y
|
||||
CONFIG_PREEMPT_TRACER=y
|
||||
CONFIG_SCHED_TRACER=y
|
||||
CONFIG_FTRACE_SYSCALLS=y
|
||||
CONFIG_STACK_TRACER=y
|
||||
CONFIG_BLK_DEV_IO_TRACE=y
|
||||
CONFIG_UPROBE_EVENT=y
|
||||
CONFIG_LKDTM=m
|
||||
CONFIG_TEST_LIST_SORT=y
|
||||
CONFIG_KPROBES_SANITY_TEST=y
|
||||
CONFIG_RBTREE_TEST=y
|
||||
CONFIG_INTERVAL_TREE_TEST=m
|
||||
CONFIG_PERCPU_TEST=m
|
||||
CONFIG_ATOMIC64_SELFTEST=y
|
||||
CONFIG_TEST_STRING_HELPERS=y
|
||||
CONFIG_TEST_KSTRTOX=y
|
||||
CONFIG_DMA_API_DEBUG=y
|
||||
CONFIG_TEST_BPF=m
|
||||
# CONFIG_STRICT_DEVMEM is not set
|
||||
CONFIG_S390_PTDUMP=y
|
||||
CONFIG_ENCRYPTED_KEYS=m
|
||||
CONFIG_KEYS_DEBUG_PROC_KEYS=y
|
||||
CONFIG_SECURITY=y
|
||||
CONFIG_SECURITY_NETWORK=y
|
||||
CONFIG_SECURITY_SELINUX=y
|
||||
CONFIG_SECURITY_SELINUX_BOOTPARAM=y
|
||||
CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0
|
||||
CONFIG_SECURITY_SELINUX_DISABLE=y
|
||||
CONFIG_IMA=y
|
||||
CONFIG_IMA_APPRAISE=y
|
||||
CONFIG_CRYPTO_USER=m
|
||||
# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
|
||||
CONFIG_CRYPTO_CRYPTD=m
|
||||
CONFIG_CRYPTO_TEST=m
|
||||
CONFIG_CRYPTO_CCM=m
|
||||
CONFIG_CRYPTO_GCM=m
|
||||
CONFIG_CRYPTO_CTS=m
|
||||
CONFIG_CRYPTO_LRW=m
|
||||
CONFIG_CRYPTO_PCBC=m
|
||||
CONFIG_CRYPTO_XTS=m
|
||||
CONFIG_CRYPTO_XCBC=m
|
||||
CONFIG_CRYPTO_VMAC=m
|
||||
CONFIG_CRYPTO_CRC32=m
|
||||
CONFIG_CRYPTO_MICHAEL_MIC=m
|
||||
CONFIG_CRYPTO_RMD128=m
|
||||
CONFIG_CRYPTO_RMD160=m
|
||||
CONFIG_CRYPTO_RMD256=m
|
||||
CONFIG_CRYPTO_RMD320=m
|
||||
CONFIG_CRYPTO_SHA512=m
|
||||
CONFIG_CRYPTO_TGR192=m
|
||||
CONFIG_CRYPTO_WP512=m
|
||||
CONFIG_CRYPTO_ANUBIS=m
|
||||
CONFIG_CRYPTO_BLOWFISH=m
|
||||
CONFIG_CRYPTO_CAMELLIA=m
|
||||
CONFIG_CRYPTO_CAST5=m
|
||||
CONFIG_CRYPTO_CAST6=m
|
||||
CONFIG_CRYPTO_FCRYPT=m
|
||||
CONFIG_CRYPTO_KHAZAD=m
|
||||
CONFIG_CRYPTO_SALSA20=m
|
||||
CONFIG_CRYPTO_SEED=m
|
||||
CONFIG_CRYPTO_SERPENT=m
|
||||
CONFIG_CRYPTO_TEA=m
|
||||
CONFIG_CRYPTO_TWOFISH=m
|
||||
CONFIG_CRYPTO_ZLIB=y
|
||||
CONFIG_CRYPTO_LZO=m
|
||||
CONFIG_CRYPTO_LZ4=m
|
||||
CONFIG_CRYPTO_LZ4HC=m
|
||||
CONFIG_CRYPTO_USER_API_HASH=m
|
||||
CONFIG_CRYPTO_USER_API_SKCIPHER=m
|
||||
CONFIG_ZCRYPT=m
|
||||
CONFIG_CRYPTO_SHA1_S390=m
|
||||
CONFIG_CRYPTO_SHA256_S390=m
|
||||
CONFIG_CRYPTO_SHA512_S390=m
|
||||
CONFIG_CRYPTO_DES_S390=m
|
||||
CONFIG_CRYPTO_AES_S390=m
|
||||
CONFIG_CRYPTO_GHASH_S390=m
|
||||
CONFIG_ASYMMETRIC_KEY_TYPE=m
|
||||
CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m
|
||||
CONFIG_X509_CERTIFICATE_PARSER=m
|
||||
CONFIG_CRC7=m
|
||||
CONFIG_CRC8=m
|
||||
CONFIG_CORDIC=m
|
||||
CONFIG_CMM=m
|
||||
CONFIG_APPLDATA_BASE=y
|
||||
CONFIG_KVM=m
|
||||
CONFIG_KVM_S390_UCONTROL=y
|
||||
624
arch/s390/configs/gcov_defconfig
Normal file
624
arch/s390/configs/gcov_defconfig
Normal file
|
|
@ -0,0 +1,624 @@
|
|||
CONFIG_SYSVIPC=y
|
||||
CONFIG_POSIX_MQUEUE=y
|
||||
CONFIG_FHANDLE=y
|
||||
CONFIG_AUDIT=y
|
||||
CONFIG_NO_HZ=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_BSD_PROCESS_ACCT=y
|
||||
CONFIG_BSD_PROCESS_ACCT_V3=y
|
||||
CONFIG_TASKSTATS=y
|
||||
CONFIG_TASK_DELAY_ACCT=y
|
||||
CONFIG_TASK_XACCT=y
|
||||
CONFIG_TASK_IO_ACCOUNTING=y
|
||||
CONFIG_RCU_FAST_NO_HZ=y
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_CGROUP_FREEZER=y
|
||||
CONFIG_CGROUP_DEVICE=y
|
||||
CONFIG_CPUSETS=y
|
||||
CONFIG_CGROUP_CPUACCT=y
|
||||
CONFIG_RESOURCE_COUNTERS=y
|
||||
CONFIG_CGROUP_PERF=y
|
||||
CONFIG_BLK_CGROUP=y
|
||||
CONFIG_SCHED_AUTOGROUP=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
CONFIG_PROFILING=y
|
||||
CONFIG_OPROFILE=m
|
||||
CONFIG_KPROBES=y
|
||||
CONFIG_JUMP_LABEL=y
|
||||
CONFIG_GCOV_KERNEL=y
|
||||
CONFIG_GCOV_PROFILE_ALL=y
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_FORCE_LOAD=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
CONFIG_MODULE_FORCE_UNLOAD=y
|
||||
CONFIG_MODVERSIONS=y
|
||||
CONFIG_MODULE_SRCVERSION_ALL=y
|
||||
CONFIG_BLK_DEV_THROTTLING=y
|
||||
CONFIG_PARTITION_ADVANCED=y
|
||||
CONFIG_IBM_PARTITION=y
|
||||
CONFIG_BSD_DISKLABEL=y
|
||||
CONFIG_MINIX_SUBPARTITION=y
|
||||
CONFIG_SOLARIS_X86_PARTITION=y
|
||||
CONFIG_UNIXWARE_DISKLABEL=y
|
||||
CONFIG_CFQ_GROUP_IOSCHED=y
|
||||
CONFIG_DEFAULT_DEADLINE=y
|
||||
CONFIG_MARCH_Z196=y
|
||||
CONFIG_TUNE_ZEC12=y
|
||||
CONFIG_NR_CPUS=256
|
||||
CONFIG_HZ_100=y
|
||||
CONFIG_MEMORY_HOTPLUG=y
|
||||
CONFIG_MEMORY_HOTREMOVE=y
|
||||
CONFIG_KSM=y
|
||||
CONFIG_TRANSPARENT_HUGEPAGE=y
|
||||
CONFIG_PCI=y
|
||||
CONFIG_HOTPLUG_PCI=y
|
||||
CONFIG_HOTPLUG_PCI_S390=y
|
||||
CONFIG_CHSC_SCH=y
|
||||
CONFIG_CRASH_DUMP=y
|
||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
|
||||
CONFIG_BINFMT_MISC=m
|
||||
CONFIG_HIBERNATION=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_PACKET_DIAG=m
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_UNIX_DIAG=m
|
||||
CONFIG_XFRM_USER=m
|
||||
CONFIG_NET_KEY=m
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
CONFIG_IP_ADVANCED_ROUTER=y
|
||||
CONFIG_IP_MULTIPLE_TABLES=y
|
||||
CONFIG_IP_ROUTE_MULTIPATH=y
|
||||
CONFIG_IP_ROUTE_VERBOSE=y
|
||||
CONFIG_NET_IPIP=m
|
||||
CONFIG_NET_IPGRE_DEMUX=m
|
||||
CONFIG_NET_IPGRE=m
|
||||
CONFIG_NET_IPGRE_BROADCAST=y
|
||||
CONFIG_IP_MROUTE=y
|
||||
CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
|
||||
CONFIG_IP_PIMSM_V1=y
|
||||
CONFIG_IP_PIMSM_V2=y
|
||||
CONFIG_SYN_COOKIES=y
|
||||
CONFIG_NET_IPVTI=m
|
||||
CONFIG_INET_AH=m
|
||||
CONFIG_INET_ESP=m
|
||||
CONFIG_INET_IPCOMP=m
|
||||
CONFIG_INET_XFRM_MODE_TRANSPORT=m
|
||||
CONFIG_INET_XFRM_MODE_TUNNEL=m
|
||||
CONFIG_INET_XFRM_MODE_BEET=m
|
||||
CONFIG_INET_DIAG=m
|
||||
CONFIG_INET_UDP_DIAG=m
|
||||
CONFIG_TCP_CONG_ADVANCED=y
|
||||
CONFIG_TCP_CONG_HSTCP=m
|
||||
CONFIG_TCP_CONG_HYBLA=m
|
||||
CONFIG_TCP_CONG_SCALABLE=m
|
||||
CONFIG_TCP_CONG_LP=m
|
||||
CONFIG_TCP_CONG_VENO=m
|
||||
CONFIG_TCP_CONG_YEAH=m
|
||||
CONFIG_TCP_CONG_ILLINOIS=m
|
||||
CONFIG_IPV6=y
|
||||
CONFIG_IPV6_ROUTER_PREF=y
|
||||
CONFIG_INET6_AH=m
|
||||
CONFIG_INET6_ESP=m
|
||||
CONFIG_INET6_IPCOMP=m
|
||||
CONFIG_IPV6_MIP6=m
|
||||
CONFIG_INET6_XFRM_MODE_TRANSPORT=m
|
||||
CONFIG_INET6_XFRM_MODE_TUNNEL=m
|
||||
CONFIG_INET6_XFRM_MODE_BEET=m
|
||||
CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
|
||||
CONFIG_IPV6_VTI=m
|
||||
CONFIG_IPV6_SIT=m
|
||||
CONFIG_IPV6_GRE=m
|
||||
CONFIG_IPV6_MULTIPLE_TABLES=y
|
||||
CONFIG_IPV6_SUBTREES=y
|
||||
CONFIG_NETFILTER=y
|
||||
CONFIG_NF_CONNTRACK=m
|
||||
CONFIG_NF_CONNTRACK_SECMARK=y
|
||||
CONFIG_NF_CONNTRACK_EVENTS=y
|
||||
CONFIG_NF_CONNTRACK_TIMEOUT=y
|
||||
CONFIG_NF_CONNTRACK_TIMESTAMP=y
|
||||
CONFIG_NF_CT_PROTO_DCCP=m
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=m
|
||||
CONFIG_NF_CONNTRACK_AMANDA=m
|
||||
CONFIG_NF_CONNTRACK_FTP=m
|
||||
CONFIG_NF_CONNTRACK_H323=m
|
||||
CONFIG_NF_CONNTRACK_IRC=m
|
||||
CONFIG_NF_CONNTRACK_NETBIOS_NS=m
|
||||
CONFIG_NF_CONNTRACK_SNMP=m
|
||||
CONFIG_NF_CONNTRACK_PPTP=m
|
||||
CONFIG_NF_CONNTRACK_SANE=m
|
||||
CONFIG_NF_CONNTRACK_SIP=m
|
||||
CONFIG_NF_CONNTRACK_TFTP=m
|
||||
CONFIG_NF_CT_NETLINK=m
|
||||
CONFIG_NF_CT_NETLINK_TIMEOUT=m
|
||||
CONFIG_NF_TABLES=m
|
||||
CONFIG_NFT_EXTHDR=m
|
||||
CONFIG_NFT_META=m
|
||||
CONFIG_NFT_CT=m
|
||||
CONFIG_NFT_RBTREE=m
|
||||
CONFIG_NFT_HASH=m
|
||||
CONFIG_NFT_COUNTER=m
|
||||
CONFIG_NFT_LOG=m
|
||||
CONFIG_NFT_LIMIT=m
|
||||
CONFIG_NFT_NAT=m
|
||||
CONFIG_NFT_COMPAT=m
|
||||
CONFIG_NETFILTER_XT_SET=m
|
||||
CONFIG_NETFILTER_XT_TARGET_AUDIT=m
|
||||
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
|
||||
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
|
||||
CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_CT=m
|
||||
CONFIG_NETFILTER_XT_TARGET_DSCP=m
|
||||
CONFIG_NETFILTER_XT_TARGET_HMARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
|
||||
CONFIG_NETFILTER_XT_TARGET_LOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TEE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TPROXY=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_SECMARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
|
||||
CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
|
||||
CONFIG_NETFILTER_XT_MATCH_BPF=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
|
||||
CONFIG_NETFILTER_XT_MATCH_COMMENT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CPU=m
|
||||
CONFIG_NETFILTER_XT_MATCH_DCCP=m
|
||||
CONFIG_NETFILTER_XT_MATCH_DEVGROUP=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_IPVS=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_NFACCT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_OSF=m
|
||||
CONFIG_NETFILTER_XT_MATCH_OWNER=m
|
||||
CONFIG_NETFILTER_XT_MATCH_POLICY=m
|
||||
CONFIG_NETFILTER_XT_MATCH_PHYSDEV=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_SOCKET=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_IP_SET=m
|
||||
CONFIG_IP_SET_BITMAP_IP=m
|
||||
CONFIG_IP_SET_BITMAP_IPMAC=m
|
||||
CONFIG_IP_SET_BITMAP_PORT=m
|
||||
CONFIG_IP_SET_HASH_IP=m
|
||||
CONFIG_IP_SET_HASH_IPPORT=m
|
||||
CONFIG_IP_SET_HASH_IPPORTIP=m
|
||||
CONFIG_IP_SET_HASH_IPPORTNET=m
|
||||
CONFIG_IP_SET_HASH_NETPORTNET=m
|
||||
CONFIG_IP_SET_HASH_NET=m
|
||||
CONFIG_IP_SET_HASH_NETNET=m
|
||||
CONFIG_IP_SET_HASH_NETPORT=m
|
||||
CONFIG_IP_SET_HASH_NETIFACE=m
|
||||
CONFIG_IP_SET_LIST_SET=m
|
||||
CONFIG_IP_VS=m
|
||||
CONFIG_IP_VS_PROTO_TCP=y
|
||||
CONFIG_IP_VS_PROTO_UDP=y
|
||||
CONFIG_IP_VS_PROTO_ESP=y
|
||||
CONFIG_IP_VS_PROTO_AH=y
|
||||
CONFIG_IP_VS_RR=m
|
||||
CONFIG_IP_VS_WRR=m
|
||||
CONFIG_IP_VS_LC=m
|
||||
CONFIG_IP_VS_WLC=m
|
||||
CONFIG_IP_VS_LBLC=m
|
||||
CONFIG_IP_VS_LBLCR=m
|
||||
CONFIG_IP_VS_DH=m
|
||||
CONFIG_IP_VS_SH=m
|
||||
CONFIG_IP_VS_SED=m
|
||||
CONFIG_IP_VS_NQ=m
|
||||
CONFIG_IP_VS_FTP=m
|
||||
CONFIG_IP_VS_PE_SIP=m
|
||||
CONFIG_NF_CONNTRACK_IPV4=m
|
||||
# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
|
||||
CONFIG_NF_TABLES_IPV4=m
|
||||
CONFIG_NFT_CHAIN_ROUTE_IPV4=m
|
||||
CONFIG_NFT_CHAIN_NAT_IPV4=m
|
||||
CONFIG_NF_TABLES_ARP=m
|
||||
CONFIG_NF_NAT_IPV4=m
|
||||
CONFIG_IP_NF_IPTABLES=m
|
||||
CONFIG_IP_NF_MATCH_AH=m
|
||||
CONFIG_IP_NF_MATCH_ECN=m
|
||||
CONFIG_IP_NF_MATCH_RPFILTER=m
|
||||
CONFIG_IP_NF_MATCH_TTL=m
|
||||
CONFIG_IP_NF_FILTER=m
|
||||
CONFIG_IP_NF_TARGET_REJECT=m
|
||||
CONFIG_IP_NF_MANGLE=m
|
||||
CONFIG_IP_NF_TARGET_CLUSTERIP=m
|
||||
CONFIG_IP_NF_TARGET_ECN=m
|
||||
CONFIG_IP_NF_TARGET_TTL=m
|
||||
CONFIG_IP_NF_RAW=m
|
||||
CONFIG_IP_NF_SECURITY=m
|
||||
CONFIG_IP_NF_ARPTABLES=m
|
||||
CONFIG_IP_NF_ARPFILTER=m
|
||||
CONFIG_IP_NF_ARP_MANGLE=m
|
||||
CONFIG_NF_CONNTRACK_IPV6=m
|
||||
CONFIG_NF_TABLES_IPV6=m
|
||||
CONFIG_NFT_CHAIN_ROUTE_IPV6=m
|
||||
CONFIG_NFT_CHAIN_NAT_IPV6=m
|
||||
CONFIG_NF_NAT_IPV6=m
|
||||
CONFIG_IP6_NF_IPTABLES=m
|
||||
CONFIG_IP6_NF_MATCH_AH=m
|
||||
CONFIG_IP6_NF_MATCH_EUI64=m
|
||||
CONFIG_IP6_NF_MATCH_FRAG=m
|
||||
CONFIG_IP6_NF_MATCH_OPTS=m
|
||||
CONFIG_IP6_NF_MATCH_HL=m
|
||||
CONFIG_IP6_NF_MATCH_IPV6HEADER=m
|
||||
CONFIG_IP6_NF_MATCH_MH=m
|
||||
CONFIG_IP6_NF_MATCH_RPFILTER=m
|
||||
CONFIG_IP6_NF_MATCH_RT=m
|
||||
CONFIG_IP6_NF_TARGET_HL=m
|
||||
CONFIG_IP6_NF_FILTER=m
|
||||
CONFIG_IP6_NF_TARGET_REJECT=m
|
||||
CONFIG_IP6_NF_MANGLE=m
|
||||
CONFIG_IP6_NF_RAW=m
|
||||
CONFIG_IP6_NF_SECURITY=m
|
||||
CONFIG_NF_TABLES_BRIDGE=m
|
||||
CONFIG_NET_SCTPPROBE=m
|
||||
CONFIG_RDS=m
|
||||
CONFIG_RDS_RDMA=m
|
||||
CONFIG_RDS_TCP=m
|
||||
CONFIG_L2TP=m
|
||||
CONFIG_L2TP_DEBUGFS=m
|
||||
CONFIG_L2TP_V3=y
|
||||
CONFIG_L2TP_IP=m
|
||||
CONFIG_L2TP_ETH=m
|
||||
CONFIG_BRIDGE=m
|
||||
CONFIG_VLAN_8021Q=m
|
||||
CONFIG_VLAN_8021Q_GVRP=y
|
||||
CONFIG_NET_SCHED=y
|
||||
CONFIG_NET_SCH_CBQ=m
|
||||
CONFIG_NET_SCH_HTB=m
|
||||
CONFIG_NET_SCH_HFSC=m
|
||||
CONFIG_NET_SCH_PRIO=m
|
||||
CONFIG_NET_SCH_MULTIQ=m
|
||||
CONFIG_NET_SCH_RED=m
|
||||
CONFIG_NET_SCH_SFB=m
|
||||
CONFIG_NET_SCH_SFQ=m
|
||||
CONFIG_NET_SCH_TEQL=m
|
||||
CONFIG_NET_SCH_TBF=m
|
||||
CONFIG_NET_SCH_GRED=m
|
||||
CONFIG_NET_SCH_DSMARK=m
|
||||
CONFIG_NET_SCH_NETEM=m
|
||||
CONFIG_NET_SCH_DRR=m
|
||||
CONFIG_NET_SCH_MQPRIO=m
|
||||
CONFIG_NET_SCH_CHOKE=m
|
||||
CONFIG_NET_SCH_QFQ=m
|
||||
CONFIG_NET_SCH_CODEL=m
|
||||
CONFIG_NET_SCH_FQ_CODEL=m
|
||||
CONFIG_NET_SCH_INGRESS=m
|
||||
CONFIG_NET_SCH_PLUG=m
|
||||
CONFIG_NET_CLS_BASIC=m
|
||||
CONFIG_NET_CLS_TCINDEX=m
|
||||
CONFIG_NET_CLS_ROUTE4=m
|
||||
CONFIG_NET_CLS_FW=m
|
||||
CONFIG_NET_CLS_U32=m
|
||||
CONFIG_CLS_U32_PERF=y
|
||||
CONFIG_CLS_U32_MARK=y
|
||||
CONFIG_NET_CLS_RSVP=m
|
||||
CONFIG_NET_CLS_RSVP6=m
|
||||
CONFIG_NET_CLS_FLOW=m
|
||||
CONFIG_NET_CLS_CGROUP=y
|
||||
CONFIG_NET_CLS_BPF=m
|
||||
CONFIG_NET_CLS_ACT=y
|
||||
CONFIG_NET_ACT_POLICE=m
|
||||
CONFIG_NET_ACT_GACT=m
|
||||
CONFIG_GACT_PROB=y
|
||||
CONFIG_NET_ACT_MIRRED=m
|
||||
CONFIG_NET_ACT_IPT=m
|
||||
CONFIG_NET_ACT_NAT=m
|
||||
CONFIG_NET_ACT_PEDIT=m
|
||||
CONFIG_NET_ACT_SIMP=m
|
||||
CONFIG_NET_ACT_SKBEDIT=m
|
||||
CONFIG_NET_ACT_CSUM=m
|
||||
CONFIG_DNS_RESOLVER=y
|
||||
CONFIG_BPF_JIT=y
|
||||
CONFIG_NET_PKTGEN=m
|
||||
CONFIG_NET_TCPPROBE=m
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_CONNECTOR=y
|
||||
CONFIG_BLK_DEV_LOOP=m
|
||||
CONFIG_BLK_DEV_CRYPTOLOOP=m
|
||||
CONFIG_BLK_DEV_NBD=m
|
||||
CONFIG_BLK_DEV_OSD=m
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_BLK_DEV_RAM_SIZE=32768
|
||||
CONFIG_BLK_DEV_XIP=y
|
||||
CONFIG_CDROM_PKTCDVD=m
|
||||
CONFIG_ATA_OVER_ETH=m
|
||||
CONFIG_VIRTIO_BLK=y
|
||||
CONFIG_ENCLOSURE_SERVICES=m
|
||||
CONFIG_RAID_ATTRS=m
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_CHR_DEV_ST=m
|
||||
CONFIG_CHR_DEV_OSST=m
|
||||
CONFIG_BLK_DEV_SR=m
|
||||
CONFIG_CHR_DEV_SG=y
|
||||
CONFIG_CHR_DEV_SCH=m
|
||||
CONFIG_SCSI_ENCLOSURE=m
|
||||
CONFIG_SCSI_CONSTANTS=y
|
||||
CONFIG_SCSI_LOGGING=y
|
||||
CONFIG_SCSI_SPI_ATTRS=m
|
||||
CONFIG_SCSI_FC_ATTRS=y
|
||||
CONFIG_SCSI_SAS_LIBSAS=m
|
||||
CONFIG_SCSI_SRP_ATTRS=m
|
||||
CONFIG_ISCSI_TCP=m
|
||||
CONFIG_SCSI_DEBUG=m
|
||||
CONFIG_ZFCP=y
|
||||
CONFIG_SCSI_VIRTIO=m
|
||||
CONFIG_SCSI_DH=m
|
||||
CONFIG_SCSI_DH_RDAC=m
|
||||
CONFIG_SCSI_DH_HP_SW=m
|
||||
CONFIG_SCSI_DH_EMC=m
|
||||
CONFIG_SCSI_DH_ALUA=m
|
||||
CONFIG_SCSI_OSD_INITIATOR=m
|
||||
CONFIG_SCSI_OSD_ULD=m
|
||||
CONFIG_MD=y
|
||||
CONFIG_BLK_DEV_MD=y
|
||||
CONFIG_MD_LINEAR=m
|
||||
CONFIG_MD_RAID0=m
|
||||
CONFIG_MD_MULTIPATH=m
|
||||
CONFIG_MD_FAULTY=m
|
||||
CONFIG_BLK_DEV_DM=m
|
||||
CONFIG_DM_CRYPT=m
|
||||
CONFIG_DM_SNAPSHOT=m
|
||||
CONFIG_DM_MIRROR=m
|
||||
CONFIG_DM_LOG_USERSPACE=m
|
||||
CONFIG_DM_RAID=m
|
||||
CONFIG_DM_ZERO=m
|
||||
CONFIG_DM_MULTIPATH=m
|
||||
CONFIG_DM_MULTIPATH_QL=m
|
||||
CONFIG_DM_MULTIPATH_ST=m
|
||||
CONFIG_DM_DELAY=m
|
||||
CONFIG_DM_UEVENT=y
|
||||
CONFIG_DM_FLAKEY=m
|
||||
CONFIG_DM_VERITY=m
|
||||
CONFIG_DM_SWITCH=m
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_BONDING=m
|
||||
CONFIG_DUMMY=m
|
||||
CONFIG_EQUALIZER=m
|
||||
CONFIG_IFB=m
|
||||
CONFIG_MACVLAN=m
|
||||
CONFIG_MACVTAP=m
|
||||
CONFIG_VXLAN=m
|
||||
CONFIG_TUN=m
|
||||
CONFIG_VETH=m
|
||||
CONFIG_VIRTIO_NET=m
|
||||
CONFIG_NLMON=m
|
||||
CONFIG_VHOST_NET=m
|
||||
# CONFIG_NET_VENDOR_ARC is not set
|
||||
# CONFIG_NET_VENDOR_CHELSIO is not set
|
||||
# CONFIG_NET_VENDOR_INTEL is not set
|
||||
# CONFIG_NET_VENDOR_MARVELL is not set
|
||||
CONFIG_MLX4_EN=m
|
||||
# CONFIG_NET_VENDOR_NATSEMI is not set
|
||||
CONFIG_PPP=m
|
||||
CONFIG_PPP_BSDCOMP=m
|
||||
CONFIG_PPP_DEFLATE=m
|
||||
CONFIG_PPP_MPPE=m
|
||||
CONFIG_PPPOE=m
|
||||
CONFIG_PPTP=m
|
||||
CONFIG_PPPOL2TP=m
|
||||
CONFIG_PPP_ASYNC=m
|
||||
CONFIG_PPP_SYNC_TTY=m
|
||||
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
|
||||
# CONFIG_INPUT_KEYBOARD is not set
|
||||
# CONFIG_INPUT_MOUSE is not set
|
||||
# CONFIG_SERIO is not set
|
||||
CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
|
||||
CONFIG_LEGACY_PTY_COUNT=0
|
||||
CONFIG_HW_RANDOM_VIRTIO=m
|
||||
CONFIG_RAW_DRIVER=m
|
||||
CONFIG_HANGCHECK_TIMER=m
|
||||
CONFIG_TN3270_FS=y
|
||||
CONFIG_WATCHDOG=y
|
||||
CONFIG_WATCHDOG_NOWAYOUT=y
|
||||
CONFIG_SOFT_WATCHDOG=m
|
||||
CONFIG_DIAG288_WATCHDOG=m
|
||||
# CONFIG_HID is not set
|
||||
# CONFIG_USB_SUPPORT is not set
|
||||
CONFIG_INFINIBAND=m
|
||||
CONFIG_INFINIBAND_USER_ACCESS=m
|
||||
CONFIG_MLX4_INFINIBAND=m
|
||||
CONFIG_VIRTIO_BALLOON=m
|
||||
# CONFIG_IOMMU_SUPPORT is not set
|
||||
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_DEFAULTS_TO_ORDERED is not set
|
||||
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_JBD_DEBUG=y
|
||||
CONFIG_JBD2_DEBUG=y
|
||||
CONFIG_JFS_FS=m
|
||||
CONFIG_JFS_POSIX_ACL=y
|
||||
CONFIG_JFS_SECURITY=y
|
||||
CONFIG_JFS_STATISTICS=y
|
||||
CONFIG_XFS_FS=y
|
||||
CONFIG_XFS_QUOTA=y
|
||||
CONFIG_XFS_POSIX_ACL=y
|
||||
CONFIG_XFS_RT=y
|
||||
CONFIG_GFS2_FS=m
|
||||
CONFIG_OCFS2_FS=m
|
||||
CONFIG_BTRFS_FS=y
|
||||
CONFIG_BTRFS_FS_POSIX_ACL=y
|
||||
CONFIG_NILFS2_FS=m
|
||||
CONFIG_FANOTIFY=y
|
||||
CONFIG_QUOTA_NETLINK_INTERFACE=y
|
||||
CONFIG_QFMT_V1=m
|
||||
CONFIG_QFMT_V2=m
|
||||
CONFIG_AUTOFS4_FS=m
|
||||
CONFIG_FUSE_FS=m
|
||||
CONFIG_CUSE=m
|
||||
CONFIG_FSCACHE=m
|
||||
CONFIG_CACHEFILES=m
|
||||
CONFIG_ISO9660_FS=y
|
||||
CONFIG_JOLIET=y
|
||||
CONFIG_ZISOFS=y
|
||||
CONFIG_UDF_FS=m
|
||||
CONFIG_MSDOS_FS=m
|
||||
CONFIG_VFAT_FS=m
|
||||
CONFIG_NTFS_FS=m
|
||||
CONFIG_NTFS_RW=y
|
||||
CONFIG_PROC_KCORE=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
CONFIG_HUGETLBFS=y
|
||||
CONFIG_CONFIGFS_FS=m
|
||||
CONFIG_ECRYPT_FS=m
|
||||
CONFIG_CRAMFS=m
|
||||
CONFIG_SQUASHFS=m
|
||||
CONFIG_SQUASHFS_XATTR=y
|
||||
CONFIG_SQUASHFS_LZO=y
|
||||
CONFIG_SQUASHFS_XZ=y
|
||||
CONFIG_ROMFS_FS=m
|
||||
CONFIG_NFS_FS=m
|
||||
CONFIG_NFS_V3_ACL=y
|
||||
CONFIG_NFS_V4=m
|
||||
CONFIG_NFS_SWAP=y
|
||||
CONFIG_NFSD=m
|
||||
CONFIG_NFSD_V3_ACL=y
|
||||
CONFIG_NFSD_V4=y
|
||||
CONFIG_NFSD_V4_SECURITY_LABEL=y
|
||||
CONFIG_CIFS=m
|
||||
CONFIG_CIFS_STATS=y
|
||||
CONFIG_CIFS_STATS2=y
|
||||
CONFIG_CIFS_WEAK_PW_HASH=y
|
||||
CONFIG_CIFS_UPCALL=y
|
||||
CONFIG_CIFS_XATTR=y
|
||||
CONFIG_CIFS_POSIX=y
|
||||
# CONFIG_CIFS_DEBUG is not set
|
||||
CONFIG_CIFS_DFS_UPCALL=y
|
||||
CONFIG_NLS_DEFAULT="utf8"
|
||||
CONFIG_NLS_CODEPAGE_437=m
|
||||
CONFIG_NLS_CODEPAGE_850=m
|
||||
CONFIG_NLS_ASCII=m
|
||||
CONFIG_NLS_ISO8859_1=m
|
||||
CONFIG_NLS_ISO8859_15=m
|
||||
CONFIG_NLS_UTF8=m
|
||||
CONFIG_DLM=m
|
||||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
# CONFIG_ENABLE_MUST_CHECK is not set
|
||||
CONFIG_FRAME_WARN=1024
|
||||
CONFIG_UNUSED_SYMBOLS=y
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_DEBUG_KERNEL=y
|
||||
CONFIG_MEMORY_NOTIFIER_ERROR_INJECT=m
|
||||
CONFIG_TIMER_STATS=y
|
||||
CONFIG_RCU_TORTURE_TEST=m
|
||||
CONFIG_RCU_CPU_STALL_TIMEOUT=60
|
||||
CONFIG_NOTIFIER_ERROR_INJECTION=m
|
||||
CONFIG_CPU_NOTIFIER_ERROR_INJECT=m
|
||||
CONFIG_PM_NOTIFIER_ERROR_INJECT=m
|
||||
CONFIG_LATENCYTOP=y
|
||||
CONFIG_BLK_DEV_IO_TRACE=y
|
||||
# CONFIG_KPROBE_EVENT is not set
|
||||
CONFIG_LKDTM=m
|
||||
CONFIG_RBTREE_TEST=m
|
||||
CONFIG_INTERVAL_TREE_TEST=m
|
||||
CONFIG_PERCPU_TEST=m
|
||||
CONFIG_ATOMIC64_SELFTEST=y
|
||||
# CONFIG_STRICT_DEVMEM is not set
|
||||
CONFIG_S390_PTDUMP=y
|
||||
CONFIG_ENCRYPTED_KEYS=m
|
||||
CONFIG_KEYS_DEBUG_PROC_KEYS=y
|
||||
CONFIG_SECURITY=y
|
||||
CONFIG_SECURITY_NETWORK=y
|
||||
CONFIG_SECURITY_SELINUX=y
|
||||
CONFIG_SECURITY_SELINUX_BOOTPARAM=y
|
||||
CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0
|
||||
CONFIG_SECURITY_SELINUX_DISABLE=y
|
||||
CONFIG_IMA=y
|
||||
CONFIG_IMA_APPRAISE=y
|
||||
CONFIG_CRYPTO_USER=m
|
||||
# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
|
||||
CONFIG_CRYPTO_CRYPTD=m
|
||||
CONFIG_CRYPTO_TEST=m
|
||||
CONFIG_CRYPTO_CCM=m
|
||||
CONFIG_CRYPTO_GCM=m
|
||||
CONFIG_CRYPTO_CTS=m
|
||||
CONFIG_CRYPTO_LRW=m
|
||||
CONFIG_CRYPTO_PCBC=m
|
||||
CONFIG_CRYPTO_XTS=m
|
||||
CONFIG_CRYPTO_XCBC=m
|
||||
CONFIG_CRYPTO_VMAC=m
|
||||
CONFIG_CRYPTO_CRC32=m
|
||||
CONFIG_CRYPTO_MICHAEL_MIC=m
|
||||
CONFIG_CRYPTO_RMD128=m
|
||||
CONFIG_CRYPTO_RMD160=m
|
||||
CONFIG_CRYPTO_RMD256=m
|
||||
CONFIG_CRYPTO_RMD320=m
|
||||
CONFIG_CRYPTO_SHA512=m
|
||||
CONFIG_CRYPTO_TGR192=m
|
||||
CONFIG_CRYPTO_WP512=m
|
||||
CONFIG_CRYPTO_ANUBIS=m
|
||||
CONFIG_CRYPTO_BLOWFISH=m
|
||||
CONFIG_CRYPTO_CAMELLIA=m
|
||||
CONFIG_CRYPTO_CAST5=m
|
||||
CONFIG_CRYPTO_CAST6=m
|
||||
CONFIG_CRYPTO_FCRYPT=m
|
||||
CONFIG_CRYPTO_KHAZAD=m
|
||||
CONFIG_CRYPTO_SALSA20=m
|
||||
CONFIG_CRYPTO_SEED=m
|
||||
CONFIG_CRYPTO_SERPENT=m
|
||||
CONFIG_CRYPTO_TEA=m
|
||||
CONFIG_CRYPTO_TWOFISH=m
|
||||
CONFIG_CRYPTO_ZLIB=y
|
||||
CONFIG_CRYPTO_LZO=m
|
||||
CONFIG_CRYPTO_LZ4=m
|
||||
CONFIG_CRYPTO_LZ4HC=m
|
||||
CONFIG_CRYPTO_USER_API_HASH=m
|
||||
CONFIG_CRYPTO_USER_API_SKCIPHER=m
|
||||
CONFIG_ZCRYPT=m
|
||||
CONFIG_CRYPTO_SHA1_S390=m
|
||||
CONFIG_CRYPTO_SHA256_S390=m
|
||||
CONFIG_CRYPTO_SHA512_S390=m
|
||||
CONFIG_CRYPTO_DES_S390=m
|
||||
CONFIG_CRYPTO_AES_S390=m
|
||||
CONFIG_CRYPTO_GHASH_S390=m
|
||||
CONFIG_ASYMMETRIC_KEY_TYPE=m
|
||||
CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m
|
||||
CONFIG_X509_CERTIFICATE_PARSER=m
|
||||
CONFIG_CRC7=m
|
||||
CONFIG_CRC8=m
|
||||
CONFIG_CORDIC=m
|
||||
CONFIG_CMM=m
|
||||
CONFIG_APPLDATA_BASE=y
|
||||
CONFIG_KVM=m
|
||||
CONFIG_KVM_S390_UCONTROL=y
|
||||
619
arch/s390/configs/performance_defconfig
Normal file
619
arch/s390/configs/performance_defconfig
Normal file
|
|
@ -0,0 +1,619 @@
|
|||
CONFIG_SYSVIPC=y
|
||||
CONFIG_POSIX_MQUEUE=y
|
||||
CONFIG_FHANDLE=y
|
||||
CONFIG_AUDIT=y
|
||||
CONFIG_NO_HZ=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_BSD_PROCESS_ACCT=y
|
||||
CONFIG_BSD_PROCESS_ACCT_V3=y
|
||||
CONFIG_TASKSTATS=y
|
||||
CONFIG_TASK_DELAY_ACCT=y
|
||||
CONFIG_TASK_XACCT=y
|
||||
CONFIG_TASK_IO_ACCOUNTING=y
|
||||
CONFIG_RCU_FAST_NO_HZ=y
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_CGROUP_FREEZER=y
|
||||
CONFIG_CGROUP_DEVICE=y
|
||||
CONFIG_CPUSETS=y
|
||||
CONFIG_CGROUP_CPUACCT=y
|
||||
CONFIG_RESOURCE_COUNTERS=y
|
||||
CONFIG_CGROUP_PERF=y
|
||||
CONFIG_BLK_CGROUP=y
|
||||
CONFIG_SCHED_AUTOGROUP=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
CONFIG_PROFILING=y
|
||||
CONFIG_OPROFILE=m
|
||||
CONFIG_KPROBES=y
|
||||
CONFIG_JUMP_LABEL=y
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_FORCE_LOAD=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
CONFIG_MODULE_FORCE_UNLOAD=y
|
||||
CONFIG_MODVERSIONS=y
|
||||
CONFIG_MODULE_SRCVERSION_ALL=y
|
||||
CONFIG_BLK_DEV_THROTTLING=y
|
||||
CONFIG_PARTITION_ADVANCED=y
|
||||
CONFIG_IBM_PARTITION=y
|
||||
CONFIG_BSD_DISKLABEL=y
|
||||
CONFIG_MINIX_SUBPARTITION=y
|
||||
CONFIG_SOLARIS_X86_PARTITION=y
|
||||
CONFIG_UNIXWARE_DISKLABEL=y
|
||||
CONFIG_CFQ_GROUP_IOSCHED=y
|
||||
CONFIG_DEFAULT_DEADLINE=y
|
||||
CONFIG_MARCH_Z196=y
|
||||
CONFIG_TUNE_ZEC12=y
|
||||
CONFIG_NR_CPUS=256
|
||||
CONFIG_HZ_100=y
|
||||
CONFIG_MEMORY_HOTPLUG=y
|
||||
CONFIG_MEMORY_HOTREMOVE=y
|
||||
CONFIG_KSM=y
|
||||
CONFIG_TRANSPARENT_HUGEPAGE=y
|
||||
CONFIG_PCI=y
|
||||
CONFIG_HOTPLUG_PCI=y
|
||||
CONFIG_HOTPLUG_PCI_S390=y
|
||||
CONFIG_CHSC_SCH=y
|
||||
CONFIG_CRASH_DUMP=y
|
||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
|
||||
CONFIG_BINFMT_MISC=m
|
||||
CONFIG_HIBERNATION=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_PACKET_DIAG=m
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_UNIX_DIAG=m
|
||||
CONFIG_XFRM_USER=m
|
||||
CONFIG_NET_KEY=m
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
CONFIG_IP_ADVANCED_ROUTER=y
|
||||
CONFIG_IP_MULTIPLE_TABLES=y
|
||||
CONFIG_IP_ROUTE_MULTIPATH=y
|
||||
CONFIG_IP_ROUTE_VERBOSE=y
|
||||
CONFIG_NET_IPIP=m
|
||||
CONFIG_NET_IPGRE_DEMUX=m
|
||||
CONFIG_NET_IPGRE=m
|
||||
CONFIG_NET_IPGRE_BROADCAST=y
|
||||
CONFIG_IP_MROUTE=y
|
||||
CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
|
||||
CONFIG_IP_PIMSM_V1=y
|
||||
CONFIG_IP_PIMSM_V2=y
|
||||
CONFIG_SYN_COOKIES=y
|
||||
CONFIG_NET_IPVTI=m
|
||||
CONFIG_INET_AH=m
|
||||
CONFIG_INET_ESP=m
|
||||
CONFIG_INET_IPCOMP=m
|
||||
CONFIG_INET_XFRM_MODE_TRANSPORT=m
|
||||
CONFIG_INET_XFRM_MODE_TUNNEL=m
|
||||
CONFIG_INET_XFRM_MODE_BEET=m
|
||||
CONFIG_INET_DIAG=m
|
||||
CONFIG_INET_UDP_DIAG=m
|
||||
CONFIG_TCP_CONG_ADVANCED=y
|
||||
CONFIG_TCP_CONG_HSTCP=m
|
||||
CONFIG_TCP_CONG_HYBLA=m
|
||||
CONFIG_TCP_CONG_SCALABLE=m
|
||||
CONFIG_TCP_CONG_LP=m
|
||||
CONFIG_TCP_CONG_VENO=m
|
||||
CONFIG_TCP_CONG_YEAH=m
|
||||
CONFIG_TCP_CONG_ILLINOIS=m
|
||||
CONFIG_IPV6=y
|
||||
CONFIG_IPV6_ROUTER_PREF=y
|
||||
CONFIG_INET6_AH=m
|
||||
CONFIG_INET6_ESP=m
|
||||
CONFIG_INET6_IPCOMP=m
|
||||
CONFIG_IPV6_MIP6=m
|
||||
CONFIG_INET6_XFRM_MODE_TRANSPORT=m
|
||||
CONFIG_INET6_XFRM_MODE_TUNNEL=m
|
||||
CONFIG_INET6_XFRM_MODE_BEET=m
|
||||
CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
|
||||
CONFIG_IPV6_VTI=m
|
||||
CONFIG_IPV6_SIT=m
|
||||
CONFIG_IPV6_GRE=m
|
||||
CONFIG_IPV6_MULTIPLE_TABLES=y
|
||||
CONFIG_IPV6_SUBTREES=y
|
||||
CONFIG_NETFILTER=y
|
||||
CONFIG_NF_CONNTRACK=m
|
||||
CONFIG_NF_CONNTRACK_SECMARK=y
|
||||
CONFIG_NF_CONNTRACK_EVENTS=y
|
||||
CONFIG_NF_CONNTRACK_TIMEOUT=y
|
||||
CONFIG_NF_CONNTRACK_TIMESTAMP=y
|
||||
CONFIG_NF_CT_PROTO_DCCP=m
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=m
|
||||
CONFIG_NF_CONNTRACK_AMANDA=m
|
||||
CONFIG_NF_CONNTRACK_FTP=m
|
||||
CONFIG_NF_CONNTRACK_H323=m
|
||||
CONFIG_NF_CONNTRACK_IRC=m
|
||||
CONFIG_NF_CONNTRACK_NETBIOS_NS=m
|
||||
CONFIG_NF_CONNTRACK_SNMP=m
|
||||
CONFIG_NF_CONNTRACK_PPTP=m
|
||||
CONFIG_NF_CONNTRACK_SANE=m
|
||||
CONFIG_NF_CONNTRACK_SIP=m
|
||||
CONFIG_NF_CONNTRACK_TFTP=m
|
||||
CONFIG_NF_CT_NETLINK=m
|
||||
CONFIG_NF_CT_NETLINK_TIMEOUT=m
|
||||
CONFIG_NF_TABLES=m
|
||||
CONFIG_NFT_EXTHDR=m
|
||||
CONFIG_NFT_META=m
|
||||
CONFIG_NFT_CT=m
|
||||
CONFIG_NFT_RBTREE=m
|
||||
CONFIG_NFT_HASH=m
|
||||
CONFIG_NFT_COUNTER=m
|
||||
CONFIG_NFT_LOG=m
|
||||
CONFIG_NFT_LIMIT=m
|
||||
CONFIG_NFT_NAT=m
|
||||
CONFIG_NFT_COMPAT=m
|
||||
CONFIG_NETFILTER_XT_SET=m
|
||||
CONFIG_NETFILTER_XT_TARGET_AUDIT=m
|
||||
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
|
||||
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
|
||||
CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_CT=m
|
||||
CONFIG_NETFILTER_XT_TARGET_DSCP=m
|
||||
CONFIG_NETFILTER_XT_TARGET_HMARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
|
||||
CONFIG_NETFILTER_XT_TARGET_LOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TEE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TPROXY=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_SECMARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
|
||||
CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
|
||||
CONFIG_NETFILTER_XT_MATCH_BPF=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
|
||||
CONFIG_NETFILTER_XT_MATCH_COMMENT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CPU=m
|
||||
CONFIG_NETFILTER_XT_MATCH_DCCP=m
|
||||
CONFIG_NETFILTER_XT_MATCH_DEVGROUP=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_IPVS=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_NFACCT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_OSF=m
|
||||
CONFIG_NETFILTER_XT_MATCH_OWNER=m
|
||||
CONFIG_NETFILTER_XT_MATCH_POLICY=m
|
||||
CONFIG_NETFILTER_XT_MATCH_PHYSDEV=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_SOCKET=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_IP_SET=m
|
||||
CONFIG_IP_SET_BITMAP_IP=m
|
||||
CONFIG_IP_SET_BITMAP_IPMAC=m
|
||||
CONFIG_IP_SET_BITMAP_PORT=m
|
||||
CONFIG_IP_SET_HASH_IP=m
|
||||
CONFIG_IP_SET_HASH_IPPORT=m
|
||||
CONFIG_IP_SET_HASH_IPPORTIP=m
|
||||
CONFIG_IP_SET_HASH_IPPORTNET=m
|
||||
CONFIG_IP_SET_HASH_NETPORTNET=m
|
||||
CONFIG_IP_SET_HASH_NET=m
|
||||
CONFIG_IP_SET_HASH_NETNET=m
|
||||
CONFIG_IP_SET_HASH_NETPORT=m
|
||||
CONFIG_IP_SET_HASH_NETIFACE=m
|
||||
CONFIG_IP_SET_LIST_SET=m
|
||||
CONFIG_IP_VS=m
|
||||
CONFIG_IP_VS_PROTO_TCP=y
|
||||
CONFIG_IP_VS_PROTO_UDP=y
|
||||
CONFIG_IP_VS_PROTO_ESP=y
|
||||
CONFIG_IP_VS_PROTO_AH=y
|
||||
CONFIG_IP_VS_RR=m
|
||||
CONFIG_IP_VS_WRR=m
|
||||
CONFIG_IP_VS_LC=m
|
||||
CONFIG_IP_VS_WLC=m
|
||||
CONFIG_IP_VS_LBLC=m
|
||||
CONFIG_IP_VS_LBLCR=m
|
||||
CONFIG_IP_VS_DH=m
|
||||
CONFIG_IP_VS_SH=m
|
||||
CONFIG_IP_VS_SED=m
|
||||
CONFIG_IP_VS_NQ=m
|
||||
CONFIG_IP_VS_FTP=m
|
||||
CONFIG_IP_VS_PE_SIP=m
|
||||
CONFIG_NF_CONNTRACK_IPV4=m
|
||||
# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
|
||||
CONFIG_NF_TABLES_IPV4=m
|
||||
CONFIG_NFT_CHAIN_ROUTE_IPV4=m
|
||||
CONFIG_NFT_CHAIN_NAT_IPV4=m
|
||||
CONFIG_NF_TABLES_ARP=m
|
||||
CONFIG_NF_NAT_IPV4=m
|
||||
CONFIG_IP_NF_IPTABLES=m
|
||||
CONFIG_IP_NF_MATCH_AH=m
|
||||
CONFIG_IP_NF_MATCH_ECN=m
|
||||
CONFIG_IP_NF_MATCH_RPFILTER=m
|
||||
CONFIG_IP_NF_MATCH_TTL=m
|
||||
CONFIG_IP_NF_FILTER=m
|
||||
CONFIG_IP_NF_TARGET_REJECT=m
|
||||
CONFIG_IP_NF_MANGLE=m
|
||||
CONFIG_IP_NF_TARGET_CLUSTERIP=m
|
||||
CONFIG_IP_NF_TARGET_ECN=m
|
||||
CONFIG_IP_NF_TARGET_TTL=m
|
||||
CONFIG_IP_NF_RAW=m
|
||||
CONFIG_IP_NF_SECURITY=m
|
||||
CONFIG_IP_NF_ARPTABLES=m
|
||||
CONFIG_IP_NF_ARPFILTER=m
|
||||
CONFIG_IP_NF_ARP_MANGLE=m
|
||||
CONFIG_NF_CONNTRACK_IPV6=m
|
||||
CONFIG_NF_TABLES_IPV6=m
|
||||
CONFIG_NFT_CHAIN_ROUTE_IPV6=m
|
||||
CONFIG_NFT_CHAIN_NAT_IPV6=m
|
||||
CONFIG_NF_NAT_IPV6=m
|
||||
CONFIG_IP6_NF_IPTABLES=m
|
||||
CONFIG_IP6_NF_MATCH_AH=m
|
||||
CONFIG_IP6_NF_MATCH_EUI64=m
|
||||
CONFIG_IP6_NF_MATCH_FRAG=m
|
||||
CONFIG_IP6_NF_MATCH_OPTS=m
|
||||
CONFIG_IP6_NF_MATCH_HL=m
|
||||
CONFIG_IP6_NF_MATCH_IPV6HEADER=m
|
||||
CONFIG_IP6_NF_MATCH_MH=m
|
||||
CONFIG_IP6_NF_MATCH_RPFILTER=m
|
||||
CONFIG_IP6_NF_MATCH_RT=m
|
||||
CONFIG_IP6_NF_TARGET_HL=m
|
||||
CONFIG_IP6_NF_FILTER=m
|
||||
CONFIG_IP6_NF_TARGET_REJECT=m
|
||||
CONFIG_IP6_NF_MANGLE=m
|
||||
CONFIG_IP6_NF_RAW=m
|
||||
CONFIG_IP6_NF_SECURITY=m
|
||||
CONFIG_NF_TABLES_BRIDGE=m
|
||||
CONFIG_NET_SCTPPROBE=m
|
||||
CONFIG_RDS=m
|
||||
CONFIG_RDS_RDMA=m
|
||||
CONFIG_RDS_TCP=m
|
||||
CONFIG_L2TP=m
|
||||
CONFIG_L2TP_DEBUGFS=m
|
||||
CONFIG_L2TP_V3=y
|
||||
CONFIG_L2TP_IP=m
|
||||
CONFIG_L2TP_ETH=m
|
||||
CONFIG_BRIDGE=m
|
||||
CONFIG_VLAN_8021Q=m
|
||||
CONFIG_VLAN_8021Q_GVRP=y
|
||||
CONFIG_NET_SCHED=y
|
||||
CONFIG_NET_SCH_CBQ=m
|
||||
CONFIG_NET_SCH_HTB=m
|
||||
CONFIG_NET_SCH_HFSC=m
|
||||
CONFIG_NET_SCH_PRIO=m
|
||||
CONFIG_NET_SCH_MULTIQ=m
|
||||
CONFIG_NET_SCH_RED=m
|
||||
CONFIG_NET_SCH_SFB=m
|
||||
CONFIG_NET_SCH_SFQ=m
|
||||
CONFIG_NET_SCH_TEQL=m
|
||||
CONFIG_NET_SCH_TBF=m
|
||||
CONFIG_NET_SCH_GRED=m
|
||||
CONFIG_NET_SCH_DSMARK=m
|
||||
CONFIG_NET_SCH_NETEM=m
|
||||
CONFIG_NET_SCH_DRR=m
|
||||
CONFIG_NET_SCH_MQPRIO=m
|
||||
CONFIG_NET_SCH_CHOKE=m
|
||||
CONFIG_NET_SCH_QFQ=m
|
||||
CONFIG_NET_SCH_CODEL=m
|
||||
CONFIG_NET_SCH_FQ_CODEL=m
|
||||
CONFIG_NET_SCH_INGRESS=m
|
||||
CONFIG_NET_SCH_PLUG=m
|
||||
CONFIG_NET_CLS_BASIC=m
|
||||
CONFIG_NET_CLS_TCINDEX=m
|
||||
CONFIG_NET_CLS_ROUTE4=m
|
||||
CONFIG_NET_CLS_FW=m
|
||||
CONFIG_NET_CLS_U32=m
|
||||
CONFIG_CLS_U32_PERF=y
|
||||
CONFIG_CLS_U32_MARK=y
|
||||
CONFIG_NET_CLS_RSVP=m
|
||||
CONFIG_NET_CLS_RSVP6=m
|
||||
CONFIG_NET_CLS_FLOW=m
|
||||
CONFIG_NET_CLS_CGROUP=y
|
||||
CONFIG_NET_CLS_BPF=m
|
||||
CONFIG_NET_CLS_ACT=y
|
||||
CONFIG_NET_ACT_POLICE=m
|
||||
CONFIG_NET_ACT_GACT=m
|
||||
CONFIG_GACT_PROB=y
|
||||
CONFIG_NET_ACT_MIRRED=m
|
||||
CONFIG_NET_ACT_IPT=m
|
||||
CONFIG_NET_ACT_NAT=m
|
||||
CONFIG_NET_ACT_PEDIT=m
|
||||
CONFIG_NET_ACT_SIMP=m
|
||||
CONFIG_NET_ACT_SKBEDIT=m
|
||||
CONFIG_NET_ACT_CSUM=m
|
||||
CONFIG_DNS_RESOLVER=y
|
||||
CONFIG_BPF_JIT=y
|
||||
CONFIG_NET_PKTGEN=m
|
||||
CONFIG_NET_TCPPROBE=m
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_CONNECTOR=y
|
||||
CONFIG_BLK_DEV_LOOP=m
|
||||
CONFIG_BLK_DEV_CRYPTOLOOP=m
|
||||
CONFIG_BLK_DEV_NBD=m
|
||||
CONFIG_BLK_DEV_OSD=m
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_BLK_DEV_RAM_SIZE=32768
|
||||
CONFIG_BLK_DEV_XIP=y
|
||||
CONFIG_CDROM_PKTCDVD=m
|
||||
CONFIG_ATA_OVER_ETH=m
|
||||
CONFIG_VIRTIO_BLK=y
|
||||
CONFIG_ENCLOSURE_SERVICES=m
|
||||
CONFIG_RAID_ATTRS=m
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_CHR_DEV_ST=m
|
||||
CONFIG_CHR_DEV_OSST=m
|
||||
CONFIG_BLK_DEV_SR=m
|
||||
CONFIG_CHR_DEV_SG=y
|
||||
CONFIG_CHR_DEV_SCH=m
|
||||
CONFIG_SCSI_ENCLOSURE=m
|
||||
CONFIG_SCSI_CONSTANTS=y
|
||||
CONFIG_SCSI_LOGGING=y
|
||||
CONFIG_SCSI_SPI_ATTRS=m
|
||||
CONFIG_SCSI_FC_ATTRS=y
|
||||
CONFIG_SCSI_SAS_LIBSAS=m
|
||||
CONFIG_SCSI_SRP_ATTRS=m
|
||||
CONFIG_ISCSI_TCP=m
|
||||
CONFIG_SCSI_DEBUG=m
|
||||
CONFIG_ZFCP=y
|
||||
CONFIG_SCSI_VIRTIO=m
|
||||
CONFIG_SCSI_DH=m
|
||||
CONFIG_SCSI_DH_RDAC=m
|
||||
CONFIG_SCSI_DH_HP_SW=m
|
||||
CONFIG_SCSI_DH_EMC=m
|
||||
CONFIG_SCSI_DH_ALUA=m
|
||||
CONFIG_SCSI_OSD_INITIATOR=m
|
||||
CONFIG_SCSI_OSD_ULD=m
|
||||
CONFIG_MD=y
|
||||
CONFIG_BLK_DEV_MD=y
|
||||
CONFIG_MD_LINEAR=m
|
||||
CONFIG_MD_RAID0=m
|
||||
CONFIG_MD_MULTIPATH=m
|
||||
CONFIG_MD_FAULTY=m
|
||||
CONFIG_BLK_DEV_DM=m
|
||||
CONFIG_DM_CRYPT=m
|
||||
CONFIG_DM_SNAPSHOT=m
|
||||
CONFIG_DM_MIRROR=m
|
||||
CONFIG_DM_LOG_USERSPACE=m
|
||||
CONFIG_DM_RAID=m
|
||||
CONFIG_DM_ZERO=m
|
||||
CONFIG_DM_MULTIPATH=m
|
||||
CONFIG_DM_MULTIPATH_QL=m
|
||||
CONFIG_DM_MULTIPATH_ST=m
|
||||
CONFIG_DM_DELAY=m
|
||||
CONFIG_DM_UEVENT=y
|
||||
CONFIG_DM_FLAKEY=m
|
||||
CONFIG_DM_VERITY=m
|
||||
CONFIG_DM_SWITCH=m
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_BONDING=m
|
||||
CONFIG_DUMMY=m
|
||||
CONFIG_EQUALIZER=m
|
||||
CONFIG_IFB=m
|
||||
CONFIG_MACVLAN=m
|
||||
CONFIG_MACVTAP=m
|
||||
CONFIG_VXLAN=m
|
||||
CONFIG_TUN=m
|
||||
CONFIG_VETH=m
|
||||
CONFIG_VIRTIO_NET=m
|
||||
CONFIG_NLMON=m
|
||||
CONFIG_VHOST_NET=m
|
||||
# CONFIG_NET_VENDOR_ARC is not set
|
||||
# CONFIG_NET_VENDOR_CHELSIO is not set
|
||||
# CONFIG_NET_VENDOR_INTEL is not set
|
||||
# CONFIG_NET_VENDOR_MARVELL is not set
|
||||
CONFIG_MLX4_EN=m
|
||||
# CONFIG_NET_VENDOR_NATSEMI is not set
|
||||
CONFIG_PPP=m
|
||||
CONFIG_PPP_BSDCOMP=m
|
||||
CONFIG_PPP_DEFLATE=m
|
||||
CONFIG_PPP_MPPE=m
|
||||
CONFIG_PPPOE=m
|
||||
CONFIG_PPTP=m
|
||||
CONFIG_PPPOL2TP=m
|
||||
CONFIG_PPP_ASYNC=m
|
||||
CONFIG_PPP_SYNC_TTY=m
|
||||
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
|
||||
# CONFIG_INPUT_KEYBOARD is not set
|
||||
# CONFIG_INPUT_MOUSE is not set
|
||||
# CONFIG_SERIO is not set
|
||||
CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
|
||||
CONFIG_LEGACY_PTY_COUNT=0
|
||||
CONFIG_HW_RANDOM_VIRTIO=m
|
||||
CONFIG_RAW_DRIVER=m
|
||||
CONFIG_HANGCHECK_TIMER=m
|
||||
CONFIG_TN3270_FS=y
|
||||
CONFIG_WATCHDOG=y
|
||||
CONFIG_WATCHDOG_NOWAYOUT=y
|
||||
CONFIG_SOFT_WATCHDOG=m
|
||||
CONFIG_DIAG288_WATCHDOG=m
|
||||
# CONFIG_HID is not set
|
||||
# CONFIG_USB_SUPPORT is not set
|
||||
CONFIG_INFINIBAND=m
|
||||
CONFIG_INFINIBAND_USER_ACCESS=m
|
||||
CONFIG_MLX4_INFINIBAND=m
|
||||
CONFIG_VIRTIO_BALLOON=m
|
||||
# CONFIG_IOMMU_SUPPORT is not set
|
||||
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_DEFAULTS_TO_ORDERED is not set
|
||||
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_JBD_DEBUG=y
|
||||
CONFIG_JBD2_DEBUG=y
|
||||
CONFIG_JFS_FS=m
|
||||
CONFIG_JFS_POSIX_ACL=y
|
||||
CONFIG_JFS_SECURITY=y
|
||||
CONFIG_JFS_STATISTICS=y
|
||||
CONFIG_XFS_FS=y
|
||||
CONFIG_XFS_QUOTA=y
|
||||
CONFIG_XFS_POSIX_ACL=y
|
||||
CONFIG_XFS_RT=y
|
||||
CONFIG_GFS2_FS=m
|
||||
CONFIG_OCFS2_FS=m
|
||||
CONFIG_BTRFS_FS=y
|
||||
CONFIG_BTRFS_FS_POSIX_ACL=y
|
||||
CONFIG_NILFS2_FS=m
|
||||
CONFIG_FANOTIFY=y
|
||||
CONFIG_QUOTA_NETLINK_INTERFACE=y
|
||||
CONFIG_QFMT_V1=m
|
||||
CONFIG_QFMT_V2=m
|
||||
CONFIG_AUTOFS4_FS=m
|
||||
CONFIG_FUSE_FS=m
|
||||
CONFIG_CUSE=m
|
||||
CONFIG_FSCACHE=m
|
||||
CONFIG_CACHEFILES=m
|
||||
CONFIG_ISO9660_FS=y
|
||||
CONFIG_JOLIET=y
|
||||
CONFIG_ZISOFS=y
|
||||
CONFIG_UDF_FS=m
|
||||
CONFIG_MSDOS_FS=m
|
||||
CONFIG_VFAT_FS=m
|
||||
CONFIG_NTFS_FS=m
|
||||
CONFIG_NTFS_RW=y
|
||||
CONFIG_PROC_KCORE=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
CONFIG_HUGETLBFS=y
|
||||
CONFIG_CONFIGFS_FS=m
|
||||
CONFIG_ECRYPT_FS=m
|
||||
CONFIG_CRAMFS=m
|
||||
CONFIG_SQUASHFS=m
|
||||
CONFIG_SQUASHFS_XATTR=y
|
||||
CONFIG_SQUASHFS_LZO=y
|
||||
CONFIG_SQUASHFS_XZ=y
|
||||
CONFIG_ROMFS_FS=m
|
||||
CONFIG_NFS_FS=m
|
||||
CONFIG_NFS_V3_ACL=y
|
||||
CONFIG_NFS_V4=m
|
||||
CONFIG_NFS_SWAP=y
|
||||
CONFIG_NFSD=m
|
||||
CONFIG_NFSD_V3_ACL=y
|
||||
CONFIG_NFSD_V4=y
|
||||
CONFIG_NFSD_V4_SECURITY_LABEL=y
|
||||
CONFIG_CIFS=m
|
||||
CONFIG_CIFS_STATS=y
|
||||
CONFIG_CIFS_STATS2=y
|
||||
CONFIG_CIFS_WEAK_PW_HASH=y
|
||||
CONFIG_CIFS_UPCALL=y
|
||||
CONFIG_CIFS_XATTR=y
|
||||
CONFIG_CIFS_POSIX=y
|
||||
# CONFIG_CIFS_DEBUG is not set
|
||||
CONFIG_CIFS_DFS_UPCALL=y
|
||||
CONFIG_NLS_DEFAULT="utf8"
|
||||
CONFIG_NLS_CODEPAGE_437=m
|
||||
CONFIG_NLS_CODEPAGE_850=m
|
||||
CONFIG_NLS_ASCII=m
|
||||
CONFIG_NLS_ISO8859_1=m
|
||||
CONFIG_NLS_ISO8859_15=m
|
||||
CONFIG_NLS_UTF8=m
|
||||
CONFIG_DLM=m
|
||||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
# CONFIG_ENABLE_MUST_CHECK is not set
|
||||
CONFIG_FRAME_WARN=1024
|
||||
CONFIG_UNUSED_SYMBOLS=y
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_DEBUG_KERNEL=y
|
||||
CONFIG_TIMER_STATS=y
|
||||
CONFIG_RCU_TORTURE_TEST=m
|
||||
CONFIG_RCU_CPU_STALL_TIMEOUT=60
|
||||
CONFIG_LATENCYTOP=y
|
||||
CONFIG_SCHED_TRACER=y
|
||||
CONFIG_FTRACE_SYSCALLS=y
|
||||
CONFIG_STACK_TRACER=y
|
||||
CONFIG_BLK_DEV_IO_TRACE=y
|
||||
CONFIG_UPROBE_EVENT=y
|
||||
CONFIG_LKDTM=m
|
||||
CONFIG_PERCPU_TEST=m
|
||||
CONFIG_ATOMIC64_SELFTEST=y
|
||||
# CONFIG_STRICT_DEVMEM is not set
|
||||
CONFIG_S390_PTDUMP=y
|
||||
CONFIG_ENCRYPTED_KEYS=m
|
||||
CONFIG_KEYS_DEBUG_PROC_KEYS=y
|
||||
CONFIG_SECURITY=y
|
||||
CONFIG_SECURITY_NETWORK=y
|
||||
CONFIG_SECURITY_SELINUX=y
|
||||
CONFIG_SECURITY_SELINUX_BOOTPARAM=y
|
||||
CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0
|
||||
CONFIG_SECURITY_SELINUX_DISABLE=y
|
||||
CONFIG_IMA=y
|
||||
CONFIG_IMA_APPRAISE=y
|
||||
CONFIG_CRYPTO_USER=m
|
||||
# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
|
||||
CONFIG_CRYPTO_CRYPTD=m
|
||||
CONFIG_CRYPTO_TEST=m
|
||||
CONFIG_CRYPTO_CCM=m
|
||||
CONFIG_CRYPTO_GCM=m
|
||||
CONFIG_CRYPTO_CTS=m
|
||||
CONFIG_CRYPTO_LRW=m
|
||||
CONFIG_CRYPTO_PCBC=m
|
||||
CONFIG_CRYPTO_XTS=m
|
||||
CONFIG_CRYPTO_XCBC=m
|
||||
CONFIG_CRYPTO_VMAC=m
|
||||
CONFIG_CRYPTO_CRC32=m
|
||||
CONFIG_CRYPTO_MICHAEL_MIC=m
|
||||
CONFIG_CRYPTO_RMD128=m
|
||||
CONFIG_CRYPTO_RMD160=m
|
||||
CONFIG_CRYPTO_RMD256=m
|
||||
CONFIG_CRYPTO_RMD320=m
|
||||
CONFIG_CRYPTO_SHA512=m
|
||||
CONFIG_CRYPTO_TGR192=m
|
||||
CONFIG_CRYPTO_WP512=m
|
||||
CONFIG_CRYPTO_ANUBIS=m
|
||||
CONFIG_CRYPTO_BLOWFISH=m
|
||||
CONFIG_CRYPTO_CAMELLIA=m
|
||||
CONFIG_CRYPTO_CAST5=m
|
||||
CONFIG_CRYPTO_CAST6=m
|
||||
CONFIG_CRYPTO_FCRYPT=m
|
||||
CONFIG_CRYPTO_KHAZAD=m
|
||||
CONFIG_CRYPTO_SALSA20=m
|
||||
CONFIG_CRYPTO_SEED=m
|
||||
CONFIG_CRYPTO_SERPENT=m
|
||||
CONFIG_CRYPTO_TEA=m
|
||||
CONFIG_CRYPTO_TWOFISH=m
|
||||
CONFIG_CRYPTO_ZLIB=y
|
||||
CONFIG_CRYPTO_LZO=m
|
||||
CONFIG_CRYPTO_LZ4=m
|
||||
CONFIG_CRYPTO_LZ4HC=m
|
||||
CONFIG_CRYPTO_USER_API_HASH=m
|
||||
CONFIG_CRYPTO_USER_API_SKCIPHER=m
|
||||
CONFIG_ZCRYPT=m
|
||||
CONFIG_CRYPTO_SHA1_S390=m
|
||||
CONFIG_CRYPTO_SHA256_S390=m
|
||||
CONFIG_CRYPTO_SHA512_S390=m
|
||||
CONFIG_CRYPTO_DES_S390=m
|
||||
CONFIG_CRYPTO_AES_S390=m
|
||||
CONFIG_CRYPTO_GHASH_S390=m
|
||||
CONFIG_ASYMMETRIC_KEY_TYPE=m
|
||||
CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m
|
||||
CONFIG_X509_CERTIFICATE_PARSER=m
|
||||
CONFIG_CRC7=m
|
||||
CONFIG_CRC8=m
|
||||
CONFIG_CORDIC=m
|
||||
CONFIG_CMM=m
|
||||
CONFIG_APPLDATA_BASE=y
|
||||
CONFIG_KVM=m
|
||||
CONFIG_KVM_S390_UCONTROL=y
|
||||
81
arch/s390/configs/zfcpdump_defconfig
Normal file
81
arch/s390/configs/zfcpdump_defconfig
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
# CONFIG_SWAP is not set
|
||||
CONFIG_NO_HZ=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_RCU_FAST_NO_HZ=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
CONFIG_PARTITION_ADVANCED=y
|
||||
CONFIG_IBM_PARTITION=y
|
||||
CONFIG_DEFAULT_DEADLINE=y
|
||||
CONFIG_MARCH_Z196=y
|
||||
CONFIG_TUNE_ZEC12=y
|
||||
# CONFIG_COMPAT is not set
|
||||
CONFIG_NR_CPUS=2
|
||||
# CONFIG_HOTPLUG_CPU is not set
|
||||
CONFIG_HZ_100=y
|
||||
# CONFIG_COMPACTION is not set
|
||||
# CONFIG_MIGRATION is not set
|
||||
# CONFIG_CHECK_STACK is not set
|
||||
# CONFIG_CHSC_SCH is not set
|
||||
# CONFIG_SCM_BUS is not set
|
||||
CONFIG_CRASH_DUMP=y
|
||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
|
||||
# CONFIG_SECCOMP is not set
|
||||
CONFIG_NET=y
|
||||
# CONFIG_IUCV is not set
|
||||
CONFIG_ATM=y
|
||||
CONFIG_ATM_LANE=y
|
||||
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
|
||||
CONFIG_DEVTMPFS=y
|
||||
# CONFIG_FIRMWARE_IN_KERNEL is not set
|
||||
# CONFIG_BLK_DEV_XPRAM is not set
|
||||
# CONFIG_DCSSBLK is not set
|
||||
# CONFIG_DASD is not set
|
||||
CONFIG_ENCLOSURE_SERVICES=y
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_SCSI_ENCLOSURE=y
|
||||
CONFIG_SCSI_CONSTANTS=y
|
||||
CONFIG_SCSI_LOGGING=y
|
||||
CONFIG_SCSI_FC_ATTRS=y
|
||||
CONFIG_SCSI_SRP_ATTRS=y
|
||||
CONFIG_ZFCP=y
|
||||
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
|
||||
# CONFIG_INPUT_KEYBOARD is not set
|
||||
# CONFIG_INPUT_MOUSE is not set
|
||||
# CONFIG_SERIO is not set
|
||||
# CONFIG_HVC_IUCV is not set
|
||||
CONFIG_RAW_DRIVER=y
|
||||
# CONFIG_SCLP_ASYNC is not set
|
||||
# CONFIG_HMC_DRV is not set
|
||||
# CONFIG_S390_TAPE is not set
|
||||
# CONFIG_VMCP is not set
|
||||
# CONFIG_MONWRITER is not set
|
||||
# CONFIG_S390_VMUR is not set
|
||||
# CONFIG_HID is not set
|
||||
CONFIG_MEMSTICK=y
|
||||
CONFIG_MEMSTICK_DEBUG=y
|
||||
CONFIG_MEMSTICK_UNSAFE_RESUME=y
|
||||
CONFIG_MSPRO_BLOCK=y
|
||||
# CONFIG_IOMMU_SUPPORT is not set
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT3_FS=y
|
||||
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
# CONFIG_INOTIFY_USER is not set
|
||||
CONFIG_CONFIGFS_FS=y
|
||||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_DEBUG_FS=y
|
||||
CONFIG_DEBUG_KERNEL=y
|
||||
# CONFIG_SCHED_DEBUG is not set
|
||||
CONFIG_RCU_CPU_STALL_TIMEOUT=60
|
||||
# CONFIG_FTRACE is not set
|
||||
# CONFIG_STRICT_DEVMEM is not set
|
||||
# CONFIG_PFAULT is not set
|
||||
# CONFIG_S390_HYPFS_FS is not set
|
||||
# CONFIG_VIRTUALIZATION is not set
|
||||
# CONFIG_S390_GUEST is not set
|
||||
11
arch/s390/crypto/Makefile
Normal file
11
arch/s390/crypto/Makefile
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#
|
||||
# Cryptographic API
|
||||
#
|
||||
|
||||
obj-$(CONFIG_CRYPTO_SHA1_S390) += sha1_s390.o sha_common.o
|
||||
obj-$(CONFIG_CRYPTO_SHA256_S390) += sha256_s390.o sha_common.o
|
||||
obj-$(CONFIG_CRYPTO_SHA512_S390) += sha512_s390.o sha_common.o
|
||||
obj-$(CONFIG_CRYPTO_DES_S390) += des_s390.o
|
||||
obj-$(CONFIG_CRYPTO_AES_S390) += aes_s390.o
|
||||
obj-$(CONFIG_S390_PRNG) += prng.o
|
||||
obj-$(CONFIG_CRYPTO_GHASH_S390) += ghash_s390.o
|
||||
985
arch/s390/crypto/aes_s390.c
Normal file
985
arch/s390/crypto/aes_s390.c
Normal file
|
|
@ -0,0 +1,985 @@
|
|||
/*
|
||||
* Cryptographic API.
|
||||
*
|
||||
* s390 implementation of the AES Cipher Algorithm.
|
||||
*
|
||||
* s390 Version:
|
||||
* Copyright IBM Corp. 2005, 2007
|
||||
* Author(s): Jan Glauber (jang@de.ibm.com)
|
||||
* Sebastian Siewior (sebastian@breakpoint.cc> SW-Fallback
|
||||
*
|
||||
* Derived from "crypto/aes_generic.c"
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#define KMSG_COMPONENT "aes_s390"
|
||||
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
|
||||
|
||||
#include <crypto/aes.h>
|
||||
#include <crypto/algapi.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include "crypt_s390.h"
|
||||
|
||||
#define AES_KEYLEN_128 1
|
||||
#define AES_KEYLEN_192 2
|
||||
#define AES_KEYLEN_256 4
|
||||
|
||||
static u8 *ctrblk;
|
||||
static DEFINE_SPINLOCK(ctrblk_lock);
|
||||
static char keylen_flag;
|
||||
|
||||
struct s390_aes_ctx {
|
||||
u8 key[AES_MAX_KEY_SIZE];
|
||||
long enc;
|
||||
long dec;
|
||||
int key_len;
|
||||
union {
|
||||
struct crypto_blkcipher *blk;
|
||||
struct crypto_cipher *cip;
|
||||
} fallback;
|
||||
};
|
||||
|
||||
struct pcc_param {
|
||||
u8 key[32];
|
||||
u8 tweak[16];
|
||||
u8 block[16];
|
||||
u8 bit[16];
|
||||
u8 xts[16];
|
||||
};
|
||||
|
||||
struct s390_xts_ctx {
|
||||
u8 key[32];
|
||||
u8 pcc_key[32];
|
||||
long enc;
|
||||
long dec;
|
||||
int key_len;
|
||||
struct crypto_blkcipher *fallback;
|
||||
};
|
||||
|
||||
/*
|
||||
* Check if the key_len is supported by the HW.
|
||||
* Returns 0 if it is, a positive number if it is not and software fallback is
|
||||
* required or a negative number in case the key size is not valid
|
||||
*/
|
||||
static int need_fallback(unsigned int key_len)
|
||||
{
|
||||
switch (key_len) {
|
||||
case 16:
|
||||
if (!(keylen_flag & AES_KEYLEN_128))
|
||||
return 1;
|
||||
break;
|
||||
case 24:
|
||||
if (!(keylen_flag & AES_KEYLEN_192))
|
||||
return 1;
|
||||
break;
|
||||
case 32:
|
||||
if (!(keylen_flag & AES_KEYLEN_256))
|
||||
return 1;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int setkey_fallback_cip(struct crypto_tfm *tfm, const u8 *in_key,
|
||||
unsigned int key_len)
|
||||
{
|
||||
struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
|
||||
int ret;
|
||||
|
||||
sctx->fallback.cip->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK;
|
||||
sctx->fallback.cip->base.crt_flags |= (tfm->crt_flags &
|
||||
CRYPTO_TFM_REQ_MASK);
|
||||
|
||||
ret = crypto_cipher_setkey(sctx->fallback.cip, in_key, key_len);
|
||||
if (ret) {
|
||||
tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK;
|
||||
tfm->crt_flags |= (sctx->fallback.cip->base.crt_flags &
|
||||
CRYPTO_TFM_RES_MASK);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
|
||||
unsigned int key_len)
|
||||
{
|
||||
struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
|
||||
u32 *flags = &tfm->crt_flags;
|
||||
int ret;
|
||||
|
||||
ret = need_fallback(key_len);
|
||||
if (ret < 0) {
|
||||
*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sctx->key_len = key_len;
|
||||
if (!ret) {
|
||||
memcpy(sctx->key, in_key, key_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return setkey_fallback_cip(tfm, in_key, key_len);
|
||||
}
|
||||
|
||||
static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
|
||||
{
|
||||
const struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
|
||||
|
||||
if (unlikely(need_fallback(sctx->key_len))) {
|
||||
crypto_cipher_encrypt_one(sctx->fallback.cip, out, in);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (sctx->key_len) {
|
||||
case 16:
|
||||
crypt_s390_km(KM_AES_128_ENCRYPT, &sctx->key, out, in,
|
||||
AES_BLOCK_SIZE);
|
||||
break;
|
||||
case 24:
|
||||
crypt_s390_km(KM_AES_192_ENCRYPT, &sctx->key, out, in,
|
||||
AES_BLOCK_SIZE);
|
||||
break;
|
||||
case 32:
|
||||
crypt_s390_km(KM_AES_256_ENCRYPT, &sctx->key, out, in,
|
||||
AES_BLOCK_SIZE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
|
||||
{
|
||||
const struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
|
||||
|
||||
if (unlikely(need_fallback(sctx->key_len))) {
|
||||
crypto_cipher_decrypt_one(sctx->fallback.cip, out, in);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (sctx->key_len) {
|
||||
case 16:
|
||||
crypt_s390_km(KM_AES_128_DECRYPT, &sctx->key, out, in,
|
||||
AES_BLOCK_SIZE);
|
||||
break;
|
||||
case 24:
|
||||
crypt_s390_km(KM_AES_192_DECRYPT, &sctx->key, out, in,
|
||||
AES_BLOCK_SIZE);
|
||||
break;
|
||||
case 32:
|
||||
crypt_s390_km(KM_AES_256_DECRYPT, &sctx->key, out, in,
|
||||
AES_BLOCK_SIZE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int fallback_init_cip(struct crypto_tfm *tfm)
|
||||
{
|
||||
const char *name = tfm->__crt_alg->cra_name;
|
||||
struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
|
||||
|
||||
sctx->fallback.cip = crypto_alloc_cipher(name, 0,
|
||||
CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK);
|
||||
|
||||
if (IS_ERR(sctx->fallback.cip)) {
|
||||
pr_err("Allocating AES fallback algorithm %s failed\n",
|
||||
name);
|
||||
return PTR_ERR(sctx->fallback.cip);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fallback_exit_cip(struct crypto_tfm *tfm)
|
||||
{
|
||||
struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
|
||||
|
||||
crypto_free_cipher(sctx->fallback.cip);
|
||||
sctx->fallback.cip = NULL;
|
||||
}
|
||||
|
||||
static struct crypto_alg aes_alg = {
|
||||
.cra_name = "aes",
|
||||
.cra_driver_name = "aes-s390",
|
||||
.cra_priority = CRYPT_S390_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_CIPHER |
|
||||
CRYPTO_ALG_NEED_FALLBACK,
|
||||
.cra_blocksize = AES_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct s390_aes_ctx),
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_init = fallback_init_cip,
|
||||
.cra_exit = fallback_exit_cip,
|
||||
.cra_u = {
|
||||
.cipher = {
|
||||
.cia_min_keysize = AES_MIN_KEY_SIZE,
|
||||
.cia_max_keysize = AES_MAX_KEY_SIZE,
|
||||
.cia_setkey = aes_set_key,
|
||||
.cia_encrypt = aes_encrypt,
|
||||
.cia_decrypt = aes_decrypt,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static int setkey_fallback_blk(struct crypto_tfm *tfm, const u8 *key,
|
||||
unsigned int len)
|
||||
{
|
||||
struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
|
||||
unsigned int ret;
|
||||
|
||||
sctx->fallback.blk->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK;
|
||||
sctx->fallback.blk->base.crt_flags |= (tfm->crt_flags &
|
||||
CRYPTO_TFM_REQ_MASK);
|
||||
|
||||
ret = crypto_blkcipher_setkey(sctx->fallback.blk, key, len);
|
||||
if (ret) {
|
||||
tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK;
|
||||
tfm->crt_flags |= (sctx->fallback.blk->base.crt_flags &
|
||||
CRYPTO_TFM_RES_MASK);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fallback_blk_dec(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
unsigned int ret;
|
||||
struct crypto_blkcipher *tfm;
|
||||
struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
|
||||
tfm = desc->tfm;
|
||||
desc->tfm = sctx->fallback.blk;
|
||||
|
||||
ret = crypto_blkcipher_decrypt_iv(desc, dst, src, nbytes);
|
||||
|
||||
desc->tfm = tfm;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fallback_blk_enc(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
unsigned int ret;
|
||||
struct crypto_blkcipher *tfm;
|
||||
struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
|
||||
tfm = desc->tfm;
|
||||
desc->tfm = sctx->fallback.blk;
|
||||
|
||||
ret = crypto_blkcipher_encrypt_iv(desc, dst, src, nbytes);
|
||||
|
||||
desc->tfm = tfm;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ecb_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
|
||||
unsigned int key_len)
|
||||
{
|
||||
struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
|
||||
int ret;
|
||||
|
||||
ret = need_fallback(key_len);
|
||||
if (ret > 0) {
|
||||
sctx->key_len = key_len;
|
||||
return setkey_fallback_blk(tfm, in_key, key_len);
|
||||
}
|
||||
|
||||
switch (key_len) {
|
||||
case 16:
|
||||
sctx->enc = KM_AES_128_ENCRYPT;
|
||||
sctx->dec = KM_AES_128_DECRYPT;
|
||||
break;
|
||||
case 24:
|
||||
sctx->enc = KM_AES_192_ENCRYPT;
|
||||
sctx->dec = KM_AES_192_DECRYPT;
|
||||
break;
|
||||
case 32:
|
||||
sctx->enc = KM_AES_256_ENCRYPT;
|
||||
sctx->dec = KM_AES_256_DECRYPT;
|
||||
break;
|
||||
}
|
||||
|
||||
return aes_set_key(tfm, in_key, key_len);
|
||||
}
|
||||
|
||||
static int ecb_aes_crypt(struct blkcipher_desc *desc, long func, void *param,
|
||||
struct blkcipher_walk *walk)
|
||||
{
|
||||
int ret = blkcipher_walk_virt(desc, walk);
|
||||
unsigned int nbytes;
|
||||
|
||||
while ((nbytes = walk->nbytes)) {
|
||||
/* only use complete blocks */
|
||||
unsigned int n = nbytes & ~(AES_BLOCK_SIZE - 1);
|
||||
u8 *out = walk->dst.virt.addr;
|
||||
u8 *in = walk->src.virt.addr;
|
||||
|
||||
ret = crypt_s390_km(func, param, out, in, n);
|
||||
if (ret < 0 || ret != n)
|
||||
return -EIO;
|
||||
|
||||
nbytes &= AES_BLOCK_SIZE - 1;
|
||||
ret = blkcipher_walk_done(desc, walk, nbytes);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ecb_aes_encrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
|
||||
if (unlikely(need_fallback(sctx->key_len)))
|
||||
return fallback_blk_enc(desc, dst, src, nbytes);
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
return ecb_aes_crypt(desc, sctx->enc, sctx->key, &walk);
|
||||
}
|
||||
|
||||
static int ecb_aes_decrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
|
||||
if (unlikely(need_fallback(sctx->key_len)))
|
||||
return fallback_blk_dec(desc, dst, src, nbytes);
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
return ecb_aes_crypt(desc, sctx->dec, sctx->key, &walk);
|
||||
}
|
||||
|
||||
static int fallback_init_blk(struct crypto_tfm *tfm)
|
||||
{
|
||||
const char *name = tfm->__crt_alg->cra_name;
|
||||
struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
|
||||
|
||||
sctx->fallback.blk = crypto_alloc_blkcipher(name, 0,
|
||||
CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK);
|
||||
|
||||
if (IS_ERR(sctx->fallback.blk)) {
|
||||
pr_err("Allocating AES fallback algorithm %s failed\n",
|
||||
name);
|
||||
return PTR_ERR(sctx->fallback.blk);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fallback_exit_blk(struct crypto_tfm *tfm)
|
||||
{
|
||||
struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
|
||||
|
||||
crypto_free_blkcipher(sctx->fallback.blk);
|
||||
sctx->fallback.blk = NULL;
|
||||
}
|
||||
|
||||
static struct crypto_alg ecb_aes_alg = {
|
||||
.cra_name = "ecb(aes)",
|
||||
.cra_driver_name = "ecb-aes-s390",
|
||||
.cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER |
|
||||
CRYPTO_ALG_NEED_FALLBACK,
|
||||
.cra_blocksize = AES_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct s390_aes_ctx),
|
||||
.cra_type = &crypto_blkcipher_type,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_init = fallback_init_blk,
|
||||
.cra_exit = fallback_exit_blk,
|
||||
.cra_u = {
|
||||
.blkcipher = {
|
||||
.min_keysize = AES_MIN_KEY_SIZE,
|
||||
.max_keysize = AES_MAX_KEY_SIZE,
|
||||
.setkey = ecb_aes_set_key,
|
||||
.encrypt = ecb_aes_encrypt,
|
||||
.decrypt = ecb_aes_decrypt,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static int cbc_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
|
||||
unsigned int key_len)
|
||||
{
|
||||
struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
|
||||
int ret;
|
||||
|
||||
ret = need_fallback(key_len);
|
||||
if (ret > 0) {
|
||||
sctx->key_len = key_len;
|
||||
return setkey_fallback_blk(tfm, in_key, key_len);
|
||||
}
|
||||
|
||||
switch (key_len) {
|
||||
case 16:
|
||||
sctx->enc = KMC_AES_128_ENCRYPT;
|
||||
sctx->dec = KMC_AES_128_DECRYPT;
|
||||
break;
|
||||
case 24:
|
||||
sctx->enc = KMC_AES_192_ENCRYPT;
|
||||
sctx->dec = KMC_AES_192_DECRYPT;
|
||||
break;
|
||||
case 32:
|
||||
sctx->enc = KMC_AES_256_ENCRYPT;
|
||||
sctx->dec = KMC_AES_256_DECRYPT;
|
||||
break;
|
||||
}
|
||||
|
||||
return aes_set_key(tfm, in_key, key_len);
|
||||
}
|
||||
|
||||
static int cbc_aes_crypt(struct blkcipher_desc *desc, long func,
|
||||
struct blkcipher_walk *walk)
|
||||
{
|
||||
struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
int ret = blkcipher_walk_virt(desc, walk);
|
||||
unsigned int nbytes = walk->nbytes;
|
||||
struct {
|
||||
u8 iv[AES_BLOCK_SIZE];
|
||||
u8 key[AES_MAX_KEY_SIZE];
|
||||
} param;
|
||||
|
||||
if (!nbytes)
|
||||
goto out;
|
||||
|
||||
memcpy(param.iv, walk->iv, AES_BLOCK_SIZE);
|
||||
memcpy(param.key, sctx->key, sctx->key_len);
|
||||
do {
|
||||
/* only use complete blocks */
|
||||
unsigned int n = nbytes & ~(AES_BLOCK_SIZE - 1);
|
||||
u8 *out = walk->dst.virt.addr;
|
||||
u8 *in = walk->src.virt.addr;
|
||||
|
||||
ret = crypt_s390_kmc(func, ¶m, out, in, n);
|
||||
if (ret < 0 || ret != n)
|
||||
return -EIO;
|
||||
|
||||
nbytes &= AES_BLOCK_SIZE - 1;
|
||||
ret = blkcipher_walk_done(desc, walk, nbytes);
|
||||
} while ((nbytes = walk->nbytes));
|
||||
memcpy(walk->iv, param.iv, AES_BLOCK_SIZE);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cbc_aes_encrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
|
||||
if (unlikely(need_fallback(sctx->key_len)))
|
||||
return fallback_blk_enc(desc, dst, src, nbytes);
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
return cbc_aes_crypt(desc, sctx->enc, &walk);
|
||||
}
|
||||
|
||||
static int cbc_aes_decrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
|
||||
if (unlikely(need_fallback(sctx->key_len)))
|
||||
return fallback_blk_dec(desc, dst, src, nbytes);
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
return cbc_aes_crypt(desc, sctx->dec, &walk);
|
||||
}
|
||||
|
||||
static struct crypto_alg cbc_aes_alg = {
|
||||
.cra_name = "cbc(aes)",
|
||||
.cra_driver_name = "cbc-aes-s390",
|
||||
.cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER |
|
||||
CRYPTO_ALG_NEED_FALLBACK,
|
||||
.cra_blocksize = AES_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct s390_aes_ctx),
|
||||
.cra_type = &crypto_blkcipher_type,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_init = fallback_init_blk,
|
||||
.cra_exit = fallback_exit_blk,
|
||||
.cra_u = {
|
||||
.blkcipher = {
|
||||
.min_keysize = AES_MIN_KEY_SIZE,
|
||||
.max_keysize = AES_MAX_KEY_SIZE,
|
||||
.ivsize = AES_BLOCK_SIZE,
|
||||
.setkey = cbc_aes_set_key,
|
||||
.encrypt = cbc_aes_encrypt,
|
||||
.decrypt = cbc_aes_decrypt,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static int xts_fallback_setkey(struct crypto_tfm *tfm, const u8 *key,
|
||||
unsigned int len)
|
||||
{
|
||||
struct s390_xts_ctx *xts_ctx = crypto_tfm_ctx(tfm);
|
||||
unsigned int ret;
|
||||
|
||||
xts_ctx->fallback->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK;
|
||||
xts_ctx->fallback->base.crt_flags |= (tfm->crt_flags &
|
||||
CRYPTO_TFM_REQ_MASK);
|
||||
|
||||
ret = crypto_blkcipher_setkey(xts_ctx->fallback, key, len);
|
||||
if (ret) {
|
||||
tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK;
|
||||
tfm->crt_flags |= (xts_ctx->fallback->base.crt_flags &
|
||||
CRYPTO_TFM_RES_MASK);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int xts_fallback_decrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct s390_xts_ctx *xts_ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct crypto_blkcipher *tfm;
|
||||
unsigned int ret;
|
||||
|
||||
tfm = desc->tfm;
|
||||
desc->tfm = xts_ctx->fallback;
|
||||
|
||||
ret = crypto_blkcipher_decrypt_iv(desc, dst, src, nbytes);
|
||||
|
||||
desc->tfm = tfm;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int xts_fallback_encrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct s390_xts_ctx *xts_ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct crypto_blkcipher *tfm;
|
||||
unsigned int ret;
|
||||
|
||||
tfm = desc->tfm;
|
||||
desc->tfm = xts_ctx->fallback;
|
||||
|
||||
ret = crypto_blkcipher_encrypt_iv(desc, dst, src, nbytes);
|
||||
|
||||
desc->tfm = tfm;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int xts_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
|
||||
unsigned int key_len)
|
||||
{
|
||||
struct s390_xts_ctx *xts_ctx = crypto_tfm_ctx(tfm);
|
||||
u32 *flags = &tfm->crt_flags;
|
||||
|
||||
switch (key_len) {
|
||||
case 32:
|
||||
xts_ctx->enc = KM_XTS_128_ENCRYPT;
|
||||
xts_ctx->dec = KM_XTS_128_DECRYPT;
|
||||
memcpy(xts_ctx->key + 16, in_key, 16);
|
||||
memcpy(xts_ctx->pcc_key + 16, in_key + 16, 16);
|
||||
break;
|
||||
case 48:
|
||||
xts_ctx->enc = 0;
|
||||
xts_ctx->dec = 0;
|
||||
xts_fallback_setkey(tfm, in_key, key_len);
|
||||
break;
|
||||
case 64:
|
||||
xts_ctx->enc = KM_XTS_256_ENCRYPT;
|
||||
xts_ctx->dec = KM_XTS_256_DECRYPT;
|
||||
memcpy(xts_ctx->key, in_key, 32);
|
||||
memcpy(xts_ctx->pcc_key, in_key + 32, 32);
|
||||
break;
|
||||
default:
|
||||
*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
|
||||
return -EINVAL;
|
||||
}
|
||||
xts_ctx->key_len = key_len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xts_aes_crypt(struct blkcipher_desc *desc, long func,
|
||||
struct s390_xts_ctx *xts_ctx,
|
||||
struct blkcipher_walk *walk)
|
||||
{
|
||||
unsigned int offset = (xts_ctx->key_len >> 1) & 0x10;
|
||||
int ret = blkcipher_walk_virt(desc, walk);
|
||||
unsigned int nbytes = walk->nbytes;
|
||||
unsigned int n;
|
||||
u8 *in, *out;
|
||||
struct pcc_param pcc_param;
|
||||
struct {
|
||||
u8 key[32];
|
||||
u8 init[16];
|
||||
} xts_param;
|
||||
|
||||
if (!nbytes)
|
||||
goto out;
|
||||
|
||||
memset(pcc_param.block, 0, sizeof(pcc_param.block));
|
||||
memset(pcc_param.bit, 0, sizeof(pcc_param.bit));
|
||||
memset(pcc_param.xts, 0, sizeof(pcc_param.xts));
|
||||
memcpy(pcc_param.tweak, walk->iv, sizeof(pcc_param.tweak));
|
||||
memcpy(pcc_param.key, xts_ctx->pcc_key, 32);
|
||||
ret = crypt_s390_pcc(func, &pcc_param.key[offset]);
|
||||
if (ret < 0)
|
||||
return -EIO;
|
||||
|
||||
memcpy(xts_param.key, xts_ctx->key, 32);
|
||||
memcpy(xts_param.init, pcc_param.xts, 16);
|
||||
do {
|
||||
/* only use complete blocks */
|
||||
n = nbytes & ~(AES_BLOCK_SIZE - 1);
|
||||
out = walk->dst.virt.addr;
|
||||
in = walk->src.virt.addr;
|
||||
|
||||
ret = crypt_s390_km(func, &xts_param.key[offset], out, in, n);
|
||||
if (ret < 0 || ret != n)
|
||||
return -EIO;
|
||||
|
||||
nbytes &= AES_BLOCK_SIZE - 1;
|
||||
ret = blkcipher_walk_done(desc, walk, nbytes);
|
||||
} while ((nbytes = walk->nbytes));
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int xts_aes_encrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct s390_xts_ctx *xts_ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
|
||||
if (unlikely(xts_ctx->key_len == 48))
|
||||
return xts_fallback_encrypt(desc, dst, src, nbytes);
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
return xts_aes_crypt(desc, xts_ctx->enc, xts_ctx, &walk);
|
||||
}
|
||||
|
||||
static int xts_aes_decrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct s390_xts_ctx *xts_ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
|
||||
if (unlikely(xts_ctx->key_len == 48))
|
||||
return xts_fallback_decrypt(desc, dst, src, nbytes);
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
return xts_aes_crypt(desc, xts_ctx->dec, xts_ctx, &walk);
|
||||
}
|
||||
|
||||
static int xts_fallback_init(struct crypto_tfm *tfm)
|
||||
{
|
||||
const char *name = tfm->__crt_alg->cra_name;
|
||||
struct s390_xts_ctx *xts_ctx = crypto_tfm_ctx(tfm);
|
||||
|
||||
xts_ctx->fallback = crypto_alloc_blkcipher(name, 0,
|
||||
CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK);
|
||||
|
||||
if (IS_ERR(xts_ctx->fallback)) {
|
||||
pr_err("Allocating XTS fallback algorithm %s failed\n",
|
||||
name);
|
||||
return PTR_ERR(xts_ctx->fallback);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void xts_fallback_exit(struct crypto_tfm *tfm)
|
||||
{
|
||||
struct s390_xts_ctx *xts_ctx = crypto_tfm_ctx(tfm);
|
||||
|
||||
crypto_free_blkcipher(xts_ctx->fallback);
|
||||
xts_ctx->fallback = NULL;
|
||||
}
|
||||
|
||||
static struct crypto_alg xts_aes_alg = {
|
||||
.cra_name = "xts(aes)",
|
||||
.cra_driver_name = "xts-aes-s390",
|
||||
.cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER |
|
||||
CRYPTO_ALG_NEED_FALLBACK,
|
||||
.cra_blocksize = AES_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct s390_xts_ctx),
|
||||
.cra_type = &crypto_blkcipher_type,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_init = xts_fallback_init,
|
||||
.cra_exit = xts_fallback_exit,
|
||||
.cra_u = {
|
||||
.blkcipher = {
|
||||
.min_keysize = 2 * AES_MIN_KEY_SIZE,
|
||||
.max_keysize = 2 * AES_MAX_KEY_SIZE,
|
||||
.ivsize = AES_BLOCK_SIZE,
|
||||
.setkey = xts_aes_set_key,
|
||||
.encrypt = xts_aes_encrypt,
|
||||
.decrypt = xts_aes_decrypt,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static int xts_aes_alg_reg;
|
||||
|
||||
static int ctr_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
|
||||
unsigned int key_len)
|
||||
{
|
||||
struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
|
||||
|
||||
switch (key_len) {
|
||||
case 16:
|
||||
sctx->enc = KMCTR_AES_128_ENCRYPT;
|
||||
sctx->dec = KMCTR_AES_128_DECRYPT;
|
||||
break;
|
||||
case 24:
|
||||
sctx->enc = KMCTR_AES_192_ENCRYPT;
|
||||
sctx->dec = KMCTR_AES_192_DECRYPT;
|
||||
break;
|
||||
case 32:
|
||||
sctx->enc = KMCTR_AES_256_ENCRYPT;
|
||||
sctx->dec = KMCTR_AES_256_DECRYPT;
|
||||
break;
|
||||
}
|
||||
|
||||
return aes_set_key(tfm, in_key, key_len);
|
||||
}
|
||||
|
||||
static unsigned int __ctrblk_init(u8 *ctrptr, unsigned int nbytes)
|
||||
{
|
||||
unsigned int i, n;
|
||||
|
||||
/* only use complete blocks, max. PAGE_SIZE */
|
||||
n = (nbytes > PAGE_SIZE) ? PAGE_SIZE : nbytes & ~(AES_BLOCK_SIZE - 1);
|
||||
for (i = AES_BLOCK_SIZE; i < n; i += AES_BLOCK_SIZE) {
|
||||
memcpy(ctrptr + i, ctrptr + i - AES_BLOCK_SIZE,
|
||||
AES_BLOCK_SIZE);
|
||||
crypto_inc(ctrptr + i, AES_BLOCK_SIZE);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
static int ctr_aes_crypt(struct blkcipher_desc *desc, long func,
|
||||
struct s390_aes_ctx *sctx, struct blkcipher_walk *walk)
|
||||
{
|
||||
int ret = blkcipher_walk_virt_block(desc, walk, AES_BLOCK_SIZE);
|
||||
unsigned int n, nbytes;
|
||||
u8 buf[AES_BLOCK_SIZE], ctrbuf[AES_BLOCK_SIZE];
|
||||
u8 *out, *in, *ctrptr = ctrbuf;
|
||||
|
||||
if (!walk->nbytes)
|
||||
return ret;
|
||||
|
||||
if (spin_trylock(&ctrblk_lock))
|
||||
ctrptr = ctrblk;
|
||||
|
||||
memcpy(ctrptr, walk->iv, AES_BLOCK_SIZE);
|
||||
while ((nbytes = walk->nbytes) >= AES_BLOCK_SIZE) {
|
||||
out = walk->dst.virt.addr;
|
||||
in = walk->src.virt.addr;
|
||||
while (nbytes >= AES_BLOCK_SIZE) {
|
||||
if (ctrptr == ctrblk)
|
||||
n = __ctrblk_init(ctrptr, nbytes);
|
||||
else
|
||||
n = AES_BLOCK_SIZE;
|
||||
ret = crypt_s390_kmctr(func, sctx->key, out, in,
|
||||
n, ctrptr);
|
||||
if (ret < 0 || ret != n) {
|
||||
if (ctrptr == ctrblk)
|
||||
spin_unlock(&ctrblk_lock);
|
||||
return -EIO;
|
||||
}
|
||||
if (n > AES_BLOCK_SIZE)
|
||||
memcpy(ctrptr, ctrptr + n - AES_BLOCK_SIZE,
|
||||
AES_BLOCK_SIZE);
|
||||
crypto_inc(ctrptr, AES_BLOCK_SIZE);
|
||||
out += n;
|
||||
in += n;
|
||||
nbytes -= n;
|
||||
}
|
||||
ret = blkcipher_walk_done(desc, walk, nbytes);
|
||||
}
|
||||
if (ctrptr == ctrblk) {
|
||||
if (nbytes)
|
||||
memcpy(ctrbuf, ctrptr, AES_BLOCK_SIZE);
|
||||
else
|
||||
memcpy(walk->iv, ctrptr, AES_BLOCK_SIZE);
|
||||
spin_unlock(&ctrblk_lock);
|
||||
} else {
|
||||
if (!nbytes)
|
||||
memcpy(walk->iv, ctrptr, AES_BLOCK_SIZE);
|
||||
}
|
||||
/*
|
||||
* final block may be < AES_BLOCK_SIZE, copy only nbytes
|
||||
*/
|
||||
if (nbytes) {
|
||||
out = walk->dst.virt.addr;
|
||||
in = walk->src.virt.addr;
|
||||
ret = crypt_s390_kmctr(func, sctx->key, buf, in,
|
||||
AES_BLOCK_SIZE, ctrbuf);
|
||||
if (ret < 0 || ret != AES_BLOCK_SIZE)
|
||||
return -EIO;
|
||||
memcpy(out, buf, nbytes);
|
||||
crypto_inc(ctrbuf, AES_BLOCK_SIZE);
|
||||
ret = blkcipher_walk_done(desc, walk, 0);
|
||||
memcpy(walk->iv, ctrbuf, AES_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ctr_aes_encrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
return ctr_aes_crypt(desc, sctx->enc, sctx, &walk);
|
||||
}
|
||||
|
||||
static int ctr_aes_decrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
return ctr_aes_crypt(desc, sctx->dec, sctx, &walk);
|
||||
}
|
||||
|
||||
static struct crypto_alg ctr_aes_alg = {
|
||||
.cra_name = "ctr(aes)",
|
||||
.cra_driver_name = "ctr-aes-s390",
|
||||
.cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||
.cra_blocksize = 1,
|
||||
.cra_ctxsize = sizeof(struct s390_aes_ctx),
|
||||
.cra_type = &crypto_blkcipher_type,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_u = {
|
||||
.blkcipher = {
|
||||
.min_keysize = AES_MIN_KEY_SIZE,
|
||||
.max_keysize = AES_MAX_KEY_SIZE,
|
||||
.ivsize = AES_BLOCK_SIZE,
|
||||
.setkey = ctr_aes_set_key,
|
||||
.encrypt = ctr_aes_encrypt,
|
||||
.decrypt = ctr_aes_decrypt,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static int ctr_aes_alg_reg;
|
||||
|
||||
static int __init aes_s390_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (crypt_s390_func_available(KM_AES_128_ENCRYPT, CRYPT_S390_MSA))
|
||||
keylen_flag |= AES_KEYLEN_128;
|
||||
if (crypt_s390_func_available(KM_AES_192_ENCRYPT, CRYPT_S390_MSA))
|
||||
keylen_flag |= AES_KEYLEN_192;
|
||||
if (crypt_s390_func_available(KM_AES_256_ENCRYPT, CRYPT_S390_MSA))
|
||||
keylen_flag |= AES_KEYLEN_256;
|
||||
|
||||
if (!keylen_flag)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* z9 109 and z9 BC/EC only support 128 bit key length */
|
||||
if (keylen_flag == AES_KEYLEN_128)
|
||||
pr_info("AES hardware acceleration is only available for"
|
||||
" 128-bit keys\n");
|
||||
|
||||
ret = crypto_register_alg(&aes_alg);
|
||||
if (ret)
|
||||
goto aes_err;
|
||||
|
||||
ret = crypto_register_alg(&ecb_aes_alg);
|
||||
if (ret)
|
||||
goto ecb_aes_err;
|
||||
|
||||
ret = crypto_register_alg(&cbc_aes_alg);
|
||||
if (ret)
|
||||
goto cbc_aes_err;
|
||||
|
||||
if (crypt_s390_func_available(KM_XTS_128_ENCRYPT,
|
||||
CRYPT_S390_MSA | CRYPT_S390_MSA4) &&
|
||||
crypt_s390_func_available(KM_XTS_256_ENCRYPT,
|
||||
CRYPT_S390_MSA | CRYPT_S390_MSA4)) {
|
||||
ret = crypto_register_alg(&xts_aes_alg);
|
||||
if (ret)
|
||||
goto xts_aes_err;
|
||||
xts_aes_alg_reg = 1;
|
||||
}
|
||||
|
||||
if (crypt_s390_func_available(KMCTR_AES_128_ENCRYPT,
|
||||
CRYPT_S390_MSA | CRYPT_S390_MSA4) &&
|
||||
crypt_s390_func_available(KMCTR_AES_192_ENCRYPT,
|
||||
CRYPT_S390_MSA | CRYPT_S390_MSA4) &&
|
||||
crypt_s390_func_available(KMCTR_AES_256_ENCRYPT,
|
||||
CRYPT_S390_MSA | CRYPT_S390_MSA4)) {
|
||||
ctrblk = (u8 *) __get_free_page(GFP_KERNEL);
|
||||
if (!ctrblk) {
|
||||
ret = -ENOMEM;
|
||||
goto ctr_aes_err;
|
||||
}
|
||||
ret = crypto_register_alg(&ctr_aes_alg);
|
||||
if (ret) {
|
||||
free_page((unsigned long) ctrblk);
|
||||
goto ctr_aes_err;
|
||||
}
|
||||
ctr_aes_alg_reg = 1;
|
||||
}
|
||||
|
||||
out:
|
||||
return ret;
|
||||
|
||||
ctr_aes_err:
|
||||
crypto_unregister_alg(&xts_aes_alg);
|
||||
xts_aes_err:
|
||||
crypto_unregister_alg(&cbc_aes_alg);
|
||||
cbc_aes_err:
|
||||
crypto_unregister_alg(&ecb_aes_alg);
|
||||
ecb_aes_err:
|
||||
crypto_unregister_alg(&aes_alg);
|
||||
aes_err:
|
||||
goto out;
|
||||
}
|
||||
|
||||
static void __exit aes_s390_fini(void)
|
||||
{
|
||||
if (ctr_aes_alg_reg) {
|
||||
crypto_unregister_alg(&ctr_aes_alg);
|
||||
free_page((unsigned long) ctrblk);
|
||||
}
|
||||
if (xts_aes_alg_reg)
|
||||
crypto_unregister_alg(&xts_aes_alg);
|
||||
crypto_unregister_alg(&cbc_aes_alg);
|
||||
crypto_unregister_alg(&ecb_aes_alg);
|
||||
crypto_unregister_alg(&aes_alg);
|
||||
}
|
||||
|
||||
module_init(aes_s390_init);
|
||||
module_exit(aes_s390_fini);
|
||||
|
||||
MODULE_ALIAS_CRYPTO("aes-all");
|
||||
|
||||
MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm");
|
||||
MODULE_LICENSE("GPL");
|
||||
437
arch/s390/crypto/crypt_s390.h
Normal file
437
arch/s390/crypto/crypt_s390.h
Normal file
|
|
@ -0,0 +1,437 @@
|
|||
/*
|
||||
* Cryptographic API.
|
||||
*
|
||||
* Support for s390 cryptographic instructions.
|
||||
*
|
||||
* Copyright IBM Corp. 2003, 2007
|
||||
* Author(s): Thomas Spatzier
|
||||
* Jan Glauber (jan.glauber@de.ibm.com)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#ifndef _CRYPTO_ARCH_S390_CRYPT_S390_H
|
||||
#define _CRYPTO_ARCH_S390_CRYPT_S390_H
|
||||
|
||||
#include <asm/errno.h>
|
||||
#include <asm/facility.h>
|
||||
|
||||
#define CRYPT_S390_OP_MASK 0xFF00
|
||||
#define CRYPT_S390_FUNC_MASK 0x00FF
|
||||
|
||||
#define CRYPT_S390_PRIORITY 300
|
||||
#define CRYPT_S390_COMPOSITE_PRIORITY 400
|
||||
|
||||
#define CRYPT_S390_MSA 0x1
|
||||
#define CRYPT_S390_MSA3 0x2
|
||||
#define CRYPT_S390_MSA4 0x4
|
||||
|
||||
/* s390 cryptographic operations */
|
||||
enum crypt_s390_operations {
|
||||
CRYPT_S390_KM = 0x0100,
|
||||
CRYPT_S390_KMC = 0x0200,
|
||||
CRYPT_S390_KIMD = 0x0300,
|
||||
CRYPT_S390_KLMD = 0x0400,
|
||||
CRYPT_S390_KMAC = 0x0500,
|
||||
CRYPT_S390_KMCTR = 0x0600
|
||||
};
|
||||
|
||||
/*
|
||||
* function codes for KM (CIPHER MESSAGE) instruction
|
||||
* 0x80 is the decipher modifier bit
|
||||
*/
|
||||
enum crypt_s390_km_func {
|
||||
KM_QUERY = CRYPT_S390_KM | 0x0,
|
||||
KM_DEA_ENCRYPT = CRYPT_S390_KM | 0x1,
|
||||
KM_DEA_DECRYPT = CRYPT_S390_KM | 0x1 | 0x80,
|
||||
KM_TDEA_128_ENCRYPT = CRYPT_S390_KM | 0x2,
|
||||
KM_TDEA_128_DECRYPT = CRYPT_S390_KM | 0x2 | 0x80,
|
||||
KM_TDEA_192_ENCRYPT = CRYPT_S390_KM | 0x3,
|
||||
KM_TDEA_192_DECRYPT = CRYPT_S390_KM | 0x3 | 0x80,
|
||||
KM_AES_128_ENCRYPT = CRYPT_S390_KM | 0x12,
|
||||
KM_AES_128_DECRYPT = CRYPT_S390_KM | 0x12 | 0x80,
|
||||
KM_AES_192_ENCRYPT = CRYPT_S390_KM | 0x13,
|
||||
KM_AES_192_DECRYPT = CRYPT_S390_KM | 0x13 | 0x80,
|
||||
KM_AES_256_ENCRYPT = CRYPT_S390_KM | 0x14,
|
||||
KM_AES_256_DECRYPT = CRYPT_S390_KM | 0x14 | 0x80,
|
||||
KM_XTS_128_ENCRYPT = CRYPT_S390_KM | 0x32,
|
||||
KM_XTS_128_DECRYPT = CRYPT_S390_KM | 0x32 | 0x80,
|
||||
KM_XTS_256_ENCRYPT = CRYPT_S390_KM | 0x34,
|
||||
KM_XTS_256_DECRYPT = CRYPT_S390_KM | 0x34 | 0x80,
|
||||
};
|
||||
|
||||
/*
|
||||
* function codes for KMC (CIPHER MESSAGE WITH CHAINING)
|
||||
* instruction
|
||||
*/
|
||||
enum crypt_s390_kmc_func {
|
||||
KMC_QUERY = CRYPT_S390_KMC | 0x0,
|
||||
KMC_DEA_ENCRYPT = CRYPT_S390_KMC | 0x1,
|
||||
KMC_DEA_DECRYPT = CRYPT_S390_KMC | 0x1 | 0x80,
|
||||
KMC_TDEA_128_ENCRYPT = CRYPT_S390_KMC | 0x2,
|
||||
KMC_TDEA_128_DECRYPT = CRYPT_S390_KMC | 0x2 | 0x80,
|
||||
KMC_TDEA_192_ENCRYPT = CRYPT_S390_KMC | 0x3,
|
||||
KMC_TDEA_192_DECRYPT = CRYPT_S390_KMC | 0x3 | 0x80,
|
||||
KMC_AES_128_ENCRYPT = CRYPT_S390_KMC | 0x12,
|
||||
KMC_AES_128_DECRYPT = CRYPT_S390_KMC | 0x12 | 0x80,
|
||||
KMC_AES_192_ENCRYPT = CRYPT_S390_KMC | 0x13,
|
||||
KMC_AES_192_DECRYPT = CRYPT_S390_KMC | 0x13 | 0x80,
|
||||
KMC_AES_256_ENCRYPT = CRYPT_S390_KMC | 0x14,
|
||||
KMC_AES_256_DECRYPT = CRYPT_S390_KMC | 0x14 | 0x80,
|
||||
KMC_PRNG = CRYPT_S390_KMC | 0x43,
|
||||
};
|
||||
|
||||
/*
|
||||
* function codes for KMCTR (CIPHER MESSAGE WITH COUNTER)
|
||||
* instruction
|
||||
*/
|
||||
enum crypt_s390_kmctr_func {
|
||||
KMCTR_QUERY = CRYPT_S390_KMCTR | 0x0,
|
||||
KMCTR_DEA_ENCRYPT = CRYPT_S390_KMCTR | 0x1,
|
||||
KMCTR_DEA_DECRYPT = CRYPT_S390_KMCTR | 0x1 | 0x80,
|
||||
KMCTR_TDEA_128_ENCRYPT = CRYPT_S390_KMCTR | 0x2,
|
||||
KMCTR_TDEA_128_DECRYPT = CRYPT_S390_KMCTR | 0x2 | 0x80,
|
||||
KMCTR_TDEA_192_ENCRYPT = CRYPT_S390_KMCTR | 0x3,
|
||||
KMCTR_TDEA_192_DECRYPT = CRYPT_S390_KMCTR | 0x3 | 0x80,
|
||||
KMCTR_AES_128_ENCRYPT = CRYPT_S390_KMCTR | 0x12,
|
||||
KMCTR_AES_128_DECRYPT = CRYPT_S390_KMCTR | 0x12 | 0x80,
|
||||
KMCTR_AES_192_ENCRYPT = CRYPT_S390_KMCTR | 0x13,
|
||||
KMCTR_AES_192_DECRYPT = CRYPT_S390_KMCTR | 0x13 | 0x80,
|
||||
KMCTR_AES_256_ENCRYPT = CRYPT_S390_KMCTR | 0x14,
|
||||
KMCTR_AES_256_DECRYPT = CRYPT_S390_KMCTR | 0x14 | 0x80,
|
||||
};
|
||||
|
||||
/*
|
||||
* function codes for KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST)
|
||||
* instruction
|
||||
*/
|
||||
enum crypt_s390_kimd_func {
|
||||
KIMD_QUERY = CRYPT_S390_KIMD | 0,
|
||||
KIMD_SHA_1 = CRYPT_S390_KIMD | 1,
|
||||
KIMD_SHA_256 = CRYPT_S390_KIMD | 2,
|
||||
KIMD_SHA_512 = CRYPT_S390_KIMD | 3,
|
||||
KIMD_GHASH = CRYPT_S390_KIMD | 65,
|
||||
};
|
||||
|
||||
/*
|
||||
* function codes for KLMD (COMPUTE LAST MESSAGE DIGEST)
|
||||
* instruction
|
||||
*/
|
||||
enum crypt_s390_klmd_func {
|
||||
KLMD_QUERY = CRYPT_S390_KLMD | 0,
|
||||
KLMD_SHA_1 = CRYPT_S390_KLMD | 1,
|
||||
KLMD_SHA_256 = CRYPT_S390_KLMD | 2,
|
||||
KLMD_SHA_512 = CRYPT_S390_KLMD | 3,
|
||||
};
|
||||
|
||||
/*
|
||||
* function codes for KMAC (COMPUTE MESSAGE AUTHENTICATION CODE)
|
||||
* instruction
|
||||
*/
|
||||
enum crypt_s390_kmac_func {
|
||||
KMAC_QUERY = CRYPT_S390_KMAC | 0,
|
||||
KMAC_DEA = CRYPT_S390_KMAC | 1,
|
||||
KMAC_TDEA_128 = CRYPT_S390_KMAC | 2,
|
||||
KMAC_TDEA_192 = CRYPT_S390_KMAC | 3
|
||||
};
|
||||
|
||||
/**
|
||||
* crypt_s390_km:
|
||||
* @func: the function code passed to KM; see crypt_s390_km_func
|
||||
* @param: address of parameter block; see POP for details on each func
|
||||
* @dest: address of destination memory area
|
||||
* @src: address of source memory area
|
||||
* @src_len: length of src operand in bytes
|
||||
*
|
||||
* Executes the KM (CIPHER MESSAGE) operation of the CPU.
|
||||
*
|
||||
* Returns -1 for failure, 0 for the query func, number of processed
|
||||
* bytes for encryption/decryption funcs
|
||||
*/
|
||||
static inline int crypt_s390_km(long func, void *param,
|
||||
u8 *dest, const u8 *src, long src_len)
|
||||
{
|
||||
register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
|
||||
register void *__param asm("1") = param;
|
||||
register const u8 *__src asm("2") = src;
|
||||
register long __src_len asm("3") = src_len;
|
||||
register u8 *__dest asm("4") = dest;
|
||||
int ret;
|
||||
|
||||
asm volatile(
|
||||
"0: .insn rre,0xb92e0000,%3,%1 \n" /* KM opcode */
|
||||
"1: brc 1,0b \n" /* handle partial completion */
|
||||
" la %0,0\n"
|
||||
"2:\n"
|
||||
EX_TABLE(0b,2b) EX_TABLE(1b,2b)
|
||||
: "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest)
|
||||
: "d" (__func), "a" (__param), "0" (-1) : "cc", "memory");
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* crypt_s390_kmc:
|
||||
* @func: the function code passed to KM; see crypt_s390_kmc_func
|
||||
* @param: address of parameter block; see POP for details on each func
|
||||
* @dest: address of destination memory area
|
||||
* @src: address of source memory area
|
||||
* @src_len: length of src operand in bytes
|
||||
*
|
||||
* Executes the KMC (CIPHER MESSAGE WITH CHAINING) operation of the CPU.
|
||||
*
|
||||
* Returns -1 for failure, 0 for the query func, number of processed
|
||||
* bytes for encryption/decryption funcs
|
||||
*/
|
||||
static inline int crypt_s390_kmc(long func, void *param,
|
||||
u8 *dest, const u8 *src, long src_len)
|
||||
{
|
||||
register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
|
||||
register void *__param asm("1") = param;
|
||||
register const u8 *__src asm("2") = src;
|
||||
register long __src_len asm("3") = src_len;
|
||||
register u8 *__dest asm("4") = dest;
|
||||
int ret;
|
||||
|
||||
asm volatile(
|
||||
"0: .insn rre,0xb92f0000,%3,%1 \n" /* KMC opcode */
|
||||
"1: brc 1,0b \n" /* handle partial completion */
|
||||
" la %0,0\n"
|
||||
"2:\n"
|
||||
EX_TABLE(0b,2b) EX_TABLE(1b,2b)
|
||||
: "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest)
|
||||
: "d" (__func), "a" (__param), "0" (-1) : "cc", "memory");
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* crypt_s390_kimd:
|
||||
* @func: the function code passed to KM; see crypt_s390_kimd_func
|
||||
* @param: address of parameter block; see POP for details on each func
|
||||
* @src: address of source memory area
|
||||
* @src_len: length of src operand in bytes
|
||||
*
|
||||
* Executes the KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) operation
|
||||
* of the CPU.
|
||||
*
|
||||
* Returns -1 for failure, 0 for the query func, number of processed
|
||||
* bytes for digest funcs
|
||||
*/
|
||||
static inline int crypt_s390_kimd(long func, void *param,
|
||||
const u8 *src, long src_len)
|
||||
{
|
||||
register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
|
||||
register void *__param asm("1") = param;
|
||||
register const u8 *__src asm("2") = src;
|
||||
register long __src_len asm("3") = src_len;
|
||||
int ret;
|
||||
|
||||
asm volatile(
|
||||
"0: .insn rre,0xb93e0000,%1,%1 \n" /* KIMD opcode */
|
||||
"1: brc 1,0b \n" /* handle partial completion */
|
||||
" la %0,0\n"
|
||||
"2:\n"
|
||||
EX_TABLE(0b,2b) EX_TABLE(1b,2b)
|
||||
: "=d" (ret), "+a" (__src), "+d" (__src_len)
|
||||
: "d" (__func), "a" (__param), "0" (-1) : "cc", "memory");
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* crypt_s390_klmd:
|
||||
* @func: the function code passed to KM; see crypt_s390_klmd_func
|
||||
* @param: address of parameter block; see POP for details on each func
|
||||
* @src: address of source memory area
|
||||
* @src_len: length of src operand in bytes
|
||||
*
|
||||
* Executes the KLMD (COMPUTE LAST MESSAGE DIGEST) operation of the CPU.
|
||||
*
|
||||
* Returns -1 for failure, 0 for the query func, number of processed
|
||||
* bytes for digest funcs
|
||||
*/
|
||||
static inline int crypt_s390_klmd(long func, void *param,
|
||||
const u8 *src, long src_len)
|
||||
{
|
||||
register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
|
||||
register void *__param asm("1") = param;
|
||||
register const u8 *__src asm("2") = src;
|
||||
register long __src_len asm("3") = src_len;
|
||||
int ret;
|
||||
|
||||
asm volatile(
|
||||
"0: .insn rre,0xb93f0000,%1,%1 \n" /* KLMD opcode */
|
||||
"1: brc 1,0b \n" /* handle partial completion */
|
||||
" la %0,0\n"
|
||||
"2:\n"
|
||||
EX_TABLE(0b,2b) EX_TABLE(1b,2b)
|
||||
: "=d" (ret), "+a" (__src), "+d" (__src_len)
|
||||
: "d" (__func), "a" (__param), "0" (-1) : "cc", "memory");
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* crypt_s390_kmac:
|
||||
* @func: the function code passed to KM; see crypt_s390_klmd_func
|
||||
* @param: address of parameter block; see POP for details on each func
|
||||
* @src: address of source memory area
|
||||
* @src_len: length of src operand in bytes
|
||||
*
|
||||
* Executes the KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) operation
|
||||
* of the CPU.
|
||||
*
|
||||
* Returns -1 for failure, 0 for the query func, number of processed
|
||||
* bytes for digest funcs
|
||||
*/
|
||||
static inline int crypt_s390_kmac(long func, void *param,
|
||||
const u8 *src, long src_len)
|
||||
{
|
||||
register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
|
||||
register void *__param asm("1") = param;
|
||||
register const u8 *__src asm("2") = src;
|
||||
register long __src_len asm("3") = src_len;
|
||||
int ret;
|
||||
|
||||
asm volatile(
|
||||
"0: .insn rre,0xb91e0000,%1,%1 \n" /* KLAC opcode */
|
||||
"1: brc 1,0b \n" /* handle partial completion */
|
||||
" la %0,0\n"
|
||||
"2:\n"
|
||||
EX_TABLE(0b,2b) EX_TABLE(1b,2b)
|
||||
: "=d" (ret), "+a" (__src), "+d" (__src_len)
|
||||
: "d" (__func), "a" (__param), "0" (-1) : "cc", "memory");
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* crypt_s390_kmctr:
|
||||
* @func: the function code passed to KMCTR; see crypt_s390_kmctr_func
|
||||
* @param: address of parameter block; see POP for details on each func
|
||||
* @dest: address of destination memory area
|
||||
* @src: address of source memory area
|
||||
* @src_len: length of src operand in bytes
|
||||
* @counter: address of counter value
|
||||
*
|
||||
* Executes the KMCTR (CIPHER MESSAGE WITH COUNTER) operation of the CPU.
|
||||
*
|
||||
* Returns -1 for failure, 0 for the query func, number of processed
|
||||
* bytes for encryption/decryption funcs
|
||||
*/
|
||||
static inline int crypt_s390_kmctr(long func, void *param, u8 *dest,
|
||||
const u8 *src, long src_len, u8 *counter)
|
||||
{
|
||||
register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
|
||||
register void *__param asm("1") = param;
|
||||
register const u8 *__src asm("2") = src;
|
||||
register long __src_len asm("3") = src_len;
|
||||
register u8 *__dest asm("4") = dest;
|
||||
register u8 *__ctr asm("6") = counter;
|
||||
int ret = -1;
|
||||
|
||||
asm volatile(
|
||||
"0: .insn rrf,0xb92d0000,%3,%1,%4,0 \n" /* KMCTR opcode */
|
||||
"1: brc 1,0b \n" /* handle partial completion */
|
||||
" la %0,0\n"
|
||||
"2:\n"
|
||||
EX_TABLE(0b,2b) EX_TABLE(1b,2b)
|
||||
: "+d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest),
|
||||
"+a" (__ctr)
|
||||
: "d" (__func), "a" (__param) : "cc", "memory");
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* crypt_s390_func_available:
|
||||
* @func: the function code of the specific function; 0 if op in general
|
||||
*
|
||||
* Tests if a specific crypto function is implemented on the machine.
|
||||
*
|
||||
* Returns 1 if func available; 0 if func or op in general not available
|
||||
*/
|
||||
static inline int crypt_s390_func_available(int func,
|
||||
unsigned int facility_mask)
|
||||
{
|
||||
unsigned char status[16];
|
||||
int ret;
|
||||
|
||||
if (facility_mask & CRYPT_S390_MSA && !test_facility(17))
|
||||
return 0;
|
||||
|
||||
if (facility_mask & CRYPT_S390_MSA3 &&
|
||||
(!test_facility(2) || !test_facility(76)))
|
||||
return 0;
|
||||
if (facility_mask & CRYPT_S390_MSA4 &&
|
||||
(!test_facility(2) || !test_facility(77)))
|
||||
return 0;
|
||||
|
||||
switch (func & CRYPT_S390_OP_MASK) {
|
||||
case CRYPT_S390_KM:
|
||||
ret = crypt_s390_km(KM_QUERY, &status, NULL, NULL, 0);
|
||||
break;
|
||||
case CRYPT_S390_KMC:
|
||||
ret = crypt_s390_kmc(KMC_QUERY, &status, NULL, NULL, 0);
|
||||
break;
|
||||
case CRYPT_S390_KIMD:
|
||||
ret = crypt_s390_kimd(KIMD_QUERY, &status, NULL, 0);
|
||||
break;
|
||||
case CRYPT_S390_KLMD:
|
||||
ret = crypt_s390_klmd(KLMD_QUERY, &status, NULL, 0);
|
||||
break;
|
||||
case CRYPT_S390_KMAC:
|
||||
ret = crypt_s390_kmac(KMAC_QUERY, &status, NULL, 0);
|
||||
break;
|
||||
case CRYPT_S390_KMCTR:
|
||||
ret = crypt_s390_kmctr(KMCTR_QUERY, &status, NULL, NULL, 0,
|
||||
NULL);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
func &= CRYPT_S390_FUNC_MASK;
|
||||
func &= 0x7f; /* mask modifier bit */
|
||||
return (status[func >> 3] & (0x80 >> (func & 7))) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* crypt_s390_pcc:
|
||||
* @func: the function code passed to KM; see crypt_s390_km_func
|
||||
* @param: address of parameter block; see POP for details on each func
|
||||
*
|
||||
* Executes the PCC (PERFORM CRYPTOGRAPHIC COMPUTATION) operation of the CPU.
|
||||
*
|
||||
* Returns -1 for failure, 0 for success.
|
||||
*/
|
||||
static inline int crypt_s390_pcc(long func, void *param)
|
||||
{
|
||||
register long __func asm("0") = func & 0x7f; /* encrypt or decrypt */
|
||||
register void *__param asm("1") = param;
|
||||
int ret = -1;
|
||||
|
||||
asm volatile(
|
||||
"0: .insn rre,0xb92c0000,0,0 \n" /* PCC opcode */
|
||||
"1: brc 1,0b \n" /* handle partial completion */
|
||||
" la %0,0\n"
|
||||
"2:\n"
|
||||
EX_TABLE(0b,2b) EX_TABLE(1b,2b)
|
||||
: "+d" (ret)
|
||||
: "d" (__func), "a" (__param) : "cc", "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#endif /* _CRYPTO_ARCH_S390_CRYPT_S390_H */
|
||||
626
arch/s390/crypto/des_s390.c
Normal file
626
arch/s390/crypto/des_s390.c
Normal file
|
|
@ -0,0 +1,626 @@
|
|||
/*
|
||||
* Cryptographic API.
|
||||
*
|
||||
* s390 implementation of the DES Cipher Algorithm.
|
||||
*
|
||||
* Copyright IBM Corp. 2003, 2011
|
||||
* Author(s): Thomas Spatzier
|
||||
* Jan Glauber (jan.glauber@de.ibm.com)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/crypto.h>
|
||||
#include <crypto/algapi.h>
|
||||
#include <crypto/des.h>
|
||||
|
||||
#include "crypt_s390.h"
|
||||
|
||||
#define DES3_KEY_SIZE (3 * DES_KEY_SIZE)
|
||||
|
||||
static u8 *ctrblk;
|
||||
static DEFINE_SPINLOCK(ctrblk_lock);
|
||||
|
||||
struct s390_des_ctx {
|
||||
u8 iv[DES_BLOCK_SIZE];
|
||||
u8 key[DES3_KEY_SIZE];
|
||||
};
|
||||
|
||||
static int des_setkey(struct crypto_tfm *tfm, const u8 *key,
|
||||
unsigned int key_len)
|
||||
{
|
||||
struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm);
|
||||
u32 *flags = &tfm->crt_flags;
|
||||
u32 tmp[DES_EXPKEY_WORDS];
|
||||
|
||||
/* check for weak keys */
|
||||
if (!des_ekey(tmp, key) && (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) {
|
||||
*flags |= CRYPTO_TFM_RES_WEAK_KEY;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memcpy(ctx->key, key, key_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void des_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
|
||||
{
|
||||
struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm);
|
||||
|
||||
crypt_s390_km(KM_DEA_ENCRYPT, ctx->key, out, in, DES_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
static void des_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
|
||||
{
|
||||
struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm);
|
||||
|
||||
crypt_s390_km(KM_DEA_DECRYPT, ctx->key, out, in, DES_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
static struct crypto_alg des_alg = {
|
||||
.cra_name = "des",
|
||||
.cra_driver_name = "des-s390",
|
||||
.cra_priority = CRYPT_S390_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
|
||||
.cra_blocksize = DES_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct s390_des_ctx),
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_u = {
|
||||
.cipher = {
|
||||
.cia_min_keysize = DES_KEY_SIZE,
|
||||
.cia_max_keysize = DES_KEY_SIZE,
|
||||
.cia_setkey = des_setkey,
|
||||
.cia_encrypt = des_encrypt,
|
||||
.cia_decrypt = des_decrypt,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static int ecb_desall_crypt(struct blkcipher_desc *desc, long func,
|
||||
u8 *key, struct blkcipher_walk *walk)
|
||||
{
|
||||
int ret = blkcipher_walk_virt(desc, walk);
|
||||
unsigned int nbytes;
|
||||
|
||||
while ((nbytes = walk->nbytes)) {
|
||||
/* only use complete blocks */
|
||||
unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1);
|
||||
u8 *out = walk->dst.virt.addr;
|
||||
u8 *in = walk->src.virt.addr;
|
||||
|
||||
ret = crypt_s390_km(func, key, out, in, n);
|
||||
if (ret < 0 || ret != n)
|
||||
return -EIO;
|
||||
|
||||
nbytes &= DES_BLOCK_SIZE - 1;
|
||||
ret = blkcipher_walk_done(desc, walk, nbytes);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cbc_desall_crypt(struct blkcipher_desc *desc, long func,
|
||||
struct blkcipher_walk *walk)
|
||||
{
|
||||
struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
int ret = blkcipher_walk_virt(desc, walk);
|
||||
unsigned int nbytes = walk->nbytes;
|
||||
struct {
|
||||
u8 iv[DES_BLOCK_SIZE];
|
||||
u8 key[DES3_KEY_SIZE];
|
||||
} param;
|
||||
|
||||
if (!nbytes)
|
||||
goto out;
|
||||
|
||||
memcpy(param.iv, walk->iv, DES_BLOCK_SIZE);
|
||||
memcpy(param.key, ctx->key, DES3_KEY_SIZE);
|
||||
do {
|
||||
/* only use complete blocks */
|
||||
unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1);
|
||||
u8 *out = walk->dst.virt.addr;
|
||||
u8 *in = walk->src.virt.addr;
|
||||
|
||||
ret = crypt_s390_kmc(func, ¶m, out, in, n);
|
||||
if (ret < 0 || ret != n)
|
||||
return -EIO;
|
||||
|
||||
nbytes &= DES_BLOCK_SIZE - 1;
|
||||
ret = blkcipher_walk_done(desc, walk, nbytes);
|
||||
} while ((nbytes = walk->nbytes));
|
||||
memcpy(walk->iv, param.iv, DES_BLOCK_SIZE);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ecb_des_encrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
return ecb_desall_crypt(desc, KM_DEA_ENCRYPT, ctx->key, &walk);
|
||||
}
|
||||
|
||||
static int ecb_des_decrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
return ecb_desall_crypt(desc, KM_DEA_DECRYPT, ctx->key, &walk);
|
||||
}
|
||||
|
||||
static struct crypto_alg ecb_des_alg = {
|
||||
.cra_name = "ecb(des)",
|
||||
.cra_driver_name = "ecb-des-s390",
|
||||
.cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||
.cra_blocksize = DES_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct s390_des_ctx),
|
||||
.cra_type = &crypto_blkcipher_type,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_u = {
|
||||
.blkcipher = {
|
||||
.min_keysize = DES_KEY_SIZE,
|
||||
.max_keysize = DES_KEY_SIZE,
|
||||
.setkey = des_setkey,
|
||||
.encrypt = ecb_des_encrypt,
|
||||
.decrypt = ecb_des_decrypt,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static int cbc_des_encrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct blkcipher_walk walk;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
return cbc_desall_crypt(desc, KMC_DEA_ENCRYPT, &walk);
|
||||
}
|
||||
|
||||
static int cbc_des_decrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct blkcipher_walk walk;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
return cbc_desall_crypt(desc, KMC_DEA_DECRYPT, &walk);
|
||||
}
|
||||
|
||||
static struct crypto_alg cbc_des_alg = {
|
||||
.cra_name = "cbc(des)",
|
||||
.cra_driver_name = "cbc-des-s390",
|
||||
.cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||
.cra_blocksize = DES_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct s390_des_ctx),
|
||||
.cra_type = &crypto_blkcipher_type,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_u = {
|
||||
.blkcipher = {
|
||||
.min_keysize = DES_KEY_SIZE,
|
||||
.max_keysize = DES_KEY_SIZE,
|
||||
.ivsize = DES_BLOCK_SIZE,
|
||||
.setkey = des_setkey,
|
||||
.encrypt = cbc_des_encrypt,
|
||||
.decrypt = cbc_des_decrypt,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* RFC2451:
|
||||
*
|
||||
* For DES-EDE3, there is no known need to reject weak or
|
||||
* complementation keys. Any weakness is obviated by the use of
|
||||
* multiple keys.
|
||||
*
|
||||
* However, if the first two or last two independent 64-bit keys are
|
||||
* equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the
|
||||
* same as DES. Implementers MUST reject keys that exhibit this
|
||||
* property.
|
||||
*
|
||||
*/
|
||||
static int des3_setkey(struct crypto_tfm *tfm, const u8 *key,
|
||||
unsigned int key_len)
|
||||
{
|
||||
struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm);
|
||||
u32 *flags = &tfm->crt_flags;
|
||||
|
||||
if (!(crypto_memneq(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) &&
|
||||
crypto_memneq(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2],
|
||||
DES_KEY_SIZE)) &&
|
||||
(*flags & CRYPTO_TFM_REQ_WEAK_KEY)) {
|
||||
*flags |= CRYPTO_TFM_RES_WEAK_KEY;
|
||||
return -EINVAL;
|
||||
}
|
||||
memcpy(ctx->key, key, key_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void des3_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
|
||||
{
|
||||
struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm);
|
||||
|
||||
crypt_s390_km(KM_TDEA_192_ENCRYPT, ctx->key, dst, src, DES_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
static void des3_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
|
||||
{
|
||||
struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm);
|
||||
|
||||
crypt_s390_km(KM_TDEA_192_DECRYPT, ctx->key, dst, src, DES_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
static struct crypto_alg des3_alg = {
|
||||
.cra_name = "des3_ede",
|
||||
.cra_driver_name = "des3_ede-s390",
|
||||
.cra_priority = CRYPT_S390_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
|
||||
.cra_blocksize = DES_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct s390_des_ctx),
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_u = {
|
||||
.cipher = {
|
||||
.cia_min_keysize = DES3_KEY_SIZE,
|
||||
.cia_max_keysize = DES3_KEY_SIZE,
|
||||
.cia_setkey = des3_setkey,
|
||||
.cia_encrypt = des3_encrypt,
|
||||
.cia_decrypt = des3_decrypt,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static int ecb_des3_encrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
return ecb_desall_crypt(desc, KM_TDEA_192_ENCRYPT, ctx->key, &walk);
|
||||
}
|
||||
|
||||
static int ecb_des3_decrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
return ecb_desall_crypt(desc, KM_TDEA_192_DECRYPT, ctx->key, &walk);
|
||||
}
|
||||
|
||||
static struct crypto_alg ecb_des3_alg = {
|
||||
.cra_name = "ecb(des3_ede)",
|
||||
.cra_driver_name = "ecb-des3_ede-s390",
|
||||
.cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||
.cra_blocksize = DES_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct s390_des_ctx),
|
||||
.cra_type = &crypto_blkcipher_type,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_u = {
|
||||
.blkcipher = {
|
||||
.min_keysize = DES3_KEY_SIZE,
|
||||
.max_keysize = DES3_KEY_SIZE,
|
||||
.setkey = des3_setkey,
|
||||
.encrypt = ecb_des3_encrypt,
|
||||
.decrypt = ecb_des3_decrypt,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static int cbc_des3_encrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct blkcipher_walk walk;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
return cbc_desall_crypt(desc, KMC_TDEA_192_ENCRYPT, &walk);
|
||||
}
|
||||
|
||||
static int cbc_des3_decrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct blkcipher_walk walk;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
return cbc_desall_crypt(desc, KMC_TDEA_192_DECRYPT, &walk);
|
||||
}
|
||||
|
||||
static struct crypto_alg cbc_des3_alg = {
|
||||
.cra_name = "cbc(des3_ede)",
|
||||
.cra_driver_name = "cbc-des3_ede-s390",
|
||||
.cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||
.cra_blocksize = DES_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct s390_des_ctx),
|
||||
.cra_type = &crypto_blkcipher_type,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_u = {
|
||||
.blkcipher = {
|
||||
.min_keysize = DES3_KEY_SIZE,
|
||||
.max_keysize = DES3_KEY_SIZE,
|
||||
.ivsize = DES_BLOCK_SIZE,
|
||||
.setkey = des3_setkey,
|
||||
.encrypt = cbc_des3_encrypt,
|
||||
.decrypt = cbc_des3_decrypt,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static unsigned int __ctrblk_init(u8 *ctrptr, unsigned int nbytes)
|
||||
{
|
||||
unsigned int i, n;
|
||||
|
||||
/* align to block size, max. PAGE_SIZE */
|
||||
n = (nbytes > PAGE_SIZE) ? PAGE_SIZE : nbytes & ~(DES_BLOCK_SIZE - 1);
|
||||
for (i = DES_BLOCK_SIZE; i < n; i += DES_BLOCK_SIZE) {
|
||||
memcpy(ctrptr + i, ctrptr + i - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
|
||||
crypto_inc(ctrptr + i, DES_BLOCK_SIZE);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
static int ctr_desall_crypt(struct blkcipher_desc *desc, long func,
|
||||
struct s390_des_ctx *ctx,
|
||||
struct blkcipher_walk *walk)
|
||||
{
|
||||
int ret = blkcipher_walk_virt_block(desc, walk, DES_BLOCK_SIZE);
|
||||
unsigned int n, nbytes;
|
||||
u8 buf[DES_BLOCK_SIZE], ctrbuf[DES_BLOCK_SIZE];
|
||||
u8 *out, *in, *ctrptr = ctrbuf;
|
||||
|
||||
if (!walk->nbytes)
|
||||
return ret;
|
||||
|
||||
if (spin_trylock(&ctrblk_lock))
|
||||
ctrptr = ctrblk;
|
||||
|
||||
memcpy(ctrptr, walk->iv, DES_BLOCK_SIZE);
|
||||
while ((nbytes = walk->nbytes) >= DES_BLOCK_SIZE) {
|
||||
out = walk->dst.virt.addr;
|
||||
in = walk->src.virt.addr;
|
||||
while (nbytes >= DES_BLOCK_SIZE) {
|
||||
if (ctrptr == ctrblk)
|
||||
n = __ctrblk_init(ctrptr, nbytes);
|
||||
else
|
||||
n = DES_BLOCK_SIZE;
|
||||
ret = crypt_s390_kmctr(func, ctx->key, out, in,
|
||||
n, ctrptr);
|
||||
if (ret < 0 || ret != n) {
|
||||
if (ctrptr == ctrblk)
|
||||
spin_unlock(&ctrblk_lock);
|
||||
return -EIO;
|
||||
}
|
||||
if (n > DES_BLOCK_SIZE)
|
||||
memcpy(ctrptr, ctrptr + n - DES_BLOCK_SIZE,
|
||||
DES_BLOCK_SIZE);
|
||||
crypto_inc(ctrptr, DES_BLOCK_SIZE);
|
||||
out += n;
|
||||
in += n;
|
||||
nbytes -= n;
|
||||
}
|
||||
ret = blkcipher_walk_done(desc, walk, nbytes);
|
||||
}
|
||||
if (ctrptr == ctrblk) {
|
||||
if (nbytes)
|
||||
memcpy(ctrbuf, ctrptr, DES_BLOCK_SIZE);
|
||||
else
|
||||
memcpy(walk->iv, ctrptr, DES_BLOCK_SIZE);
|
||||
spin_unlock(&ctrblk_lock);
|
||||
} else {
|
||||
if (!nbytes)
|
||||
memcpy(walk->iv, ctrptr, DES_BLOCK_SIZE);
|
||||
}
|
||||
/* final block may be < DES_BLOCK_SIZE, copy only nbytes */
|
||||
if (nbytes) {
|
||||
out = walk->dst.virt.addr;
|
||||
in = walk->src.virt.addr;
|
||||
ret = crypt_s390_kmctr(func, ctx->key, buf, in,
|
||||
DES_BLOCK_SIZE, ctrbuf);
|
||||
if (ret < 0 || ret != DES_BLOCK_SIZE)
|
||||
return -EIO;
|
||||
memcpy(out, buf, nbytes);
|
||||
crypto_inc(ctrbuf, DES_BLOCK_SIZE);
|
||||
ret = blkcipher_walk_done(desc, walk, 0);
|
||||
memcpy(walk->iv, ctrbuf, DES_BLOCK_SIZE);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ctr_des_encrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
return ctr_desall_crypt(desc, KMCTR_DEA_ENCRYPT, ctx, &walk);
|
||||
}
|
||||
|
||||
static int ctr_des_decrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
return ctr_desall_crypt(desc, KMCTR_DEA_DECRYPT, ctx, &walk);
|
||||
}
|
||||
|
||||
static struct crypto_alg ctr_des_alg = {
|
||||
.cra_name = "ctr(des)",
|
||||
.cra_driver_name = "ctr-des-s390",
|
||||
.cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||
.cra_blocksize = 1,
|
||||
.cra_ctxsize = sizeof(struct s390_des_ctx),
|
||||
.cra_type = &crypto_blkcipher_type,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_u = {
|
||||
.blkcipher = {
|
||||
.min_keysize = DES_KEY_SIZE,
|
||||
.max_keysize = DES_KEY_SIZE,
|
||||
.ivsize = DES_BLOCK_SIZE,
|
||||
.setkey = des_setkey,
|
||||
.encrypt = ctr_des_encrypt,
|
||||
.decrypt = ctr_des_decrypt,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static int ctr_des3_encrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
return ctr_desall_crypt(desc, KMCTR_TDEA_192_ENCRYPT, ctx, &walk);
|
||||
}
|
||||
|
||||
static int ctr_des3_decrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
return ctr_desall_crypt(desc, KMCTR_TDEA_192_DECRYPT, ctx, &walk);
|
||||
}
|
||||
|
||||
static struct crypto_alg ctr_des3_alg = {
|
||||
.cra_name = "ctr(des3_ede)",
|
||||
.cra_driver_name = "ctr-des3_ede-s390",
|
||||
.cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||
.cra_blocksize = 1,
|
||||
.cra_ctxsize = sizeof(struct s390_des_ctx),
|
||||
.cra_type = &crypto_blkcipher_type,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_u = {
|
||||
.blkcipher = {
|
||||
.min_keysize = DES3_KEY_SIZE,
|
||||
.max_keysize = DES3_KEY_SIZE,
|
||||
.ivsize = DES_BLOCK_SIZE,
|
||||
.setkey = des3_setkey,
|
||||
.encrypt = ctr_des3_encrypt,
|
||||
.decrypt = ctr_des3_decrypt,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static int __init des_s390_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!crypt_s390_func_available(KM_DEA_ENCRYPT, CRYPT_S390_MSA) ||
|
||||
!crypt_s390_func_available(KM_TDEA_192_ENCRYPT, CRYPT_S390_MSA))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ret = crypto_register_alg(&des_alg);
|
||||
if (ret)
|
||||
goto des_err;
|
||||
ret = crypto_register_alg(&ecb_des_alg);
|
||||
if (ret)
|
||||
goto ecb_des_err;
|
||||
ret = crypto_register_alg(&cbc_des_alg);
|
||||
if (ret)
|
||||
goto cbc_des_err;
|
||||
ret = crypto_register_alg(&des3_alg);
|
||||
if (ret)
|
||||
goto des3_err;
|
||||
ret = crypto_register_alg(&ecb_des3_alg);
|
||||
if (ret)
|
||||
goto ecb_des3_err;
|
||||
ret = crypto_register_alg(&cbc_des3_alg);
|
||||
if (ret)
|
||||
goto cbc_des3_err;
|
||||
|
||||
if (crypt_s390_func_available(KMCTR_DEA_ENCRYPT,
|
||||
CRYPT_S390_MSA | CRYPT_S390_MSA4) &&
|
||||
crypt_s390_func_available(KMCTR_TDEA_192_ENCRYPT,
|
||||
CRYPT_S390_MSA | CRYPT_S390_MSA4)) {
|
||||
ret = crypto_register_alg(&ctr_des_alg);
|
||||
if (ret)
|
||||
goto ctr_des_err;
|
||||
ret = crypto_register_alg(&ctr_des3_alg);
|
||||
if (ret)
|
||||
goto ctr_des3_err;
|
||||
ctrblk = (u8 *) __get_free_page(GFP_KERNEL);
|
||||
if (!ctrblk) {
|
||||
ret = -ENOMEM;
|
||||
goto ctr_mem_err;
|
||||
}
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
|
||||
ctr_mem_err:
|
||||
crypto_unregister_alg(&ctr_des3_alg);
|
||||
ctr_des3_err:
|
||||
crypto_unregister_alg(&ctr_des_alg);
|
||||
ctr_des_err:
|
||||
crypto_unregister_alg(&cbc_des3_alg);
|
||||
cbc_des3_err:
|
||||
crypto_unregister_alg(&ecb_des3_alg);
|
||||
ecb_des3_err:
|
||||
crypto_unregister_alg(&des3_alg);
|
||||
des3_err:
|
||||
crypto_unregister_alg(&cbc_des_alg);
|
||||
cbc_des_err:
|
||||
crypto_unregister_alg(&ecb_des_alg);
|
||||
ecb_des_err:
|
||||
crypto_unregister_alg(&des_alg);
|
||||
des_err:
|
||||
goto out;
|
||||
}
|
||||
|
||||
static void __exit des_s390_exit(void)
|
||||
{
|
||||
if (ctrblk) {
|
||||
crypto_unregister_alg(&ctr_des_alg);
|
||||
crypto_unregister_alg(&ctr_des3_alg);
|
||||
free_page((unsigned long) ctrblk);
|
||||
}
|
||||
crypto_unregister_alg(&cbc_des3_alg);
|
||||
crypto_unregister_alg(&ecb_des3_alg);
|
||||
crypto_unregister_alg(&des3_alg);
|
||||
crypto_unregister_alg(&cbc_des_alg);
|
||||
crypto_unregister_alg(&ecb_des_alg);
|
||||
crypto_unregister_alg(&des_alg);
|
||||
}
|
||||
|
||||
module_init(des_s390_init);
|
||||
module_exit(des_s390_exit);
|
||||
|
||||
MODULE_ALIAS_CRYPTO("des");
|
||||
MODULE_ALIAS_CRYPTO("des3_ede");
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms");
|
||||
166
arch/s390/crypto/ghash_s390.c
Normal file
166
arch/s390/crypto/ghash_s390.c
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* Cryptographic API.
|
||||
*
|
||||
* s390 implementation of the GHASH algorithm for GCM (Galois/Counter Mode).
|
||||
*
|
||||
* Copyright IBM Corp. 2011
|
||||
* Author(s): Gerald Schaefer <gerald.schaefer@de.ibm.com>
|
||||
*/
|
||||
|
||||
#include <crypto/internal/hash.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "crypt_s390.h"
|
||||
|
||||
#define GHASH_BLOCK_SIZE 16
|
||||
#define GHASH_DIGEST_SIZE 16
|
||||
|
||||
struct ghash_ctx {
|
||||
u8 icv[16];
|
||||
u8 key[16];
|
||||
};
|
||||
|
||||
struct ghash_desc_ctx {
|
||||
u8 buffer[GHASH_BLOCK_SIZE];
|
||||
u32 bytes;
|
||||
};
|
||||
|
||||
static int ghash_init(struct shash_desc *desc)
|
||||
{
|
||||
struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
|
||||
|
||||
memset(dctx, 0, sizeof(*dctx));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ghash_setkey(struct crypto_shash *tfm,
|
||||
const u8 *key, unsigned int keylen)
|
||||
{
|
||||
struct ghash_ctx *ctx = crypto_shash_ctx(tfm);
|
||||
|
||||
if (keylen != GHASH_BLOCK_SIZE) {
|
||||
crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memcpy(ctx->key, key, GHASH_BLOCK_SIZE);
|
||||
memset(ctx->icv, 0, GHASH_BLOCK_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ghash_update(struct shash_desc *desc,
|
||||
const u8 *src, unsigned int srclen)
|
||||
{
|
||||
struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
|
||||
struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm);
|
||||
unsigned int n;
|
||||
u8 *buf = dctx->buffer;
|
||||
int ret;
|
||||
|
||||
if (dctx->bytes) {
|
||||
u8 *pos = buf + (GHASH_BLOCK_SIZE - dctx->bytes);
|
||||
|
||||
n = min(srclen, dctx->bytes);
|
||||
dctx->bytes -= n;
|
||||
srclen -= n;
|
||||
|
||||
memcpy(pos, src, n);
|
||||
src += n;
|
||||
|
||||
if (!dctx->bytes) {
|
||||
ret = crypt_s390_kimd(KIMD_GHASH, ctx, buf,
|
||||
GHASH_BLOCK_SIZE);
|
||||
if (ret != GHASH_BLOCK_SIZE)
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
|
||||
n = srclen & ~(GHASH_BLOCK_SIZE - 1);
|
||||
if (n) {
|
||||
ret = crypt_s390_kimd(KIMD_GHASH, ctx, src, n);
|
||||
if (ret != n)
|
||||
return -EIO;
|
||||
src += n;
|
||||
srclen -= n;
|
||||
}
|
||||
|
||||
if (srclen) {
|
||||
dctx->bytes = GHASH_BLOCK_SIZE - srclen;
|
||||
memcpy(buf, src, srclen);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ghash_flush(struct ghash_ctx *ctx, struct ghash_desc_ctx *dctx)
|
||||
{
|
||||
u8 *buf = dctx->buffer;
|
||||
int ret;
|
||||
|
||||
if (dctx->bytes) {
|
||||
u8 *pos = buf + (GHASH_BLOCK_SIZE - dctx->bytes);
|
||||
|
||||
memset(pos, 0, dctx->bytes);
|
||||
|
||||
ret = crypt_s390_kimd(KIMD_GHASH, ctx, buf, GHASH_BLOCK_SIZE);
|
||||
if (ret != GHASH_BLOCK_SIZE)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
dctx->bytes = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ghash_final(struct shash_desc *desc, u8 *dst)
|
||||
{
|
||||
struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
|
||||
struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm);
|
||||
int ret;
|
||||
|
||||
ret = ghash_flush(ctx, dctx);
|
||||
if (!ret)
|
||||
memcpy(dst, ctx->icv, GHASH_BLOCK_SIZE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct shash_alg ghash_alg = {
|
||||
.digestsize = GHASH_DIGEST_SIZE,
|
||||
.init = ghash_init,
|
||||
.update = ghash_update,
|
||||
.final = ghash_final,
|
||||
.setkey = ghash_setkey,
|
||||
.descsize = sizeof(struct ghash_desc_ctx),
|
||||
.base = {
|
||||
.cra_name = "ghash",
|
||||
.cra_driver_name = "ghash-s390",
|
||||
.cra_priority = CRYPT_S390_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_SHASH,
|
||||
.cra_blocksize = GHASH_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct ghash_ctx),
|
||||
.cra_module = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init ghash_mod_init(void)
|
||||
{
|
||||
if (!crypt_s390_func_available(KIMD_GHASH,
|
||||
CRYPT_S390_MSA | CRYPT_S390_MSA4))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return crypto_register_shash(&ghash_alg);
|
||||
}
|
||||
|
||||
static void __exit ghash_mod_exit(void)
|
||||
{
|
||||
crypto_unregister_shash(&ghash_alg);
|
||||
}
|
||||
|
||||
module_init(ghash_mod_init);
|
||||
module_exit(ghash_mod_exit);
|
||||
|
||||
MODULE_ALIAS_CRYPTO("ghash");
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("GHASH Message Digest Algorithm, s390 implementation");
|
||||
211
arch/s390/crypto/prng.c
Normal file
211
arch/s390/crypto/prng.c
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
/*
|
||||
* Copyright IBM Corp. 2006, 2007
|
||||
* Author(s): Jan Glauber <jan.glauber@de.ibm.com>
|
||||
* Driver for the s390 pseudo random number generator
|
||||
*/
|
||||
#include <linux/fs.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/slab.h>
|
||||
#include <asm/debug.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#include "crypt_s390.h"
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Jan Glauber <jan.glauber@de.ibm.com>");
|
||||
MODULE_DESCRIPTION("s390 PRNG interface");
|
||||
|
||||
static int prng_chunk_size = 256;
|
||||
module_param(prng_chunk_size, int, S_IRUSR | S_IRGRP | S_IROTH);
|
||||
MODULE_PARM_DESC(prng_chunk_size, "PRNG read chunk size in bytes");
|
||||
|
||||
static int prng_entropy_limit = 4096;
|
||||
module_param(prng_entropy_limit, int, S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR);
|
||||
MODULE_PARM_DESC(prng_entropy_limit,
|
||||
"PRNG add entropy after that much bytes were produced");
|
||||
|
||||
/*
|
||||
* Any one who considers arithmetical methods of producing random digits is,
|
||||
* of course, in a state of sin. -- John von Neumann
|
||||
*/
|
||||
|
||||
struct s390_prng_data {
|
||||
unsigned long count; /* how many bytes were produced */
|
||||
char *buf;
|
||||
};
|
||||
|
||||
static struct s390_prng_data *p;
|
||||
|
||||
/* copied from libica, use a non-zero initial parameter block */
|
||||
static unsigned char parm_block[32] = {
|
||||
0x0F,0x2B,0x8E,0x63,0x8C,0x8E,0xD2,0x52,0x64,0xB7,0xA0,0x7B,0x75,0x28,0xB8,0xF4,
|
||||
0x75,0x5F,0xD2,0xA6,0x8D,0x97,0x11,0xFF,0x49,0xD8,0x23,0xF3,0x7E,0x21,0xEC,0xA0,
|
||||
};
|
||||
|
||||
static int prng_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return nonseekable_open(inode, file);
|
||||
}
|
||||
|
||||
static void prng_add_entropy(void)
|
||||
{
|
||||
__u64 entropy[4];
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
ret = crypt_s390_kmc(KMC_PRNG, parm_block, (char *)entropy,
|
||||
(char *)entropy, sizeof(entropy));
|
||||
BUG_ON(ret < 0 || ret != sizeof(entropy));
|
||||
memcpy(parm_block, entropy, sizeof(entropy));
|
||||
}
|
||||
}
|
||||
|
||||
static void prng_seed(int nbytes)
|
||||
{
|
||||
char buf[16];
|
||||
int i = 0;
|
||||
|
||||
BUG_ON(nbytes > 16);
|
||||
get_random_bytes(buf, nbytes);
|
||||
|
||||
/* Add the entropy */
|
||||
while (nbytes >= 8) {
|
||||
*((__u64 *)parm_block) ^= *((__u64 *)(buf+i));
|
||||
prng_add_entropy();
|
||||
i += 8;
|
||||
nbytes -= 8;
|
||||
}
|
||||
prng_add_entropy();
|
||||
}
|
||||
|
||||
static ssize_t prng_read(struct file *file, char __user *ubuf, size_t nbytes,
|
||||
loff_t *ppos)
|
||||
{
|
||||
int chunk, n;
|
||||
int ret = 0;
|
||||
int tmp;
|
||||
|
||||
/* nbytes can be arbitrary length, we split it into chunks */
|
||||
while (nbytes) {
|
||||
/* same as in extract_entropy_user in random.c */
|
||||
if (need_resched()) {
|
||||
if (signal_pending(current)) {
|
||||
if (ret == 0)
|
||||
ret = -ERESTARTSYS;
|
||||
break;
|
||||
}
|
||||
schedule();
|
||||
}
|
||||
|
||||
/*
|
||||
* we lose some random bytes if an attacker issues
|
||||
* reads < 8 bytes, but we don't care
|
||||
*/
|
||||
chunk = min_t(int, nbytes, prng_chunk_size);
|
||||
|
||||
/* PRNG only likes multiples of 8 bytes */
|
||||
n = (chunk + 7) & -8;
|
||||
|
||||
if (p->count > prng_entropy_limit)
|
||||
prng_seed(8);
|
||||
|
||||
/* if the CPU supports PRNG stckf is present too */
|
||||
asm volatile(".insn s,0xb27c0000,%0"
|
||||
: "=m" (*((unsigned long long *)p->buf)) : : "cc");
|
||||
|
||||
/*
|
||||
* Beside the STCKF the input for the TDES-EDE is the output
|
||||
* of the last operation. We differ here from X9.17 since we
|
||||
* only store one timestamp into the buffer. Padding the whole
|
||||
* buffer with timestamps does not improve security, since
|
||||
* successive stckf have nearly constant offsets.
|
||||
* If an attacker knows the first timestamp it would be
|
||||
* trivial to guess the additional values. One timestamp
|
||||
* is therefore enough and still guarantees unique input values.
|
||||
*
|
||||
* Note: you can still get strict X9.17 conformity by setting
|
||||
* prng_chunk_size to 8 bytes.
|
||||
*/
|
||||
tmp = crypt_s390_kmc(KMC_PRNG, parm_block, p->buf, p->buf, n);
|
||||
BUG_ON((tmp < 0) || (tmp != n));
|
||||
|
||||
p->count += n;
|
||||
|
||||
if (copy_to_user(ubuf, p->buf, chunk))
|
||||
return -EFAULT;
|
||||
|
||||
nbytes -= chunk;
|
||||
ret += chunk;
|
||||
ubuf += chunk;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct file_operations prng_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = &prng_open,
|
||||
.release = NULL,
|
||||
.read = &prng_read,
|
||||
.llseek = noop_llseek,
|
||||
};
|
||||
|
||||
static struct miscdevice prng_dev = {
|
||||
.name = "prandom",
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.fops = &prng_fops,
|
||||
};
|
||||
|
||||
static int __init prng_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* check if the CPU has a PRNG */
|
||||
if (!crypt_s390_func_available(KMC_PRNG, CRYPT_S390_MSA))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (prng_chunk_size < 8)
|
||||
return -EINVAL;
|
||||
|
||||
p = kmalloc(sizeof(struct s390_prng_data), GFP_KERNEL);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
p->count = 0;
|
||||
|
||||
p->buf = kmalloc(prng_chunk_size, GFP_KERNEL);
|
||||
if (!p->buf) {
|
||||
ret = -ENOMEM;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
/* initialize the PRNG, add 128 bits of entropy */
|
||||
prng_seed(16);
|
||||
|
||||
ret = misc_register(&prng_dev);
|
||||
if (ret)
|
||||
goto out_buf;
|
||||
return 0;
|
||||
|
||||
out_buf:
|
||||
kfree(p->buf);
|
||||
out_free:
|
||||
kfree(p);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit prng_exit(void)
|
||||
{
|
||||
/* wipe me */
|
||||
kzfree(p->buf);
|
||||
kfree(p);
|
||||
|
||||
misc_deregister(&prng_dev);
|
||||
}
|
||||
|
||||
module_init(prng_init);
|
||||
module_exit(prng_exit);
|
||||
37
arch/s390/crypto/sha.h
Normal file
37
arch/s390/crypto/sha.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Cryptographic API.
|
||||
*
|
||||
* s390 generic implementation of the SHA Secure Hash Algorithms.
|
||||
*
|
||||
* Copyright IBM Corp. 2007
|
||||
* Author(s): Jan Glauber (jang@de.ibm.com)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#ifndef _CRYPTO_ARCH_S390_SHA_H
|
||||
#define _CRYPTO_ARCH_S390_SHA_H
|
||||
|
||||
#include <linux/crypto.h>
|
||||
#include <crypto/sha.h>
|
||||
|
||||
/* must be big enough for the largest SHA variant */
|
||||
#define SHA_MAX_STATE_SIZE 16
|
||||
#define SHA_MAX_BLOCK_SIZE SHA512_BLOCK_SIZE
|
||||
|
||||
struct s390_sha_ctx {
|
||||
u64 count; /* message length in bytes */
|
||||
u32 state[SHA_MAX_STATE_SIZE];
|
||||
u8 buf[2 * SHA_MAX_BLOCK_SIZE];
|
||||
int func; /* KIMD function to use */
|
||||
};
|
||||
|
||||
struct shash_desc;
|
||||
|
||||
int s390_sha_update(struct shash_desc *desc, const u8 *data, unsigned int len);
|
||||
int s390_sha_final(struct shash_desc *desc, u8 *out);
|
||||
|
||||
#endif
|
||||
108
arch/s390/crypto/sha1_s390.c
Normal file
108
arch/s390/crypto/sha1_s390.c
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Cryptographic API.
|
||||
*
|
||||
* s390 implementation of the SHA1 Secure Hash Algorithm.
|
||||
*
|
||||
* Derived from cryptoapi implementation, adapted for in-place
|
||||
* scatterlist interface. Originally based on the public domain
|
||||
* implementation written by Steve Reid.
|
||||
*
|
||||
* s390 Version:
|
||||
* Copyright IBM Corp. 2003, 2007
|
||||
* Author(s): Thomas Spatzier
|
||||
* Jan Glauber (jan.glauber@de.ibm.com)
|
||||
*
|
||||
* Derived from "crypto/sha1_generic.c"
|
||||
* Copyright (c) Alan Smithee.
|
||||
* Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
|
||||
* Copyright (c) Jean-Francois Dive <jef@linuxbe.org>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#include <crypto/internal/hash.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <crypto/sha.h>
|
||||
|
||||
#include "crypt_s390.h"
|
||||
#include "sha.h"
|
||||
|
||||
static int sha1_init(struct shash_desc *desc)
|
||||
{
|
||||
struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
|
||||
|
||||
sctx->state[0] = SHA1_H0;
|
||||
sctx->state[1] = SHA1_H1;
|
||||
sctx->state[2] = SHA1_H2;
|
||||
sctx->state[3] = SHA1_H3;
|
||||
sctx->state[4] = SHA1_H4;
|
||||
sctx->count = 0;
|
||||
sctx->func = KIMD_SHA_1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sha1_export(struct shash_desc *desc, void *out)
|
||||
{
|
||||
struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
|
||||
struct sha1_state *octx = out;
|
||||
|
||||
octx->count = sctx->count;
|
||||
memcpy(octx->state, sctx->state, sizeof(octx->state));
|
||||
memcpy(octx->buffer, sctx->buf, sizeof(octx->buffer));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sha1_import(struct shash_desc *desc, const void *in)
|
||||
{
|
||||
struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
|
||||
const struct sha1_state *ictx = in;
|
||||
|
||||
sctx->count = ictx->count;
|
||||
memcpy(sctx->state, ictx->state, sizeof(ictx->state));
|
||||
memcpy(sctx->buf, ictx->buffer, sizeof(ictx->buffer));
|
||||
sctx->func = KIMD_SHA_1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct shash_alg alg = {
|
||||
.digestsize = SHA1_DIGEST_SIZE,
|
||||
.init = sha1_init,
|
||||
.update = s390_sha_update,
|
||||
.final = s390_sha_final,
|
||||
.export = sha1_export,
|
||||
.import = sha1_import,
|
||||
.descsize = sizeof(struct s390_sha_ctx),
|
||||
.statesize = sizeof(struct sha1_state),
|
||||
.base = {
|
||||
.cra_name = "sha1",
|
||||
.cra_driver_name= "sha1-s390",
|
||||
.cra_priority = CRYPT_S390_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_SHASH,
|
||||
.cra_blocksize = SHA1_BLOCK_SIZE,
|
||||
.cra_module = THIS_MODULE,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init sha1_s390_init(void)
|
||||
{
|
||||
if (!crypt_s390_func_available(KIMD_SHA_1, CRYPT_S390_MSA))
|
||||
return -EOPNOTSUPP;
|
||||
return crypto_register_shash(&alg);
|
||||
}
|
||||
|
||||
static void __exit sha1_s390_fini(void)
|
||||
{
|
||||
crypto_unregister_shash(&alg);
|
||||
}
|
||||
|
||||
module_init(sha1_s390_init);
|
||||
module_exit(sha1_s390_fini);
|
||||
|
||||
MODULE_ALIAS_CRYPTO("sha1");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm");
|
||||
149
arch/s390/crypto/sha256_s390.c
Normal file
149
arch/s390/crypto/sha256_s390.c
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* Cryptographic API.
|
||||
*
|
||||
* s390 implementation of the SHA256 and SHA224 Secure Hash Algorithm.
|
||||
*
|
||||
* s390 Version:
|
||||
* Copyright IBM Corp. 2005, 2011
|
||||
* Author(s): Jan Glauber (jang@de.ibm.com)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#include <crypto/internal/hash.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <crypto/sha.h>
|
||||
|
||||
#include "crypt_s390.h"
|
||||
#include "sha.h"
|
||||
|
||||
static int sha256_init(struct shash_desc *desc)
|
||||
{
|
||||
struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
|
||||
|
||||
sctx->state[0] = SHA256_H0;
|
||||
sctx->state[1] = SHA256_H1;
|
||||
sctx->state[2] = SHA256_H2;
|
||||
sctx->state[3] = SHA256_H3;
|
||||
sctx->state[4] = SHA256_H4;
|
||||
sctx->state[5] = SHA256_H5;
|
||||
sctx->state[6] = SHA256_H6;
|
||||
sctx->state[7] = SHA256_H7;
|
||||
sctx->count = 0;
|
||||
sctx->func = KIMD_SHA_256;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sha256_export(struct shash_desc *desc, void *out)
|
||||
{
|
||||
struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
|
||||
struct sha256_state *octx = out;
|
||||
|
||||
octx->count = sctx->count;
|
||||
memcpy(octx->state, sctx->state, sizeof(octx->state));
|
||||
memcpy(octx->buf, sctx->buf, sizeof(octx->buf));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sha256_import(struct shash_desc *desc, const void *in)
|
||||
{
|
||||
struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
|
||||
const struct sha256_state *ictx = in;
|
||||
|
||||
sctx->count = ictx->count;
|
||||
memcpy(sctx->state, ictx->state, sizeof(ictx->state));
|
||||
memcpy(sctx->buf, ictx->buf, sizeof(ictx->buf));
|
||||
sctx->func = KIMD_SHA_256;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct shash_alg sha256_alg = {
|
||||
.digestsize = SHA256_DIGEST_SIZE,
|
||||
.init = sha256_init,
|
||||
.update = s390_sha_update,
|
||||
.final = s390_sha_final,
|
||||
.export = sha256_export,
|
||||
.import = sha256_import,
|
||||
.descsize = sizeof(struct s390_sha_ctx),
|
||||
.statesize = sizeof(struct sha256_state),
|
||||
.base = {
|
||||
.cra_name = "sha256",
|
||||
.cra_driver_name= "sha256-s390",
|
||||
.cra_priority = CRYPT_S390_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_SHASH,
|
||||
.cra_blocksize = SHA256_BLOCK_SIZE,
|
||||
.cra_module = THIS_MODULE,
|
||||
}
|
||||
};
|
||||
|
||||
static int sha224_init(struct shash_desc *desc)
|
||||
{
|
||||
struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
|
||||
|
||||
sctx->state[0] = SHA224_H0;
|
||||
sctx->state[1] = SHA224_H1;
|
||||
sctx->state[2] = SHA224_H2;
|
||||
sctx->state[3] = SHA224_H3;
|
||||
sctx->state[4] = SHA224_H4;
|
||||
sctx->state[5] = SHA224_H5;
|
||||
sctx->state[6] = SHA224_H6;
|
||||
sctx->state[7] = SHA224_H7;
|
||||
sctx->count = 0;
|
||||
sctx->func = KIMD_SHA_256;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct shash_alg sha224_alg = {
|
||||
.digestsize = SHA224_DIGEST_SIZE,
|
||||
.init = sha224_init,
|
||||
.update = s390_sha_update,
|
||||
.final = s390_sha_final,
|
||||
.export = sha256_export,
|
||||
.import = sha256_import,
|
||||
.descsize = sizeof(struct s390_sha_ctx),
|
||||
.statesize = sizeof(struct sha256_state),
|
||||
.base = {
|
||||
.cra_name = "sha224",
|
||||
.cra_driver_name= "sha224-s390",
|
||||
.cra_priority = CRYPT_S390_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_SHASH,
|
||||
.cra_blocksize = SHA224_BLOCK_SIZE,
|
||||
.cra_module = THIS_MODULE,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init sha256_s390_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!crypt_s390_func_available(KIMD_SHA_256, CRYPT_S390_MSA))
|
||||
return -EOPNOTSUPP;
|
||||
ret = crypto_register_shash(&sha256_alg);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
ret = crypto_register_shash(&sha224_alg);
|
||||
if (ret < 0)
|
||||
crypto_unregister_shash(&sha256_alg);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit sha256_s390_fini(void)
|
||||
{
|
||||
crypto_unregister_shash(&sha224_alg);
|
||||
crypto_unregister_shash(&sha256_alg);
|
||||
}
|
||||
|
||||
module_init(sha256_s390_init);
|
||||
module_exit(sha256_s390_fini);
|
||||
|
||||
MODULE_ALIAS_CRYPTO("sha256");
|
||||
MODULE_ALIAS_CRYPTO("sha224");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("SHA256 and SHA224 Secure Hash Algorithm");
|
||||
155
arch/s390/crypto/sha512_s390.c
Normal file
155
arch/s390/crypto/sha512_s390.c
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* Cryptographic API.
|
||||
*
|
||||
* s390 implementation of the SHA512 and SHA38 Secure Hash Algorithm.
|
||||
*
|
||||
* Copyright IBM Corp. 2007
|
||||
* Author(s): Jan Glauber (jang@de.ibm.com)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#include <crypto/internal/hash.h>
|
||||
#include <crypto/sha.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "sha.h"
|
||||
#include "crypt_s390.h"
|
||||
|
||||
static int sha512_init(struct shash_desc *desc)
|
||||
{
|
||||
struct s390_sha_ctx *ctx = shash_desc_ctx(desc);
|
||||
|
||||
*(__u64 *)&ctx->state[0] = 0x6a09e667f3bcc908ULL;
|
||||
*(__u64 *)&ctx->state[2] = 0xbb67ae8584caa73bULL;
|
||||
*(__u64 *)&ctx->state[4] = 0x3c6ef372fe94f82bULL;
|
||||
*(__u64 *)&ctx->state[6] = 0xa54ff53a5f1d36f1ULL;
|
||||
*(__u64 *)&ctx->state[8] = 0x510e527fade682d1ULL;
|
||||
*(__u64 *)&ctx->state[10] = 0x9b05688c2b3e6c1fULL;
|
||||
*(__u64 *)&ctx->state[12] = 0x1f83d9abfb41bd6bULL;
|
||||
*(__u64 *)&ctx->state[14] = 0x5be0cd19137e2179ULL;
|
||||
ctx->count = 0;
|
||||
ctx->func = KIMD_SHA_512;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sha512_export(struct shash_desc *desc, void *out)
|
||||
{
|
||||
struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
|
||||
struct sha512_state *octx = out;
|
||||
|
||||
octx->count[0] = sctx->count;
|
||||
octx->count[1] = 0;
|
||||
memcpy(octx->state, sctx->state, sizeof(octx->state));
|
||||
memcpy(octx->buf, sctx->buf, sizeof(octx->buf));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sha512_import(struct shash_desc *desc, const void *in)
|
||||
{
|
||||
struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
|
||||
const struct sha512_state *ictx = in;
|
||||
|
||||
if (unlikely(ictx->count[1]))
|
||||
return -ERANGE;
|
||||
sctx->count = ictx->count[0];
|
||||
|
||||
memcpy(sctx->state, ictx->state, sizeof(ictx->state));
|
||||
memcpy(sctx->buf, ictx->buf, sizeof(ictx->buf));
|
||||
sctx->func = KIMD_SHA_512;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct shash_alg sha512_alg = {
|
||||
.digestsize = SHA512_DIGEST_SIZE,
|
||||
.init = sha512_init,
|
||||
.update = s390_sha_update,
|
||||
.final = s390_sha_final,
|
||||
.export = sha512_export,
|
||||
.import = sha512_import,
|
||||
.descsize = sizeof(struct s390_sha_ctx),
|
||||
.statesize = sizeof(struct sha512_state),
|
||||
.base = {
|
||||
.cra_name = "sha512",
|
||||
.cra_driver_name= "sha512-s390",
|
||||
.cra_priority = CRYPT_S390_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_SHASH,
|
||||
.cra_blocksize = SHA512_BLOCK_SIZE,
|
||||
.cra_module = THIS_MODULE,
|
||||
}
|
||||
};
|
||||
|
||||
MODULE_ALIAS_CRYPTO("sha512");
|
||||
|
||||
static int sha384_init(struct shash_desc *desc)
|
||||
{
|
||||
struct s390_sha_ctx *ctx = shash_desc_ctx(desc);
|
||||
|
||||
*(__u64 *)&ctx->state[0] = 0xcbbb9d5dc1059ed8ULL;
|
||||
*(__u64 *)&ctx->state[2] = 0x629a292a367cd507ULL;
|
||||
*(__u64 *)&ctx->state[4] = 0x9159015a3070dd17ULL;
|
||||
*(__u64 *)&ctx->state[6] = 0x152fecd8f70e5939ULL;
|
||||
*(__u64 *)&ctx->state[8] = 0x67332667ffc00b31ULL;
|
||||
*(__u64 *)&ctx->state[10] = 0x8eb44a8768581511ULL;
|
||||
*(__u64 *)&ctx->state[12] = 0xdb0c2e0d64f98fa7ULL;
|
||||
*(__u64 *)&ctx->state[14] = 0x47b5481dbefa4fa4ULL;
|
||||
ctx->count = 0;
|
||||
ctx->func = KIMD_SHA_512;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct shash_alg sha384_alg = {
|
||||
.digestsize = SHA384_DIGEST_SIZE,
|
||||
.init = sha384_init,
|
||||
.update = s390_sha_update,
|
||||
.final = s390_sha_final,
|
||||
.export = sha512_export,
|
||||
.import = sha512_import,
|
||||
.descsize = sizeof(struct s390_sha_ctx),
|
||||
.statesize = sizeof(struct sha512_state),
|
||||
.base = {
|
||||
.cra_name = "sha384",
|
||||
.cra_driver_name= "sha384-s390",
|
||||
.cra_priority = CRYPT_S390_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_SHASH,
|
||||
.cra_blocksize = SHA384_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct s390_sha_ctx),
|
||||
.cra_module = THIS_MODULE,
|
||||
}
|
||||
};
|
||||
|
||||
MODULE_ALIAS_CRYPTO("sha384");
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!crypt_s390_func_available(KIMD_SHA_512, CRYPT_S390_MSA))
|
||||
return -EOPNOTSUPP;
|
||||
if ((ret = crypto_register_shash(&sha512_alg)) < 0)
|
||||
goto out;
|
||||
if ((ret = crypto_register_shash(&sha384_alg)) < 0)
|
||||
crypto_unregister_shash(&sha512_alg);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
crypto_unregister_shash(&sha512_alg);
|
||||
crypto_unregister_shash(&sha384_alg);
|
||||
}
|
||||
|
||||
module_init(init);
|
||||
module_exit(fini);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("SHA512 and SHA-384 Secure Hash Algorithm");
|
||||
106
arch/s390/crypto/sha_common.c
Normal file
106
arch/s390/crypto/sha_common.c
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* Cryptographic API.
|
||||
*
|
||||
* s390 generic implementation of the SHA Secure Hash Algorithms.
|
||||
*
|
||||
* Copyright IBM Corp. 2007
|
||||
* Author(s): Jan Glauber (jang@de.ibm.com)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <crypto/internal/hash.h>
|
||||
#include <linux/module.h>
|
||||
#include "sha.h"
|
||||
#include "crypt_s390.h"
|
||||
|
||||
int s390_sha_update(struct shash_desc *desc, const u8 *data, unsigned int len)
|
||||
{
|
||||
struct s390_sha_ctx *ctx = shash_desc_ctx(desc);
|
||||
unsigned int bsize = crypto_shash_blocksize(desc->tfm);
|
||||
unsigned int index;
|
||||
int ret;
|
||||
|
||||
/* how much is already in the buffer? */
|
||||
index = ctx->count & (bsize - 1);
|
||||
ctx->count += len;
|
||||
|
||||
if ((index + len) < bsize)
|
||||
goto store;
|
||||
|
||||
/* process one stored block */
|
||||
if (index) {
|
||||
memcpy(ctx->buf + index, data, bsize - index);
|
||||
ret = crypt_s390_kimd(ctx->func, ctx->state, ctx->buf, bsize);
|
||||
if (ret != bsize)
|
||||
return -EIO;
|
||||
data += bsize - index;
|
||||
len -= bsize - index;
|
||||
index = 0;
|
||||
}
|
||||
|
||||
/* process as many blocks as possible */
|
||||
if (len >= bsize) {
|
||||
ret = crypt_s390_kimd(ctx->func, ctx->state, data,
|
||||
len & ~(bsize - 1));
|
||||
if (ret != (len & ~(bsize - 1)))
|
||||
return -EIO;
|
||||
data += ret;
|
||||
len -= ret;
|
||||
}
|
||||
store:
|
||||
if (len)
|
||||
memcpy(ctx->buf + index , data, len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(s390_sha_update);
|
||||
|
||||
int s390_sha_final(struct shash_desc *desc, u8 *out)
|
||||
{
|
||||
struct s390_sha_ctx *ctx = shash_desc_ctx(desc);
|
||||
unsigned int bsize = crypto_shash_blocksize(desc->tfm);
|
||||
u64 bits;
|
||||
unsigned int index, end, plen;
|
||||
int ret;
|
||||
|
||||
/* SHA-512 uses 128 bit padding length */
|
||||
plen = (bsize > SHA256_BLOCK_SIZE) ? 16 : 8;
|
||||
|
||||
/* must perform manual padding */
|
||||
index = ctx->count & (bsize - 1);
|
||||
end = (index < bsize - plen) ? bsize : (2 * bsize);
|
||||
|
||||
/* start pad with 1 */
|
||||
ctx->buf[index] = 0x80;
|
||||
index++;
|
||||
|
||||
/* pad with zeros */
|
||||
memset(ctx->buf + index, 0x00, end - index - 8);
|
||||
|
||||
/*
|
||||
* Append message length. Well, SHA-512 wants a 128 bit length value,
|
||||
* nevertheless we use u64, should be enough for now...
|
||||
*/
|
||||
bits = ctx->count * 8;
|
||||
memcpy(ctx->buf + end - 8, &bits, sizeof(bits));
|
||||
|
||||
ret = crypt_s390_kimd(ctx->func, ctx->state, ctx->buf, end);
|
||||
if (ret != end)
|
||||
return -EIO;
|
||||
|
||||
/* copy digest to out */
|
||||
memcpy(out, ctx->state, crypto_shash_digestsize(desc->tfm));
|
||||
/* wipe context */
|
||||
memset(ctx, 0, sizeof *ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(s390_sha_final);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("s390 SHA cipher common functions");
|
||||
208
arch/s390/defconfig
Normal file
208
arch/s390/defconfig
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
CONFIG_SYSVIPC=y
|
||||
CONFIG_POSIX_MQUEUE=y
|
||||
CONFIG_FHANDLE=y
|
||||
CONFIG_AUDIT=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_RCU_FAST_NO_HZ=y
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_CGROUPS=y
|
||||
CONFIG_CPUSETS=y
|
||||
CONFIG_CGROUP_CPUACCT=y
|
||||
CONFIG_RESOURCE_COUNTERS=y
|
||||
CONFIG_MEMCG=y
|
||||
CONFIG_MEMCG_SWAP=y
|
||||
CONFIG_CGROUP_SCHED=y
|
||||
CONFIG_RT_GROUP_SCHED=y
|
||||
CONFIG_BLK_CGROUP=y
|
||||
CONFIG_NAMESPACES=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
CONFIG_RD_BZIP2=y
|
||||
CONFIG_RD_LZMA=y
|
||||
CONFIG_RD_XZ=y
|
||||
CONFIG_RD_LZO=y
|
||||
CONFIG_RD_LZ4=y
|
||||
CONFIG_EXPERT=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_PARTITION_ADVANCED=y
|
||||
CONFIG_IBM_PARTITION=y
|
||||
CONFIG_DEFAULT_DEADLINE=y
|
||||
CONFIG_MARCH_Z196=y
|
||||
CONFIG_NR_CPUS=256
|
||||
CONFIG_HZ_100=y
|
||||
CONFIG_MEMORY_HOTPLUG=y
|
||||
CONFIG_MEMORY_HOTREMOVE=y
|
||||
CONFIG_KSM=y
|
||||
CONFIG_TRANSPARENT_HUGEPAGE=y
|
||||
CONFIG_CMA=y
|
||||
CONFIG_CRASH_DUMP=y
|
||||
CONFIG_BINFMT_MISC=m
|
||||
CONFIG_HIBERNATION=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_NET_KEY=y
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
# CONFIG_INET_LRO is not set
|
||||
CONFIG_IPV6=y
|
||||
CONFIG_L2TP=m
|
||||
CONFIG_L2TP_DEBUGFS=m
|
||||
CONFIG_VLAN_8021Q=y
|
||||
CONFIG_NET_SCHED=y
|
||||
CONFIG_NET_SCH_CBQ=m
|
||||
CONFIG_NET_SCH_PRIO=m
|
||||
CONFIG_NET_SCH_RED=m
|
||||
CONFIG_NET_SCH_SFQ=m
|
||||
CONFIG_NET_SCH_TEQL=m
|
||||
CONFIG_NET_SCH_TBF=m
|
||||
CONFIG_NET_SCH_GRED=m
|
||||
CONFIG_NET_SCH_DSMARK=m
|
||||
CONFIG_NET_CLS_TCINDEX=m
|
||||
CONFIG_NET_CLS_ROUTE4=m
|
||||
CONFIG_NET_CLS_FW=m
|
||||
CONFIG_NET_CLS_U32=m
|
||||
CONFIG_CLS_U32_MARK=y
|
||||
CONFIG_NET_CLS_RSVP=m
|
||||
CONFIG_NET_CLS_RSVP6=m
|
||||
CONFIG_NET_CLS_ACT=y
|
||||
CONFIG_NET_ACT_POLICE=y
|
||||
CONFIG_BPF_JIT=y
|
||||
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_BLK_DEV_LOOP=m
|
||||
CONFIG_BLK_DEV_NBD=m
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_VIRTIO_BLK=y
|
||||
CONFIG_SCSI=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_CONSTANTS=y
|
||||
CONFIG_SCSI_LOGGING=y
|
||||
CONFIG_SCSI_SCAN_ASYNC=y
|
||||
CONFIG_SCSI_FC_ATTRS=y
|
||||
CONFIG_ZFCP=y
|
||||
CONFIG_SCSI_VIRTIO=y
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_BONDING=m
|
||||
CONFIG_DUMMY=m
|
||||
CONFIG_EQUALIZER=m
|
||||
CONFIG_TUN=m
|
||||
CONFIG_VIRTIO_NET=y
|
||||
# CONFIG_INPUT is not set
|
||||
# CONFIG_SERIO is not set
|
||||
CONFIG_RAW_DRIVER=m
|
||||
CONFIG_VIRTIO_BALLOON=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
CONFIG_XFS_FS=y
|
||||
CONFIG_XFS_QUOTA=y
|
||||
CONFIG_XFS_POSIX_ACL=y
|
||||
CONFIG_XFS_RT=y
|
||||
CONFIG_BTRFS_FS=y
|
||||
CONFIG_BTRFS_FS_POSIX_ACL=y
|
||||
CONFIG_FANOTIFY=y
|
||||
CONFIG_FUSE_FS=y
|
||||
CONFIG_PROC_KCORE=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
CONFIG_HUGETLBFS=y
|
||||
# CONFIG_NETWORK_FILESYSTEMS is not set
|
||||
CONFIG_UNUSED_SYMBOLS=y
|
||||
CONFIG_DEBUG_SECTION_MISMATCH=y
|
||||
CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_DEBUG_PAGEALLOC=y
|
||||
CONFIG_DETECT_HUNG_TASK=y
|
||||
CONFIG_TIMER_STATS=y
|
||||
CONFIG_DEBUG_RT_MUTEXES=y
|
||||
CONFIG_PROVE_LOCKING=y
|
||||
CONFIG_LOCK_STAT=y
|
||||
CONFIG_DEBUG_LOCKDEP=y
|
||||
CONFIG_DEBUG_ATOMIC_SLEEP=y
|
||||
CONFIG_DEBUG_LIST=y
|
||||
CONFIG_DEBUG_PI_LIST=y
|
||||
CONFIG_DEBUG_SG=y
|
||||
CONFIG_DEBUG_NOTIFIERS=y
|
||||
CONFIG_PROVE_RCU=y
|
||||
CONFIG_RCU_CPU_STALL_TIMEOUT=60
|
||||
CONFIG_RCU_TRACE=y
|
||||
CONFIG_LATENCYTOP=y
|
||||
CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y
|
||||
CONFIG_BLK_DEV_IO_TRACE=y
|
||||
CONFIG_KPROBES_SANITY_TEST=y
|
||||
# CONFIG_STRICT_DEVMEM is not set
|
||||
CONFIG_S390_PTDUMP=y
|
||||
CONFIG_CRYPTO_CRYPTD=m
|
||||
CONFIG_CRYPTO_AUTHENC=m
|
||||
CONFIG_CRYPTO_TEST=m
|
||||
CONFIG_CRYPTO_CCM=m
|
||||
CONFIG_CRYPTO_GCM=m
|
||||
CONFIG_CRYPTO_CBC=y
|
||||
CONFIG_CRYPTO_CTS=m
|
||||
CONFIG_CRYPTO_ECB=m
|
||||
CONFIG_CRYPTO_LRW=m
|
||||
CONFIG_CRYPTO_PCBC=m
|
||||
CONFIG_CRYPTO_XTS=m
|
||||
CONFIG_CRYPTO_CMAC=m
|
||||
CONFIG_CRYPTO_XCBC=m
|
||||
CONFIG_CRYPTO_VMAC=m
|
||||
CONFIG_CRYPTO_CRC32=m
|
||||
CONFIG_CRYPTO_MD4=m
|
||||
CONFIG_CRYPTO_MICHAEL_MIC=m
|
||||
CONFIG_CRYPTO_RMD128=m
|
||||
CONFIG_CRYPTO_RMD160=m
|
||||
CONFIG_CRYPTO_RMD256=m
|
||||
CONFIG_CRYPTO_RMD320=m
|
||||
CONFIG_CRYPTO_SHA256=y
|
||||
CONFIG_CRYPTO_SHA512=m
|
||||
CONFIG_CRYPTO_TGR192=m
|
||||
CONFIG_CRYPTO_WP512=m
|
||||
CONFIG_CRYPTO_ANUBIS=m
|
||||
CONFIG_CRYPTO_ARC4=m
|
||||
CONFIG_CRYPTO_BLOWFISH=m
|
||||
CONFIG_CRYPTO_CAMELLIA=m
|
||||
CONFIG_CRYPTO_CAST5=m
|
||||
CONFIG_CRYPTO_CAST6=m
|
||||
CONFIG_CRYPTO_FCRYPT=m
|
||||
CONFIG_CRYPTO_KHAZAD=m
|
||||
CONFIG_CRYPTO_SALSA20=m
|
||||
CONFIG_CRYPTO_SEED=m
|
||||
CONFIG_CRYPTO_SERPENT=m
|
||||
CONFIG_CRYPTO_TEA=m
|
||||
CONFIG_CRYPTO_TWOFISH=m
|
||||
CONFIG_CRYPTO_DEFLATE=m
|
||||
CONFIG_CRYPTO_ZLIB=m
|
||||
CONFIG_CRYPTO_LZO=m
|
||||
CONFIG_CRYPTO_LZ4=m
|
||||
CONFIG_CRYPTO_LZ4HC=m
|
||||
CONFIG_ZCRYPT=m
|
||||
CONFIG_CRYPTO_SHA1_S390=m
|
||||
CONFIG_CRYPTO_SHA256_S390=m
|
||||
CONFIG_CRYPTO_SHA512_S390=m
|
||||
CONFIG_CRYPTO_DES_S390=m
|
||||
CONFIG_CRYPTO_AES_S390=m
|
||||
CONFIG_CRC7=m
|
||||
# CONFIG_XZ_DEC_X86 is not set
|
||||
# CONFIG_XZ_DEC_POWERPC is not set
|
||||
# CONFIG_XZ_DEC_IA64 is not set
|
||||
# CONFIG_XZ_DEC_ARM is not set
|
||||
# CONFIG_XZ_DEC_ARMTHUMB is not set
|
||||
# CONFIG_XZ_DEC_SPARC is not set
|
||||
CONFIG_CMM=m
|
||||
7
arch/s390/hypfs/Makefile
Normal file
7
arch/s390/hypfs/Makefile
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#
|
||||
# Makefile for the linux hypfs filesystem routines.
|
||||
#
|
||||
|
||||
obj-$(CONFIG_S390_HYPFS_FS) += s390_hypfs.o
|
||||
|
||||
s390_hypfs-objs := inode.o hypfs_diag.o hypfs_vm.o hypfs_dbfs.o hypfs_sprp.o
|
||||
75
arch/s390/hypfs/hypfs.h
Normal file
75
arch/s390/hypfs/hypfs.h
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Hypervisor filesystem for Linux on s390.
|
||||
*
|
||||
* Copyright IBM Corp. 2006
|
||||
* Author(s): Michael Holzheu <holzheu@de.ibm.com>
|
||||
*/
|
||||
|
||||
#ifndef _HYPFS_H_
|
||||
#define _HYPFS_H_
|
||||
|
||||
#include <linux/fs.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/kref.h>
|
||||
#include <asm/hypfs.h>
|
||||
|
||||
#define REG_FILE_MODE 0440
|
||||
#define UPDATE_FILE_MODE 0220
|
||||
#define DIR_MODE 0550
|
||||
|
||||
extern struct dentry *hypfs_mkdir(struct dentry *parent, const char *name);
|
||||
|
||||
extern struct dentry *hypfs_create_u64(struct dentry *dir, const char *name,
|
||||
__u64 value);
|
||||
|
||||
extern struct dentry *hypfs_create_str(struct dentry *dir, const char *name,
|
||||
char *string);
|
||||
|
||||
/* LPAR Hypervisor */
|
||||
extern int hypfs_diag_init(void);
|
||||
extern void hypfs_diag_exit(void);
|
||||
extern int hypfs_diag_create_files(struct dentry *root);
|
||||
|
||||
/* VM Hypervisor */
|
||||
extern int hypfs_vm_init(void);
|
||||
extern void hypfs_vm_exit(void);
|
||||
extern int hypfs_vm_create_files(struct dentry *root);
|
||||
|
||||
/* Set Partition-Resource Parameter */
|
||||
int hypfs_sprp_init(void);
|
||||
void hypfs_sprp_exit(void);
|
||||
|
||||
/* debugfs interface */
|
||||
struct hypfs_dbfs_file;
|
||||
|
||||
struct hypfs_dbfs_data {
|
||||
void *buf;
|
||||
void *buf_free_ptr;
|
||||
size_t size;
|
||||
struct hypfs_dbfs_file *dbfs_file;
|
||||
struct kref kref;
|
||||
};
|
||||
|
||||
struct hypfs_dbfs_file {
|
||||
const char *name;
|
||||
int (*data_create)(void **data, void **data_free_ptr,
|
||||
size_t *size);
|
||||
void (*data_free)(const void *buf_free_ptr);
|
||||
long (*unlocked_ioctl) (struct file *, unsigned int,
|
||||
unsigned long);
|
||||
|
||||
/* Private data for hypfs_dbfs.c */
|
||||
struct hypfs_dbfs_data *data;
|
||||
struct delayed_work data_free_work;
|
||||
struct mutex lock;
|
||||
struct dentry *dentry;
|
||||
};
|
||||
|
||||
extern int hypfs_dbfs_init(void);
|
||||
extern void hypfs_dbfs_exit(void);
|
||||
extern int hypfs_dbfs_create_file(struct hypfs_dbfs_file *df);
|
||||
extern void hypfs_dbfs_remove_file(struct hypfs_dbfs_file *df);
|
||||
|
||||
#endif /* _HYPFS_H_ */
|
||||
130
arch/s390/hypfs/hypfs_dbfs.c
Normal file
130
arch/s390/hypfs/hypfs_dbfs.c
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* Hypervisor filesystem for Linux on s390 - debugfs interface
|
||||
*
|
||||
* Copyright IBM Corp. 2010
|
||||
* Author(s): Michael Holzheu <holzheu@linux.vnet.ibm.com>
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include "hypfs.h"
|
||||
|
||||
static struct dentry *dbfs_dir;
|
||||
|
||||
static struct hypfs_dbfs_data *hypfs_dbfs_data_alloc(struct hypfs_dbfs_file *f)
|
||||
{
|
||||
struct hypfs_dbfs_data *data;
|
||||
|
||||
data = kmalloc(sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return NULL;
|
||||
kref_init(&data->kref);
|
||||
data->dbfs_file = f;
|
||||
return data;
|
||||
}
|
||||
|
||||
static void hypfs_dbfs_data_free(struct kref *kref)
|
||||
{
|
||||
struct hypfs_dbfs_data *data;
|
||||
|
||||
data = container_of(kref, struct hypfs_dbfs_data, kref);
|
||||
data->dbfs_file->data_free(data->buf_free_ptr);
|
||||
kfree(data);
|
||||
}
|
||||
|
||||
static void data_free_delayed(struct work_struct *work)
|
||||
{
|
||||
struct hypfs_dbfs_data *data;
|
||||
struct hypfs_dbfs_file *df;
|
||||
|
||||
df = container_of(work, struct hypfs_dbfs_file, data_free_work.work);
|
||||
mutex_lock(&df->lock);
|
||||
data = df->data;
|
||||
df->data = NULL;
|
||||
mutex_unlock(&df->lock);
|
||||
kref_put(&data->kref, hypfs_dbfs_data_free);
|
||||
}
|
||||
|
||||
static ssize_t dbfs_read(struct file *file, char __user *buf,
|
||||
size_t size, loff_t *ppos)
|
||||
{
|
||||
struct hypfs_dbfs_data *data;
|
||||
struct hypfs_dbfs_file *df;
|
||||
ssize_t rc;
|
||||
|
||||
if (*ppos != 0)
|
||||
return 0;
|
||||
|
||||
df = file_inode(file)->i_private;
|
||||
mutex_lock(&df->lock);
|
||||
if (!df->data) {
|
||||
data = hypfs_dbfs_data_alloc(df);
|
||||
if (!data) {
|
||||
mutex_unlock(&df->lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
rc = df->data_create(&data->buf, &data->buf_free_ptr,
|
||||
&data->size);
|
||||
if (rc) {
|
||||
mutex_unlock(&df->lock);
|
||||
kfree(data);
|
||||
return rc;
|
||||
}
|
||||
df->data = data;
|
||||
schedule_delayed_work(&df->data_free_work, HZ);
|
||||
}
|
||||
data = df->data;
|
||||
kref_get(&data->kref);
|
||||
mutex_unlock(&df->lock);
|
||||
|
||||
rc = simple_read_from_buffer(buf, size, ppos, data->buf, data->size);
|
||||
kref_put(&data->kref, hypfs_dbfs_data_free);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static long dbfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct hypfs_dbfs_file *df;
|
||||
long rc;
|
||||
|
||||
df = file->f_path.dentry->d_inode->i_private;
|
||||
mutex_lock(&df->lock);
|
||||
if (df->unlocked_ioctl)
|
||||
rc = df->unlocked_ioctl(file, cmd, arg);
|
||||
else
|
||||
rc = -ENOTTY;
|
||||
mutex_unlock(&df->lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static const struct file_operations dbfs_ops = {
|
||||
.read = dbfs_read,
|
||||
.llseek = no_llseek,
|
||||
.unlocked_ioctl = dbfs_ioctl,
|
||||
};
|
||||
|
||||
int hypfs_dbfs_create_file(struct hypfs_dbfs_file *df)
|
||||
{
|
||||
df->dentry = debugfs_create_file(df->name, 0400, dbfs_dir, df,
|
||||
&dbfs_ops);
|
||||
if (IS_ERR(df->dentry))
|
||||
return PTR_ERR(df->dentry);
|
||||
mutex_init(&df->lock);
|
||||
INIT_DELAYED_WORK(&df->data_free_work, data_free_delayed);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hypfs_dbfs_remove_file(struct hypfs_dbfs_file *df)
|
||||
{
|
||||
debugfs_remove(df->dentry);
|
||||
}
|
||||
|
||||
int hypfs_dbfs_init(void)
|
||||
{
|
||||
dbfs_dir = debugfs_create_dir("s390_hypfs", NULL);
|
||||
return PTR_ERR_OR_ZERO(dbfs_dir);
|
||||
}
|
||||
|
||||
void hypfs_dbfs_exit(void)
|
||||
{
|
||||
debugfs_remove(dbfs_dir);
|
||||
}
|
||||
769
arch/s390/hypfs/hypfs_diag.c
Normal file
769
arch/s390/hypfs/hypfs_diag.c
Normal file
|
|
@ -0,0 +1,769 @@
|
|||
/*
|
||||
* Hypervisor filesystem for Linux on s390. Diag 204 and 224
|
||||
* implementation.
|
||||
*
|
||||
* Copyright IBM Corp. 2006, 2008
|
||||
* Author(s): Michael Holzheu <holzheu@de.ibm.com>
|
||||
*/
|
||||
|
||||
#define KMSG_COMPONENT "hypfs"
|
||||
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/mm.h>
|
||||
#include <asm/ebcdic.h>
|
||||
#include "hypfs.h"
|
||||
|
||||
#define LPAR_NAME_LEN 8 /* lpar name len in diag 204 data */
|
||||
#define CPU_NAME_LEN 16 /* type name len of cpus in diag224 name table */
|
||||
#define TMP_SIZE 64 /* size of temporary buffers */
|
||||
|
||||
#define DBFS_D204_HDR_VERSION 0
|
||||
|
||||
/* diag 204 subcodes */
|
||||
enum diag204_sc {
|
||||
SUBC_STIB4 = 4,
|
||||
SUBC_RSI = 5,
|
||||
SUBC_STIB6 = 6,
|
||||
SUBC_STIB7 = 7
|
||||
};
|
||||
|
||||
/* The two available diag 204 data formats */
|
||||
enum diag204_format {
|
||||
INFO_SIMPLE = 0,
|
||||
INFO_EXT = 0x00010000
|
||||
};
|
||||
|
||||
/* bit is set in flags, when physical cpu info is included in diag 204 data */
|
||||
#define LPAR_PHYS_FLG 0x80
|
||||
|
||||
static char *diag224_cpu_names; /* diag 224 name table */
|
||||
static enum diag204_sc diag204_store_sc; /* used subcode for store */
|
||||
static enum diag204_format diag204_info_type; /* used diag 204 data format */
|
||||
|
||||
static void *diag204_buf; /* 4K aligned buffer for diag204 data */
|
||||
static void *diag204_buf_vmalloc; /* vmalloc pointer for diag204 data */
|
||||
static int diag204_buf_pages; /* number of pages for diag204 data */
|
||||
|
||||
static struct dentry *dbfs_d204_file;
|
||||
|
||||
/*
|
||||
* DIAG 204 data structures and member access functions.
|
||||
*
|
||||
* Since we have two different diag 204 data formats for old and new s390
|
||||
* machines, we do not access the structs directly, but use getter functions for
|
||||
* each struct member instead. This should make the code more readable.
|
||||
*/
|
||||
|
||||
/* Time information block */
|
||||
|
||||
struct info_blk_hdr {
|
||||
__u8 npar;
|
||||
__u8 flags;
|
||||
__u16 tslice;
|
||||
__u16 phys_cpus;
|
||||
__u16 this_part;
|
||||
__u64 curtod;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct x_info_blk_hdr {
|
||||
__u8 npar;
|
||||
__u8 flags;
|
||||
__u16 tslice;
|
||||
__u16 phys_cpus;
|
||||
__u16 this_part;
|
||||
__u64 curtod1;
|
||||
__u64 curtod2;
|
||||
char reserved[40];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
static inline int info_blk_hdr__size(enum diag204_format type)
|
||||
{
|
||||
if (type == INFO_SIMPLE)
|
||||
return sizeof(struct info_blk_hdr);
|
||||
else /* INFO_EXT */
|
||||
return sizeof(struct x_info_blk_hdr);
|
||||
}
|
||||
|
||||
static inline __u8 info_blk_hdr__npar(enum diag204_format type, void *hdr)
|
||||
{
|
||||
if (type == INFO_SIMPLE)
|
||||
return ((struct info_blk_hdr *)hdr)->npar;
|
||||
else /* INFO_EXT */
|
||||
return ((struct x_info_blk_hdr *)hdr)->npar;
|
||||
}
|
||||
|
||||
static inline __u8 info_blk_hdr__flags(enum diag204_format type, void *hdr)
|
||||
{
|
||||
if (type == INFO_SIMPLE)
|
||||
return ((struct info_blk_hdr *)hdr)->flags;
|
||||
else /* INFO_EXT */
|
||||
return ((struct x_info_blk_hdr *)hdr)->flags;
|
||||
}
|
||||
|
||||
static inline __u16 info_blk_hdr__pcpus(enum diag204_format type, void *hdr)
|
||||
{
|
||||
if (type == INFO_SIMPLE)
|
||||
return ((struct info_blk_hdr *)hdr)->phys_cpus;
|
||||
else /* INFO_EXT */
|
||||
return ((struct x_info_blk_hdr *)hdr)->phys_cpus;
|
||||
}
|
||||
|
||||
/* Partition header */
|
||||
|
||||
struct part_hdr {
|
||||
__u8 pn;
|
||||
__u8 cpus;
|
||||
char reserved[6];
|
||||
char part_name[LPAR_NAME_LEN];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct x_part_hdr {
|
||||
__u8 pn;
|
||||
__u8 cpus;
|
||||
__u8 rcpus;
|
||||
__u8 pflag;
|
||||
__u32 mlu;
|
||||
char part_name[LPAR_NAME_LEN];
|
||||
char lpc_name[8];
|
||||
char os_name[8];
|
||||
__u64 online_cs;
|
||||
__u64 online_es;
|
||||
__u8 upid;
|
||||
char reserved1[3];
|
||||
__u32 group_mlu;
|
||||
char group_name[8];
|
||||
char reserved2[32];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
static inline int part_hdr__size(enum diag204_format type)
|
||||
{
|
||||
if (type == INFO_SIMPLE)
|
||||
return sizeof(struct part_hdr);
|
||||
else /* INFO_EXT */
|
||||
return sizeof(struct x_part_hdr);
|
||||
}
|
||||
|
||||
static inline __u8 part_hdr__rcpus(enum diag204_format type, void *hdr)
|
||||
{
|
||||
if (type == INFO_SIMPLE)
|
||||
return ((struct part_hdr *)hdr)->cpus;
|
||||
else /* INFO_EXT */
|
||||
return ((struct x_part_hdr *)hdr)->rcpus;
|
||||
}
|
||||
|
||||
static inline void part_hdr__part_name(enum diag204_format type, void *hdr,
|
||||
char *name)
|
||||
{
|
||||
if (type == INFO_SIMPLE)
|
||||
memcpy(name, ((struct part_hdr *)hdr)->part_name,
|
||||
LPAR_NAME_LEN);
|
||||
else /* INFO_EXT */
|
||||
memcpy(name, ((struct x_part_hdr *)hdr)->part_name,
|
||||
LPAR_NAME_LEN);
|
||||
EBCASC(name, LPAR_NAME_LEN);
|
||||
name[LPAR_NAME_LEN] = 0;
|
||||
strim(name);
|
||||
}
|
||||
|
||||
struct cpu_info {
|
||||
__u16 cpu_addr;
|
||||
char reserved1[2];
|
||||
__u8 ctidx;
|
||||
__u8 cflag;
|
||||
__u16 weight;
|
||||
__u64 acc_time;
|
||||
__u64 lp_time;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct x_cpu_info {
|
||||
__u16 cpu_addr;
|
||||
char reserved1[2];
|
||||
__u8 ctidx;
|
||||
__u8 cflag;
|
||||
__u16 weight;
|
||||
__u64 acc_time;
|
||||
__u64 lp_time;
|
||||
__u16 min_weight;
|
||||
__u16 cur_weight;
|
||||
__u16 max_weight;
|
||||
char reseved2[2];
|
||||
__u64 online_time;
|
||||
__u64 wait_time;
|
||||
__u32 pma_weight;
|
||||
__u32 polar_weight;
|
||||
char reserved3[40];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* CPU info block */
|
||||
|
||||
static inline int cpu_info__size(enum diag204_format type)
|
||||
{
|
||||
if (type == INFO_SIMPLE)
|
||||
return sizeof(struct cpu_info);
|
||||
else /* INFO_EXT */
|
||||
return sizeof(struct x_cpu_info);
|
||||
}
|
||||
|
||||
static inline __u8 cpu_info__ctidx(enum diag204_format type, void *hdr)
|
||||
{
|
||||
if (type == INFO_SIMPLE)
|
||||
return ((struct cpu_info *)hdr)->ctidx;
|
||||
else /* INFO_EXT */
|
||||
return ((struct x_cpu_info *)hdr)->ctidx;
|
||||
}
|
||||
|
||||
static inline __u16 cpu_info__cpu_addr(enum diag204_format type, void *hdr)
|
||||
{
|
||||
if (type == INFO_SIMPLE)
|
||||
return ((struct cpu_info *)hdr)->cpu_addr;
|
||||
else /* INFO_EXT */
|
||||
return ((struct x_cpu_info *)hdr)->cpu_addr;
|
||||
}
|
||||
|
||||
static inline __u64 cpu_info__acc_time(enum diag204_format type, void *hdr)
|
||||
{
|
||||
if (type == INFO_SIMPLE)
|
||||
return ((struct cpu_info *)hdr)->acc_time;
|
||||
else /* INFO_EXT */
|
||||
return ((struct x_cpu_info *)hdr)->acc_time;
|
||||
}
|
||||
|
||||
static inline __u64 cpu_info__lp_time(enum diag204_format type, void *hdr)
|
||||
{
|
||||
if (type == INFO_SIMPLE)
|
||||
return ((struct cpu_info *)hdr)->lp_time;
|
||||
else /* INFO_EXT */
|
||||
return ((struct x_cpu_info *)hdr)->lp_time;
|
||||
}
|
||||
|
||||
static inline __u64 cpu_info__online_time(enum diag204_format type, void *hdr)
|
||||
{
|
||||
if (type == INFO_SIMPLE)
|
||||
return 0; /* online_time not available in simple info */
|
||||
else /* INFO_EXT */
|
||||
return ((struct x_cpu_info *)hdr)->online_time;
|
||||
}
|
||||
|
||||
/* Physical header */
|
||||
|
||||
struct phys_hdr {
|
||||
char reserved1[1];
|
||||
__u8 cpus;
|
||||
char reserved2[6];
|
||||
char mgm_name[8];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct x_phys_hdr {
|
||||
char reserved1[1];
|
||||
__u8 cpus;
|
||||
char reserved2[6];
|
||||
char mgm_name[8];
|
||||
char reserved3[80];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
static inline int phys_hdr__size(enum diag204_format type)
|
||||
{
|
||||
if (type == INFO_SIMPLE)
|
||||
return sizeof(struct phys_hdr);
|
||||
else /* INFO_EXT */
|
||||
return sizeof(struct x_phys_hdr);
|
||||
}
|
||||
|
||||
static inline __u8 phys_hdr__cpus(enum diag204_format type, void *hdr)
|
||||
{
|
||||
if (type == INFO_SIMPLE)
|
||||
return ((struct phys_hdr *)hdr)->cpus;
|
||||
else /* INFO_EXT */
|
||||
return ((struct x_phys_hdr *)hdr)->cpus;
|
||||
}
|
||||
|
||||
/* Physical CPU info block */
|
||||
|
||||
struct phys_cpu {
|
||||
__u16 cpu_addr;
|
||||
char reserved1[2];
|
||||
__u8 ctidx;
|
||||
char reserved2[3];
|
||||
__u64 mgm_time;
|
||||
char reserved3[8];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct x_phys_cpu {
|
||||
__u16 cpu_addr;
|
||||
char reserved1[2];
|
||||
__u8 ctidx;
|
||||
char reserved2[3];
|
||||
__u64 mgm_time;
|
||||
char reserved3[80];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
static inline int phys_cpu__size(enum diag204_format type)
|
||||
{
|
||||
if (type == INFO_SIMPLE)
|
||||
return sizeof(struct phys_cpu);
|
||||
else /* INFO_EXT */
|
||||
return sizeof(struct x_phys_cpu);
|
||||
}
|
||||
|
||||
static inline __u16 phys_cpu__cpu_addr(enum diag204_format type, void *hdr)
|
||||
{
|
||||
if (type == INFO_SIMPLE)
|
||||
return ((struct phys_cpu *)hdr)->cpu_addr;
|
||||
else /* INFO_EXT */
|
||||
return ((struct x_phys_cpu *)hdr)->cpu_addr;
|
||||
}
|
||||
|
||||
static inline __u64 phys_cpu__mgm_time(enum diag204_format type, void *hdr)
|
||||
{
|
||||
if (type == INFO_SIMPLE)
|
||||
return ((struct phys_cpu *)hdr)->mgm_time;
|
||||
else /* INFO_EXT */
|
||||
return ((struct x_phys_cpu *)hdr)->mgm_time;
|
||||
}
|
||||
|
||||
static inline __u64 phys_cpu__ctidx(enum diag204_format type, void *hdr)
|
||||
{
|
||||
if (type == INFO_SIMPLE)
|
||||
return ((struct phys_cpu *)hdr)->ctidx;
|
||||
else /* INFO_EXT */
|
||||
return ((struct x_phys_cpu *)hdr)->ctidx;
|
||||
}
|
||||
|
||||
/* Diagnose 204 functions */
|
||||
|
||||
static int diag204(unsigned long subcode, unsigned long size, void *addr)
|
||||
{
|
||||
register unsigned long _subcode asm("0") = subcode;
|
||||
register unsigned long _size asm("1") = size;
|
||||
|
||||
asm volatile(
|
||||
" diag %2,%0,0x204\n"
|
||||
"0:\n"
|
||||
EX_TABLE(0b,0b)
|
||||
: "+d" (_subcode), "+d" (_size) : "d" (addr) : "memory");
|
||||
if (_subcode)
|
||||
return -1;
|
||||
return _size;
|
||||
}
|
||||
|
||||
/*
|
||||
* For the old diag subcode 4 with simple data format we have to use real
|
||||
* memory. If we use subcode 6 or 7 with extended data format, we can (and
|
||||
* should) use vmalloc, since we need a lot of memory in that case. Currently
|
||||
* up to 93 pages!
|
||||
*/
|
||||
|
||||
static void diag204_free_buffer(void)
|
||||
{
|
||||
if (!diag204_buf)
|
||||
return;
|
||||
if (diag204_buf_vmalloc) {
|
||||
vfree(diag204_buf_vmalloc);
|
||||
diag204_buf_vmalloc = NULL;
|
||||
} else {
|
||||
free_pages((unsigned long) diag204_buf, 0);
|
||||
}
|
||||
diag204_buf = NULL;
|
||||
}
|
||||
|
||||
static void *page_align_ptr(void *ptr)
|
||||
{
|
||||
return (void *) PAGE_ALIGN((unsigned long) ptr);
|
||||
}
|
||||
|
||||
static void *diag204_alloc_vbuf(int pages)
|
||||
{
|
||||
/* The buffer has to be page aligned! */
|
||||
diag204_buf_vmalloc = vmalloc(PAGE_SIZE * (pages + 1));
|
||||
if (!diag204_buf_vmalloc)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
diag204_buf = page_align_ptr(diag204_buf_vmalloc);
|
||||
diag204_buf_pages = pages;
|
||||
return diag204_buf;
|
||||
}
|
||||
|
||||
static void *diag204_alloc_rbuf(void)
|
||||
{
|
||||
diag204_buf = (void*)__get_free_pages(GFP_KERNEL,0);
|
||||
if (!diag204_buf)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
diag204_buf_pages = 1;
|
||||
return diag204_buf;
|
||||
}
|
||||
|
||||
static void *diag204_get_buffer(enum diag204_format fmt, int *pages)
|
||||
{
|
||||
if (diag204_buf) {
|
||||
*pages = diag204_buf_pages;
|
||||
return diag204_buf;
|
||||
}
|
||||
if (fmt == INFO_SIMPLE) {
|
||||
*pages = 1;
|
||||
return diag204_alloc_rbuf();
|
||||
} else {/* INFO_EXT */
|
||||
*pages = diag204((unsigned long)SUBC_RSI |
|
||||
(unsigned long)INFO_EXT, 0, NULL);
|
||||
if (*pages <= 0)
|
||||
return ERR_PTR(-ENOSYS);
|
||||
else
|
||||
return diag204_alloc_vbuf(*pages);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* diag204_probe() has to find out, which type of diagnose 204 implementation
|
||||
* we have on our machine. Currently there are three possible scanarios:
|
||||
* - subcode 4 + simple data format (only one page)
|
||||
* - subcode 4-6 + extended data format
|
||||
* - subcode 4-7 + extended data format
|
||||
*
|
||||
* Subcode 5 is used to retrieve the size of the data, provided by subcodes
|
||||
* 6 and 7. Subcode 7 basically has the same function as subcode 6. In addition
|
||||
* to subcode 6 it provides also information about secondary cpus.
|
||||
* In order to get as much information as possible, we first try
|
||||
* subcode 7, then 6 and if both fail, we use subcode 4.
|
||||
*/
|
||||
|
||||
static int diag204_probe(void)
|
||||
{
|
||||
void *buf;
|
||||
int pages, rc;
|
||||
|
||||
buf = diag204_get_buffer(INFO_EXT, &pages);
|
||||
if (!IS_ERR(buf)) {
|
||||
if (diag204((unsigned long)SUBC_STIB7 |
|
||||
(unsigned long)INFO_EXT, pages, buf) >= 0) {
|
||||
diag204_store_sc = SUBC_STIB7;
|
||||
diag204_info_type = INFO_EXT;
|
||||
goto out;
|
||||
}
|
||||
if (diag204((unsigned long)SUBC_STIB6 |
|
||||
(unsigned long)INFO_EXT, pages, buf) >= 0) {
|
||||
diag204_store_sc = SUBC_STIB6;
|
||||
diag204_info_type = INFO_EXT;
|
||||
goto out;
|
||||
}
|
||||
diag204_free_buffer();
|
||||
}
|
||||
|
||||
/* subcodes 6 and 7 failed, now try subcode 4 */
|
||||
|
||||
buf = diag204_get_buffer(INFO_SIMPLE, &pages);
|
||||
if (IS_ERR(buf)) {
|
||||
rc = PTR_ERR(buf);
|
||||
goto fail_alloc;
|
||||
}
|
||||
if (diag204((unsigned long)SUBC_STIB4 |
|
||||
(unsigned long)INFO_SIMPLE, pages, buf) >= 0) {
|
||||
diag204_store_sc = SUBC_STIB4;
|
||||
diag204_info_type = INFO_SIMPLE;
|
||||
goto out;
|
||||
} else {
|
||||
rc = -ENOSYS;
|
||||
goto fail_store;
|
||||
}
|
||||
out:
|
||||
rc = 0;
|
||||
fail_store:
|
||||
diag204_free_buffer();
|
||||
fail_alloc:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int diag204_do_store(void *buf, int pages)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = diag204((unsigned long) diag204_store_sc |
|
||||
(unsigned long) diag204_info_type, pages, buf);
|
||||
return rc < 0 ? -ENOSYS : 0;
|
||||
}
|
||||
|
||||
static void *diag204_store(void)
|
||||
{
|
||||
void *buf;
|
||||
int pages, rc;
|
||||
|
||||
buf = diag204_get_buffer(diag204_info_type, &pages);
|
||||
if (IS_ERR(buf))
|
||||
goto out;
|
||||
rc = diag204_do_store(buf, pages);
|
||||
if (rc)
|
||||
return ERR_PTR(rc);
|
||||
out:
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* Diagnose 224 functions */
|
||||
|
||||
static int diag224(void *ptr)
|
||||
{
|
||||
int rc = -EOPNOTSUPP;
|
||||
|
||||
asm volatile(
|
||||
" diag %1,%2,0x224\n"
|
||||
"0: lhi %0,0x0\n"
|
||||
"1:\n"
|
||||
EX_TABLE(0b,1b)
|
||||
: "+d" (rc) :"d" (0), "d" (ptr) : "memory");
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int diag224_get_name_table(void)
|
||||
{
|
||||
/* memory must be below 2GB */
|
||||
diag224_cpu_names = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA);
|
||||
if (!diag224_cpu_names)
|
||||
return -ENOMEM;
|
||||
if (diag224(diag224_cpu_names)) {
|
||||
kfree(diag224_cpu_names);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
EBCASC(diag224_cpu_names + 16, (*diag224_cpu_names + 1) * 16);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void diag224_delete_name_table(void)
|
||||
{
|
||||
kfree(diag224_cpu_names);
|
||||
}
|
||||
|
||||
static int diag224_idx2name(int index, char *name)
|
||||
{
|
||||
memcpy(name, diag224_cpu_names + ((index + 1) * CPU_NAME_LEN),
|
||||
CPU_NAME_LEN);
|
||||
name[CPU_NAME_LEN] = 0;
|
||||
strim(name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct dbfs_d204_hdr {
|
||||
u64 len; /* Length of d204 buffer without header */
|
||||
u16 version; /* Version of header */
|
||||
u8 sc; /* Used subcode */
|
||||
char reserved[53];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct dbfs_d204 {
|
||||
struct dbfs_d204_hdr hdr; /* 64 byte header */
|
||||
char buf[]; /* d204 buffer */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
static int dbfs_d204_create(void **data, void **data_free_ptr, size_t *size)
|
||||
{
|
||||
struct dbfs_d204 *d204;
|
||||
int rc, buf_size;
|
||||
void *base;
|
||||
|
||||
buf_size = PAGE_SIZE * (diag204_buf_pages + 1) + sizeof(d204->hdr);
|
||||
base = vzalloc(buf_size);
|
||||
if (!base)
|
||||
return -ENOMEM;
|
||||
d204 = page_align_ptr(base + sizeof(d204->hdr)) - sizeof(d204->hdr);
|
||||
rc = diag204_do_store(d204->buf, diag204_buf_pages);
|
||||
if (rc) {
|
||||
vfree(base);
|
||||
return rc;
|
||||
}
|
||||
d204->hdr.version = DBFS_D204_HDR_VERSION;
|
||||
d204->hdr.len = PAGE_SIZE * diag204_buf_pages;
|
||||
d204->hdr.sc = diag204_store_sc;
|
||||
*data = d204;
|
||||
*data_free_ptr = base;
|
||||
*size = d204->hdr.len + sizeof(struct dbfs_d204_hdr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct hypfs_dbfs_file dbfs_file_d204 = {
|
||||
.name = "diag_204",
|
||||
.data_create = dbfs_d204_create,
|
||||
.data_free = vfree,
|
||||
};
|
||||
|
||||
__init int hypfs_diag_init(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (diag204_probe()) {
|
||||
pr_err("The hardware system does not support hypfs\n");
|
||||
return -ENODATA;
|
||||
}
|
||||
if (diag204_info_type == INFO_EXT) {
|
||||
rc = hypfs_dbfs_create_file(&dbfs_file_d204);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
if (MACHINE_IS_LPAR) {
|
||||
rc = diag224_get_name_table();
|
||||
if (rc) {
|
||||
pr_err("The hardware system does not provide all "
|
||||
"functions required by hypfs\n");
|
||||
debugfs_remove(dbfs_d204_file);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hypfs_diag_exit(void)
|
||||
{
|
||||
debugfs_remove(dbfs_d204_file);
|
||||
diag224_delete_name_table();
|
||||
diag204_free_buffer();
|
||||
hypfs_dbfs_remove_file(&dbfs_file_d204);
|
||||
}
|
||||
|
||||
/*
|
||||
* Functions to create the directory structure
|
||||
* *******************************************
|
||||
*/
|
||||
|
||||
static int hypfs_create_cpu_files(struct dentry *cpus_dir, void *cpu_info)
|
||||
{
|
||||
struct dentry *cpu_dir;
|
||||
char buffer[TMP_SIZE];
|
||||
void *rc;
|
||||
|
||||
snprintf(buffer, TMP_SIZE, "%d", cpu_info__cpu_addr(diag204_info_type,
|
||||
cpu_info));
|
||||
cpu_dir = hypfs_mkdir(cpus_dir, buffer);
|
||||
rc = hypfs_create_u64(cpu_dir, "mgmtime",
|
||||
cpu_info__acc_time(diag204_info_type, cpu_info) -
|
||||
cpu_info__lp_time(diag204_info_type, cpu_info));
|
||||
if (IS_ERR(rc))
|
||||
return PTR_ERR(rc);
|
||||
rc = hypfs_create_u64(cpu_dir, "cputime",
|
||||
cpu_info__lp_time(diag204_info_type, cpu_info));
|
||||
if (IS_ERR(rc))
|
||||
return PTR_ERR(rc);
|
||||
if (diag204_info_type == INFO_EXT) {
|
||||
rc = hypfs_create_u64(cpu_dir, "onlinetime",
|
||||
cpu_info__online_time(diag204_info_type,
|
||||
cpu_info));
|
||||
if (IS_ERR(rc))
|
||||
return PTR_ERR(rc);
|
||||
}
|
||||
diag224_idx2name(cpu_info__ctidx(diag204_info_type, cpu_info), buffer);
|
||||
rc = hypfs_create_str(cpu_dir, "type", buffer);
|
||||
return PTR_RET(rc);
|
||||
}
|
||||
|
||||
static void *hypfs_create_lpar_files(struct dentry *systems_dir, void *part_hdr)
|
||||
{
|
||||
struct dentry *cpus_dir;
|
||||
struct dentry *lpar_dir;
|
||||
char lpar_name[LPAR_NAME_LEN + 1];
|
||||
void *cpu_info;
|
||||
int i;
|
||||
|
||||
part_hdr__part_name(diag204_info_type, part_hdr, lpar_name);
|
||||
lpar_name[LPAR_NAME_LEN] = 0;
|
||||
lpar_dir = hypfs_mkdir(systems_dir, lpar_name);
|
||||
if (IS_ERR(lpar_dir))
|
||||
return lpar_dir;
|
||||
cpus_dir = hypfs_mkdir(lpar_dir, "cpus");
|
||||
if (IS_ERR(cpus_dir))
|
||||
return cpus_dir;
|
||||
cpu_info = part_hdr + part_hdr__size(diag204_info_type);
|
||||
for (i = 0; i < part_hdr__rcpus(diag204_info_type, part_hdr); i++) {
|
||||
int rc;
|
||||
rc = hypfs_create_cpu_files(cpus_dir, cpu_info);
|
||||
if (rc)
|
||||
return ERR_PTR(rc);
|
||||
cpu_info += cpu_info__size(diag204_info_type);
|
||||
}
|
||||
return cpu_info;
|
||||
}
|
||||
|
||||
static int hypfs_create_phys_cpu_files(struct dentry *cpus_dir, void *cpu_info)
|
||||
{
|
||||
struct dentry *cpu_dir;
|
||||
char buffer[TMP_SIZE];
|
||||
void *rc;
|
||||
|
||||
snprintf(buffer, TMP_SIZE, "%i", phys_cpu__cpu_addr(diag204_info_type,
|
||||
cpu_info));
|
||||
cpu_dir = hypfs_mkdir(cpus_dir, buffer);
|
||||
if (IS_ERR(cpu_dir))
|
||||
return PTR_ERR(cpu_dir);
|
||||
rc = hypfs_create_u64(cpu_dir, "mgmtime",
|
||||
phys_cpu__mgm_time(diag204_info_type, cpu_info));
|
||||
if (IS_ERR(rc))
|
||||
return PTR_ERR(rc);
|
||||
diag224_idx2name(phys_cpu__ctidx(diag204_info_type, cpu_info), buffer);
|
||||
rc = hypfs_create_str(cpu_dir, "type", buffer);
|
||||
return PTR_RET(rc);
|
||||
}
|
||||
|
||||
static void *hypfs_create_phys_files(struct dentry *parent_dir, void *phys_hdr)
|
||||
{
|
||||
int i;
|
||||
void *cpu_info;
|
||||
struct dentry *cpus_dir;
|
||||
|
||||
cpus_dir = hypfs_mkdir(parent_dir, "cpus");
|
||||
if (IS_ERR(cpus_dir))
|
||||
return cpus_dir;
|
||||
cpu_info = phys_hdr + phys_hdr__size(diag204_info_type);
|
||||
for (i = 0; i < phys_hdr__cpus(diag204_info_type, phys_hdr); i++) {
|
||||
int rc;
|
||||
rc = hypfs_create_phys_cpu_files(cpus_dir, cpu_info);
|
||||
if (rc)
|
||||
return ERR_PTR(rc);
|
||||
cpu_info += phys_cpu__size(diag204_info_type);
|
||||
}
|
||||
return cpu_info;
|
||||
}
|
||||
|
||||
int hypfs_diag_create_files(struct dentry *root)
|
||||
{
|
||||
struct dentry *systems_dir, *hyp_dir;
|
||||
void *time_hdr, *part_hdr;
|
||||
int i, rc;
|
||||
void *buffer, *ptr;
|
||||
|
||||
buffer = diag204_store();
|
||||
if (IS_ERR(buffer))
|
||||
return PTR_ERR(buffer);
|
||||
|
||||
systems_dir = hypfs_mkdir(root, "systems");
|
||||
if (IS_ERR(systems_dir)) {
|
||||
rc = PTR_ERR(systems_dir);
|
||||
goto err_out;
|
||||
}
|
||||
time_hdr = (struct x_info_blk_hdr *)buffer;
|
||||
part_hdr = time_hdr + info_blk_hdr__size(diag204_info_type);
|
||||
for (i = 0; i < info_blk_hdr__npar(diag204_info_type, time_hdr); i++) {
|
||||
part_hdr = hypfs_create_lpar_files(systems_dir, part_hdr);
|
||||
if (IS_ERR(part_hdr)) {
|
||||
rc = PTR_ERR(part_hdr);
|
||||
goto err_out;
|
||||
}
|
||||
}
|
||||
if (info_blk_hdr__flags(diag204_info_type, time_hdr) & LPAR_PHYS_FLG) {
|
||||
ptr = hypfs_create_phys_files(root, part_hdr);
|
||||
if (IS_ERR(ptr)) {
|
||||
rc = PTR_ERR(ptr);
|
||||
goto err_out;
|
||||
}
|
||||
}
|
||||
hyp_dir = hypfs_mkdir(root, "hyp");
|
||||
if (IS_ERR(hyp_dir)) {
|
||||
rc = PTR_ERR(hyp_dir);
|
||||
goto err_out;
|
||||
}
|
||||
ptr = hypfs_create_str(hyp_dir, "type", "LPAR Hypervisor");
|
||||
if (IS_ERR(ptr)) {
|
||||
rc = PTR_ERR(ptr);
|
||||
goto err_out;
|
||||
}
|
||||
rc = 0;
|
||||
|
||||
err_out:
|
||||
return rc;
|
||||
}
|
||||
141
arch/s390/hypfs/hypfs_sprp.c
Normal file
141
arch/s390/hypfs/hypfs_sprp.c
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Hypervisor filesystem for Linux on s390.
|
||||
* Set Partition-Resource Parameter interface.
|
||||
*
|
||||
* Copyright IBM Corp. 2013
|
||||
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
|
||||
*/
|
||||
|
||||
#include <linux/compat.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/compat.h>
|
||||
#include <asm/sclp.h>
|
||||
#include "hypfs.h"
|
||||
|
||||
#define DIAG304_SET_WEIGHTS 0
|
||||
#define DIAG304_QUERY_PRP 1
|
||||
#define DIAG304_SET_CAPPING 2
|
||||
|
||||
#define DIAG304_CMD_MAX 2
|
||||
|
||||
static unsigned long hypfs_sprp_diag304(void *data, unsigned long cmd)
|
||||
{
|
||||
register unsigned long _data asm("2") = (unsigned long) data;
|
||||
register unsigned long _rc asm("3");
|
||||
register unsigned long _cmd asm("4") = cmd;
|
||||
|
||||
asm volatile("diag %1,%2,0x304\n"
|
||||
: "=d" (_rc) : "d" (_data), "d" (_cmd) : "memory");
|
||||
|
||||
return _rc;
|
||||
}
|
||||
|
||||
static void hypfs_sprp_free(const void *data)
|
||||
{
|
||||
free_page((unsigned long) data);
|
||||
}
|
||||
|
||||
static int hypfs_sprp_create(void **data_ptr, void **free_ptr, size_t *size)
|
||||
{
|
||||
unsigned long rc;
|
||||
void *data;
|
||||
|
||||
data = (void *) get_zeroed_page(GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
rc = hypfs_sprp_diag304(data, DIAG304_QUERY_PRP);
|
||||
if (rc != 1) {
|
||||
*data_ptr = *free_ptr = NULL;
|
||||
*size = 0;
|
||||
free_page((unsigned long) data);
|
||||
return -EIO;
|
||||
}
|
||||
*data_ptr = *free_ptr = data;
|
||||
*size = PAGE_SIZE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __hypfs_sprp_ioctl(void __user *user_area)
|
||||
{
|
||||
struct hypfs_diag304 diag304;
|
||||
unsigned long cmd;
|
||||
void __user *udata;
|
||||
void *data;
|
||||
int rc;
|
||||
|
||||
if (copy_from_user(&diag304, user_area, sizeof(diag304)))
|
||||
return -EFAULT;
|
||||
if ((diag304.args[0] >> 8) != 0 || diag304.args[1] > DIAG304_CMD_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
data = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
udata = (void __user *)(unsigned long) diag304.data;
|
||||
if (diag304.args[1] == DIAG304_SET_WEIGHTS ||
|
||||
diag304.args[1] == DIAG304_SET_CAPPING)
|
||||
if (copy_from_user(data, udata, PAGE_SIZE)) {
|
||||
rc = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
cmd = *(unsigned long *) &diag304.args[0];
|
||||
diag304.rc = hypfs_sprp_diag304(data, cmd);
|
||||
|
||||
if (diag304.args[1] == DIAG304_QUERY_PRP)
|
||||
if (copy_to_user(udata, data, PAGE_SIZE)) {
|
||||
rc = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = copy_to_user(user_area, &diag304, sizeof(diag304)) ? -EFAULT : 0;
|
||||
out:
|
||||
free_page((unsigned long) data);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static long hypfs_sprp_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
void __user *argp;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return -EACCES;
|
||||
if (is_compat_task())
|
||||
argp = compat_ptr(arg);
|
||||
else
|
||||
argp = (void __user *) arg;
|
||||
switch (cmd) {
|
||||
case HYPFS_DIAG304:
|
||||
return __hypfs_sprp_ioctl(argp);
|
||||
default: /* unknown ioctl number */
|
||||
return -ENOTTY;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct hypfs_dbfs_file hypfs_sprp_file = {
|
||||
.name = "diag_304",
|
||||
.data_create = hypfs_sprp_create,
|
||||
.data_free = hypfs_sprp_free,
|
||||
.unlocked_ioctl = hypfs_sprp_ioctl,
|
||||
};
|
||||
|
||||
int hypfs_sprp_init(void)
|
||||
{
|
||||
if (!sclp_has_sprp())
|
||||
return 0;
|
||||
return hypfs_dbfs_create_file(&hypfs_sprp_file);
|
||||
}
|
||||
|
||||
void hypfs_sprp_exit(void)
|
||||
{
|
||||
if (!sclp_has_sprp())
|
||||
return;
|
||||
hypfs_dbfs_remove_file(&hypfs_sprp_file);
|
||||
}
|
||||
287
arch/s390/hypfs/hypfs_vm.c
Normal file
287
arch/s390/hypfs/hypfs_vm.c
Normal file
|
|
@ -0,0 +1,287 @@
|
|||
/*
|
||||
* Hypervisor filesystem for Linux on s390. z/VM implementation.
|
||||
*
|
||||
* Copyright IBM Corp. 2006
|
||||
* Author(s): Michael Holzheu <holzheu@de.ibm.com>
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <asm/ebcdic.h>
|
||||
#include <asm/timex.h>
|
||||
#include "hypfs.h"
|
||||
|
||||
#define NAME_LEN 8
|
||||
#define DBFS_D2FC_HDR_VERSION 0
|
||||
|
||||
static char local_guest[] = " ";
|
||||
static char all_guests[] = "* ";
|
||||
static char *guest_query;
|
||||
|
||||
struct diag2fc_data {
|
||||
__u32 version;
|
||||
__u32 flags;
|
||||
__u64 used_cpu;
|
||||
__u64 el_time;
|
||||
__u64 mem_min_kb;
|
||||
__u64 mem_max_kb;
|
||||
__u64 mem_share_kb;
|
||||
__u64 mem_used_kb;
|
||||
__u32 pcpus;
|
||||
__u32 lcpus;
|
||||
__u32 vcpus;
|
||||
__u32 ocpus;
|
||||
__u32 cpu_max;
|
||||
__u32 cpu_shares;
|
||||
__u32 cpu_use_samp;
|
||||
__u32 cpu_delay_samp;
|
||||
__u32 page_wait_samp;
|
||||
__u32 idle_samp;
|
||||
__u32 other_samp;
|
||||
__u32 total_samp;
|
||||
char guest_name[NAME_LEN];
|
||||
};
|
||||
|
||||
struct diag2fc_parm_list {
|
||||
char userid[NAME_LEN];
|
||||
char aci_grp[NAME_LEN];
|
||||
__u64 addr;
|
||||
__u32 size;
|
||||
__u32 fmt;
|
||||
};
|
||||
|
||||
static int diag2fc(int size, char* query, void *addr)
|
||||
{
|
||||
unsigned long residual_cnt;
|
||||
unsigned long rc;
|
||||
struct diag2fc_parm_list parm_list;
|
||||
|
||||
memcpy(parm_list.userid, query, NAME_LEN);
|
||||
ASCEBC(parm_list.userid, NAME_LEN);
|
||||
parm_list.addr = (unsigned long) addr ;
|
||||
parm_list.size = size;
|
||||
parm_list.fmt = 0x02;
|
||||
memset(parm_list.aci_grp, 0x40, NAME_LEN);
|
||||
rc = -1;
|
||||
|
||||
asm volatile(
|
||||
" diag %0,%1,0x2fc\n"
|
||||
"0:\n"
|
||||
EX_TABLE(0b,0b)
|
||||
: "=d" (residual_cnt), "+d" (rc) : "0" (&parm_list) : "memory");
|
||||
|
||||
if ((rc != 0 ) && (rc != -2))
|
||||
return rc;
|
||||
else
|
||||
return -residual_cnt;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate buffer for "query" and store diag 2fc at "offset"
|
||||
*/
|
||||
static void *diag2fc_store(char *query, unsigned int *count, int offset)
|
||||
{
|
||||
void *data;
|
||||
int size;
|
||||
|
||||
do {
|
||||
size = diag2fc(0, query, NULL);
|
||||
if (size < 0)
|
||||
return ERR_PTR(-EACCES);
|
||||
data = vmalloc(size + offset);
|
||||
if (!data)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
if (diag2fc(size, query, data + offset) == 0)
|
||||
break;
|
||||
vfree(data);
|
||||
} while (1);
|
||||
*count = (size / sizeof(struct diag2fc_data));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void diag2fc_free(const void *data)
|
||||
{
|
||||
vfree(data);
|
||||
}
|
||||
|
||||
#define ATTRIBUTE(dir, name, member) \
|
||||
do { \
|
||||
void *rc; \
|
||||
rc = hypfs_create_u64(dir, name, member); \
|
||||
if (IS_ERR(rc)) \
|
||||
return PTR_ERR(rc); \
|
||||
} while(0)
|
||||
|
||||
static int hpyfs_vm_create_guest(struct dentry *systems_dir,
|
||||
struct diag2fc_data *data)
|
||||
{
|
||||
char guest_name[NAME_LEN + 1] = {};
|
||||
struct dentry *guest_dir, *cpus_dir, *samples_dir, *mem_dir;
|
||||
int dedicated_flag, capped_value;
|
||||
|
||||
capped_value = (data->flags & 0x00000006) >> 1;
|
||||
dedicated_flag = (data->flags & 0x00000008) >> 3;
|
||||
|
||||
/* guest dir */
|
||||
memcpy(guest_name, data->guest_name, NAME_LEN);
|
||||
EBCASC(guest_name, NAME_LEN);
|
||||
strim(guest_name);
|
||||
guest_dir = hypfs_mkdir(systems_dir, guest_name);
|
||||
if (IS_ERR(guest_dir))
|
||||
return PTR_ERR(guest_dir);
|
||||
ATTRIBUTE(guest_dir, "onlinetime_us", data->el_time);
|
||||
|
||||
/* logical cpu information */
|
||||
cpus_dir = hypfs_mkdir(guest_dir, "cpus");
|
||||
if (IS_ERR(cpus_dir))
|
||||
return PTR_ERR(cpus_dir);
|
||||
ATTRIBUTE(cpus_dir, "cputime_us", data->used_cpu);
|
||||
ATTRIBUTE(cpus_dir, "capped", capped_value);
|
||||
ATTRIBUTE(cpus_dir, "dedicated", dedicated_flag);
|
||||
ATTRIBUTE(cpus_dir, "count", data->vcpus);
|
||||
/*
|
||||
* Note: The "weight_min" attribute got the wrong name.
|
||||
* The value represents the number of non-stopped (operating)
|
||||
* CPUS.
|
||||
*/
|
||||
ATTRIBUTE(cpus_dir, "weight_min", data->ocpus);
|
||||
ATTRIBUTE(cpus_dir, "weight_max", data->cpu_max);
|
||||
ATTRIBUTE(cpus_dir, "weight_cur", data->cpu_shares);
|
||||
|
||||
/* memory information */
|
||||
mem_dir = hypfs_mkdir(guest_dir, "mem");
|
||||
if (IS_ERR(mem_dir))
|
||||
return PTR_ERR(mem_dir);
|
||||
ATTRIBUTE(mem_dir, "min_KiB", data->mem_min_kb);
|
||||
ATTRIBUTE(mem_dir, "max_KiB", data->mem_max_kb);
|
||||
ATTRIBUTE(mem_dir, "used_KiB", data->mem_used_kb);
|
||||
ATTRIBUTE(mem_dir, "share_KiB", data->mem_share_kb);
|
||||
|
||||
/* samples */
|
||||
samples_dir = hypfs_mkdir(guest_dir, "samples");
|
||||
if (IS_ERR(samples_dir))
|
||||
return PTR_ERR(samples_dir);
|
||||
ATTRIBUTE(samples_dir, "cpu_using", data->cpu_use_samp);
|
||||
ATTRIBUTE(samples_dir, "cpu_delay", data->cpu_delay_samp);
|
||||
ATTRIBUTE(samples_dir, "mem_delay", data->page_wait_samp);
|
||||
ATTRIBUTE(samples_dir, "idle", data->idle_samp);
|
||||
ATTRIBUTE(samples_dir, "other", data->other_samp);
|
||||
ATTRIBUTE(samples_dir, "total", data->total_samp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hypfs_vm_create_files(struct dentry *root)
|
||||
{
|
||||
struct dentry *dir, *file;
|
||||
struct diag2fc_data *data;
|
||||
unsigned int count = 0;
|
||||
int rc, i;
|
||||
|
||||
data = diag2fc_store(guest_query, &count, 0);
|
||||
if (IS_ERR(data))
|
||||
return PTR_ERR(data);
|
||||
|
||||
/* Hpervisor Info */
|
||||
dir = hypfs_mkdir(root, "hyp");
|
||||
if (IS_ERR(dir)) {
|
||||
rc = PTR_ERR(dir);
|
||||
goto failed;
|
||||
}
|
||||
file = hypfs_create_str(dir, "type", "z/VM Hypervisor");
|
||||
if (IS_ERR(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* physical cpus */
|
||||
dir = hypfs_mkdir(root, "cpus");
|
||||
if (IS_ERR(dir)) {
|
||||
rc = PTR_ERR(dir);
|
||||
goto failed;
|
||||
}
|
||||
file = hypfs_create_u64(dir, "count", data->lcpus);
|
||||
if (IS_ERR(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* guests */
|
||||
dir = hypfs_mkdir(root, "systems");
|
||||
if (IS_ERR(dir)) {
|
||||
rc = PTR_ERR(dir);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
rc = hpyfs_vm_create_guest(dir, &(data[i]));
|
||||
if (rc)
|
||||
goto failed;
|
||||
}
|
||||
diag2fc_free(data);
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
diag2fc_free(data);
|
||||
return rc;
|
||||
}
|
||||
|
||||
struct dbfs_d2fc_hdr {
|
||||
u64 len; /* Length of d2fc buffer without header */
|
||||
u16 version; /* Version of header */
|
||||
char tod_ext[16]; /* TOD clock for d2fc */
|
||||
u64 count; /* Number of VM guests in d2fc buffer */
|
||||
char reserved[30];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct dbfs_d2fc {
|
||||
struct dbfs_d2fc_hdr hdr; /* 64 byte header */
|
||||
char buf[]; /* d2fc buffer */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
static int dbfs_diag2fc_create(void **data, void **data_free_ptr, size_t *size)
|
||||
{
|
||||
struct dbfs_d2fc *d2fc;
|
||||
unsigned int count;
|
||||
|
||||
d2fc = diag2fc_store(guest_query, &count, sizeof(d2fc->hdr));
|
||||
if (IS_ERR(d2fc))
|
||||
return PTR_ERR(d2fc);
|
||||
get_tod_clock_ext(d2fc->hdr.tod_ext);
|
||||
d2fc->hdr.len = count * sizeof(struct diag2fc_data);
|
||||
d2fc->hdr.version = DBFS_D2FC_HDR_VERSION;
|
||||
d2fc->hdr.count = count;
|
||||
memset(&d2fc->hdr.reserved, 0, sizeof(d2fc->hdr.reserved));
|
||||
*data = d2fc;
|
||||
*data_free_ptr = d2fc;
|
||||
*size = d2fc->hdr.len + sizeof(struct dbfs_d2fc_hdr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct hypfs_dbfs_file dbfs_file_2fc = {
|
||||
.name = "diag_2fc",
|
||||
.data_create = dbfs_diag2fc_create,
|
||||
.data_free = diag2fc_free,
|
||||
};
|
||||
|
||||
int hypfs_vm_init(void)
|
||||
{
|
||||
if (!MACHINE_IS_VM)
|
||||
return 0;
|
||||
if (diag2fc(0, all_guests, NULL) > 0)
|
||||
guest_query = all_guests;
|
||||
else if (diag2fc(0, local_guest, NULL) > 0)
|
||||
guest_query = local_guest;
|
||||
else
|
||||
return -EACCES;
|
||||
return hypfs_dbfs_create_file(&dbfs_file_2fc);
|
||||
}
|
||||
|
||||
void hypfs_vm_exit(void)
|
||||
{
|
||||
if (!MACHINE_IS_VM)
|
||||
return;
|
||||
hypfs_dbfs_remove_file(&dbfs_file_2fc);
|
||||
}
|
||||
524
arch/s390/hypfs/inode.c
Normal file
524
arch/s390/hypfs/inode.c
Normal file
|
|
@ -0,0 +1,524 @@
|
|||
/*
|
||||
* Hypervisor filesystem for Linux on s390.
|
||||
*
|
||||
* Copyright IBM Corp. 2006, 2008
|
||||
* Author(s): Michael Holzheu <holzheu@de.ibm.com>
|
||||
*/
|
||||
|
||||
#define KMSG_COMPONENT "hypfs"
|
||||
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/namei.h>
|
||||
#include <linux/vfs.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/pagemap.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/parser.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/mount.h>
|
||||
#include <linux/aio.h>
|
||||
#include <asm/ebcdic.h>
|
||||
#include "hypfs.h"
|
||||
|
||||
#define HYPFS_MAGIC 0x687970 /* ASCII 'hyp' */
|
||||
#define TMP_SIZE 64 /* size of temporary buffers */
|
||||
|
||||
static struct dentry *hypfs_create_update_file(struct dentry *dir);
|
||||
|
||||
struct hypfs_sb_info {
|
||||
kuid_t uid; /* uid used for files and dirs */
|
||||
kgid_t gid; /* gid used for files and dirs */
|
||||
struct dentry *update_file; /* file to trigger update */
|
||||
time_t last_update; /* last update time in secs since 1970 */
|
||||
struct mutex lock; /* lock to protect update process */
|
||||
};
|
||||
|
||||
static const struct file_operations hypfs_file_ops;
|
||||
static struct file_system_type hypfs_type;
|
||||
static const struct super_operations hypfs_s_ops;
|
||||
|
||||
/* start of list of all dentries, which have to be deleted on update */
|
||||
static struct dentry *hypfs_last_dentry;
|
||||
|
||||
static void hypfs_update_update(struct super_block *sb)
|
||||
{
|
||||
struct hypfs_sb_info *sb_info = sb->s_fs_info;
|
||||
struct inode *inode = sb_info->update_file->d_inode;
|
||||
|
||||
sb_info->last_update = get_seconds();
|
||||
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
|
||||
}
|
||||
|
||||
/* directory tree removal functions */
|
||||
|
||||
static void hypfs_add_dentry(struct dentry *dentry)
|
||||
{
|
||||
dentry->d_fsdata = hypfs_last_dentry;
|
||||
hypfs_last_dentry = dentry;
|
||||
}
|
||||
|
||||
static inline int hypfs_positive(struct dentry *dentry)
|
||||
{
|
||||
return dentry->d_inode && !d_unhashed(dentry);
|
||||
}
|
||||
|
||||
static void hypfs_remove(struct dentry *dentry)
|
||||
{
|
||||
struct dentry *parent;
|
||||
|
||||
parent = dentry->d_parent;
|
||||
mutex_lock(&parent->d_inode->i_mutex);
|
||||
if (hypfs_positive(dentry)) {
|
||||
if (S_ISDIR(dentry->d_inode->i_mode))
|
||||
simple_rmdir(parent->d_inode, dentry);
|
||||
else
|
||||
simple_unlink(parent->d_inode, dentry);
|
||||
}
|
||||
d_delete(dentry);
|
||||
dput(dentry);
|
||||
mutex_unlock(&parent->d_inode->i_mutex);
|
||||
}
|
||||
|
||||
static void hypfs_delete_tree(struct dentry *root)
|
||||
{
|
||||
while (hypfs_last_dentry) {
|
||||
struct dentry *next_dentry;
|
||||
next_dentry = hypfs_last_dentry->d_fsdata;
|
||||
hypfs_remove(hypfs_last_dentry);
|
||||
hypfs_last_dentry = next_dentry;
|
||||
}
|
||||
}
|
||||
|
||||
static struct inode *hypfs_make_inode(struct super_block *sb, umode_t mode)
|
||||
{
|
||||
struct inode *ret = new_inode(sb);
|
||||
|
||||
if (ret) {
|
||||
struct hypfs_sb_info *hypfs_info = sb->s_fs_info;
|
||||
ret->i_ino = get_next_ino();
|
||||
ret->i_mode = mode;
|
||||
ret->i_uid = hypfs_info->uid;
|
||||
ret->i_gid = hypfs_info->gid;
|
||||
ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME;
|
||||
if (S_ISDIR(mode))
|
||||
set_nlink(ret, 2);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void hypfs_evict_inode(struct inode *inode)
|
||||
{
|
||||
clear_inode(inode);
|
||||
kfree(inode->i_private);
|
||||
}
|
||||
|
||||
static int hypfs_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
char *data = file_inode(filp)->i_private;
|
||||
struct hypfs_sb_info *fs_info;
|
||||
|
||||
if (filp->f_mode & FMODE_WRITE) {
|
||||
if (!(inode->i_mode & S_IWUGO))
|
||||
return -EACCES;
|
||||
}
|
||||
if (filp->f_mode & FMODE_READ) {
|
||||
if (!(inode->i_mode & S_IRUGO))
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
fs_info = inode->i_sb->s_fs_info;
|
||||
if(data) {
|
||||
mutex_lock(&fs_info->lock);
|
||||
filp->private_data = kstrdup(data, GFP_KERNEL);
|
||||
if (!filp->private_data) {
|
||||
mutex_unlock(&fs_info->lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
mutex_unlock(&fs_info->lock);
|
||||
}
|
||||
return nonseekable_open(inode, filp);
|
||||
}
|
||||
|
||||
static ssize_t hypfs_aio_read(struct kiocb *iocb, const struct iovec *iov,
|
||||
unsigned long nr_segs, loff_t offset)
|
||||
{
|
||||
char *data;
|
||||
ssize_t ret;
|
||||
struct file *filp = iocb->ki_filp;
|
||||
/* XXX: temporary */
|
||||
char __user *buf = iov[0].iov_base;
|
||||
size_t count = iov[0].iov_len;
|
||||
|
||||
if (nr_segs != 1)
|
||||
return -EINVAL;
|
||||
|
||||
data = filp->private_data;
|
||||
ret = simple_read_from_buffer(buf, count, &offset, data, strlen(data));
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
iocb->ki_pos += ret;
|
||||
file_accessed(filp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
static ssize_t hypfs_aio_write(struct kiocb *iocb, const struct iovec *iov,
|
||||
unsigned long nr_segs, loff_t offset)
|
||||
{
|
||||
int rc;
|
||||
struct super_block *sb = file_inode(iocb->ki_filp)->i_sb;
|
||||
struct hypfs_sb_info *fs_info = sb->s_fs_info;
|
||||
size_t count = iov_length(iov, nr_segs);
|
||||
|
||||
/*
|
||||
* Currently we only allow one update per second for two reasons:
|
||||
* 1. diag 204 is VERY expensive
|
||||
* 2. If several processes do updates in parallel and then read the
|
||||
* hypfs data, the likelihood of collisions is reduced, if we restrict
|
||||
* the minimum update interval. A collision occurs, if during the
|
||||
* data gathering of one process another process triggers an update
|
||||
* If the first process wants to ensure consistent data, it has
|
||||
* to restart data collection in this case.
|
||||
*/
|
||||
mutex_lock(&fs_info->lock);
|
||||
if (fs_info->last_update == get_seconds()) {
|
||||
rc = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
hypfs_delete_tree(sb->s_root);
|
||||
if (MACHINE_IS_VM)
|
||||
rc = hypfs_vm_create_files(sb->s_root);
|
||||
else
|
||||
rc = hypfs_diag_create_files(sb->s_root);
|
||||
if (rc) {
|
||||
pr_err("Updating the hypfs tree failed\n");
|
||||
hypfs_delete_tree(sb->s_root);
|
||||
goto out;
|
||||
}
|
||||
hypfs_update_update(sb);
|
||||
rc = count;
|
||||
out:
|
||||
mutex_unlock(&fs_info->lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int hypfs_release(struct inode *inode, struct file *filp)
|
||||
{
|
||||
kfree(filp->private_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum { opt_uid, opt_gid, opt_err };
|
||||
|
||||
static const match_table_t hypfs_tokens = {
|
||||
{opt_uid, "uid=%u"},
|
||||
{opt_gid, "gid=%u"},
|
||||
{opt_err, NULL}
|
||||
};
|
||||
|
||||
static int hypfs_parse_options(char *options, struct super_block *sb)
|
||||
{
|
||||
char *str;
|
||||
substring_t args[MAX_OPT_ARGS];
|
||||
kuid_t uid;
|
||||
kgid_t gid;
|
||||
|
||||
if (!options)
|
||||
return 0;
|
||||
while ((str = strsep(&options, ",")) != NULL) {
|
||||
int token, option;
|
||||
struct hypfs_sb_info *hypfs_info = sb->s_fs_info;
|
||||
|
||||
if (!*str)
|
||||
continue;
|
||||
token = match_token(str, hypfs_tokens, args);
|
||||
switch (token) {
|
||||
case opt_uid:
|
||||
if (match_int(&args[0], &option))
|
||||
return -EINVAL;
|
||||
uid = make_kuid(current_user_ns(), option);
|
||||
if (!uid_valid(uid))
|
||||
return -EINVAL;
|
||||
hypfs_info->uid = uid;
|
||||
break;
|
||||
case opt_gid:
|
||||
if (match_int(&args[0], &option))
|
||||
return -EINVAL;
|
||||
gid = make_kgid(current_user_ns(), option);
|
||||
if (!gid_valid(gid))
|
||||
return -EINVAL;
|
||||
hypfs_info->gid = gid;
|
||||
break;
|
||||
case opt_err:
|
||||
default:
|
||||
pr_err("%s is not a valid mount option\n", str);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hypfs_show_options(struct seq_file *s, struct dentry *root)
|
||||
{
|
||||
struct hypfs_sb_info *hypfs_info = root->d_sb->s_fs_info;
|
||||
|
||||
seq_printf(s, ",uid=%u", from_kuid_munged(&init_user_ns, hypfs_info->uid));
|
||||
seq_printf(s, ",gid=%u", from_kgid_munged(&init_user_ns, hypfs_info->gid));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hypfs_fill_super(struct super_block *sb, void *data, int silent)
|
||||
{
|
||||
struct inode *root_inode;
|
||||
struct dentry *root_dentry;
|
||||
int rc = 0;
|
||||
struct hypfs_sb_info *sbi;
|
||||
|
||||
sbi = kzalloc(sizeof(struct hypfs_sb_info), GFP_KERNEL);
|
||||
if (!sbi)
|
||||
return -ENOMEM;
|
||||
mutex_init(&sbi->lock);
|
||||
sbi->uid = current_uid();
|
||||
sbi->gid = current_gid();
|
||||
sb->s_fs_info = sbi;
|
||||
sb->s_blocksize = PAGE_CACHE_SIZE;
|
||||
sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
|
||||
sb->s_magic = HYPFS_MAGIC;
|
||||
sb->s_op = &hypfs_s_ops;
|
||||
if (hypfs_parse_options(data, sb))
|
||||
return -EINVAL;
|
||||
root_inode = hypfs_make_inode(sb, S_IFDIR | 0755);
|
||||
if (!root_inode)
|
||||
return -ENOMEM;
|
||||
root_inode->i_op = &simple_dir_inode_operations;
|
||||
root_inode->i_fop = &simple_dir_operations;
|
||||
sb->s_root = root_dentry = d_make_root(root_inode);
|
||||
if (!root_dentry)
|
||||
return -ENOMEM;
|
||||
if (MACHINE_IS_VM)
|
||||
rc = hypfs_vm_create_files(root_dentry);
|
||||
else
|
||||
rc = hypfs_diag_create_files(root_dentry);
|
||||
if (rc)
|
||||
return rc;
|
||||
sbi->update_file = hypfs_create_update_file(root_dentry);
|
||||
if (IS_ERR(sbi->update_file))
|
||||
return PTR_ERR(sbi->update_file);
|
||||
hypfs_update_update(sb);
|
||||
pr_info("Hypervisor filesystem mounted\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dentry *hypfs_mount(struct file_system_type *fst, int flags,
|
||||
const char *devname, void *data)
|
||||
{
|
||||
return mount_single(fst, flags, data, hypfs_fill_super);
|
||||
}
|
||||
|
||||
static void hypfs_kill_super(struct super_block *sb)
|
||||
{
|
||||
struct hypfs_sb_info *sb_info = sb->s_fs_info;
|
||||
|
||||
if (sb->s_root)
|
||||
hypfs_delete_tree(sb->s_root);
|
||||
if (sb_info->update_file)
|
||||
hypfs_remove(sb_info->update_file);
|
||||
kfree(sb->s_fs_info);
|
||||
sb->s_fs_info = NULL;
|
||||
kill_litter_super(sb);
|
||||
}
|
||||
|
||||
static struct dentry *hypfs_create_file(struct dentry *parent, const char *name,
|
||||
char *data, umode_t mode)
|
||||
{
|
||||
struct dentry *dentry;
|
||||
struct inode *inode;
|
||||
|
||||
mutex_lock(&parent->d_inode->i_mutex);
|
||||
dentry = lookup_one_len(name, parent, strlen(name));
|
||||
if (IS_ERR(dentry)) {
|
||||
dentry = ERR_PTR(-ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
inode = hypfs_make_inode(parent->d_sb, mode);
|
||||
if (!inode) {
|
||||
dput(dentry);
|
||||
dentry = ERR_PTR(-ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
if (S_ISREG(mode)) {
|
||||
inode->i_fop = &hypfs_file_ops;
|
||||
if (data)
|
||||
inode->i_size = strlen(data);
|
||||
else
|
||||
inode->i_size = 0;
|
||||
} else if (S_ISDIR(mode)) {
|
||||
inode->i_op = &simple_dir_inode_operations;
|
||||
inode->i_fop = &simple_dir_operations;
|
||||
inc_nlink(parent->d_inode);
|
||||
} else
|
||||
BUG();
|
||||
inode->i_private = data;
|
||||
d_instantiate(dentry, inode);
|
||||
dget(dentry);
|
||||
fail:
|
||||
mutex_unlock(&parent->d_inode->i_mutex);
|
||||
return dentry;
|
||||
}
|
||||
|
||||
struct dentry *hypfs_mkdir(struct dentry *parent, const char *name)
|
||||
{
|
||||
struct dentry *dentry;
|
||||
|
||||
dentry = hypfs_create_file(parent, name, NULL, S_IFDIR | DIR_MODE);
|
||||
if (IS_ERR(dentry))
|
||||
return dentry;
|
||||
hypfs_add_dentry(dentry);
|
||||
return dentry;
|
||||
}
|
||||
|
||||
static struct dentry *hypfs_create_update_file(struct dentry *dir)
|
||||
{
|
||||
struct dentry *dentry;
|
||||
|
||||
dentry = hypfs_create_file(dir, "update", NULL,
|
||||
S_IFREG | UPDATE_FILE_MODE);
|
||||
/*
|
||||
* We do not put the update file on the 'delete' list with
|
||||
* hypfs_add_dentry(), since it should not be removed when the tree
|
||||
* is updated.
|
||||
*/
|
||||
return dentry;
|
||||
}
|
||||
|
||||
struct dentry *hypfs_create_u64(struct dentry *dir,
|
||||
const char *name, __u64 value)
|
||||
{
|
||||
char *buffer;
|
||||
char tmp[TMP_SIZE];
|
||||
struct dentry *dentry;
|
||||
|
||||
snprintf(tmp, TMP_SIZE, "%llu\n", (unsigned long long int)value);
|
||||
buffer = kstrdup(tmp, GFP_KERNEL);
|
||||
if (!buffer)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
dentry =
|
||||
hypfs_create_file(dir, name, buffer, S_IFREG | REG_FILE_MODE);
|
||||
if (IS_ERR(dentry)) {
|
||||
kfree(buffer);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
hypfs_add_dentry(dentry);
|
||||
return dentry;
|
||||
}
|
||||
|
||||
struct dentry *hypfs_create_str(struct dentry *dir,
|
||||
const char *name, char *string)
|
||||
{
|
||||
char *buffer;
|
||||
struct dentry *dentry;
|
||||
|
||||
buffer = kmalloc(strlen(string) + 2, GFP_KERNEL);
|
||||
if (!buffer)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
sprintf(buffer, "%s\n", string);
|
||||
dentry =
|
||||
hypfs_create_file(dir, name, buffer, S_IFREG | REG_FILE_MODE);
|
||||
if (IS_ERR(dentry)) {
|
||||
kfree(buffer);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
hypfs_add_dentry(dentry);
|
||||
return dentry;
|
||||
}
|
||||
|
||||
static const struct file_operations hypfs_file_ops = {
|
||||
.open = hypfs_open,
|
||||
.release = hypfs_release,
|
||||
.read = do_sync_read,
|
||||
.write = do_sync_write,
|
||||
.aio_read = hypfs_aio_read,
|
||||
.aio_write = hypfs_aio_write,
|
||||
.llseek = no_llseek,
|
||||
};
|
||||
|
||||
static struct file_system_type hypfs_type = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "s390_hypfs",
|
||||
.mount = hypfs_mount,
|
||||
.kill_sb = hypfs_kill_super
|
||||
};
|
||||
MODULE_ALIAS_FS("s390_hypfs");
|
||||
|
||||
static const struct super_operations hypfs_s_ops = {
|
||||
.statfs = simple_statfs,
|
||||
.evict_inode = hypfs_evict_inode,
|
||||
.show_options = hypfs_show_options,
|
||||
};
|
||||
|
||||
static struct kobject *s390_kobj;
|
||||
|
||||
static int __init hypfs_init(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = hypfs_dbfs_init();
|
||||
if (rc)
|
||||
return rc;
|
||||
if (hypfs_diag_init()) {
|
||||
rc = -ENODATA;
|
||||
goto fail_dbfs_exit;
|
||||
}
|
||||
if (hypfs_vm_init()) {
|
||||
rc = -ENODATA;
|
||||
goto fail_hypfs_diag_exit;
|
||||
}
|
||||
if (hypfs_sprp_init()) {
|
||||
rc = -ENODATA;
|
||||
goto fail_hypfs_vm_exit;
|
||||
}
|
||||
s390_kobj = kobject_create_and_add("s390", hypervisor_kobj);
|
||||
if (!s390_kobj) {
|
||||
rc = -ENOMEM;
|
||||
goto fail_hypfs_sprp_exit;
|
||||
}
|
||||
rc = register_filesystem(&hypfs_type);
|
||||
if (rc)
|
||||
goto fail_filesystem;
|
||||
return 0;
|
||||
|
||||
fail_filesystem:
|
||||
kobject_put(s390_kobj);
|
||||
fail_hypfs_sprp_exit:
|
||||
hypfs_sprp_exit();
|
||||
fail_hypfs_vm_exit:
|
||||
hypfs_vm_exit();
|
||||
fail_hypfs_diag_exit:
|
||||
hypfs_diag_exit();
|
||||
fail_dbfs_exit:
|
||||
hypfs_dbfs_exit();
|
||||
pr_err("Initialization of hypfs failed with rc=%i\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void __exit hypfs_exit(void)
|
||||
{
|
||||
unregister_filesystem(&hypfs_type);
|
||||
kobject_put(s390_kobj);
|
||||
hypfs_sprp_exit();
|
||||
hypfs_vm_exit();
|
||||
hypfs_diag_exit();
|
||||
hypfs_dbfs_exit();
|
||||
}
|
||||
|
||||
module_init(hypfs_init)
|
||||
module_exit(hypfs_exit)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Michael Holzheu <holzheu@de.ibm.com>");
|
||||
MODULE_DESCRIPTION("s390 Hypervisor Filesystem");
|
||||
9
arch/s390/include/asm/Kbuild
Normal file
9
arch/s390/include/asm/Kbuild
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
|
||||
generic-y += clkdev.h
|
||||
generic-y += hash.h
|
||||
generic-y += irq_work.h
|
||||
generic-y += mcs_spinlock.h
|
||||
generic-y += preempt.h
|
||||
generic-y += scatterlist.h
|
||||
generic-y += trace_clock.h
|
||||
103
arch/s390/include/asm/airq.h
Normal file
103
arch/s390/include/asm/airq.h
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright IBM Corp. 2002, 2007
|
||||
* Author(s): Ingo Adlung <adlung@de.ibm.com>
|
||||
* Cornelia Huck <cornelia.huck@de.ibm.com>
|
||||
* Arnd Bergmann <arndb@de.ibm.com>
|
||||
* Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
|
||||
*/
|
||||
|
||||
#ifndef _ASM_S390_AIRQ_H
|
||||
#define _ASM_S390_AIRQ_H
|
||||
|
||||
#include <linux/bit_spinlock.h>
|
||||
|
||||
struct airq_struct {
|
||||
struct hlist_node list; /* Handler queueing. */
|
||||
void (*handler)(struct airq_struct *); /* Thin-interrupt handler */
|
||||
u8 *lsi_ptr; /* Local-Summary-Indicator pointer */
|
||||
u8 lsi_mask; /* Local-Summary-Indicator mask */
|
||||
u8 isc; /* Interrupt-subclass */
|
||||
u8 flags;
|
||||
};
|
||||
|
||||
#define AIRQ_PTR_ALLOCATED 0x01
|
||||
|
||||
int register_adapter_interrupt(struct airq_struct *airq);
|
||||
void unregister_adapter_interrupt(struct airq_struct *airq);
|
||||
|
||||
/* Adapter interrupt bit vector */
|
||||
struct airq_iv {
|
||||
unsigned long *vector; /* Adapter interrupt bit vector */
|
||||
unsigned long *avail; /* Allocation bit mask for the bit vector */
|
||||
unsigned long *bitlock; /* Lock bit mask for the bit vector */
|
||||
unsigned long *ptr; /* Pointer associated with each bit */
|
||||
unsigned int *data; /* 32 bit value associated with each bit */
|
||||
unsigned long bits; /* Number of bits in the vector */
|
||||
unsigned long end; /* Number of highest allocated bit + 1 */
|
||||
spinlock_t lock; /* Lock to protect alloc & free */
|
||||
};
|
||||
|
||||
#define AIRQ_IV_ALLOC 1 /* Use an allocation bit mask */
|
||||
#define AIRQ_IV_BITLOCK 2 /* Allocate the lock bit mask */
|
||||
#define AIRQ_IV_PTR 4 /* Allocate the ptr array */
|
||||
#define AIRQ_IV_DATA 8 /* Allocate the data array */
|
||||
|
||||
struct airq_iv *airq_iv_create(unsigned long bits, unsigned long flags);
|
||||
void airq_iv_release(struct airq_iv *iv);
|
||||
unsigned long airq_iv_alloc(struct airq_iv *iv, unsigned long num);
|
||||
void airq_iv_free(struct airq_iv *iv, unsigned long bit, unsigned long num);
|
||||
unsigned long airq_iv_scan(struct airq_iv *iv, unsigned long start,
|
||||
unsigned long end);
|
||||
|
||||
static inline unsigned long airq_iv_alloc_bit(struct airq_iv *iv)
|
||||
{
|
||||
return airq_iv_alloc(iv, 1);
|
||||
}
|
||||
|
||||
static inline void airq_iv_free_bit(struct airq_iv *iv, unsigned long bit)
|
||||
{
|
||||
airq_iv_free(iv, bit, 1);
|
||||
}
|
||||
|
||||
static inline unsigned long airq_iv_end(struct airq_iv *iv)
|
||||
{
|
||||
return iv->end;
|
||||
}
|
||||
|
||||
static inline void airq_iv_lock(struct airq_iv *iv, unsigned long bit)
|
||||
{
|
||||
const unsigned long be_to_le = BITS_PER_LONG - 1;
|
||||
bit_spin_lock(bit ^ be_to_le, iv->bitlock);
|
||||
}
|
||||
|
||||
static inline void airq_iv_unlock(struct airq_iv *iv, unsigned long bit)
|
||||
{
|
||||
const unsigned long be_to_le = BITS_PER_LONG - 1;
|
||||
bit_spin_unlock(bit ^ be_to_le, iv->bitlock);
|
||||
}
|
||||
|
||||
static inline void airq_iv_set_data(struct airq_iv *iv, unsigned long bit,
|
||||
unsigned int data)
|
||||
{
|
||||
iv->data[bit] = data;
|
||||
}
|
||||
|
||||
static inline unsigned int airq_iv_get_data(struct airq_iv *iv,
|
||||
unsigned long bit)
|
||||
{
|
||||
return iv->data[bit];
|
||||
}
|
||||
|
||||
static inline void airq_iv_set_ptr(struct airq_iv *iv, unsigned long bit,
|
||||
unsigned long ptr)
|
||||
{
|
||||
iv->ptr[bit] = ptr;
|
||||
}
|
||||
|
||||
static inline unsigned long airq_iv_get_ptr(struct airq_iv *iv,
|
||||
unsigned long bit)
|
||||
{
|
||||
return iv->ptr[bit];
|
||||
}
|
||||
|
||||
#endif /* _ASM_S390_AIRQ_H */
|
||||
88
arch/s390/include/asm/appldata.h
Normal file
88
arch/s390/include/asm/appldata.h
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright IBM Corp. 2006
|
||||
*
|
||||
* Author(s): Melissa Howland <melissah@us.ibm.com>
|
||||
*/
|
||||
|
||||
#ifndef _ASM_S390_APPLDATA_H
|
||||
#define _ASM_S390_APPLDATA_H
|
||||
|
||||
#include <asm/io.h>
|
||||
|
||||
#ifndef CONFIG_64BIT
|
||||
|
||||
#define APPLDATA_START_INTERVAL_REC 0x00 /* Function codes for */
|
||||
#define APPLDATA_STOP_REC 0x01 /* DIAG 0xDC */
|
||||
#define APPLDATA_GEN_EVENT_REC 0x02
|
||||
#define APPLDATA_START_CONFIG_REC 0x03
|
||||
|
||||
/*
|
||||
* Parameter list for DIAGNOSE X'DC'
|
||||
*/
|
||||
struct appldata_parameter_list {
|
||||
u16 diag; /* The DIAGNOSE code X'00DC' */
|
||||
u8 function; /* The function code for the DIAGNOSE */
|
||||
u8 parlist_length; /* Length of the parameter list */
|
||||
u32 product_id_addr; /* Address of the 16-byte product ID */
|
||||
u16 reserved;
|
||||
u16 buffer_length; /* Length of the application data buffer */
|
||||
u32 buffer_addr; /* Address of the application data buffer */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#else /* CONFIG_64BIT */
|
||||
|
||||
#define APPLDATA_START_INTERVAL_REC 0x80
|
||||
#define APPLDATA_STOP_REC 0x81
|
||||
#define APPLDATA_GEN_EVENT_REC 0x82
|
||||
#define APPLDATA_START_CONFIG_REC 0x83
|
||||
|
||||
/*
|
||||
* Parameter list for DIAGNOSE X'DC'
|
||||
*/
|
||||
struct appldata_parameter_list {
|
||||
u16 diag;
|
||||
u8 function;
|
||||
u8 parlist_length;
|
||||
u32 unused01;
|
||||
u16 reserved;
|
||||
u16 buffer_length;
|
||||
u32 unused02;
|
||||
u64 product_id_addr;
|
||||
u64 buffer_addr;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#endif /* CONFIG_64BIT */
|
||||
|
||||
struct appldata_product_id {
|
||||
char prod_nr[7]; /* product number */
|
||||
u16 prod_fn; /* product function */
|
||||
u8 record_nr; /* record number */
|
||||
u16 version_nr; /* version */
|
||||
u16 release_nr; /* release */
|
||||
u16 mod_lvl; /* modification level */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
static inline int appldata_asm(struct appldata_product_id *id,
|
||||
unsigned short fn, void *buffer,
|
||||
unsigned short length)
|
||||
{
|
||||
struct appldata_parameter_list parm_list;
|
||||
int ry;
|
||||
|
||||
if (!MACHINE_IS_VM)
|
||||
return -EOPNOTSUPP;
|
||||
parm_list.diag = 0xdc;
|
||||
parm_list.function = fn;
|
||||
parm_list.parlist_length = sizeof(parm_list);
|
||||
parm_list.buffer_length = length;
|
||||
parm_list.product_id_addr = (unsigned long) id;
|
||||
parm_list.buffer_addr = virt_to_phys(buffer);
|
||||
asm volatile(
|
||||
" diag %1,%0,0xdc"
|
||||
: "=d" (ry)
|
||||
: "d" (&parm_list), "m" (parm_list), "m" (*id)
|
||||
: "cc");
|
||||
return ry;
|
||||
}
|
||||
|
||||
#endif /* _ASM_S390_APPLDATA_H */
|
||||
1
arch/s390/include/asm/asm-offsets.h
Normal file
1
arch/s390/include/asm/asm-offsets.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
#include <generated/asm-offsets.h>
|
||||
415
arch/s390/include/asm/atomic.h
Normal file
415
arch/s390/include/asm/atomic.h
Normal file
|
|
@ -0,0 +1,415 @@
|
|||
/*
|
||||
* Copyright IBM Corp. 1999, 2009
|
||||
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>,
|
||||
* Denis Joseph Barrow,
|
||||
* Arnd Bergmann <arndb@de.ibm.com>,
|
||||
*
|
||||
* Atomic operations that C can't guarantee us.
|
||||
* Useful for resource counting etc.
|
||||
* s390 uses 'Compare And Swap' for atomicity in SMP environment.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_S390_ATOMIC__
|
||||
#define __ARCH_S390_ATOMIC__
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/types.h>
|
||||
#include <asm/barrier.h>
|
||||
#include <asm/cmpxchg.h>
|
||||
|
||||
#define ATOMIC_INIT(i) { (i) }
|
||||
|
||||
#define __ATOMIC_NO_BARRIER "\n"
|
||||
|
||||
#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES
|
||||
|
||||
#define __ATOMIC_OR "lao"
|
||||
#define __ATOMIC_AND "lan"
|
||||
#define __ATOMIC_ADD "laa"
|
||||
#define __ATOMIC_BARRIER "bcr 14,0\n"
|
||||
|
||||
#define __ATOMIC_LOOP(ptr, op_val, op_string, __barrier) \
|
||||
({ \
|
||||
int old_val; \
|
||||
\
|
||||
typecheck(atomic_t *, ptr); \
|
||||
asm volatile( \
|
||||
__barrier \
|
||||
op_string " %0,%2,%1\n" \
|
||||
__barrier \
|
||||
: "=d" (old_val), "+Q" ((ptr)->counter) \
|
||||
: "d" (op_val) \
|
||||
: "cc", "memory"); \
|
||||
old_val; \
|
||||
})
|
||||
|
||||
#else /* CONFIG_HAVE_MARCH_Z196_FEATURES */
|
||||
|
||||
#define __ATOMIC_OR "or"
|
||||
#define __ATOMIC_AND "nr"
|
||||
#define __ATOMIC_ADD "ar"
|
||||
#define __ATOMIC_BARRIER "\n"
|
||||
|
||||
#define __ATOMIC_LOOP(ptr, op_val, op_string, __barrier) \
|
||||
({ \
|
||||
int old_val, new_val; \
|
||||
\
|
||||
typecheck(atomic_t *, ptr); \
|
||||
asm volatile( \
|
||||
" l %0,%2\n" \
|
||||
"0: lr %1,%0\n" \
|
||||
op_string " %1,%3\n" \
|
||||
" cs %0,%1,%2\n" \
|
||||
" jl 0b" \
|
||||
: "=&d" (old_val), "=&d" (new_val), "+Q" ((ptr)->counter)\
|
||||
: "d" (op_val) \
|
||||
: "cc", "memory"); \
|
||||
old_val; \
|
||||
})
|
||||
|
||||
#endif /* CONFIG_HAVE_MARCH_Z196_FEATURES */
|
||||
|
||||
static inline int atomic_read(const atomic_t *v)
|
||||
{
|
||||
int c;
|
||||
|
||||
asm volatile(
|
||||
" l %0,%1\n"
|
||||
: "=d" (c) : "Q" (v->counter));
|
||||
return c;
|
||||
}
|
||||
|
||||
static inline void atomic_set(atomic_t *v, int i)
|
||||
{
|
||||
asm volatile(
|
||||
" st %1,%0\n"
|
||||
: "=Q" (v->counter) : "d" (i));
|
||||
}
|
||||
|
||||
static inline int atomic_add_return(int i, atomic_t *v)
|
||||
{
|
||||
return __ATOMIC_LOOP(v, i, __ATOMIC_ADD, __ATOMIC_BARRIER) + i;
|
||||
}
|
||||
|
||||
static inline void atomic_add(int i, atomic_t *v)
|
||||
{
|
||||
#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES
|
||||
if (__builtin_constant_p(i) && (i > -129) && (i < 128)) {
|
||||
asm volatile(
|
||||
"asi %0,%1\n"
|
||||
: "+Q" (v->counter)
|
||||
: "i" (i)
|
||||
: "cc", "memory");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
__ATOMIC_LOOP(v, i, __ATOMIC_ADD, __ATOMIC_NO_BARRIER);
|
||||
}
|
||||
|
||||
#define atomic_add_negative(_i, _v) (atomic_add_return(_i, _v) < 0)
|
||||
#define atomic_inc(_v) atomic_add(1, _v)
|
||||
#define atomic_inc_return(_v) atomic_add_return(1, _v)
|
||||
#define atomic_inc_and_test(_v) (atomic_add_return(1, _v) == 0)
|
||||
#define atomic_sub(_i, _v) atomic_add(-(int)(_i), _v)
|
||||
#define atomic_sub_return(_i, _v) atomic_add_return(-(int)(_i), _v)
|
||||
#define atomic_sub_and_test(_i, _v) (atomic_sub_return(_i, _v) == 0)
|
||||
#define atomic_dec(_v) atomic_sub(1, _v)
|
||||
#define atomic_dec_return(_v) atomic_sub_return(1, _v)
|
||||
#define atomic_dec_and_test(_v) (atomic_sub_return(1, _v) == 0)
|
||||
|
||||
static inline void atomic_clear_mask(unsigned int mask, atomic_t *v)
|
||||
{
|
||||
__ATOMIC_LOOP(v, ~mask, __ATOMIC_AND, __ATOMIC_NO_BARRIER);
|
||||
}
|
||||
|
||||
static inline void atomic_set_mask(unsigned int mask, atomic_t *v)
|
||||
{
|
||||
__ATOMIC_LOOP(v, mask, __ATOMIC_OR, __ATOMIC_NO_BARRIER);
|
||||
}
|
||||
|
||||
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
|
||||
|
||||
static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
|
||||
{
|
||||
asm volatile(
|
||||
" cs %0,%2,%1"
|
||||
: "+d" (old), "+Q" (v->counter)
|
||||
: "d" (new)
|
||||
: "cc", "memory");
|
||||
return old;
|
||||
}
|
||||
|
||||
static inline int __atomic_add_unless(atomic_t *v, int a, int u)
|
||||
{
|
||||
int c, old;
|
||||
c = atomic_read(v);
|
||||
for (;;) {
|
||||
if (unlikely(c == u))
|
||||
break;
|
||||
old = atomic_cmpxchg(v, c, c + a);
|
||||
if (likely(old == c))
|
||||
break;
|
||||
c = old;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
#undef __ATOMIC_LOOP
|
||||
|
||||
#define ATOMIC64_INIT(i) { (i) }
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
|
||||
#define __ATOMIC64_NO_BARRIER "\n"
|
||||
|
||||
#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES
|
||||
|
||||
#define __ATOMIC64_OR "laog"
|
||||
#define __ATOMIC64_AND "lang"
|
||||
#define __ATOMIC64_ADD "laag"
|
||||
#define __ATOMIC64_BARRIER "bcr 14,0\n"
|
||||
|
||||
#define __ATOMIC64_LOOP(ptr, op_val, op_string, __barrier) \
|
||||
({ \
|
||||
long long old_val; \
|
||||
\
|
||||
typecheck(atomic64_t *, ptr); \
|
||||
asm volatile( \
|
||||
__barrier \
|
||||
op_string " %0,%2,%1\n" \
|
||||
__barrier \
|
||||
: "=d" (old_val), "+Q" ((ptr)->counter) \
|
||||
: "d" (op_val) \
|
||||
: "cc", "memory"); \
|
||||
old_val; \
|
||||
})
|
||||
|
||||
#else /* CONFIG_HAVE_MARCH_Z196_FEATURES */
|
||||
|
||||
#define __ATOMIC64_OR "ogr"
|
||||
#define __ATOMIC64_AND "ngr"
|
||||
#define __ATOMIC64_ADD "agr"
|
||||
#define __ATOMIC64_BARRIER "\n"
|
||||
|
||||
#define __ATOMIC64_LOOP(ptr, op_val, op_string, __barrier) \
|
||||
({ \
|
||||
long long old_val, new_val; \
|
||||
\
|
||||
typecheck(atomic64_t *, ptr); \
|
||||
asm volatile( \
|
||||
" lg %0,%2\n" \
|
||||
"0: lgr %1,%0\n" \
|
||||
op_string " %1,%3\n" \
|
||||
" csg %0,%1,%2\n" \
|
||||
" jl 0b" \
|
||||
: "=&d" (old_val), "=&d" (new_val), "+Q" ((ptr)->counter)\
|
||||
: "d" (op_val) \
|
||||
: "cc", "memory"); \
|
||||
old_val; \
|
||||
})
|
||||
|
||||
#endif /* CONFIG_HAVE_MARCH_Z196_FEATURES */
|
||||
|
||||
static inline long long atomic64_read(const atomic64_t *v)
|
||||
{
|
||||
long long c;
|
||||
|
||||
asm volatile(
|
||||
" lg %0,%1\n"
|
||||
: "=d" (c) : "Q" (v->counter));
|
||||
return c;
|
||||
}
|
||||
|
||||
static inline void atomic64_set(atomic64_t *v, long long i)
|
||||
{
|
||||
asm volatile(
|
||||
" stg %1,%0\n"
|
||||
: "=Q" (v->counter) : "d" (i));
|
||||
}
|
||||
|
||||
static inline long long atomic64_add_return(long long i, atomic64_t *v)
|
||||
{
|
||||
return __ATOMIC64_LOOP(v, i, __ATOMIC64_ADD, __ATOMIC64_BARRIER) + i;
|
||||
}
|
||||
|
||||
static inline void atomic64_add(long long i, atomic64_t *v)
|
||||
{
|
||||
#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES
|
||||
if (__builtin_constant_p(i) && (i > -129) && (i < 128)) {
|
||||
asm volatile(
|
||||
"agsi %0,%1\n"
|
||||
: "+Q" (v->counter)
|
||||
: "i" (i)
|
||||
: "cc", "memory");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
__ATOMIC64_LOOP(v, i, __ATOMIC64_ADD, __ATOMIC64_NO_BARRIER);
|
||||
}
|
||||
|
||||
static inline void atomic64_clear_mask(unsigned long mask, atomic64_t *v)
|
||||
{
|
||||
__ATOMIC64_LOOP(v, ~mask, __ATOMIC64_AND, __ATOMIC64_NO_BARRIER);
|
||||
}
|
||||
|
||||
static inline void atomic64_set_mask(unsigned long mask, atomic64_t *v)
|
||||
{
|
||||
__ATOMIC64_LOOP(v, mask, __ATOMIC64_OR, __ATOMIC64_NO_BARRIER);
|
||||
}
|
||||
|
||||
#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
|
||||
|
||||
static inline long long atomic64_cmpxchg(atomic64_t *v,
|
||||
long long old, long long new)
|
||||
{
|
||||
asm volatile(
|
||||
" csg %0,%2,%1"
|
||||
: "+d" (old), "+Q" (v->counter)
|
||||
: "d" (new)
|
||||
: "cc", "memory");
|
||||
return old;
|
||||
}
|
||||
|
||||
#undef __ATOMIC64_LOOP
|
||||
|
||||
#else /* CONFIG_64BIT */
|
||||
|
||||
typedef struct {
|
||||
long long counter;
|
||||
} atomic64_t;
|
||||
|
||||
static inline long long atomic64_read(const atomic64_t *v)
|
||||
{
|
||||
register_pair rp;
|
||||
|
||||
asm volatile(
|
||||
" lm %0,%N0,%1"
|
||||
: "=&d" (rp) : "Q" (v->counter) );
|
||||
return rp.pair;
|
||||
}
|
||||
|
||||
static inline void atomic64_set(atomic64_t *v, long long i)
|
||||
{
|
||||
register_pair rp = {.pair = i};
|
||||
|
||||
asm volatile(
|
||||
" stm %1,%N1,%0"
|
||||
: "=Q" (v->counter) : "d" (rp) );
|
||||
}
|
||||
|
||||
static inline long long atomic64_xchg(atomic64_t *v, long long new)
|
||||
{
|
||||
register_pair rp_new = {.pair = new};
|
||||
register_pair rp_old;
|
||||
|
||||
asm volatile(
|
||||
" lm %0,%N0,%1\n"
|
||||
"0: cds %0,%2,%1\n"
|
||||
" jl 0b\n"
|
||||
: "=&d" (rp_old), "+Q" (v->counter)
|
||||
: "d" (rp_new)
|
||||
: "cc");
|
||||
return rp_old.pair;
|
||||
}
|
||||
|
||||
static inline long long atomic64_cmpxchg(atomic64_t *v,
|
||||
long long old, long long new)
|
||||
{
|
||||
register_pair rp_old = {.pair = old};
|
||||
register_pair rp_new = {.pair = new};
|
||||
|
||||
asm volatile(
|
||||
" cds %0,%2,%1"
|
||||
: "+&d" (rp_old), "+Q" (v->counter)
|
||||
: "d" (rp_new)
|
||||
: "cc");
|
||||
return rp_old.pair;
|
||||
}
|
||||
|
||||
|
||||
static inline long long atomic64_add_return(long long i, atomic64_t *v)
|
||||
{
|
||||
long long old, new;
|
||||
|
||||
do {
|
||||
old = atomic64_read(v);
|
||||
new = old + i;
|
||||
} while (atomic64_cmpxchg(v, old, new) != old);
|
||||
return new;
|
||||
}
|
||||
|
||||
static inline void atomic64_set_mask(unsigned long long mask, atomic64_t *v)
|
||||
{
|
||||
long long old, new;
|
||||
|
||||
do {
|
||||
old = atomic64_read(v);
|
||||
new = old | mask;
|
||||
} while (atomic64_cmpxchg(v, old, new) != old);
|
||||
}
|
||||
|
||||
static inline void atomic64_clear_mask(unsigned long long mask, atomic64_t *v)
|
||||
{
|
||||
long long old, new;
|
||||
|
||||
do {
|
||||
old = atomic64_read(v);
|
||||
new = old & mask;
|
||||
} while (atomic64_cmpxchg(v, old, new) != old);
|
||||
}
|
||||
|
||||
static inline void atomic64_add(long long i, atomic64_t *v)
|
||||
{
|
||||
atomic64_add_return(i, v);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_64BIT */
|
||||
|
||||
static inline int atomic64_add_unless(atomic64_t *v, long long i, long long u)
|
||||
{
|
||||
long long c, old;
|
||||
|
||||
c = atomic64_read(v);
|
||||
for (;;) {
|
||||
if (unlikely(c == u))
|
||||
break;
|
||||
old = atomic64_cmpxchg(v, c, c + i);
|
||||
if (likely(old == c))
|
||||
break;
|
||||
c = old;
|
||||
}
|
||||
return c != u;
|
||||
}
|
||||
|
||||
static inline long long atomic64_dec_if_positive(atomic64_t *v)
|
||||
{
|
||||
long long c, old, dec;
|
||||
|
||||
c = atomic64_read(v);
|
||||
for (;;) {
|
||||
dec = c - 1;
|
||||
if (unlikely(dec < 0))
|
||||
break;
|
||||
old = atomic64_cmpxchg((v), c, dec);
|
||||
if (likely(old == c))
|
||||
break;
|
||||
c = old;
|
||||
}
|
||||
return dec;
|
||||
}
|
||||
|
||||
#define atomic64_add_negative(_i, _v) (atomic64_add_return(_i, _v) < 0)
|
||||
#define atomic64_inc(_v) atomic64_add(1, _v)
|
||||
#define atomic64_inc_return(_v) atomic64_add_return(1, _v)
|
||||
#define atomic64_inc_and_test(_v) (atomic64_add_return(1, _v) == 0)
|
||||
#define atomic64_sub_return(_i, _v) atomic64_add_return(-(long long)(_i), _v)
|
||||
#define atomic64_sub(_i, _v) atomic64_add(-(long long)(_i), _v)
|
||||
#define atomic64_sub_and_test(_i, _v) (atomic64_sub_return(_i, _v) == 0)
|
||||
#define atomic64_dec(_v) atomic64_sub(1, _v)
|
||||
#define atomic64_dec_return(_v) atomic64_sub_return(1, _v)
|
||||
#define atomic64_dec_and_test(_v) (atomic64_sub_return(1, _v) == 0)
|
||||
#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
|
||||
|
||||
#endif /* __ARCH_S390_ATOMIC__ */
|
||||
53
arch/s390/include/asm/barrier.h
Normal file
53
arch/s390/include/asm/barrier.h
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright IBM Corp. 1999, 2009
|
||||
*
|
||||
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
|
||||
*/
|
||||
|
||||
#ifndef __ASM_BARRIER_H
|
||||
#define __ASM_BARRIER_H
|
||||
|
||||
/*
|
||||
* Force strict CPU ordering.
|
||||
* And yes, this is required on UP too when we're talking
|
||||
* to devices.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES
|
||||
/* Fast-BCR without checkpoint synchronization */
|
||||
#define __ASM_BARRIER "bcr 14,0\n"
|
||||
#else
|
||||
#define __ASM_BARRIER "bcr 15,0\n"
|
||||
#endif
|
||||
|
||||
#define mb() do { asm volatile(__ASM_BARRIER : : : "memory"); } while (0)
|
||||
|
||||
#define rmb() mb()
|
||||
#define wmb() mb()
|
||||
#define read_barrier_depends() do { } while(0)
|
||||
#define smp_mb() mb()
|
||||
#define smp_rmb() rmb()
|
||||
#define smp_wmb() wmb()
|
||||
#define smp_read_barrier_depends() read_barrier_depends()
|
||||
|
||||
#define smp_mb__before_atomic() smp_mb()
|
||||
#define smp_mb__after_atomic() smp_mb()
|
||||
|
||||
#define set_mb(var, value) do { var = value; mb(); } while (0)
|
||||
|
||||
#define smp_store_release(p, v) \
|
||||
do { \
|
||||
compiletime_assert_atomic_type(*p); \
|
||||
barrier(); \
|
||||
ACCESS_ONCE(*p) = (v); \
|
||||
} while (0)
|
||||
|
||||
#define smp_load_acquire(p) \
|
||||
({ \
|
||||
typeof(*p) ___p1 = ACCESS_ONCE(*p); \
|
||||
compiletime_assert_atomic_type(*p); \
|
||||
barrier(); \
|
||||
___p1; \
|
||||
})
|
||||
|
||||
#endif /* __ASM_BARRIER_H */
|
||||
482
arch/s390/include/asm/bitops.h
Normal file
482
arch/s390/include/asm/bitops.h
Normal file
|
|
@ -0,0 +1,482 @@
|
|||
/*
|
||||
* Copyright IBM Corp. 1999,2013
|
||||
*
|
||||
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>,
|
||||
*
|
||||
* The description below was taken in large parts from the powerpc
|
||||
* bitops header file:
|
||||
* Within a word, bits are numbered LSB first. Lot's of places make
|
||||
* this assumption by directly testing bits with (val & (1<<nr)).
|
||||
* This can cause confusion for large (> 1 word) bitmaps on a
|
||||
* big-endian system because, unlike little endian, the number of each
|
||||
* bit depends on the word size.
|
||||
*
|
||||
* The bitop functions are defined to work on unsigned longs, so for an
|
||||
* s390x system the bits end up numbered:
|
||||
* |63..............0|127............64|191...........128|255...........192|
|
||||
* and on s390:
|
||||
* |31.....0|63....32|95....64|127...96|159..128|191..160|223..192|255..224|
|
||||
*
|
||||
* There are a few little-endian macros used mostly for filesystem
|
||||
* bitmaps, these work on similar bit arrays layouts, but
|
||||
* byte-oriented:
|
||||
* |7...0|15...8|23...16|31...24|39...32|47...40|55...48|63...56|
|
||||
*
|
||||
* The main difference is that bit 3-5 (64b) or 3-4 (32b) in the bit
|
||||
* number field needs to be reversed compared to the big-endian bit
|
||||
* fields. This can be achieved by XOR with 0x38 (64b) or 0x18 (32b).
|
||||
*
|
||||
* We also have special functions which work with an MSB0 encoding:
|
||||
* on an s390x system the bits are numbered:
|
||||
* |0..............63|64............127|128...........191|192...........255|
|
||||
* and on s390:
|
||||
* |0.....31|32....63|64....95|96...127|128..159|160..191|192..223|224..255|
|
||||
*
|
||||
* The main difference is that bit 0-63 (64b) or 0-31 (32b) in the bit
|
||||
* number field needs to be reversed compared to the LSB0 encoded bit
|
||||
* fields. This can be achieved by XOR with 0x3f (64b) or 0x1f (32b).
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _S390_BITOPS_H
|
||||
#define _S390_BITOPS_H
|
||||
|
||||
#ifndef _LINUX_BITOPS_H
|
||||
#error only <linux/bitops.h> can be included directly
|
||||
#endif
|
||||
|
||||
#include <linux/typecheck.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <asm/barrier.h>
|
||||
|
||||
#define __BITOPS_NO_BARRIER "\n"
|
||||
|
||||
#ifndef CONFIG_64BIT
|
||||
|
||||
#define __BITOPS_OR "or"
|
||||
#define __BITOPS_AND "nr"
|
||||
#define __BITOPS_XOR "xr"
|
||||
#define __BITOPS_BARRIER "\n"
|
||||
|
||||
#define __BITOPS_LOOP(__addr, __val, __op_string, __barrier) \
|
||||
({ \
|
||||
unsigned long __old, __new; \
|
||||
\
|
||||
typecheck(unsigned long *, (__addr)); \
|
||||
asm volatile( \
|
||||
" l %0,%2\n" \
|
||||
"0: lr %1,%0\n" \
|
||||
__op_string " %1,%3\n" \
|
||||
" cs %0,%1,%2\n" \
|
||||
" jl 0b" \
|
||||
: "=&d" (__old), "=&d" (__new), "+Q" (*(__addr))\
|
||||
: "d" (__val) \
|
||||
: "cc", "memory"); \
|
||||
__old; \
|
||||
})
|
||||
|
||||
#else /* CONFIG_64BIT */
|
||||
|
||||
#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES
|
||||
|
||||
#define __BITOPS_OR "laog"
|
||||
#define __BITOPS_AND "lang"
|
||||
#define __BITOPS_XOR "laxg"
|
||||
#define __BITOPS_BARRIER "bcr 14,0\n"
|
||||
|
||||
#define __BITOPS_LOOP(__addr, __val, __op_string, __barrier) \
|
||||
({ \
|
||||
unsigned long __old; \
|
||||
\
|
||||
typecheck(unsigned long *, (__addr)); \
|
||||
asm volatile( \
|
||||
__barrier \
|
||||
__op_string " %0,%2,%1\n" \
|
||||
__barrier \
|
||||
: "=d" (__old), "+Q" (*(__addr)) \
|
||||
: "d" (__val) \
|
||||
: "cc", "memory"); \
|
||||
__old; \
|
||||
})
|
||||
|
||||
#else /* CONFIG_HAVE_MARCH_Z196_FEATURES */
|
||||
|
||||
#define __BITOPS_OR "ogr"
|
||||
#define __BITOPS_AND "ngr"
|
||||
#define __BITOPS_XOR "xgr"
|
||||
#define __BITOPS_BARRIER "\n"
|
||||
|
||||
#define __BITOPS_LOOP(__addr, __val, __op_string, __barrier) \
|
||||
({ \
|
||||
unsigned long __old, __new; \
|
||||
\
|
||||
typecheck(unsigned long *, (__addr)); \
|
||||
asm volatile( \
|
||||
" lg %0,%2\n" \
|
||||
"0: lgr %1,%0\n" \
|
||||
__op_string " %1,%3\n" \
|
||||
" csg %0,%1,%2\n" \
|
||||
" jl 0b" \
|
||||
: "=&d" (__old), "=&d" (__new), "+Q" (*(__addr))\
|
||||
: "d" (__val) \
|
||||
: "cc", "memory"); \
|
||||
__old; \
|
||||
})
|
||||
|
||||
#endif /* CONFIG_HAVE_MARCH_Z196_FEATURES */
|
||||
|
||||
#endif /* CONFIG_64BIT */
|
||||
|
||||
#define __BITOPS_WORDS(bits) (((bits) + BITS_PER_LONG - 1) / BITS_PER_LONG)
|
||||
|
||||
static inline unsigned long *
|
||||
__bitops_word(unsigned long nr, volatile unsigned long *ptr)
|
||||
{
|
||||
unsigned long addr;
|
||||
|
||||
addr = (unsigned long)ptr + ((nr ^ (nr & (BITS_PER_LONG - 1))) >> 3);
|
||||
return (unsigned long *)addr;
|
||||
}
|
||||
|
||||
static inline unsigned char *
|
||||
__bitops_byte(unsigned long nr, volatile unsigned long *ptr)
|
||||
{
|
||||
return ((unsigned char *)ptr) + ((nr ^ (BITS_PER_LONG - 8)) >> 3);
|
||||
}
|
||||
|
||||
static inline void set_bit(unsigned long nr, volatile unsigned long *ptr)
|
||||
{
|
||||
unsigned long *addr = __bitops_word(nr, ptr);
|
||||
unsigned long mask;
|
||||
|
||||
#ifdef CONFIG_HAVE_MARCH_ZEC12_FEATURES
|
||||
if (__builtin_constant_p(nr)) {
|
||||
unsigned char *caddr = __bitops_byte(nr, ptr);
|
||||
|
||||
asm volatile(
|
||||
"oi %0,%b1\n"
|
||||
: "+Q" (*caddr)
|
||||
: "i" (1 << (nr & 7))
|
||||
: "cc", "memory");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
mask = 1UL << (nr & (BITS_PER_LONG - 1));
|
||||
__BITOPS_LOOP(addr, mask, __BITOPS_OR, __BITOPS_NO_BARRIER);
|
||||
}
|
||||
|
||||
static inline void clear_bit(unsigned long nr, volatile unsigned long *ptr)
|
||||
{
|
||||
unsigned long *addr = __bitops_word(nr, ptr);
|
||||
unsigned long mask;
|
||||
|
||||
#ifdef CONFIG_HAVE_MARCH_ZEC12_FEATURES
|
||||
if (__builtin_constant_p(nr)) {
|
||||
unsigned char *caddr = __bitops_byte(nr, ptr);
|
||||
|
||||
asm volatile(
|
||||
"ni %0,%b1\n"
|
||||
: "+Q" (*caddr)
|
||||
: "i" (~(1 << (nr & 7)))
|
||||
: "cc", "memory");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
mask = ~(1UL << (nr & (BITS_PER_LONG - 1)));
|
||||
__BITOPS_LOOP(addr, mask, __BITOPS_AND, __BITOPS_NO_BARRIER);
|
||||
}
|
||||
|
||||
static inline void change_bit(unsigned long nr, volatile unsigned long *ptr)
|
||||
{
|
||||
unsigned long *addr = __bitops_word(nr, ptr);
|
||||
unsigned long mask;
|
||||
|
||||
#ifdef CONFIG_HAVE_MARCH_ZEC12_FEATURES
|
||||
if (__builtin_constant_p(nr)) {
|
||||
unsigned char *caddr = __bitops_byte(nr, ptr);
|
||||
|
||||
asm volatile(
|
||||
"xi %0,%b1\n"
|
||||
: "+Q" (*caddr)
|
||||
: "i" (1 << (nr & 7))
|
||||
: "cc", "memory");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
mask = 1UL << (nr & (BITS_PER_LONG - 1));
|
||||
__BITOPS_LOOP(addr, mask, __BITOPS_XOR, __BITOPS_NO_BARRIER);
|
||||
}
|
||||
|
||||
static inline int
|
||||
test_and_set_bit(unsigned long nr, volatile unsigned long *ptr)
|
||||
{
|
||||
unsigned long *addr = __bitops_word(nr, ptr);
|
||||
unsigned long old, mask;
|
||||
|
||||
mask = 1UL << (nr & (BITS_PER_LONG - 1));
|
||||
old = __BITOPS_LOOP(addr, mask, __BITOPS_OR, __BITOPS_BARRIER);
|
||||
return (old & mask) != 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
test_and_clear_bit(unsigned long nr, volatile unsigned long *ptr)
|
||||
{
|
||||
unsigned long *addr = __bitops_word(nr, ptr);
|
||||
unsigned long old, mask;
|
||||
|
||||
mask = ~(1UL << (nr & (BITS_PER_LONG - 1)));
|
||||
old = __BITOPS_LOOP(addr, mask, __BITOPS_AND, __BITOPS_BARRIER);
|
||||
return (old & ~mask) != 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
test_and_change_bit(unsigned long nr, volatile unsigned long *ptr)
|
||||
{
|
||||
unsigned long *addr = __bitops_word(nr, ptr);
|
||||
unsigned long old, mask;
|
||||
|
||||
mask = 1UL << (nr & (BITS_PER_LONG - 1));
|
||||
old = __BITOPS_LOOP(addr, mask, __BITOPS_XOR, __BITOPS_BARRIER);
|
||||
return (old & mask) != 0;
|
||||
}
|
||||
|
||||
static inline void __set_bit(unsigned long nr, volatile unsigned long *ptr)
|
||||
{
|
||||
unsigned char *addr = __bitops_byte(nr, ptr);
|
||||
|
||||
*addr |= 1 << (nr & 7);
|
||||
}
|
||||
|
||||
static inline void
|
||||
__clear_bit(unsigned long nr, volatile unsigned long *ptr)
|
||||
{
|
||||
unsigned char *addr = __bitops_byte(nr, ptr);
|
||||
|
||||
*addr &= ~(1 << (nr & 7));
|
||||
}
|
||||
|
||||
static inline void __change_bit(unsigned long nr, volatile unsigned long *ptr)
|
||||
{
|
||||
unsigned char *addr = __bitops_byte(nr, ptr);
|
||||
|
||||
*addr ^= 1 << (nr & 7);
|
||||
}
|
||||
|
||||
static inline int
|
||||
__test_and_set_bit(unsigned long nr, volatile unsigned long *ptr)
|
||||
{
|
||||
unsigned char *addr = __bitops_byte(nr, ptr);
|
||||
unsigned char ch;
|
||||
|
||||
ch = *addr;
|
||||
*addr |= 1 << (nr & 7);
|
||||
return (ch >> (nr & 7)) & 1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
__test_and_clear_bit(unsigned long nr, volatile unsigned long *ptr)
|
||||
{
|
||||
unsigned char *addr = __bitops_byte(nr, ptr);
|
||||
unsigned char ch;
|
||||
|
||||
ch = *addr;
|
||||
*addr &= ~(1 << (nr & 7));
|
||||
return (ch >> (nr & 7)) & 1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
__test_and_change_bit(unsigned long nr, volatile unsigned long *ptr)
|
||||
{
|
||||
unsigned char *addr = __bitops_byte(nr, ptr);
|
||||
unsigned char ch;
|
||||
|
||||
ch = *addr;
|
||||
*addr ^= 1 << (nr & 7);
|
||||
return (ch >> (nr & 7)) & 1;
|
||||
}
|
||||
|
||||
static inline int test_bit(unsigned long nr, const volatile unsigned long *ptr)
|
||||
{
|
||||
const volatile unsigned char *addr;
|
||||
|
||||
addr = ((const volatile unsigned char *)ptr);
|
||||
addr += (nr ^ (BITS_PER_LONG - 8)) >> 3;
|
||||
return (*addr >> (nr & 7)) & 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Functions which use MSB0 bit numbering.
|
||||
* On an s390x system the bits are numbered:
|
||||
* |0..............63|64............127|128...........191|192...........255|
|
||||
* and on s390:
|
||||
* |0.....31|32....63|64....95|96...127|128..159|160..191|192..223|224..255|
|
||||
*/
|
||||
unsigned long find_first_bit_inv(const unsigned long *addr, unsigned long size);
|
||||
unsigned long find_next_bit_inv(const unsigned long *addr, unsigned long size,
|
||||
unsigned long offset);
|
||||
|
||||
static inline void set_bit_inv(unsigned long nr, volatile unsigned long *ptr)
|
||||
{
|
||||
return set_bit(nr ^ (BITS_PER_LONG - 1), ptr);
|
||||
}
|
||||
|
||||
static inline void clear_bit_inv(unsigned long nr, volatile unsigned long *ptr)
|
||||
{
|
||||
return clear_bit(nr ^ (BITS_PER_LONG - 1), ptr);
|
||||
}
|
||||
|
||||
static inline void __set_bit_inv(unsigned long nr, volatile unsigned long *ptr)
|
||||
{
|
||||
return __set_bit(nr ^ (BITS_PER_LONG - 1), ptr);
|
||||
}
|
||||
|
||||
static inline void __clear_bit_inv(unsigned long nr, volatile unsigned long *ptr)
|
||||
{
|
||||
return __clear_bit(nr ^ (BITS_PER_LONG - 1), ptr);
|
||||
}
|
||||
|
||||
static inline int test_bit_inv(unsigned long nr,
|
||||
const volatile unsigned long *ptr)
|
||||
{
|
||||
return test_bit(nr ^ (BITS_PER_LONG - 1), ptr);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HAVE_MARCH_Z9_109_FEATURES
|
||||
|
||||
/**
|
||||
* __flogr - find leftmost one
|
||||
* @word - The word to search
|
||||
*
|
||||
* Returns the bit number of the most significant bit set,
|
||||
* where the most significant bit has bit number 0.
|
||||
* If no bit is set this function returns 64.
|
||||
*/
|
||||
static inline unsigned char __flogr(unsigned long word)
|
||||
{
|
||||
if (__builtin_constant_p(word)) {
|
||||
unsigned long bit = 0;
|
||||
|
||||
if (!word)
|
||||
return 64;
|
||||
if (!(word & 0xffffffff00000000UL)) {
|
||||
word <<= 32;
|
||||
bit += 32;
|
||||
}
|
||||
if (!(word & 0xffff000000000000UL)) {
|
||||
word <<= 16;
|
||||
bit += 16;
|
||||
}
|
||||
if (!(word & 0xff00000000000000UL)) {
|
||||
word <<= 8;
|
||||
bit += 8;
|
||||
}
|
||||
if (!(word & 0xf000000000000000UL)) {
|
||||
word <<= 4;
|
||||
bit += 4;
|
||||
}
|
||||
if (!(word & 0xc000000000000000UL)) {
|
||||
word <<= 2;
|
||||
bit += 2;
|
||||
}
|
||||
if (!(word & 0x8000000000000000UL)) {
|
||||
word <<= 1;
|
||||
bit += 1;
|
||||
}
|
||||
return bit;
|
||||
} else {
|
||||
register unsigned long bit asm("4") = word;
|
||||
register unsigned long out asm("5");
|
||||
|
||||
asm volatile(
|
||||
" flogr %[bit],%[bit]\n"
|
||||
: [bit] "+d" (bit), [out] "=d" (out) : : "cc");
|
||||
return bit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* __ffs - find first bit in word.
|
||||
* @word: The word to search
|
||||
*
|
||||
* Undefined if no bit exists, so code should check against 0 first.
|
||||
*/
|
||||
static inline unsigned long __ffs(unsigned long word)
|
||||
{
|
||||
return __flogr(-word & word) ^ (BITS_PER_LONG - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* ffs - find first bit set
|
||||
* @word: the word to search
|
||||
*
|
||||
* This is defined the same way as the libc and
|
||||
* compiler builtin ffs routines (man ffs).
|
||||
*/
|
||||
static inline int ffs(int word)
|
||||
{
|
||||
unsigned long mask = 2 * BITS_PER_LONG - 1;
|
||||
unsigned int val = (unsigned int)word;
|
||||
|
||||
return (1 + (__flogr(-val & val) ^ (BITS_PER_LONG - 1))) & mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* __fls - find last (most-significant) set bit in a long word
|
||||
* @word: the word to search
|
||||
*
|
||||
* Undefined if no set bit exists, so code should check against 0 first.
|
||||
*/
|
||||
static inline unsigned long __fls(unsigned long word)
|
||||
{
|
||||
return __flogr(word) ^ (BITS_PER_LONG - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* fls64 - find last set bit in a 64-bit word
|
||||
* @word: the word to search
|
||||
*
|
||||
* This is defined in a similar way as the libc and compiler builtin
|
||||
* ffsll, but returns the position of the most significant set bit.
|
||||
*
|
||||
* fls64(value) returns 0 if value is 0 or the position of the last
|
||||
* set bit if value is nonzero. The last (most significant) bit is
|
||||
* at position 64.
|
||||
*/
|
||||
static inline int fls64(unsigned long word)
|
||||
{
|
||||
unsigned long mask = 2 * BITS_PER_LONG - 1;
|
||||
|
||||
return (1 + (__flogr(word) ^ (BITS_PER_LONG - 1))) & mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* fls - find last (most-significant) bit set
|
||||
* @word: the word to search
|
||||
*
|
||||
* This is defined the same way as ffs.
|
||||
* Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
|
||||
*/
|
||||
static inline int fls(int word)
|
||||
{
|
||||
return fls64((unsigned int)word);
|
||||
}
|
||||
|
||||
#else /* CONFIG_HAVE_MARCH_Z9_109_FEATURES */
|
||||
|
||||
#include <asm-generic/bitops/__ffs.h>
|
||||
#include <asm-generic/bitops/ffs.h>
|
||||
#include <asm-generic/bitops/__fls.h>
|
||||
#include <asm-generic/bitops/fls.h>
|
||||
#include <asm-generic/bitops/fls64.h>
|
||||
|
||||
#endif /* CONFIG_HAVE_MARCH_Z9_109_FEATURES */
|
||||
|
||||
#include <asm-generic/bitops/ffz.h>
|
||||
#include <asm-generic/bitops/find.h>
|
||||
#include <asm-generic/bitops/hweight.h>
|
||||
#include <asm-generic/bitops/lock.h>
|
||||
#include <asm-generic/bitops/sched.h>
|
||||
#include <asm-generic/bitops/le.h>
|
||||
#include <asm-generic/bitops/ext2-atomic-setbit.h>
|
||||
|
||||
#endif /* _S390_BITOPS_H */
|
||||
71
arch/s390/include/asm/bug.h
Normal file
71
arch/s390/include/asm/bug.h
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
#ifndef _ASM_S390_BUG_H
|
||||
#define _ASM_S390_BUG_H
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#ifdef CONFIG_BUG
|
||||
|
||||
#ifdef CONFIG_DEBUG_BUGVERBOSE
|
||||
|
||||
#define __EMIT_BUG(x) do { \
|
||||
asm volatile( \
|
||||
"0: j 0b+2\n" \
|
||||
"1:\n" \
|
||||
".section .rodata.str,\"aMS\",@progbits,1\n" \
|
||||
"2: .asciz \""__FILE__"\"\n" \
|
||||
".previous\n" \
|
||||
".section __bug_table,\"a\"\n" \
|
||||
"3: .long 1b-3b,2b-3b\n" \
|
||||
" .short %0,%1\n" \
|
||||
" .org 3b+%2\n" \
|
||||
".previous\n" \
|
||||
: : "i" (__LINE__), \
|
||||
"i" (x), \
|
||||
"i" (sizeof(struct bug_entry))); \
|
||||
} while (0)
|
||||
|
||||
#else /* CONFIG_DEBUG_BUGVERBOSE */
|
||||
|
||||
#define __EMIT_BUG(x) do { \
|
||||
asm volatile( \
|
||||
"0: j 0b+2\n" \
|
||||
"1:\n" \
|
||||
".section __bug_table,\"a\"\n" \
|
||||
"2: .long 1b-2b\n" \
|
||||
" .short %0\n" \
|
||||
" .org 2b+%1\n" \
|
||||
".previous\n" \
|
||||
: : "i" (x), \
|
||||
"i" (sizeof(struct bug_entry))); \
|
||||
} while (0)
|
||||
|
||||
#endif /* CONFIG_DEBUG_BUGVERBOSE */
|
||||
|
||||
#define BUG() do { \
|
||||
__EMIT_BUG(0); \
|
||||
unreachable(); \
|
||||
} while (0)
|
||||
|
||||
#define __WARN_TAINT(taint) do { \
|
||||
__EMIT_BUG(BUGFLAG_TAINT(taint)); \
|
||||
} while (0)
|
||||
|
||||
#define WARN_ON(x) ({ \
|
||||
int __ret_warn_on = !!(x); \
|
||||
if (__builtin_constant_p(__ret_warn_on)) { \
|
||||
if (__ret_warn_on) \
|
||||
__WARN(); \
|
||||
} else { \
|
||||
if (unlikely(__ret_warn_on)) \
|
||||
__WARN(); \
|
||||
} \
|
||||
unlikely(__ret_warn_on); \
|
||||
})
|
||||
|
||||
#define HAVE_ARCH_BUG
|
||||
#define HAVE_ARCH_WARN_ON
|
||||
#endif /* CONFIG_BUG */
|
||||
|
||||
#include <asm-generic/bug.h>
|
||||
|
||||
#endif /* _ASM_S390_BUG_H */
|
||||
20
arch/s390/include/asm/bugs.h
Normal file
20
arch/s390/include/asm/bugs.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* S390 version
|
||||
* Copyright IBM Corp. 1999
|
||||
* Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
|
||||
*
|
||||
* Derived from "include/asm-i386/bugs.h"
|
||||
* Copyright (C) 1994 Linus Torvalds
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is included by init/main.c to check for architecture-dependent bugs.
|
||||
*
|
||||
* Needs:
|
||||
* void check_bugs(void);
|
||||
*/
|
||||
|
||||
static inline void check_bugs(void)
|
||||
{
|
||||
/* s390 has no bugs ... */
|
||||
}
|
||||
18
arch/s390/include/asm/cache.h
Normal file
18
arch/s390/include/asm/cache.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* S390 version
|
||||
* Copyright IBM Corp. 1999
|
||||
*
|
||||
* Derived from "include/asm-i386/cache.h"
|
||||
* Copyright (C) 1992, Linus Torvalds
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_S390_CACHE_H
|
||||
#define __ARCH_S390_CACHE_H
|
||||
|
||||
#define L1_CACHE_BYTES 256
|
||||
#define L1_CACHE_SHIFT 8
|
||||
#define NET_SKB_PAD 32
|
||||
|
||||
#define __read_mostly __attribute__((__section__(".data..read_mostly")))
|
||||
|
||||
#endif
|
||||
16
arch/s390/include/asm/cacheflush.h
Normal file
16
arch/s390/include/asm/cacheflush.h
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef _S390_CACHEFLUSH_H
|
||||
#define _S390_CACHEFLUSH_H
|
||||
|
||||
/* Caches aren't brain-dead on the s390. */
|
||||
#include <asm-generic/cacheflush.h>
|
||||
|
||||
#ifdef CONFIG_DEBUG_PAGEALLOC
|
||||
void kernel_map_pages(struct page *page, int numpages, int enable);
|
||||
#endif
|
||||
|
||||
int set_memory_ro(unsigned long addr, int numpages);
|
||||
int set_memory_rw(unsigned long addr, int numpages);
|
||||
int set_memory_nx(unsigned long addr, int numpages);
|
||||
int set_memory_x(unsigned long addr, int numpages);
|
||||
|
||||
#endif /* _S390_CACHEFLUSH_H */
|
||||
233
arch/s390/include/asm/ccwdev.h
Normal file
233
arch/s390/include/asm/ccwdev.h
Normal file
|
|
@ -0,0 +1,233 @@
|
|||
/*
|
||||
* Copyright IBM Corp. 2002, 2009
|
||||
*
|
||||
* Author(s): Arnd Bergmann <arndb@de.ibm.com>
|
||||
*
|
||||
* Interface for CCW device drivers
|
||||
*/
|
||||
#ifndef _S390_CCWDEV_H_
|
||||
#define _S390_CCWDEV_H_
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <asm/fcx.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/schid.h>
|
||||
|
||||
/* structs from asm/cio.h */
|
||||
struct irb;
|
||||
struct ccw1;
|
||||
struct ccw_dev_id;
|
||||
|
||||
/* simplified initializers for struct ccw_device:
|
||||
* CCW_DEVICE and CCW_DEVICE_DEVTYPE initialize one
|
||||
* entry in your MODULE_DEVICE_TABLE and set the match_flag correctly */
|
||||
#define CCW_DEVICE(cu, cum) \
|
||||
.cu_type=(cu), .cu_model=(cum), \
|
||||
.match_flags=(CCW_DEVICE_ID_MATCH_CU_TYPE \
|
||||
| (cum ? CCW_DEVICE_ID_MATCH_CU_MODEL : 0))
|
||||
|
||||
#define CCW_DEVICE_DEVTYPE(cu, cum, dev, devm) \
|
||||
.cu_type=(cu), .cu_model=(cum), .dev_type=(dev), .dev_model=(devm),\
|
||||
.match_flags=CCW_DEVICE_ID_MATCH_CU_TYPE \
|
||||
| ((cum) ? CCW_DEVICE_ID_MATCH_CU_MODEL : 0) \
|
||||
| CCW_DEVICE_ID_MATCH_DEVICE_TYPE \
|
||||
| ((devm) ? CCW_DEVICE_ID_MATCH_DEVICE_MODEL : 0)
|
||||
|
||||
/* scan through an array of device ids and return the first
|
||||
* entry that matches the device.
|
||||
*
|
||||
* the array must end with an entry containing zero match_flags
|
||||
*/
|
||||
static inline const struct ccw_device_id *
|
||||
ccw_device_id_match(const struct ccw_device_id *array,
|
||||
const struct ccw_device_id *match)
|
||||
{
|
||||
const struct ccw_device_id *id = array;
|
||||
|
||||
for (id = array; id->match_flags; id++) {
|
||||
if ((id->match_flags & CCW_DEVICE_ID_MATCH_CU_TYPE)
|
||||
&& (id->cu_type != match->cu_type))
|
||||
continue;
|
||||
|
||||
if ((id->match_flags & CCW_DEVICE_ID_MATCH_CU_MODEL)
|
||||
&& (id->cu_model != match->cu_model))
|
||||
continue;
|
||||
|
||||
if ((id->match_flags & CCW_DEVICE_ID_MATCH_DEVICE_TYPE)
|
||||
&& (id->dev_type != match->dev_type))
|
||||
continue;
|
||||
|
||||
if ((id->match_flags & CCW_DEVICE_ID_MATCH_DEVICE_MODEL)
|
||||
&& (id->dev_model != match->dev_model))
|
||||
continue;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* struct ccw_device - channel attached device
|
||||
* @ccwlock: pointer to device lock
|
||||
* @id: id of this device
|
||||
* @drv: ccw driver for this device
|
||||
* @dev: embedded device structure
|
||||
* @online: online status of device
|
||||
* @handler: interrupt handler
|
||||
*
|
||||
* @handler is a member of the device rather than the driver since a driver
|
||||
* can have different interrupt handlers for different ccw devices
|
||||
* (multi-subchannel drivers).
|
||||
*/
|
||||
struct ccw_device {
|
||||
spinlock_t *ccwlock;
|
||||
/* private: */
|
||||
struct ccw_device_private *private; /* cio private information */
|
||||
/* public: */
|
||||
struct ccw_device_id id;
|
||||
struct ccw_driver *drv;
|
||||
struct device dev;
|
||||
int online;
|
||||
void (*handler) (struct ccw_device *, unsigned long, struct irb *);
|
||||
};
|
||||
|
||||
/*
|
||||
* Possible events used by the path_event notifier.
|
||||
*/
|
||||
#define PE_NONE 0x0
|
||||
#define PE_PATH_GONE 0x1 /* A path is no longer available. */
|
||||
#define PE_PATH_AVAILABLE 0x2 /* A path has become available and
|
||||
was successfully verified. */
|
||||
#define PE_PATHGROUP_ESTABLISHED 0x4 /* A pathgroup was reset and had
|
||||
to be established again. */
|
||||
|
||||
/*
|
||||
* Possible CIO actions triggered by the unit check handler.
|
||||
*/
|
||||
enum uc_todo {
|
||||
UC_TODO_RETRY,
|
||||
UC_TODO_RETRY_ON_NEW_PATH,
|
||||
UC_TODO_STOP
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ccw driver - device driver for channel attached devices
|
||||
* @ids: ids supported by this driver
|
||||
* @probe: function called on probe
|
||||
* @remove: function called on remove
|
||||
* @set_online: called when setting device online
|
||||
* @set_offline: called when setting device offline
|
||||
* @notify: notify driver of device state changes
|
||||
* @path_event: notify driver of channel path events
|
||||
* @shutdown: called at device shutdown
|
||||
* @prepare: prepare for pm state transition
|
||||
* @complete: undo work done in @prepare
|
||||
* @freeze: callback for freezing during hibernation snapshotting
|
||||
* @thaw: undo work done in @freeze
|
||||
* @restore: callback for restoring after hibernation
|
||||
* @uc_handler: callback for unit check handler
|
||||
* @driver: embedded device driver structure
|
||||
* @int_class: interruption class to use for accounting interrupts
|
||||
*/
|
||||
struct ccw_driver {
|
||||
struct ccw_device_id *ids;
|
||||
int (*probe) (struct ccw_device *);
|
||||
void (*remove) (struct ccw_device *);
|
||||
int (*set_online) (struct ccw_device *);
|
||||
int (*set_offline) (struct ccw_device *);
|
||||
int (*notify) (struct ccw_device *, int);
|
||||
void (*path_event) (struct ccw_device *, int *);
|
||||
void (*shutdown) (struct ccw_device *);
|
||||
int (*prepare) (struct ccw_device *);
|
||||
void (*complete) (struct ccw_device *);
|
||||
int (*freeze)(struct ccw_device *);
|
||||
int (*thaw) (struct ccw_device *);
|
||||
int (*restore)(struct ccw_device *);
|
||||
enum uc_todo (*uc_handler) (struct ccw_device *, struct irb *);
|
||||
struct device_driver driver;
|
||||
enum interruption_class int_class;
|
||||
};
|
||||
|
||||
extern struct ccw_device *get_ccwdev_by_busid(struct ccw_driver *cdrv,
|
||||
const char *bus_id);
|
||||
|
||||
/* devices drivers call these during module load and unload.
|
||||
* When a driver is registered, its probe method is called
|
||||
* when new devices for its type pop up */
|
||||
extern int ccw_driver_register (struct ccw_driver *driver);
|
||||
extern void ccw_driver_unregister (struct ccw_driver *driver);
|
||||
|
||||
struct ccw1;
|
||||
|
||||
extern int ccw_device_set_options_mask(struct ccw_device *, unsigned long);
|
||||
extern int ccw_device_set_options(struct ccw_device *, unsigned long);
|
||||
extern void ccw_device_clear_options(struct ccw_device *, unsigned long);
|
||||
int ccw_device_is_pathgroup(struct ccw_device *cdev);
|
||||
int ccw_device_is_multipath(struct ccw_device *cdev);
|
||||
|
||||
/* Allow for i/o completion notification after primary interrupt status. */
|
||||
#define CCWDEV_EARLY_NOTIFICATION 0x0001
|
||||
/* Report all interrupt conditions. */
|
||||
#define CCWDEV_REPORT_ALL 0x0002
|
||||
/* Try to perform path grouping. */
|
||||
#define CCWDEV_DO_PATHGROUP 0x0004
|
||||
/* Allow forced onlining of boxed devices. */
|
||||
#define CCWDEV_ALLOW_FORCE 0x0008
|
||||
/* Try to use multipath mode. */
|
||||
#define CCWDEV_DO_MULTIPATH 0x0010
|
||||
|
||||
extern int ccw_device_start(struct ccw_device *, struct ccw1 *,
|
||||
unsigned long, __u8, unsigned long);
|
||||
extern int ccw_device_start_timeout(struct ccw_device *, struct ccw1 *,
|
||||
unsigned long, __u8, unsigned long, int);
|
||||
extern int ccw_device_start_key(struct ccw_device *, struct ccw1 *,
|
||||
unsigned long, __u8, __u8, unsigned long);
|
||||
extern int ccw_device_start_timeout_key(struct ccw_device *, struct ccw1 *,
|
||||
unsigned long, __u8, __u8,
|
||||
unsigned long, int);
|
||||
|
||||
|
||||
extern int ccw_device_resume(struct ccw_device *);
|
||||
extern int ccw_device_halt(struct ccw_device *, unsigned long);
|
||||
extern int ccw_device_clear(struct ccw_device *, unsigned long);
|
||||
int ccw_device_tm_start_key(struct ccw_device *cdev, struct tcw *tcw,
|
||||
unsigned long intparm, u8 lpm, u8 key);
|
||||
int ccw_device_tm_start_key(struct ccw_device *, struct tcw *,
|
||||
unsigned long, u8, u8);
|
||||
int ccw_device_tm_start_timeout_key(struct ccw_device *, struct tcw *,
|
||||
unsigned long, u8, u8, int);
|
||||
int ccw_device_tm_start(struct ccw_device *, struct tcw *,
|
||||
unsigned long, u8);
|
||||
int ccw_device_tm_start_timeout(struct ccw_device *, struct tcw *,
|
||||
unsigned long, u8, int);
|
||||
int ccw_device_tm_intrg(struct ccw_device *cdev);
|
||||
|
||||
int ccw_device_get_mdc(struct ccw_device *cdev, u8 mask);
|
||||
|
||||
extern int ccw_device_set_online(struct ccw_device *cdev);
|
||||
extern int ccw_device_set_offline(struct ccw_device *cdev);
|
||||
|
||||
|
||||
extern struct ciw *ccw_device_get_ciw(struct ccw_device *, __u32 cmd);
|
||||
extern __u8 ccw_device_get_path_mask(struct ccw_device *);
|
||||
extern void ccw_device_get_id(struct ccw_device *, struct ccw_dev_id *);
|
||||
|
||||
#define get_ccwdev_lock(x) (x)->ccwlock
|
||||
|
||||
#define to_ccwdev(n) container_of(n, struct ccw_device, dev)
|
||||
#define to_ccwdrv(n) container_of(n, struct ccw_driver, driver)
|
||||
|
||||
extern struct ccw_device *ccw_device_create_console(struct ccw_driver *);
|
||||
extern void ccw_device_destroy_console(struct ccw_device *);
|
||||
extern int ccw_device_enable_console(struct ccw_device *);
|
||||
extern void ccw_device_wait_idle(struct ccw_device *);
|
||||
extern int ccw_device_force_console(struct ccw_device *);
|
||||
|
||||
int ccw_device_siosl(struct ccw_device *);
|
||||
|
||||
extern void ccw_device_get_schid(struct ccw_device *, struct subchannel_id *);
|
||||
|
||||
struct channel_path_desc *ccw_device_get_chp_desc(struct ccw_device *, int);
|
||||
#endif /* _S390_CCWDEV_H_ */
|
||||
73
arch/s390/include/asm/ccwgroup.h
Normal file
73
arch/s390/include/asm/ccwgroup.h
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
#ifndef S390_CCWGROUP_H
|
||||
#define S390_CCWGROUP_H
|
||||
|
||||
struct ccw_device;
|
||||
struct ccw_driver;
|
||||
|
||||
/**
|
||||
* struct ccwgroup_device - ccw group device
|
||||
* @state: online/offline state
|
||||
* @count: number of attached slave devices
|
||||
* @dev: embedded device structure
|
||||
* @cdev: variable number of slave devices, allocated as needed
|
||||
* @ungroup_work: work to be done when a ccwgroup notifier has action
|
||||
* type %BUS_NOTIFY_UNBIND_DRIVER
|
||||
*/
|
||||
struct ccwgroup_device {
|
||||
enum {
|
||||
CCWGROUP_OFFLINE,
|
||||
CCWGROUP_ONLINE,
|
||||
} state;
|
||||
/* private: */
|
||||
atomic_t onoff;
|
||||
struct mutex reg_mutex;
|
||||
/* public: */
|
||||
unsigned int count;
|
||||
struct device dev;
|
||||
struct work_struct ungroup_work;
|
||||
struct ccw_device *cdev[0];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ccwgroup_driver - driver for ccw group devices
|
||||
* @setup: function called during device creation to setup the device
|
||||
* @remove: function called on remove
|
||||
* @set_online: function called when device is set online
|
||||
* @set_offline: function called when device is set offline
|
||||
* @shutdown: function called when device is shut down
|
||||
* @prepare: prepare for pm state transition
|
||||
* @complete: undo work done in @prepare
|
||||
* @freeze: callback for freezing during hibernation snapshotting
|
||||
* @thaw: undo work done in @freeze
|
||||
* @restore: callback for restoring after hibernation
|
||||
* @driver: embedded driver structure
|
||||
*/
|
||||
struct ccwgroup_driver {
|
||||
int (*setup) (struct ccwgroup_device *);
|
||||
void (*remove) (struct ccwgroup_device *);
|
||||
int (*set_online) (struct ccwgroup_device *);
|
||||
int (*set_offline) (struct ccwgroup_device *);
|
||||
void (*shutdown)(struct ccwgroup_device *);
|
||||
int (*prepare) (struct ccwgroup_device *);
|
||||
void (*complete) (struct ccwgroup_device *);
|
||||
int (*freeze)(struct ccwgroup_device *);
|
||||
int (*thaw) (struct ccwgroup_device *);
|
||||
int (*restore)(struct ccwgroup_device *);
|
||||
|
||||
struct device_driver driver;
|
||||
};
|
||||
|
||||
extern int ccwgroup_driver_register (struct ccwgroup_driver *cdriver);
|
||||
extern void ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver);
|
||||
int ccwgroup_create_dev(struct device *root, struct ccwgroup_driver *gdrv,
|
||||
int num_devices, const char *buf);
|
||||
|
||||
extern int ccwgroup_set_online(struct ccwgroup_device *gdev);
|
||||
extern int ccwgroup_set_offline(struct ccwgroup_device *gdev);
|
||||
|
||||
extern int ccwgroup_probe_ccwdev(struct ccw_device *cdev);
|
||||
extern void ccwgroup_remove_ccwdev(struct ccw_device *cdev);
|
||||
|
||||
#define to_ccwgroupdev(x) container_of((x), struct ccwgroup_device, dev)
|
||||
#define to_ccwgroupdrv(x) container_of((x), struct ccwgroup_driver, driver)
|
||||
#endif
|
||||
140
arch/s390/include/asm/checksum.h
Normal file
140
arch/s390/include/asm/checksum.h
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* S390 fast network checksum routines
|
||||
*
|
||||
* S390 version
|
||||
* Copyright IBM Corp. 1999
|
||||
* Author(s): Ulrich Hild (first version)
|
||||
* Martin Schwidefsky (heavily optimized CKSM version)
|
||||
* D.J. Barrow (third attempt)
|
||||
*/
|
||||
|
||||
#ifndef _S390_CHECKSUM_H
|
||||
#define _S390_CHECKSUM_H
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
/*
|
||||
* computes the checksum of a memory block at buff, length len,
|
||||
* and adds in "sum" (32-bit)
|
||||
*
|
||||
* returns a 32-bit number suitable for feeding into itself
|
||||
* or csum_tcpudp_magic
|
||||
*
|
||||
* this function must be called with even lengths, except
|
||||
* for the last fragment, which may be odd
|
||||
*
|
||||
* it's best to have buff aligned on a 32-bit boundary
|
||||
*/
|
||||
static inline __wsum
|
||||
csum_partial(const void *buff, int len, __wsum sum)
|
||||
{
|
||||
register unsigned long reg2 asm("2") = (unsigned long) buff;
|
||||
register unsigned long reg3 asm("3") = (unsigned long) len;
|
||||
|
||||
asm volatile(
|
||||
"0: cksm %0,%1\n" /* do checksum on longs */
|
||||
" jo 0b\n"
|
||||
: "+d" (sum), "+d" (reg2), "+d" (reg3) : : "cc", "memory");
|
||||
return sum;
|
||||
}
|
||||
|
||||
/*
|
||||
* the same as csum_partial_copy, but copies from user space.
|
||||
*
|
||||
* here even more important to align src and dst on a 32-bit (or even
|
||||
* better 64-bit) boundary
|
||||
*
|
||||
* Copy from userspace and compute checksum.
|
||||
*/
|
||||
static inline __wsum
|
||||
csum_partial_copy_from_user(const void __user *src, void *dst,
|
||||
int len, __wsum sum,
|
||||
int *err_ptr)
|
||||
{
|
||||
if (unlikely(copy_from_user(dst, src, len)))
|
||||
*err_ptr = -EFAULT;
|
||||
return csum_partial(dst, len, sum);
|
||||
}
|
||||
|
||||
|
||||
static inline __wsum
|
||||
csum_partial_copy_nocheck (const void *src, void *dst, int len, __wsum sum)
|
||||
{
|
||||
memcpy(dst,src,len);
|
||||
return csum_partial(dst, len, sum);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fold a partial checksum without adding pseudo headers
|
||||
*/
|
||||
static inline __sum16 csum_fold(__wsum sum)
|
||||
{
|
||||
u32 csum = (__force u32) sum;
|
||||
|
||||
csum += (csum >> 16) + (csum << 16);
|
||||
csum >>= 16;
|
||||
return (__force __sum16) ~csum;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a version of ip_compute_csum() optimized for IP headers,
|
||||
* which always checksum on 4 octet boundaries.
|
||||
*
|
||||
*/
|
||||
static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
|
||||
{
|
||||
return csum_fold(csum_partial(iph, ihl*4, 0));
|
||||
}
|
||||
|
||||
/*
|
||||
* computes the checksum of the TCP/UDP pseudo-header
|
||||
* returns a 32-bit checksum
|
||||
*/
|
||||
static inline __wsum
|
||||
csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
|
||||
unsigned short len, unsigned short proto,
|
||||
__wsum sum)
|
||||
{
|
||||
__u32 csum = (__force __u32)sum;
|
||||
|
||||
csum += (__force __u32)saddr;
|
||||
if (csum < (__force __u32)saddr)
|
||||
csum++;
|
||||
|
||||
csum += (__force __u32)daddr;
|
||||
if (csum < (__force __u32)daddr)
|
||||
csum++;
|
||||
|
||||
csum += len + proto;
|
||||
if (csum < len + proto)
|
||||
csum++;
|
||||
|
||||
return (__force __wsum)csum;
|
||||
}
|
||||
|
||||
/*
|
||||
* computes the checksum of the TCP/UDP pseudo-header
|
||||
* returns a 16-bit checksum, already complemented
|
||||
*/
|
||||
|
||||
static inline __sum16
|
||||
csum_tcpudp_magic(__be32 saddr, __be32 daddr,
|
||||
unsigned short len, unsigned short proto,
|
||||
__wsum sum)
|
||||
{
|
||||
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
|
||||
}
|
||||
|
||||
/*
|
||||
* this routine is used for miscellaneous IP-like checksums, mainly
|
||||
* in icmp.c
|
||||
*/
|
||||
|
||||
static inline __sum16 ip_compute_csum(const void *buff, int len)
|
||||
{
|
||||
return csum_fold(csum_partial(buff, len, 0));
|
||||
}
|
||||
|
||||
#endif /* _S390_CHECKSUM_H */
|
||||
|
||||
|
||||
50
arch/s390/include/asm/chpid.h
Normal file
50
arch/s390/include/asm/chpid.h
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright IBM Corp. 2007, 2012
|
||||
* Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
|
||||
*/
|
||||
#ifndef _ASM_S390_CHPID_H
|
||||
#define _ASM_S390_CHPID_H
|
||||
|
||||
#include <uapi/asm/chpid.h>
|
||||
#include <asm/cio.h>
|
||||
|
||||
struct channel_path_desc {
|
||||
u8 flags;
|
||||
u8 lsn;
|
||||
u8 desc;
|
||||
u8 chpid;
|
||||
u8 swla;
|
||||
u8 zeroes;
|
||||
u8 chla;
|
||||
u8 chpp;
|
||||
} __packed;
|
||||
|
||||
static inline void chp_id_init(struct chp_id *chpid)
|
||||
{
|
||||
memset(chpid, 0, sizeof(struct chp_id));
|
||||
}
|
||||
|
||||
static inline int chp_id_is_equal(struct chp_id *a, struct chp_id *b)
|
||||
{
|
||||
return (a->id == b->id) && (a->cssid == b->cssid);
|
||||
}
|
||||
|
||||
static inline void chp_id_next(struct chp_id *chpid)
|
||||
{
|
||||
if (chpid->id < __MAX_CHPID)
|
||||
chpid->id++;
|
||||
else {
|
||||
chpid->id = 0;
|
||||
chpid->cssid++;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int chp_id_is_valid(struct chp_id *chpid)
|
||||
{
|
||||
return (chpid->cssid <= __MAX_CSSID);
|
||||
}
|
||||
|
||||
|
||||
#define chp_id_for_each(c) \
|
||||
for (chp_id_init(c); chp_id_is_valid(c); chp_id_next(c))
|
||||
#endif /* _ASM_S390_CHPID_H */
|
||||
315
arch/s390/include/asm/cio.h
Normal file
315
arch/s390/include/asm/cio.h
Normal file
|
|
@ -0,0 +1,315 @@
|
|||
/*
|
||||
* Common interface for I/O on S/390
|
||||
*/
|
||||
#ifndef _ASM_S390_CIO_H_
|
||||
#define _ASM_S390_CIO_H_
|
||||
|
||||
#include <linux/spinlock.h>
|
||||
#include <asm/types.h>
|
||||
|
||||
#define LPM_ANYPATH 0xff
|
||||
#define __MAX_CSSID 0
|
||||
#define __MAX_SUBCHANNEL 65535
|
||||
#define __MAX_SSID 3
|
||||
|
||||
#include <asm/scsw.h>
|
||||
|
||||
/**
|
||||
* struct ccw1 - channel command word
|
||||
* @cmd_code: command code
|
||||
* @flags: flags, like IDA addressing, etc.
|
||||
* @count: byte count
|
||||
* @cda: data address
|
||||
*
|
||||
* The ccw is the basic structure to build channel programs that perform
|
||||
* operations with the device or the control unit. Only Format-1 channel
|
||||
* command words are supported.
|
||||
*/
|
||||
struct ccw1 {
|
||||
__u8 cmd_code;
|
||||
__u8 flags;
|
||||
__u16 count;
|
||||
__u32 cda;
|
||||
} __attribute__ ((packed,aligned(8)));
|
||||
|
||||
#define CCW_FLAG_DC 0x80
|
||||
#define CCW_FLAG_CC 0x40
|
||||
#define CCW_FLAG_SLI 0x20
|
||||
#define CCW_FLAG_SKIP 0x10
|
||||
#define CCW_FLAG_PCI 0x08
|
||||
#define CCW_FLAG_IDA 0x04
|
||||
#define CCW_FLAG_SUSPEND 0x02
|
||||
|
||||
#define CCW_CMD_READ_IPL 0x02
|
||||
#define CCW_CMD_NOOP 0x03
|
||||
#define CCW_CMD_BASIC_SENSE 0x04
|
||||
#define CCW_CMD_TIC 0x08
|
||||
#define CCW_CMD_STLCK 0x14
|
||||
#define CCW_CMD_SENSE_PGID 0x34
|
||||
#define CCW_CMD_SUSPEND_RECONN 0x5B
|
||||
#define CCW_CMD_RDC 0x64
|
||||
#define CCW_CMD_RELEASE 0x94
|
||||
#define CCW_CMD_SET_PGID 0xAF
|
||||
#define CCW_CMD_SENSE_ID 0xE4
|
||||
#define CCW_CMD_DCTL 0xF3
|
||||
|
||||
#define SENSE_MAX_COUNT 0x20
|
||||
|
||||
/**
|
||||
* struct erw - extended report word
|
||||
* @res0: reserved
|
||||
* @auth: authorization check
|
||||
* @pvrf: path-verification-required flag
|
||||
* @cpt: channel-path timeout
|
||||
* @fsavf: failing storage address validity flag
|
||||
* @cons: concurrent sense
|
||||
* @scavf: secondary ccw address validity flag
|
||||
* @fsaf: failing storage address format
|
||||
* @scnt: sense count, if @cons == %1
|
||||
* @res16: reserved
|
||||
*/
|
||||
struct erw {
|
||||
__u32 res0 : 3;
|
||||
__u32 auth : 1;
|
||||
__u32 pvrf : 1;
|
||||
__u32 cpt : 1;
|
||||
__u32 fsavf : 1;
|
||||
__u32 cons : 1;
|
||||
__u32 scavf : 1;
|
||||
__u32 fsaf : 1;
|
||||
__u32 scnt : 6;
|
||||
__u32 res16 : 16;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/**
|
||||
* struct erw_eadm - EADM Subchannel extended report word
|
||||
* @b: aob error
|
||||
* @r: arsb error
|
||||
*/
|
||||
struct erw_eadm {
|
||||
__u32 : 16;
|
||||
__u32 b : 1;
|
||||
__u32 r : 1;
|
||||
__u32 : 14;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct sublog - subchannel logout area
|
||||
* @res0: reserved
|
||||
* @esf: extended status flags
|
||||
* @lpum: last path used mask
|
||||
* @arep: ancillary report
|
||||
* @fvf: field-validity flags
|
||||
* @sacc: storage access code
|
||||
* @termc: termination code
|
||||
* @devsc: device-status check
|
||||
* @serr: secondary error
|
||||
* @ioerr: i/o-error alert
|
||||
* @seqc: sequence code
|
||||
*/
|
||||
struct sublog {
|
||||
__u32 res0 : 1;
|
||||
__u32 esf : 7;
|
||||
__u32 lpum : 8;
|
||||
__u32 arep : 1;
|
||||
__u32 fvf : 5;
|
||||
__u32 sacc : 2;
|
||||
__u32 termc : 2;
|
||||
__u32 devsc : 1;
|
||||
__u32 serr : 1;
|
||||
__u32 ioerr : 1;
|
||||
__u32 seqc : 3;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/**
|
||||
* struct esw0 - Format 0 Extended Status Word (ESW)
|
||||
* @sublog: subchannel logout
|
||||
* @erw: extended report word
|
||||
* @faddr: failing storage address
|
||||
* @saddr: secondary ccw address
|
||||
*/
|
||||
struct esw0 {
|
||||
struct sublog sublog;
|
||||
struct erw erw;
|
||||
__u32 faddr[2];
|
||||
__u32 saddr;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/**
|
||||
* struct esw1 - Format 1 Extended Status Word (ESW)
|
||||
* @zero0: reserved zeros
|
||||
* @lpum: last path used mask
|
||||
* @zero16: reserved zeros
|
||||
* @erw: extended report word
|
||||
* @zeros: three fullwords of zeros
|
||||
*/
|
||||
struct esw1 {
|
||||
__u8 zero0;
|
||||
__u8 lpum;
|
||||
__u16 zero16;
|
||||
struct erw erw;
|
||||
__u32 zeros[3];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/**
|
||||
* struct esw2 - Format 2 Extended Status Word (ESW)
|
||||
* @zero0: reserved zeros
|
||||
* @lpum: last path used mask
|
||||
* @dcti: device-connect-time interval
|
||||
* @erw: extended report word
|
||||
* @zeros: three fullwords of zeros
|
||||
*/
|
||||
struct esw2 {
|
||||
__u8 zero0;
|
||||
__u8 lpum;
|
||||
__u16 dcti;
|
||||
struct erw erw;
|
||||
__u32 zeros[3];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/**
|
||||
* struct esw3 - Format 3 Extended Status Word (ESW)
|
||||
* @zero0: reserved zeros
|
||||
* @lpum: last path used mask
|
||||
* @res: reserved
|
||||
* @erw: extended report word
|
||||
* @zeros: three fullwords of zeros
|
||||
*/
|
||||
struct esw3 {
|
||||
__u8 zero0;
|
||||
__u8 lpum;
|
||||
__u16 res;
|
||||
struct erw erw;
|
||||
__u32 zeros[3];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/**
|
||||
* struct esw_eadm - EADM Subchannel Extended Status Word (ESW)
|
||||
* @sublog: subchannel logout
|
||||
* @erw: extended report word
|
||||
*/
|
||||
struct esw_eadm {
|
||||
__u32 sublog;
|
||||
struct erw_eadm erw;
|
||||
__u32 : 32;
|
||||
__u32 : 32;
|
||||
__u32 : 32;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct irb - interruption response block
|
||||
* @scsw: subchannel status word
|
||||
* @esw: extended status word
|
||||
* @ecw: extended control word
|
||||
*
|
||||
* The irb that is handed to the device driver when an interrupt occurs. For
|
||||
* solicited interrupts, the common I/O layer already performs checks whether
|
||||
* a field is valid; a field not being valid is always passed as %0.
|
||||
* If a unit check occurred, @ecw may contain sense data; this is retrieved
|
||||
* by the common I/O layer itself if the device doesn't support concurrent
|
||||
* sense (so that the device driver never needs to perform basic sene itself).
|
||||
* For unsolicited interrupts, the irb is passed as-is (expect for sense data,
|
||||
* if applicable).
|
||||
*/
|
||||
struct irb {
|
||||
union scsw scsw;
|
||||
union {
|
||||
struct esw0 esw0;
|
||||
struct esw1 esw1;
|
||||
struct esw2 esw2;
|
||||
struct esw3 esw3;
|
||||
struct esw_eadm eadm;
|
||||
} esw;
|
||||
__u8 ecw[32];
|
||||
} __attribute__ ((packed,aligned(4)));
|
||||
|
||||
/**
|
||||
* struct ciw - command information word (CIW) layout
|
||||
* @et: entry type
|
||||
* @reserved: reserved bits
|
||||
* @ct: command type
|
||||
* @cmd: command code
|
||||
* @count: command count
|
||||
*/
|
||||
struct ciw {
|
||||
__u32 et : 2;
|
||||
__u32 reserved : 2;
|
||||
__u32 ct : 4;
|
||||
__u32 cmd : 8;
|
||||
__u32 count : 16;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define CIW_TYPE_RCD 0x0 /* read configuration data */
|
||||
#define CIW_TYPE_SII 0x1 /* set interface identifier */
|
||||
#define CIW_TYPE_RNI 0x2 /* read node identifier */
|
||||
|
||||
/*
|
||||
* Flags used as input parameters for do_IO()
|
||||
*/
|
||||
#define DOIO_ALLOW_SUSPEND 0x0001 /* allow for channel prog. suspend */
|
||||
#define DOIO_DENY_PREFETCH 0x0002 /* don't allow for CCW prefetch */
|
||||
#define DOIO_SUPPRESS_INTER 0x0004 /* suppress intermediate inter. */
|
||||
/* ... for suspended CCWs */
|
||||
/* Device or subchannel gone. */
|
||||
#define CIO_GONE 0x0001
|
||||
/* No path to device. */
|
||||
#define CIO_NO_PATH 0x0002
|
||||
/* Device has appeared. */
|
||||
#define CIO_OPER 0x0004
|
||||
/* Sick revalidation of device. */
|
||||
#define CIO_REVALIDATE 0x0008
|
||||
/* Device did not respond in time. */
|
||||
#define CIO_BOXED 0x0010
|
||||
|
||||
/**
|
||||
* struct ccw_dev_id - unique identifier for ccw devices
|
||||
* @ssid: subchannel set id
|
||||
* @devno: device number
|
||||
*
|
||||
* This structure is not directly based on any hardware structure. The
|
||||
* hardware identifies a device by its device number and its subchannel,
|
||||
* which is in turn identified by its id. In order to get a unique identifier
|
||||
* for ccw devices across subchannel sets, @struct ccw_dev_id has been
|
||||
* introduced.
|
||||
*/
|
||||
struct ccw_dev_id {
|
||||
u8 ssid;
|
||||
u16 devno;
|
||||
};
|
||||
|
||||
/**
|
||||
* ccw_device_id_is_equal() - compare two ccw_dev_ids
|
||||
* @dev_id1: a ccw_dev_id
|
||||
* @dev_id2: another ccw_dev_id
|
||||
* Returns:
|
||||
* %1 if the two structures are equal field-by-field,
|
||||
* %0 if not.
|
||||
* Context:
|
||||
* any
|
||||
*/
|
||||
static inline int ccw_dev_id_is_equal(struct ccw_dev_id *dev_id1,
|
||||
struct ccw_dev_id *dev_id2)
|
||||
{
|
||||
if ((dev_id1->ssid == dev_id2->ssid) &&
|
||||
(dev_id1->devno == dev_id2->devno))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void channel_subsystem_reinit(void);
|
||||
extern void css_schedule_reprobe(void);
|
||||
|
||||
extern void reipl_ccw_dev(struct ccw_dev_id *id);
|
||||
|
||||
struct cio_iplinfo {
|
||||
u16 devno;
|
||||
int is_qdio;
|
||||
};
|
||||
|
||||
extern int cio_get_iplinfo(struct cio_iplinfo *iplinfo);
|
||||
|
||||
/* Function from drivers/s390/cio/chsc.c */
|
||||
int chsc_sstpc(void *page, unsigned int op, u16 ctrl);
|
||||
int chsc_sstpi(void *page, void *result, size_t size);
|
||||
|
||||
#endif
|
||||
28
arch/s390/include/asm/clp.h
Normal file
28
arch/s390/include/asm/clp.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef _ASM_S390_CLP_H
|
||||
#define _ASM_S390_CLP_H
|
||||
|
||||
/* CLP common request & response block size */
|
||||
#define CLP_BLK_SIZE PAGE_SIZE
|
||||
|
||||
struct clp_req_hdr {
|
||||
u16 len;
|
||||
u16 cmd;
|
||||
} __packed;
|
||||
|
||||
struct clp_rsp_hdr {
|
||||
u16 len;
|
||||
u16 rsp;
|
||||
} __packed;
|
||||
|
||||
/* CLP Response Codes */
|
||||
#define CLP_RC_OK 0x0010 /* Command request successfully */
|
||||
#define CLP_RC_CMD 0x0020 /* Command code not recognized */
|
||||
#define CLP_RC_PERM 0x0030 /* Command not authorized */
|
||||
#define CLP_RC_FMT 0x0040 /* Invalid command request format */
|
||||
#define CLP_RC_LEN 0x0050 /* Invalid command request length */
|
||||
#define CLP_RC_8K 0x0060 /* Command requires 8K LPCB */
|
||||
#define CLP_RC_RESNOT0 0x0070 /* Reserved field not zero */
|
||||
#define CLP_RC_NODATA 0x0080 /* No data available */
|
||||
#define CLP_RC_FC_UNKNOWN 0x0100 /* Function code not recognized */
|
||||
|
||||
#endif
|
||||
12
arch/s390/include/asm/cmb.h
Normal file
12
arch/s390/include/asm/cmb.h
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef S390_CMB_H
|
||||
#define S390_CMB_H
|
||||
|
||||
#include <uapi/asm/cmb.h>
|
||||
|
||||
struct ccw_device;
|
||||
extern int enable_cmf(struct ccw_device *cdev);
|
||||
extern int disable_cmf(struct ccw_device *cdev);
|
||||
extern u64 cmf_read(struct ccw_device *cdev, int index);
|
||||
extern int cmf_readall(struct ccw_device *cdev, struct cmbdata *data);
|
||||
|
||||
#endif /* S390_CMB_H */
|
||||
304
arch/s390/include/asm/cmpxchg.h
Normal file
304
arch/s390/include/asm/cmpxchg.h
Normal file
|
|
@ -0,0 +1,304 @@
|
|||
/*
|
||||
* Copyright IBM Corp. 1999, 2011
|
||||
*
|
||||
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>,
|
||||
*/
|
||||
|
||||
#ifndef __ASM_CMPXCHG_H
|
||||
#define __ASM_CMPXCHG_H
|
||||
|
||||
#include <linux/mmdebug.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/bug.h>
|
||||
|
||||
extern void __xchg_called_with_bad_pointer(void);
|
||||
|
||||
static inline unsigned long __xchg(unsigned long x, void *ptr, int size)
|
||||
{
|
||||
unsigned long addr, old;
|
||||
int shift;
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
addr = (unsigned long) ptr;
|
||||
shift = (3 ^ (addr & 3)) << 3;
|
||||
addr ^= addr & 3;
|
||||
asm volatile(
|
||||
" l %0,%4\n"
|
||||
"0: lr 0,%0\n"
|
||||
" nr 0,%3\n"
|
||||
" or 0,%2\n"
|
||||
" cs %0,0,%4\n"
|
||||
" jl 0b\n"
|
||||
: "=&d" (old), "=Q" (*(int *) addr)
|
||||
: "d" ((x & 0xff) << shift), "d" (~(0xff << shift)),
|
||||
"Q" (*(int *) addr) : "memory", "cc", "0");
|
||||
return old >> shift;
|
||||
case 2:
|
||||
addr = (unsigned long) ptr;
|
||||
shift = (2 ^ (addr & 2)) << 3;
|
||||
addr ^= addr & 2;
|
||||
asm volatile(
|
||||
" l %0,%4\n"
|
||||
"0: lr 0,%0\n"
|
||||
" nr 0,%3\n"
|
||||
" or 0,%2\n"
|
||||
" cs %0,0,%4\n"
|
||||
" jl 0b\n"
|
||||
: "=&d" (old), "=Q" (*(int *) addr)
|
||||
: "d" ((x & 0xffff) << shift), "d" (~(0xffff << shift)),
|
||||
"Q" (*(int *) addr) : "memory", "cc", "0");
|
||||
return old >> shift;
|
||||
case 4:
|
||||
asm volatile(
|
||||
" l %0,%3\n"
|
||||
"0: cs %0,%2,%3\n"
|
||||
" jl 0b\n"
|
||||
: "=&d" (old), "=Q" (*(int *) ptr)
|
||||
: "d" (x), "Q" (*(int *) ptr)
|
||||
: "memory", "cc");
|
||||
return old;
|
||||
#ifdef CONFIG_64BIT
|
||||
case 8:
|
||||
asm volatile(
|
||||
" lg %0,%3\n"
|
||||
"0: csg %0,%2,%3\n"
|
||||
" jl 0b\n"
|
||||
: "=&d" (old), "=m" (*(long *) ptr)
|
||||
: "d" (x), "Q" (*(long *) ptr)
|
||||
: "memory", "cc");
|
||||
return old;
|
||||
#endif /* CONFIG_64BIT */
|
||||
}
|
||||
__xchg_called_with_bad_pointer();
|
||||
return x;
|
||||
}
|
||||
|
||||
#define xchg(ptr, x) \
|
||||
({ \
|
||||
__typeof__(*(ptr)) __ret; \
|
||||
__ret = (__typeof__(*(ptr))) \
|
||||
__xchg((unsigned long)(x), (void *)(ptr), sizeof(*(ptr)));\
|
||||
__ret; \
|
||||
})
|
||||
|
||||
/*
|
||||
* Atomic compare and exchange. Compare OLD with MEM, if identical,
|
||||
* store NEW in MEM. Return the initial value in MEM. Success is
|
||||
* indicated by comparing RETURN with OLD.
|
||||
*/
|
||||
|
||||
#define __HAVE_ARCH_CMPXCHG
|
||||
|
||||
extern void __cmpxchg_called_with_bad_pointer(void);
|
||||
|
||||
static inline unsigned long __cmpxchg(void *ptr, unsigned long old,
|
||||
unsigned long new, int size)
|
||||
{
|
||||
unsigned long addr, prev, tmp;
|
||||
int shift;
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
addr = (unsigned long) ptr;
|
||||
shift = (3 ^ (addr & 3)) << 3;
|
||||
addr ^= addr & 3;
|
||||
asm volatile(
|
||||
" l %0,%2\n"
|
||||
"0: nr %0,%5\n"
|
||||
" lr %1,%0\n"
|
||||
" or %0,%3\n"
|
||||
" or %1,%4\n"
|
||||
" cs %0,%1,%2\n"
|
||||
" jnl 1f\n"
|
||||
" xr %1,%0\n"
|
||||
" nr %1,%5\n"
|
||||
" jnz 0b\n"
|
||||
"1:"
|
||||
: "=&d" (prev), "=&d" (tmp), "+Q" (*(int *) addr)
|
||||
: "d" ((old & 0xff) << shift),
|
||||
"d" ((new & 0xff) << shift),
|
||||
"d" (~(0xff << shift))
|
||||
: "memory", "cc");
|
||||
return prev >> shift;
|
||||
case 2:
|
||||
addr = (unsigned long) ptr;
|
||||
shift = (2 ^ (addr & 2)) << 3;
|
||||
addr ^= addr & 2;
|
||||
asm volatile(
|
||||
" l %0,%2\n"
|
||||
"0: nr %0,%5\n"
|
||||
" lr %1,%0\n"
|
||||
" or %0,%3\n"
|
||||
" or %1,%4\n"
|
||||
" cs %0,%1,%2\n"
|
||||
" jnl 1f\n"
|
||||
" xr %1,%0\n"
|
||||
" nr %1,%5\n"
|
||||
" jnz 0b\n"
|
||||
"1:"
|
||||
: "=&d" (prev), "=&d" (tmp), "+Q" (*(int *) addr)
|
||||
: "d" ((old & 0xffff) << shift),
|
||||
"d" ((new & 0xffff) << shift),
|
||||
"d" (~(0xffff << shift))
|
||||
: "memory", "cc");
|
||||
return prev >> shift;
|
||||
case 4:
|
||||
asm volatile(
|
||||
" cs %0,%3,%1\n"
|
||||
: "=&d" (prev), "=Q" (*(int *) ptr)
|
||||
: "0" (old), "d" (new), "Q" (*(int *) ptr)
|
||||
: "memory", "cc");
|
||||
return prev;
|
||||
#ifdef CONFIG_64BIT
|
||||
case 8:
|
||||
asm volatile(
|
||||
" csg %0,%3,%1\n"
|
||||
: "=&d" (prev), "=Q" (*(long *) ptr)
|
||||
: "0" (old), "d" (new), "Q" (*(long *) ptr)
|
||||
: "memory", "cc");
|
||||
return prev;
|
||||
#endif /* CONFIG_64BIT */
|
||||
}
|
||||
__cmpxchg_called_with_bad_pointer();
|
||||
return old;
|
||||
}
|
||||
|
||||
#define cmpxchg(ptr, o, n) \
|
||||
({ \
|
||||
__typeof__(*(ptr)) __ret; \
|
||||
__ret = (__typeof__(*(ptr))) \
|
||||
__cmpxchg((ptr), (unsigned long)(o), (unsigned long)(n), \
|
||||
sizeof(*(ptr))); \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
#define cmpxchg64(ptr, o, n) \
|
||||
({ \
|
||||
cmpxchg((ptr), (o), (n)); \
|
||||
})
|
||||
#else /* CONFIG_64BIT */
|
||||
static inline unsigned long long __cmpxchg64(void *ptr,
|
||||
unsigned long long old,
|
||||
unsigned long long new)
|
||||
{
|
||||
register_pair rp_old = {.pair = old};
|
||||
register_pair rp_new = {.pair = new};
|
||||
unsigned long long *ullptr = ptr;
|
||||
|
||||
asm volatile(
|
||||
" cds %0,%2,%1"
|
||||
: "+d" (rp_old), "+Q" (*ullptr)
|
||||
: "d" (rp_new)
|
||||
: "memory", "cc");
|
||||
return rp_old.pair;
|
||||
}
|
||||
|
||||
#define cmpxchg64(ptr, o, n) \
|
||||
({ \
|
||||
__typeof__(*(ptr)) __ret; \
|
||||
__ret = (__typeof__(*(ptr))) \
|
||||
__cmpxchg64((ptr), \
|
||||
(unsigned long long)(o), \
|
||||
(unsigned long long)(n)); \
|
||||
__ret; \
|
||||
})
|
||||
#endif /* CONFIG_64BIT */
|
||||
|
||||
#define __cmpxchg_double_op(p1, p2, o1, o2, n1, n2, insn) \
|
||||
({ \
|
||||
register __typeof__(*(p1)) __old1 asm("2") = (o1); \
|
||||
register __typeof__(*(p2)) __old2 asm("3") = (o2); \
|
||||
register __typeof__(*(p1)) __new1 asm("4") = (n1); \
|
||||
register __typeof__(*(p2)) __new2 asm("5") = (n2); \
|
||||
int cc; \
|
||||
asm volatile( \
|
||||
insn " %[old],%[new],%[ptr]\n" \
|
||||
" ipm %[cc]\n" \
|
||||
" srl %[cc],28" \
|
||||
: [cc] "=d" (cc), [old] "+d" (__old1), "+d" (__old2) \
|
||||
: [new] "d" (__new1), "d" (__new2), \
|
||||
[ptr] "Q" (*(p1)), "Q" (*(p2)) \
|
||||
: "memory", "cc"); \
|
||||
!cc; \
|
||||
})
|
||||
|
||||
#define __cmpxchg_double_4(p1, p2, o1, o2, n1, n2) \
|
||||
__cmpxchg_double_op(p1, p2, o1, o2, n1, n2, "cds")
|
||||
|
||||
#define __cmpxchg_double_8(p1, p2, o1, o2, n1, n2) \
|
||||
__cmpxchg_double_op(p1, p2, o1, o2, n1, n2, "cdsg")
|
||||
|
||||
extern void __cmpxchg_double_called_with_bad_pointer(void);
|
||||
|
||||
#define __cmpxchg_double(p1, p2, o1, o2, n1, n2) \
|
||||
({ \
|
||||
int __ret; \
|
||||
switch (sizeof(*(p1))) { \
|
||||
case 4: \
|
||||
__ret = __cmpxchg_double_4(p1, p2, o1, o2, n1, n2); \
|
||||
break; \
|
||||
case 8: \
|
||||
__ret = __cmpxchg_double_8(p1, p2, o1, o2, n1, n2); \
|
||||
break; \
|
||||
default: \
|
||||
__cmpxchg_double_called_with_bad_pointer(); \
|
||||
} \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
#define cmpxchg_double(p1, p2, o1, o2, n1, n2) \
|
||||
({ \
|
||||
__typeof__(p1) __p1 = (p1); \
|
||||
__typeof__(p2) __p2 = (p2); \
|
||||
int __ret; \
|
||||
BUILD_BUG_ON(sizeof(*(p1)) != sizeof(long)); \
|
||||
BUILD_BUG_ON(sizeof(*(p2)) != sizeof(long)); \
|
||||
VM_BUG_ON((unsigned long)((__p1) + 1) != (unsigned long)(__p2));\
|
||||
if (sizeof(long) == 4) \
|
||||
__ret = __cmpxchg_double_4(__p1, __p2, o1, o2, n1, n2); \
|
||||
else \
|
||||
__ret = __cmpxchg_double_8(__p1, __p2, o1, o2, n1, n2); \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
#define system_has_cmpxchg_double() 1
|
||||
|
||||
#include <asm-generic/cmpxchg-local.h>
|
||||
|
||||
static inline unsigned long __cmpxchg_local(void *ptr,
|
||||
unsigned long old,
|
||||
unsigned long new, int size)
|
||||
{
|
||||
switch (size) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
#ifdef CONFIG_64BIT
|
||||
case 8:
|
||||
#endif
|
||||
return __cmpxchg(ptr, old, new, size);
|
||||
default:
|
||||
return __cmpxchg_local_generic(ptr, old, new, size);
|
||||
}
|
||||
|
||||
return old;
|
||||
}
|
||||
|
||||
/*
|
||||
* cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
|
||||
* them available.
|
||||
*/
|
||||
#define cmpxchg_local(ptr, o, n) \
|
||||
({ \
|
||||
__typeof__(*(ptr)) __ret; \
|
||||
__ret = (__typeof__(*(ptr))) \
|
||||
__cmpxchg_local((ptr), (unsigned long)(o), \
|
||||
(unsigned long)(n), sizeof(*(ptr))); \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
#define cmpxchg64_local(ptr, o, n) cmpxchg64((ptr), (o), (n))
|
||||
|
||||
#endif /* __ASM_CMPXCHG_H */
|
||||
359
arch/s390/include/asm/compat.h
Normal file
359
arch/s390/include/asm/compat.h
Normal file
|
|
@ -0,0 +1,359 @@
|
|||
#ifndef _ASM_S390X_COMPAT_H
|
||||
#define _ASM_S390X_COMPAT_H
|
||||
/*
|
||||
* Architecture specific compatibility types
|
||||
*/
|
||||
#include <linux/types.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/thread_info.h>
|
||||
|
||||
#define __TYPE_IS_PTR(t) (!__builtin_types_compatible_p(typeof(0?(t)0:0ULL), u64))
|
||||
|
||||
#define __SC_DELOUSE(t,v) ({ \
|
||||
BUILD_BUG_ON(sizeof(t) > 4 && !__TYPE_IS_PTR(t)); \
|
||||
(t)(__TYPE_IS_PTR(t) ? ((v) & 0x7fffffff) : (v)); \
|
||||
})
|
||||
|
||||
#define PSW32_MASK_PER 0x40000000UL
|
||||
#define PSW32_MASK_DAT 0x04000000UL
|
||||
#define PSW32_MASK_IO 0x02000000UL
|
||||
#define PSW32_MASK_EXT 0x01000000UL
|
||||
#define PSW32_MASK_KEY 0x00F00000UL
|
||||
#define PSW32_MASK_BASE 0x00080000UL /* Always one */
|
||||
#define PSW32_MASK_MCHECK 0x00040000UL
|
||||
#define PSW32_MASK_WAIT 0x00020000UL
|
||||
#define PSW32_MASK_PSTATE 0x00010000UL
|
||||
#define PSW32_MASK_ASC 0x0000C000UL
|
||||
#define PSW32_MASK_CC 0x00003000UL
|
||||
#define PSW32_MASK_PM 0x00000f00UL
|
||||
#define PSW32_MASK_RI 0x00000080UL
|
||||
|
||||
#define PSW32_MASK_USER 0x0000FF00UL
|
||||
|
||||
#define PSW32_ADDR_AMODE 0x80000000UL
|
||||
#define PSW32_ADDR_INSN 0x7FFFFFFFUL
|
||||
|
||||
#define PSW32_DEFAULT_KEY (((u32) PAGE_DEFAULT_ACC) << 20)
|
||||
|
||||
#define PSW32_ASC_PRIMARY 0x00000000UL
|
||||
#define PSW32_ASC_ACCREG 0x00004000UL
|
||||
#define PSW32_ASC_SECONDARY 0x00008000UL
|
||||
#define PSW32_ASC_HOME 0x0000C000UL
|
||||
|
||||
#define PSW32_USER_BITS (PSW32_MASK_DAT | PSW32_MASK_IO | PSW32_MASK_EXT | \
|
||||
PSW32_DEFAULT_KEY | PSW32_MASK_BASE | \
|
||||
PSW32_MASK_MCHECK | PSW32_MASK_PSTATE | \
|
||||
PSW32_ASC_PRIMARY)
|
||||
|
||||
#define COMPAT_USER_HZ 100
|
||||
#define COMPAT_UTS_MACHINE "s390\0\0\0\0"
|
||||
|
||||
typedef u32 compat_size_t;
|
||||
typedef s32 compat_ssize_t;
|
||||
typedef s32 compat_time_t;
|
||||
typedef s32 compat_clock_t;
|
||||
typedef s32 compat_pid_t;
|
||||
typedef u16 __compat_uid_t;
|
||||
typedef u16 __compat_gid_t;
|
||||
typedef u32 __compat_uid32_t;
|
||||
typedef u32 __compat_gid32_t;
|
||||
typedef u16 compat_mode_t;
|
||||
typedef u32 compat_ino_t;
|
||||
typedef u16 compat_dev_t;
|
||||
typedef s32 compat_off_t;
|
||||
typedef s64 compat_loff_t;
|
||||
typedef u16 compat_nlink_t;
|
||||
typedef u16 compat_ipc_pid_t;
|
||||
typedef s32 compat_daddr_t;
|
||||
typedef u32 compat_caddr_t;
|
||||
typedef __kernel_fsid_t compat_fsid_t;
|
||||
typedef s32 compat_key_t;
|
||||
typedef s32 compat_timer_t;
|
||||
|
||||
typedef s32 compat_int_t;
|
||||
typedef s32 compat_long_t;
|
||||
typedef s64 compat_s64;
|
||||
typedef u32 compat_uint_t;
|
||||
typedef u32 compat_ulong_t;
|
||||
typedef u64 compat_u64;
|
||||
typedef u32 compat_uptr_t;
|
||||
|
||||
typedef struct {
|
||||
u32 mask;
|
||||
u32 addr;
|
||||
} __aligned(8) psw_compat_t;
|
||||
|
||||
typedef struct {
|
||||
psw_compat_t psw;
|
||||
u32 gprs[NUM_GPRS];
|
||||
u32 acrs[NUM_ACRS];
|
||||
u32 orig_gpr2;
|
||||
} s390_compat_regs;
|
||||
|
||||
typedef struct {
|
||||
u32 gprs_high[NUM_GPRS];
|
||||
} s390_compat_regs_high;
|
||||
|
||||
struct compat_timespec {
|
||||
compat_time_t tv_sec;
|
||||
s32 tv_nsec;
|
||||
};
|
||||
|
||||
struct compat_timeval {
|
||||
compat_time_t tv_sec;
|
||||
s32 tv_usec;
|
||||
};
|
||||
|
||||
struct compat_stat {
|
||||
compat_dev_t st_dev;
|
||||
u16 __pad1;
|
||||
compat_ino_t st_ino;
|
||||
compat_mode_t st_mode;
|
||||
compat_nlink_t st_nlink;
|
||||
__compat_uid_t st_uid;
|
||||
__compat_gid_t st_gid;
|
||||
compat_dev_t st_rdev;
|
||||
u16 __pad2;
|
||||
u32 st_size;
|
||||
u32 st_blksize;
|
||||
u32 st_blocks;
|
||||
u32 st_atime;
|
||||
u32 st_atime_nsec;
|
||||
u32 st_mtime;
|
||||
u32 st_mtime_nsec;
|
||||
u32 st_ctime;
|
||||
u32 st_ctime_nsec;
|
||||
u32 __unused4;
|
||||
u32 __unused5;
|
||||
};
|
||||
|
||||
struct compat_flock {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
compat_off_t l_start;
|
||||
compat_off_t l_len;
|
||||
compat_pid_t l_pid;
|
||||
};
|
||||
|
||||
#define F_GETLK64 12
|
||||
#define F_SETLK64 13
|
||||
#define F_SETLKW64 14
|
||||
|
||||
struct compat_flock64 {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
compat_loff_t l_start;
|
||||
compat_loff_t l_len;
|
||||
compat_pid_t l_pid;
|
||||
};
|
||||
|
||||
struct compat_statfs {
|
||||
u32 f_type;
|
||||
u32 f_bsize;
|
||||
u32 f_blocks;
|
||||
u32 f_bfree;
|
||||
u32 f_bavail;
|
||||
u32 f_files;
|
||||
u32 f_ffree;
|
||||
compat_fsid_t f_fsid;
|
||||
u32 f_namelen;
|
||||
u32 f_frsize;
|
||||
u32 f_flags;
|
||||
u32 f_spare[4];
|
||||
};
|
||||
|
||||
struct compat_statfs64 {
|
||||
u32 f_type;
|
||||
u32 f_bsize;
|
||||
u64 f_blocks;
|
||||
u64 f_bfree;
|
||||
u64 f_bavail;
|
||||
u64 f_files;
|
||||
u64 f_ffree;
|
||||
compat_fsid_t f_fsid;
|
||||
u32 f_namelen;
|
||||
u32 f_frsize;
|
||||
u32 f_flags;
|
||||
u32 f_spare[4];
|
||||
};
|
||||
|
||||
#define COMPAT_RLIM_OLD_INFINITY 0x7fffffff
|
||||
#define COMPAT_RLIM_INFINITY 0xffffffff
|
||||
|
||||
typedef u32 compat_old_sigset_t; /* at least 32 bits */
|
||||
|
||||
#define _COMPAT_NSIG 64
|
||||
#define _COMPAT_NSIG_BPW 32
|
||||
|
||||
typedef u32 compat_sigset_word;
|
||||
|
||||
typedef union compat_sigval {
|
||||
compat_int_t sival_int;
|
||||
compat_uptr_t sival_ptr;
|
||||
} compat_sigval_t;
|
||||
|
||||
typedef struct compat_siginfo {
|
||||
int si_signo;
|
||||
int si_errno;
|
||||
int si_code;
|
||||
|
||||
union {
|
||||
int _pad[128/sizeof(int) - 3];
|
||||
|
||||
/* kill() */
|
||||
struct {
|
||||
pid_t _pid; /* sender's pid */
|
||||
uid_t _uid; /* sender's uid */
|
||||
} _kill;
|
||||
|
||||
/* POSIX.1b timers */
|
||||
struct {
|
||||
compat_timer_t _tid; /* timer id */
|
||||
int _overrun; /* overrun count */
|
||||
compat_sigval_t _sigval; /* same as below */
|
||||
int _sys_private; /* not to be passed to user */
|
||||
} _timer;
|
||||
|
||||
/* POSIX.1b signals */
|
||||
struct {
|
||||
pid_t _pid; /* sender's pid */
|
||||
uid_t _uid; /* sender's uid */
|
||||
compat_sigval_t _sigval;
|
||||
} _rt;
|
||||
|
||||
/* SIGCHLD */
|
||||
struct {
|
||||
pid_t _pid; /* which child */
|
||||
uid_t _uid; /* sender's uid */
|
||||
int _status;/* exit code */
|
||||
compat_clock_t _utime;
|
||||
compat_clock_t _stime;
|
||||
} _sigchld;
|
||||
|
||||
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
|
||||
struct {
|
||||
__u32 _addr; /* faulting insn/memory ref. - pointer */
|
||||
} _sigfault;
|
||||
|
||||
/* SIGPOLL */
|
||||
struct {
|
||||
int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
|
||||
int _fd;
|
||||
} _sigpoll;
|
||||
} _sifields;
|
||||
} compat_siginfo_t;
|
||||
|
||||
/*
|
||||
* How these fields are to be accessed.
|
||||
*/
|
||||
#define si_pid _sifields._kill._pid
|
||||
#define si_uid _sifields._kill._uid
|
||||
#define si_status _sifields._sigchld._status
|
||||
#define si_utime _sifields._sigchld._utime
|
||||
#define si_stime _sifields._sigchld._stime
|
||||
#define si_value _sifields._rt._sigval
|
||||
#define si_int _sifields._rt._sigval.sival_int
|
||||
#define si_ptr _sifields._rt._sigval.sival_ptr
|
||||
#define si_addr _sifields._sigfault._addr
|
||||
#define si_band _sifields._sigpoll._band
|
||||
#define si_fd _sifields._sigpoll._fd
|
||||
#define si_tid _sifields._timer._tid
|
||||
#define si_overrun _sifields._timer._overrun
|
||||
|
||||
#define COMPAT_OFF_T_MAX 0x7fffffff
|
||||
#define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL
|
||||
|
||||
/*
|
||||
* A pointer passed in from user mode. This should not
|
||||
* be used for syscall parameters, just declare them
|
||||
* as pointers because the syscall entry code will have
|
||||
* appropriately converted them already.
|
||||
*/
|
||||
|
||||
static inline void __user *compat_ptr(compat_uptr_t uptr)
|
||||
{
|
||||
return (void __user *)(unsigned long)(uptr & 0x7fffffffUL);
|
||||
}
|
||||
|
||||
static inline compat_uptr_t ptr_to_compat(void __user *uptr)
|
||||
{
|
||||
return (u32)(unsigned long)uptr;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
||||
static inline int is_compat_task(void)
|
||||
{
|
||||
return is_32bit_task();
|
||||
}
|
||||
|
||||
static inline void __user *arch_compat_alloc_user_space(long len)
|
||||
{
|
||||
unsigned long stack;
|
||||
|
||||
stack = KSTK_ESP(current);
|
||||
if (is_compat_task())
|
||||
stack &= 0x7fffffffUL;
|
||||
return (void __user *) (stack - len);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
struct compat_ipc64_perm {
|
||||
compat_key_t key;
|
||||
__compat_uid32_t uid;
|
||||
__compat_gid32_t gid;
|
||||
__compat_uid32_t cuid;
|
||||
__compat_gid32_t cgid;
|
||||
compat_mode_t mode;
|
||||
unsigned short __pad1;
|
||||
unsigned short seq;
|
||||
unsigned short __pad2;
|
||||
unsigned int __unused1;
|
||||
unsigned int __unused2;
|
||||
};
|
||||
|
||||
struct compat_semid64_ds {
|
||||
struct compat_ipc64_perm sem_perm;
|
||||
compat_time_t sem_otime;
|
||||
compat_ulong_t __pad1;
|
||||
compat_time_t sem_ctime;
|
||||
compat_ulong_t __pad2;
|
||||
compat_ulong_t sem_nsems;
|
||||
compat_ulong_t __unused1;
|
||||
compat_ulong_t __unused2;
|
||||
};
|
||||
|
||||
struct compat_msqid64_ds {
|
||||
struct compat_ipc64_perm msg_perm;
|
||||
compat_time_t msg_stime;
|
||||
compat_ulong_t __pad1;
|
||||
compat_time_t msg_rtime;
|
||||
compat_ulong_t __pad2;
|
||||
compat_time_t msg_ctime;
|
||||
compat_ulong_t __pad3;
|
||||
compat_ulong_t msg_cbytes;
|
||||
compat_ulong_t msg_qnum;
|
||||
compat_ulong_t msg_qbytes;
|
||||
compat_pid_t msg_lspid;
|
||||
compat_pid_t msg_lrpid;
|
||||
compat_ulong_t __unused1;
|
||||
compat_ulong_t __unused2;
|
||||
};
|
||||
|
||||
struct compat_shmid64_ds {
|
||||
struct compat_ipc64_perm shm_perm;
|
||||
compat_size_t shm_segsz;
|
||||
compat_time_t shm_atime;
|
||||
compat_ulong_t __pad1;
|
||||
compat_time_t shm_dtime;
|
||||
compat_ulong_t __pad2;
|
||||
compat_time_t shm_ctime;
|
||||
compat_ulong_t __pad3;
|
||||
compat_pid_t shm_cpid;
|
||||
compat_pid_t shm_lpid;
|
||||
compat_ulong_t shm_nattch;
|
||||
compat_ulong_t __unused1;
|
||||
compat_ulong_t __unused2;
|
||||
};
|
||||
#endif /* _ASM_S390X_COMPAT_H */
|
||||
32
arch/s390/include/asm/cpcmd.h
Normal file
32
arch/s390/include/asm/cpcmd.h
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* S390 version
|
||||
* Copyright IBM Corp. 1999
|
||||
* Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
|
||||
* Christian Borntraeger (cborntra@de.ibm.com),
|
||||
*/
|
||||
|
||||
#ifndef _ASM_S390_CPCMD_H
|
||||
#define _ASM_S390_CPCMD_H
|
||||
|
||||
/*
|
||||
* the lowlevel function for cpcmd
|
||||
* the caller of __cpcmd has to ensure that the response buffer is below 2 GB
|
||||
*/
|
||||
extern int __cpcmd(const char *cmd, char *response, int rlen, int *response_code);
|
||||
|
||||
/*
|
||||
* cpcmd is the in-kernel interface for issuing CP commands
|
||||
*
|
||||
* cmd: null-terminated command string, max 240 characters
|
||||
* response: response buffer for VM's textual response
|
||||
* rlen: size of the response buffer, cpcmd will not exceed this size
|
||||
* but will cap the output, if its too large. Everything that
|
||||
* did not fit into the buffer will be silently dropped
|
||||
* response_code: return pointer for VM's error code
|
||||
* return value: the size of the response. The caller can check if the buffer
|
||||
* was large enough by comparing the return value and rlen
|
||||
* NOTE: If the response buffer is not below 2 GB, cpcmd can sleep
|
||||
*/
|
||||
extern int cpcmd(const char *cmd, char *response, int rlen, int *response_code);
|
||||
|
||||
#endif /* _ASM_S390_CPCMD_H */
|
||||
26
arch/s390/include/asm/cpu.h
Normal file
26
arch/s390/include/asm/cpu.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright IBM Corp. 2000, 2009
|
||||
* Author(s): Hartmut Penner <hp@de.ibm.com>,
|
||||
* Martin Schwidefsky <schwidefsky@de.ibm.com>,
|
||||
* Christian Ehrhardt <ehrhardt@de.ibm.com>,
|
||||
*/
|
||||
|
||||
#ifndef _ASM_S390_CPU_H
|
||||
#define _ASM_S390_CPU_H
|
||||
|
||||
#define MAX_CPU_ADDRESS 255
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct cpuid
|
||||
{
|
||||
unsigned int version : 8;
|
||||
unsigned int ident : 24;
|
||||
unsigned int machine : 16;
|
||||
unsigned int unused : 16;
|
||||
} __attribute__ ((packed, aligned(8)));
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* _ASM_S390_CPU_H */
|
||||
283
arch/s390/include/asm/cpu_mf.h
Normal file
283
arch/s390/include/asm/cpu_mf.h
Normal file
|
|
@ -0,0 +1,283 @@
|
|||
/*
|
||||
* CPU-measurement facilities
|
||||
*
|
||||
* Copyright IBM Corp. 2012
|
||||
* Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
|
||||
* Jan Glauber <jang@linux.vnet.ibm.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License (version 2 only)
|
||||
* as published by the Free Software Foundation.
|
||||
*/
|
||||
#ifndef _ASM_S390_CPU_MF_H
|
||||
#define _ASM_S390_CPU_MF_H
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <asm/facility.h>
|
||||
|
||||
#define CPU_MF_INT_SF_IAE (1 << 31) /* invalid entry address */
|
||||
#define CPU_MF_INT_SF_ISE (1 << 30) /* incorrect SDBT entry */
|
||||
#define CPU_MF_INT_SF_PRA (1 << 29) /* program request alert */
|
||||
#define CPU_MF_INT_SF_SACA (1 << 23) /* sampler auth. change alert */
|
||||
#define CPU_MF_INT_SF_LSDA (1 << 22) /* loss of sample data alert */
|
||||
#define CPU_MF_INT_CF_CACA (1 << 7) /* counter auth. change alert */
|
||||
#define CPU_MF_INT_CF_LCDA (1 << 6) /* loss of counter data alert */
|
||||
#define CPU_MF_INT_RI_HALTED (1 << 5) /* run-time instr. halted */
|
||||
#define CPU_MF_INT_RI_BUF_FULL (1 << 4) /* run-time instr. program
|
||||
buffer full */
|
||||
|
||||
#define CPU_MF_INT_CF_MASK (CPU_MF_INT_CF_CACA|CPU_MF_INT_CF_LCDA)
|
||||
#define CPU_MF_INT_SF_MASK (CPU_MF_INT_SF_IAE|CPU_MF_INT_SF_ISE| \
|
||||
CPU_MF_INT_SF_PRA|CPU_MF_INT_SF_SACA| \
|
||||
CPU_MF_INT_SF_LSDA)
|
||||
#define CPU_MF_INT_RI_MASK (CPU_MF_INT_RI_HALTED|CPU_MF_INT_RI_BUF_FULL)
|
||||
|
||||
/* CPU measurement facility support */
|
||||
static inline int cpum_cf_avail(void)
|
||||
{
|
||||
return MACHINE_HAS_LPP && test_facility(67);
|
||||
}
|
||||
|
||||
static inline int cpum_sf_avail(void)
|
||||
{
|
||||
return MACHINE_HAS_LPP && test_facility(68);
|
||||
}
|
||||
|
||||
|
||||
struct cpumf_ctr_info {
|
||||
u16 cfvn;
|
||||
u16 auth_ctl;
|
||||
u16 enable_ctl;
|
||||
u16 act_ctl;
|
||||
u16 max_cpu;
|
||||
u16 csvn;
|
||||
u16 max_cg;
|
||||
u16 reserved1;
|
||||
u32 reserved2[12];
|
||||
} __packed;
|
||||
|
||||
/* QUERY SAMPLING INFORMATION block */
|
||||
struct hws_qsi_info_block { /* Bit(s) */
|
||||
unsigned int b0_13:14; /* 0-13: zeros */
|
||||
unsigned int as:1; /* 14: basic-sampling authorization */
|
||||
unsigned int ad:1; /* 15: diag-sampling authorization */
|
||||
unsigned int b16_21:6; /* 16-21: zeros */
|
||||
unsigned int es:1; /* 22: basic-sampling enable control */
|
||||
unsigned int ed:1; /* 23: diag-sampling enable control */
|
||||
unsigned int b24_29:6; /* 24-29: zeros */
|
||||
unsigned int cs:1; /* 30: basic-sampling activation control */
|
||||
unsigned int cd:1; /* 31: diag-sampling activation control */
|
||||
unsigned int bsdes:16; /* 4-5: size of basic sampling entry */
|
||||
unsigned int dsdes:16; /* 6-7: size of diagnostic sampling entry */
|
||||
unsigned long min_sampl_rate; /* 8-15: minimum sampling interval */
|
||||
unsigned long max_sampl_rate; /* 16-23: maximum sampling interval*/
|
||||
unsigned long tear; /* 24-31: TEAR contents */
|
||||
unsigned long dear; /* 32-39: DEAR contents */
|
||||
unsigned int rsvrd0; /* 40-43: reserved */
|
||||
unsigned int cpu_speed; /* 44-47: CPU speed */
|
||||
unsigned long long rsvrd1; /* 48-55: reserved */
|
||||
unsigned long long rsvrd2; /* 56-63: reserved */
|
||||
} __packed;
|
||||
|
||||
/* SET SAMPLING CONTROLS request block */
|
||||
struct hws_lsctl_request_block {
|
||||
unsigned int s:1; /* 0: maximum buffer indicator */
|
||||
unsigned int h:1; /* 1: part. level reserved for VM use*/
|
||||
unsigned long long b2_53:52;/* 2-53: zeros */
|
||||
unsigned int es:1; /* 54: basic-sampling enable control */
|
||||
unsigned int ed:1; /* 55: diag-sampling enable control */
|
||||
unsigned int b56_61:6; /* 56-61: - zeros */
|
||||
unsigned int cs:1; /* 62: basic-sampling activation control */
|
||||
unsigned int cd:1; /* 63: diag-sampling activation control */
|
||||
unsigned long interval; /* 8-15: sampling interval */
|
||||
unsigned long tear; /* 16-23: TEAR contents */
|
||||
unsigned long dear; /* 24-31: DEAR contents */
|
||||
/* 32-63: */
|
||||
unsigned long rsvrd1; /* reserved */
|
||||
unsigned long rsvrd2; /* reserved */
|
||||
unsigned long rsvrd3; /* reserved */
|
||||
unsigned long rsvrd4; /* reserved */
|
||||
} __packed;
|
||||
|
||||
struct hws_basic_entry {
|
||||
unsigned int def:16; /* 0-15 Data Entry Format */
|
||||
unsigned int R:4; /* 16-19 reserved */
|
||||
unsigned int U:4; /* 20-23 Number of unique instruct. */
|
||||
unsigned int z:2; /* zeros */
|
||||
unsigned int T:1; /* 26 PSW DAT mode */
|
||||
unsigned int W:1; /* 27 PSW wait state */
|
||||
unsigned int P:1; /* 28 PSW Problem state */
|
||||
unsigned int AS:2; /* 29-30 PSW address-space control */
|
||||
unsigned int I:1; /* 31 entry valid or invalid */
|
||||
unsigned int:16;
|
||||
unsigned int prim_asn:16; /* primary ASN */
|
||||
unsigned long long ia; /* Instruction Address */
|
||||
unsigned long long gpp; /* Guest Program Parameter */
|
||||
unsigned long long hpp; /* Host Program Parameter */
|
||||
} __packed;
|
||||
|
||||
struct hws_diag_entry {
|
||||
unsigned int def:16; /* 0-15 Data Entry Format */
|
||||
unsigned int R:14; /* 16-19 and 20-30 reserved */
|
||||
unsigned int I:1; /* 31 entry valid or invalid */
|
||||
u8 data[]; /* Machine-dependent sample data */
|
||||
} __packed;
|
||||
|
||||
struct hws_combined_entry {
|
||||
struct hws_basic_entry basic; /* Basic-sampling data entry */
|
||||
struct hws_diag_entry diag; /* Diagnostic-sampling data entry */
|
||||
} __packed;
|
||||
|
||||
struct hws_trailer_entry {
|
||||
union {
|
||||
struct {
|
||||
unsigned int f:1; /* 0 - Block Full Indicator */
|
||||
unsigned int a:1; /* 1 - Alert request control */
|
||||
unsigned int t:1; /* 2 - Timestamp format */
|
||||
unsigned long long:61; /* 3 - 63: Reserved */
|
||||
};
|
||||
unsigned long long flags; /* 0 - 63: All indicators */
|
||||
};
|
||||
unsigned long long overflow; /* 64 - sample Overflow count */
|
||||
unsigned char timestamp[16]; /* 16 - 31 timestamp */
|
||||
unsigned long long reserved1; /* 32 -Reserved */
|
||||
unsigned long long reserved2; /* */
|
||||
unsigned long long progusage1; /* 48 - reserved for programming use */
|
||||
unsigned long long progusage2; /* */
|
||||
} __packed;
|
||||
|
||||
/* Query counter information */
|
||||
static inline int qctri(struct cpumf_ctr_info *info)
|
||||
{
|
||||
int rc = -EINVAL;
|
||||
|
||||
asm volatile (
|
||||
"0: .insn s,0xb28e0000,%1\n"
|
||||
"1: lhi %0,0\n"
|
||||
"2:\n"
|
||||
EX_TABLE(1b, 2b)
|
||||
: "+d" (rc), "=Q" (*info));
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Load CPU-counter-set controls */
|
||||
static inline int lcctl(u64 ctl)
|
||||
{
|
||||
int cc;
|
||||
|
||||
asm volatile (
|
||||
" .insn s,0xb2840000,%1\n"
|
||||
" ipm %0\n"
|
||||
" srl %0,28\n"
|
||||
: "=d" (cc) : "m" (ctl) : "cc");
|
||||
return cc;
|
||||
}
|
||||
|
||||
/* Extract CPU counter */
|
||||
static inline int ecctr(u64 ctr, u64 *val)
|
||||
{
|
||||
register u64 content asm("4") = 0;
|
||||
int cc;
|
||||
|
||||
asm volatile (
|
||||
" .insn rre,0xb2e40000,%0,%2\n"
|
||||
" ipm %1\n"
|
||||
" srl %1,28\n"
|
||||
: "=d" (content), "=d" (cc) : "d" (ctr) : "cc");
|
||||
if (!cc)
|
||||
*val = content;
|
||||
return cc;
|
||||
}
|
||||
|
||||
/* Query sampling information */
|
||||
static inline int qsi(struct hws_qsi_info_block *info)
|
||||
{
|
||||
int cc;
|
||||
cc = 1;
|
||||
|
||||
asm volatile(
|
||||
"0: .insn s,0xb2860000,0(%1)\n"
|
||||
"1: lhi %0,0\n"
|
||||
"2:\n"
|
||||
EX_TABLE(0b, 2b) EX_TABLE(1b, 2b)
|
||||
: "=d" (cc), "+a" (info)
|
||||
: "m" (*info)
|
||||
: "cc", "memory");
|
||||
|
||||
return cc ? -EINVAL : 0;
|
||||
}
|
||||
|
||||
/* Load sampling controls */
|
||||
static inline int lsctl(struct hws_lsctl_request_block *req)
|
||||
{
|
||||
int cc;
|
||||
|
||||
cc = 1;
|
||||
asm volatile(
|
||||
"0: .insn s,0xb2870000,0(%1)\n"
|
||||
"1: ipm %0\n"
|
||||
" srl %0,28\n"
|
||||
"2:\n"
|
||||
EX_TABLE(0b, 2b) EX_TABLE(1b, 2b)
|
||||
: "+d" (cc), "+a" (req)
|
||||
: "m" (*req)
|
||||
: "cc", "memory");
|
||||
|
||||
return cc ? -EINVAL : 0;
|
||||
}
|
||||
|
||||
/* Sampling control helper functions */
|
||||
|
||||
#include <linux/time.h>
|
||||
|
||||
static inline unsigned long freq_to_sample_rate(struct hws_qsi_info_block *qsi,
|
||||
unsigned long freq)
|
||||
{
|
||||
return (USEC_PER_SEC / freq) * qsi->cpu_speed;
|
||||
}
|
||||
|
||||
static inline unsigned long sample_rate_to_freq(struct hws_qsi_info_block *qsi,
|
||||
unsigned long rate)
|
||||
{
|
||||
return USEC_PER_SEC * qsi->cpu_speed / rate;
|
||||
}
|
||||
|
||||
#define SDB_TE_ALERT_REQ_MASK 0x4000000000000000UL
|
||||
#define SDB_TE_BUFFER_FULL_MASK 0x8000000000000000UL
|
||||
|
||||
/* Return TOD timestamp contained in an trailer entry */
|
||||
static inline unsigned long long trailer_timestamp(struct hws_trailer_entry *te)
|
||||
{
|
||||
/* TOD in STCKE format */
|
||||
if (te->t)
|
||||
return *((unsigned long long *) &te->timestamp[1]);
|
||||
|
||||
/* TOD in STCK format */
|
||||
return *((unsigned long long *) &te->timestamp[0]);
|
||||
}
|
||||
|
||||
/* Return pointer to trailer entry of an sample data block */
|
||||
static inline unsigned long *trailer_entry_ptr(unsigned long v)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
ret = (void *) v;
|
||||
ret += PAGE_SIZE;
|
||||
ret -= sizeof(struct hws_trailer_entry);
|
||||
|
||||
return (unsigned long *) ret;
|
||||
}
|
||||
|
||||
/* Return if the entry in the sample data block table (sdbt)
|
||||
* is a link to the next sdbt */
|
||||
static inline int is_link_entry(unsigned long *s)
|
||||
{
|
||||
return *s & 0x1ul ? 1 : 0;
|
||||
}
|
||||
|
||||
/* Return pointer to the linked sdbt */
|
||||
static inline unsigned long *get_next_sdbt(unsigned long *s)
|
||||
{
|
||||
return (unsigned long *) (*s & ~0x1ul);
|
||||
}
|
||||
#endif /* _ASM_S390_CPU_MF_H */
|
||||
172
arch/s390/include/asm/cputime.h
Normal file
172
arch/s390/include/asm/cputime.h
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
* Copyright IBM Corp. 2004
|
||||
*
|
||||
* Author: Martin Schwidefsky <schwidefsky@de.ibm.com>
|
||||
*/
|
||||
|
||||
#ifndef _S390_CPUTIME_H
|
||||
#define _S390_CPUTIME_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <asm/div64.h>
|
||||
|
||||
|
||||
/* We want to use full resolution of the CPU timer: 2**-12 micro-seconds. */
|
||||
|
||||
typedef unsigned long long __nocast cputime_t;
|
||||
typedef unsigned long long __nocast cputime64_t;
|
||||
|
||||
#define cmpxchg_cputime(ptr, old, new) cmpxchg64(ptr, old, new)
|
||||
|
||||
static inline unsigned long __div(unsigned long long n, unsigned long base)
|
||||
{
|
||||
#ifndef CONFIG_64BIT
|
||||
register_pair rp;
|
||||
|
||||
rp.pair = n >> 1;
|
||||
asm ("dr %0,%1" : "+d" (rp) : "d" (base >> 1));
|
||||
return rp.subreg.odd;
|
||||
#else /* CONFIG_64BIT */
|
||||
return n / base;
|
||||
#endif /* CONFIG_64BIT */
|
||||
}
|
||||
|
||||
#define cputime_one_jiffy jiffies_to_cputime(1)
|
||||
|
||||
/*
|
||||
* Convert cputime to jiffies and back.
|
||||
*/
|
||||
static inline unsigned long cputime_to_jiffies(const cputime_t cputime)
|
||||
{
|
||||
return __div((__force unsigned long long) cputime, 4096000000ULL / HZ);
|
||||
}
|
||||
|
||||
static inline cputime_t jiffies_to_cputime(const unsigned int jif)
|
||||
{
|
||||
return (__force cputime_t)(jif * (4096000000ULL / HZ));
|
||||
}
|
||||
|
||||
static inline u64 cputime64_to_jiffies64(cputime64_t cputime)
|
||||
{
|
||||
unsigned long long jif = (__force unsigned long long) cputime;
|
||||
do_div(jif, 4096000000ULL / HZ);
|
||||
return jif;
|
||||
}
|
||||
|
||||
static inline cputime64_t jiffies64_to_cputime64(const u64 jif)
|
||||
{
|
||||
return (__force cputime64_t)(jif * (4096000000ULL / HZ));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert cputime to microseconds and back.
|
||||
*/
|
||||
static inline unsigned int cputime_to_usecs(const cputime_t cputime)
|
||||
{
|
||||
return (__force unsigned long long) cputime >> 12;
|
||||
}
|
||||
|
||||
static inline cputime_t usecs_to_cputime(const unsigned int m)
|
||||
{
|
||||
return (__force cputime_t)(m * 4096ULL);
|
||||
}
|
||||
|
||||
#define usecs_to_cputime64(m) usecs_to_cputime(m)
|
||||
|
||||
/*
|
||||
* Convert cputime to milliseconds and back.
|
||||
*/
|
||||
static inline unsigned int cputime_to_secs(const cputime_t cputime)
|
||||
{
|
||||
return __div((__force unsigned long long) cputime, 2048000000) >> 1;
|
||||
}
|
||||
|
||||
static inline cputime_t secs_to_cputime(const unsigned int s)
|
||||
{
|
||||
return (__force cputime_t)(s * 4096000000ULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert cputime to timespec and back.
|
||||
*/
|
||||
static inline cputime_t timespec_to_cputime(const struct timespec *value)
|
||||
{
|
||||
unsigned long long ret = value->tv_sec * 4096000000ULL;
|
||||
return (__force cputime_t)(ret + value->tv_nsec * 4096 / 1000);
|
||||
}
|
||||
|
||||
static inline void cputime_to_timespec(const cputime_t cputime,
|
||||
struct timespec *value)
|
||||
{
|
||||
unsigned long long __cputime = (__force unsigned long long) cputime;
|
||||
#ifndef CONFIG_64BIT
|
||||
register_pair rp;
|
||||
|
||||
rp.pair = __cputime >> 1;
|
||||
asm ("dr %0,%1" : "+d" (rp) : "d" (2048000000UL));
|
||||
value->tv_nsec = rp.subreg.even * 1000 / 4096;
|
||||
value->tv_sec = rp.subreg.odd;
|
||||
#else
|
||||
value->tv_nsec = (__cputime % 4096000000ULL) * 1000 / 4096;
|
||||
value->tv_sec = __cputime / 4096000000ULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert cputime to timeval and back.
|
||||
* Since cputime and timeval have the same resolution (microseconds)
|
||||
* this is easy.
|
||||
*/
|
||||
static inline cputime_t timeval_to_cputime(const struct timeval *value)
|
||||
{
|
||||
unsigned long long ret = value->tv_sec * 4096000000ULL;
|
||||
return (__force cputime_t)(ret + value->tv_usec * 4096ULL);
|
||||
}
|
||||
|
||||
static inline void cputime_to_timeval(const cputime_t cputime,
|
||||
struct timeval *value)
|
||||
{
|
||||
unsigned long long __cputime = (__force unsigned long long) cputime;
|
||||
#ifndef CONFIG_64BIT
|
||||
register_pair rp;
|
||||
|
||||
rp.pair = __cputime >> 1;
|
||||
asm ("dr %0,%1" : "+d" (rp) : "d" (2048000000UL));
|
||||
value->tv_usec = rp.subreg.even / 4096;
|
||||
value->tv_sec = rp.subreg.odd;
|
||||
#else
|
||||
value->tv_usec = (__cputime % 4096000000ULL) / 4096;
|
||||
value->tv_sec = __cputime / 4096000000ULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert cputime to clock and back.
|
||||
*/
|
||||
static inline clock_t cputime_to_clock_t(cputime_t cputime)
|
||||
{
|
||||
unsigned long long clock = (__force unsigned long long) cputime;
|
||||
do_div(clock, 4096000000ULL / USER_HZ);
|
||||
return clock;
|
||||
}
|
||||
|
||||
static inline cputime_t clock_t_to_cputime(unsigned long x)
|
||||
{
|
||||
return (__force cputime_t)(x * (4096000000ULL / USER_HZ));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert cputime64 to clock.
|
||||
*/
|
||||
static inline clock_t cputime64_to_clock_t(cputime64_t cputime)
|
||||
{
|
||||
unsigned long long clock = (__force unsigned long long) cputime;
|
||||
do_div(clock, 4096000000ULL / USER_HZ);
|
||||
return clock;
|
||||
}
|
||||
|
||||
cputime64_t arch_cpu_idle_time(int cpu);
|
||||
|
||||
#define arch_idle_time(cpu) arch_cpu_idle_time(cpu)
|
||||
|
||||
#endif /* _S390_CPUTIME_H */
|
||||
69
arch/s390/include/asm/crw.h
Normal file
69
arch/s390/include/asm/crw.h
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Data definitions for channel report processing
|
||||
* Copyright IBM Corp. 2000, 2009
|
||||
* Author(s): Ingo Adlung <adlung@de.ibm.com>,
|
||||
* Martin Schwidefsky <schwidefsky@de.ibm.com>,
|
||||
* Cornelia Huck <cornelia.huck@de.ibm.com>,
|
||||
* Heiko Carstens <heiko.carstens@de.ibm.com>,
|
||||
*/
|
||||
|
||||
#ifndef _ASM_S390_CRW_H
|
||||
#define _ASM_S390_CRW_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/*
|
||||
* Channel Report Word
|
||||
*/
|
||||
struct crw {
|
||||
__u32 res1 : 1; /* reserved zero */
|
||||
__u32 slct : 1; /* solicited */
|
||||
__u32 oflw : 1; /* overflow */
|
||||
__u32 chn : 1; /* chained */
|
||||
__u32 rsc : 4; /* reporting source code */
|
||||
__u32 anc : 1; /* ancillary report */
|
||||
__u32 res2 : 1; /* reserved zero */
|
||||
__u32 erc : 6; /* error-recovery code */
|
||||
__u32 rsid : 16; /* reporting-source ID */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
typedef void (*crw_handler_t)(struct crw *, struct crw *, int);
|
||||
|
||||
extern int crw_register_handler(int rsc, crw_handler_t handler);
|
||||
extern void crw_unregister_handler(int rsc);
|
||||
extern void crw_handle_channel_report(void);
|
||||
void crw_wait_for_channel_report(void);
|
||||
|
||||
#define NR_RSCS 16
|
||||
|
||||
#define CRW_RSC_MONITOR 0x2 /* monitoring facility */
|
||||
#define CRW_RSC_SCH 0x3 /* subchannel */
|
||||
#define CRW_RSC_CPATH 0x4 /* channel path */
|
||||
#define CRW_RSC_CONFIG 0x9 /* configuration-alert facility */
|
||||
#define CRW_RSC_CSS 0xB /* channel subsystem */
|
||||
|
||||
#define CRW_ERC_EVENT 0x00 /* event information pending */
|
||||
#define CRW_ERC_AVAIL 0x01 /* available */
|
||||
#define CRW_ERC_INIT 0x02 /* initialized */
|
||||
#define CRW_ERC_TERROR 0x03 /* temporary error */
|
||||
#define CRW_ERC_IPARM 0x04 /* installed parm initialized */
|
||||
#define CRW_ERC_TERM 0x05 /* terminal */
|
||||
#define CRW_ERC_PERRN 0x06 /* perm. error, fac. not init */
|
||||
#define CRW_ERC_PERRI 0x07 /* perm. error, facility init */
|
||||
#define CRW_ERC_PMOD 0x08 /* installed parameters modified */
|
||||
|
||||
static inline int stcrw(struct crw *pcrw)
|
||||
{
|
||||
int ccode;
|
||||
|
||||
asm volatile(
|
||||
" stcrw 0(%2)\n"
|
||||
" ipm %0\n"
|
||||
" srl %0,28\n"
|
||||
: "=d" (ccode), "=m" (*pcrw)
|
||||
: "a" (pcrw)
|
||||
: "cc" );
|
||||
return ccode;
|
||||
}
|
||||
|
||||
#endif /* _ASM_S390_CRW_H */
|
||||
38
arch/s390/include/asm/css_chars.h
Normal file
38
arch/s390/include/asm/css_chars.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#ifndef _ASM_CSS_CHARS_H
|
||||
#define _ASM_CSS_CHARS_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct css_general_char {
|
||||
u64 : 12;
|
||||
u32 dynio : 1; /* bit 12 */
|
||||
u32 : 4;
|
||||
u32 eadm : 1; /* bit 17 */
|
||||
u32 : 23;
|
||||
u32 aif : 1; /* bit 41 */
|
||||
u32 : 3;
|
||||
u32 mcss : 1; /* bit 45 */
|
||||
u32 fcs : 1; /* bit 46 */
|
||||
u32 : 1;
|
||||
u32 ext_mb : 1; /* bit 48 */
|
||||
u32 : 7;
|
||||
u32 aif_tdd : 1; /* bit 56 */
|
||||
u32 : 1;
|
||||
u32 qebsm : 1; /* bit 58 */
|
||||
u32 : 8;
|
||||
u32 aif_osa : 1; /* bit 67 */
|
||||
u32 : 12;
|
||||
u32 eadm_rf : 1; /* bit 80 */
|
||||
u32 : 1;
|
||||
u32 cib : 1; /* bit 82 */
|
||||
u32 : 5;
|
||||
u32 fcx : 1; /* bit 88 */
|
||||
u32 : 19;
|
||||
u32 alt_ssi : 1; /* bit 108 */
|
||||
u32:1;
|
||||
u32 narf:1; /* bit 110 */
|
||||
} __packed;
|
||||
|
||||
extern struct css_general_char css_general_characteristics;
|
||||
|
||||
#endif
|
||||
82
arch/s390/include/asm/ctl_reg.h
Normal file
82
arch/s390/include/asm/ctl_reg.h
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright IBM Corp. 1999, 2009
|
||||
*
|
||||
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
|
||||
*/
|
||||
|
||||
#ifndef __ASM_CTL_REG_H
|
||||
#define __ASM_CTL_REG_H
|
||||
|
||||
#include <linux/bug.h>
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
# define __CTL_LOAD "lctlg"
|
||||
# define __CTL_STORE "stctg"
|
||||
#else
|
||||
# define __CTL_LOAD "lctl"
|
||||
# define __CTL_STORE "stctl"
|
||||
#endif
|
||||
|
||||
#define __ctl_load(array, low, high) { \
|
||||
typedef struct { char _[sizeof(array)]; } addrtype; \
|
||||
\
|
||||
BUILD_BUG_ON(sizeof(addrtype) != (high - low + 1) * sizeof(long));\
|
||||
asm volatile( \
|
||||
__CTL_LOAD " %1,%2,%0\n" \
|
||||
: : "Q" (*(addrtype *)(&array)), "i" (low), "i" (high));\
|
||||
}
|
||||
|
||||
#define __ctl_store(array, low, high) { \
|
||||
typedef struct { char _[sizeof(array)]; } addrtype; \
|
||||
\
|
||||
BUILD_BUG_ON(sizeof(addrtype) != (high - low + 1) * sizeof(long));\
|
||||
asm volatile( \
|
||||
__CTL_STORE " %1,%2,%0\n" \
|
||||
: "=Q" (*(addrtype *)(&array)) \
|
||||
: "i" (low), "i" (high)); \
|
||||
}
|
||||
|
||||
static inline void __ctl_set_bit(unsigned int cr, unsigned int bit)
|
||||
{
|
||||
unsigned long reg;
|
||||
|
||||
__ctl_store(reg, cr, cr);
|
||||
reg |= 1UL << bit;
|
||||
__ctl_load(reg, cr, cr);
|
||||
}
|
||||
|
||||
static inline void __ctl_clear_bit(unsigned int cr, unsigned int bit)
|
||||
{
|
||||
unsigned long reg;
|
||||
|
||||
__ctl_store(reg, cr, cr);
|
||||
reg &= ~(1UL << bit);
|
||||
__ctl_load(reg, cr, cr);
|
||||
}
|
||||
|
||||
void smp_ctl_set_bit(int cr, int bit);
|
||||
void smp_ctl_clear_bit(int cr, int bit);
|
||||
|
||||
union ctlreg0 {
|
||||
unsigned long val;
|
||||
struct {
|
||||
#ifdef CONFIG_64BIT
|
||||
unsigned long : 32;
|
||||
#endif
|
||||
unsigned long : 3;
|
||||
unsigned long lap : 1; /* Low-address-protection control */
|
||||
unsigned long : 4;
|
||||
unsigned long edat : 1; /* Enhanced-DAT-enablement control */
|
||||
unsigned long : 23;
|
||||
};
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
# define ctl_set_bit(cr, bit) smp_ctl_set_bit(cr, bit)
|
||||
# define ctl_clear_bit(cr, bit) smp_ctl_clear_bit(cr, bit)
|
||||
#else
|
||||
# define ctl_set_bit(cr, bit) __ctl_set_bit(cr, bit)
|
||||
# define ctl_clear_bit(cr, bit) __ctl_clear_bit(cr, bit)
|
||||
#endif
|
||||
|
||||
#endif /* __ASM_CTL_REG_H */
|
||||
18
arch/s390/include/asm/current.h
Normal file
18
arch/s390/include/asm/current.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* S390 version
|
||||
* Copyright IBM Corp. 1999
|
||||
* Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
|
||||
*
|
||||
* Derived from "include/asm-i386/current.h"
|
||||
*/
|
||||
|
||||
#ifndef _S390_CURRENT_H
|
||||
#define _S390_CURRENT_H
|
||||
|
||||
#include <asm/lowcore.h>
|
||||
|
||||
struct task_struct;
|
||||
|
||||
#define current ((struct task_struct *const)S390_lowcore.current_task)
|
||||
|
||||
#endif /* !(_S390_CURRENT_H) */
|
||||
237
arch/s390/include/asm/debug.h
Normal file
237
arch/s390/include/asm/debug.h
Normal file
|
|
@ -0,0 +1,237 @@
|
|||
/*
|
||||
* S/390 debug facility
|
||||
*
|
||||
* Copyright IBM Corp. 1999, 2000
|
||||
*/
|
||||
#ifndef DEBUG_H
|
||||
#define DEBUG_H
|
||||
|
||||
#include <linux/string.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/time.h>
|
||||
#include <uapi/asm/debug.h>
|
||||
|
||||
#define DEBUG_MAX_LEVEL 6 /* debug levels range from 0 to 6 */
|
||||
#define DEBUG_OFF_LEVEL -1 /* level where debug is switched off */
|
||||
#define DEBUG_FLUSH_ALL -1 /* parameter to flush all areas */
|
||||
#define DEBUG_MAX_VIEWS 10 /* max number of views in proc fs */
|
||||
#define DEBUG_MAX_NAME_LEN 64 /* max length for a debugfs file name */
|
||||
#define DEBUG_DEFAULT_LEVEL 3 /* initial debug level */
|
||||
|
||||
#define DEBUG_DIR_ROOT "s390dbf" /* name of debug root directory in proc fs */
|
||||
|
||||
#define DEBUG_DATA(entry) (char*)(entry + 1) /* data is stored behind */
|
||||
/* the entry information */
|
||||
|
||||
typedef struct __debug_entry debug_entry_t;
|
||||
|
||||
struct debug_view;
|
||||
|
||||
typedef struct debug_info {
|
||||
struct debug_info* next;
|
||||
struct debug_info* prev;
|
||||
atomic_t ref_count;
|
||||
spinlock_t lock;
|
||||
int level;
|
||||
int nr_areas;
|
||||
int pages_per_area;
|
||||
int buf_size;
|
||||
int entry_size;
|
||||
debug_entry_t*** areas;
|
||||
int active_area;
|
||||
int *active_pages;
|
||||
int *active_entries;
|
||||
struct dentry* debugfs_root_entry;
|
||||
struct dentry* debugfs_entries[DEBUG_MAX_VIEWS];
|
||||
struct debug_view* views[DEBUG_MAX_VIEWS];
|
||||
char name[DEBUG_MAX_NAME_LEN];
|
||||
umode_t mode;
|
||||
} debug_info_t;
|
||||
|
||||
typedef int (debug_header_proc_t) (debug_info_t* id,
|
||||
struct debug_view* view,
|
||||
int area,
|
||||
debug_entry_t* entry,
|
||||
char* out_buf);
|
||||
|
||||
typedef int (debug_format_proc_t) (debug_info_t* id,
|
||||
struct debug_view* view, char* out_buf,
|
||||
const char* in_buf);
|
||||
typedef int (debug_prolog_proc_t) (debug_info_t* id,
|
||||
struct debug_view* view,
|
||||
char* out_buf);
|
||||
typedef int (debug_input_proc_t) (debug_info_t* id,
|
||||
struct debug_view* view,
|
||||
struct file* file,
|
||||
const char __user *user_buf,
|
||||
size_t in_buf_size, loff_t* offset);
|
||||
|
||||
int debug_dflt_header_fn(debug_info_t* id, struct debug_view* view,
|
||||
int area, debug_entry_t* entry, char* out_buf);
|
||||
|
||||
struct debug_view {
|
||||
char name[DEBUG_MAX_NAME_LEN];
|
||||
debug_prolog_proc_t* prolog_proc;
|
||||
debug_header_proc_t* header_proc;
|
||||
debug_format_proc_t* format_proc;
|
||||
debug_input_proc_t* input_proc;
|
||||
void* private_data;
|
||||
};
|
||||
|
||||
extern struct debug_view debug_hex_ascii_view;
|
||||
extern struct debug_view debug_raw_view;
|
||||
extern struct debug_view debug_sprintf_view;
|
||||
|
||||
/* do NOT use the _common functions */
|
||||
|
||||
debug_entry_t* debug_event_common(debug_info_t* id, int level,
|
||||
const void* data, int length);
|
||||
|
||||
debug_entry_t* debug_exception_common(debug_info_t* id, int level,
|
||||
const void* data, int length);
|
||||
|
||||
/* Debug Feature API: */
|
||||
|
||||
debug_info_t *debug_register(const char *name, int pages, int nr_areas,
|
||||
int buf_size);
|
||||
|
||||
debug_info_t *debug_register_mode(const char *name, int pages, int nr_areas,
|
||||
int buf_size, umode_t mode, uid_t uid,
|
||||
gid_t gid);
|
||||
|
||||
void debug_unregister(debug_info_t* id);
|
||||
|
||||
void debug_set_level(debug_info_t* id, int new_level);
|
||||
|
||||
void debug_set_critical(void);
|
||||
void debug_stop_all(void);
|
||||
|
||||
static inline bool debug_level_enabled(debug_info_t* id, int level)
|
||||
{
|
||||
return level <= id->level;
|
||||
}
|
||||
|
||||
static inline debug_entry_t*
|
||||
debug_event(debug_info_t* id, int level, void* data, int length)
|
||||
{
|
||||
if ((!id) || (level > id->level) || (id->pages_per_area == 0))
|
||||
return NULL;
|
||||
return debug_event_common(id,level,data,length);
|
||||
}
|
||||
|
||||
static inline debug_entry_t*
|
||||
debug_int_event(debug_info_t* id, int level, unsigned int tag)
|
||||
{
|
||||
unsigned int t=tag;
|
||||
if ((!id) || (level > id->level) || (id->pages_per_area == 0))
|
||||
return NULL;
|
||||
return debug_event_common(id,level,&t,sizeof(unsigned int));
|
||||
}
|
||||
|
||||
static inline debug_entry_t *
|
||||
debug_long_event (debug_info_t* id, int level, unsigned long tag)
|
||||
{
|
||||
unsigned long t=tag;
|
||||
if ((!id) || (level > id->level) || (id->pages_per_area == 0))
|
||||
return NULL;
|
||||
return debug_event_common(id,level,&t,sizeof(unsigned long));
|
||||
}
|
||||
|
||||
static inline debug_entry_t*
|
||||
debug_text_event(debug_info_t* id, int level, const char* txt)
|
||||
{
|
||||
if ((!id) || (level > id->level) || (id->pages_per_area == 0))
|
||||
return NULL;
|
||||
return debug_event_common(id,level,txt,strlen(txt));
|
||||
}
|
||||
|
||||
/*
|
||||
* IMPORTANT: Use "%s" in sprintf format strings with care! Only pointers are
|
||||
* stored in the s390dbf. See Documentation/s390/s390dbf.txt for more details!
|
||||
*/
|
||||
extern debug_entry_t *
|
||||
debug_sprintf_event(debug_info_t* id,int level,char *string,...)
|
||||
__attribute__ ((format(printf, 3, 4)));
|
||||
|
||||
|
||||
static inline debug_entry_t*
|
||||
debug_exception(debug_info_t* id, int level, void* data, int length)
|
||||
{
|
||||
if ((!id) || (level > id->level) || (id->pages_per_area == 0))
|
||||
return NULL;
|
||||
return debug_exception_common(id,level,data,length);
|
||||
}
|
||||
|
||||
static inline debug_entry_t*
|
||||
debug_int_exception(debug_info_t* id, int level, unsigned int tag)
|
||||
{
|
||||
unsigned int t=tag;
|
||||
if ((!id) || (level > id->level) || (id->pages_per_area == 0))
|
||||
return NULL;
|
||||
return debug_exception_common(id,level,&t,sizeof(unsigned int));
|
||||
}
|
||||
|
||||
static inline debug_entry_t *
|
||||
debug_long_exception (debug_info_t* id, int level, unsigned long tag)
|
||||
{
|
||||
unsigned long t=tag;
|
||||
if ((!id) || (level > id->level) || (id->pages_per_area == 0))
|
||||
return NULL;
|
||||
return debug_exception_common(id,level,&t,sizeof(unsigned long));
|
||||
}
|
||||
|
||||
static inline debug_entry_t*
|
||||
debug_text_exception(debug_info_t* id, int level, const char* txt)
|
||||
{
|
||||
if ((!id) || (level > id->level) || (id->pages_per_area == 0))
|
||||
return NULL;
|
||||
return debug_exception_common(id,level,txt,strlen(txt));
|
||||
}
|
||||
|
||||
/*
|
||||
* IMPORTANT: Use "%s" in sprintf format strings with care! Only pointers are
|
||||
* stored in the s390dbf. See Documentation/s390/s390dbf.txt for more details!
|
||||
*/
|
||||
extern debug_entry_t *
|
||||
debug_sprintf_exception(debug_info_t* id,int level,char *string,...)
|
||||
__attribute__ ((format(printf, 3, 4)));
|
||||
|
||||
int debug_register_view(debug_info_t* id, struct debug_view* view);
|
||||
int debug_unregister_view(debug_info_t* id, struct debug_view* view);
|
||||
|
||||
/*
|
||||
define the debug levels:
|
||||
- 0 No debugging output to console or syslog
|
||||
- 1 Log internal errors to syslog, ignore check conditions
|
||||
- 2 Log internal errors and check conditions to syslog
|
||||
- 3 Log internal errors to console, log check conditions to syslog
|
||||
- 4 Log internal errors and check conditions to console
|
||||
- 5 panic on internal errors, log check conditions to console
|
||||
- 6 panic on both, internal errors and check conditions
|
||||
*/
|
||||
|
||||
#ifndef DEBUG_LEVEL
|
||||
#define DEBUG_LEVEL 4
|
||||
#endif
|
||||
|
||||
#define INTERNAL_ERRMSG(x,y...) "E" __FILE__ "%d: " x, __LINE__, y
|
||||
#define INTERNAL_WRNMSG(x,y...) "W" __FILE__ "%d: " x, __LINE__, y
|
||||
#define INTERNAL_INFMSG(x,y...) "I" __FILE__ "%d: " x, __LINE__, y
|
||||
#define INTERNAL_DEBMSG(x,y...) "D" __FILE__ "%d: " x, __LINE__, y
|
||||
|
||||
#if DEBUG_LEVEL > 0
|
||||
#define PRINT_DEBUG(x...) printk ( KERN_DEBUG PRINTK_HEADER x )
|
||||
#define PRINT_INFO(x...) printk ( KERN_INFO PRINTK_HEADER x )
|
||||
#define PRINT_WARN(x...) printk ( KERN_WARNING PRINTK_HEADER x )
|
||||
#define PRINT_ERR(x...) printk ( KERN_ERR PRINTK_HEADER x )
|
||||
#define PRINT_FATAL(x...) panic ( PRINTK_HEADER x )
|
||||
#else
|
||||
#define PRINT_DEBUG(x...) printk ( KERN_DEBUG PRINTK_HEADER x )
|
||||
#define PRINT_INFO(x...) printk ( KERN_DEBUG PRINTK_HEADER x )
|
||||
#define PRINT_WARN(x...) printk ( KERN_DEBUG PRINTK_HEADER x )
|
||||
#define PRINT_ERR(x...) printk ( KERN_DEBUG PRINTK_HEADER x )
|
||||
#define PRINT_FATAL(x...) printk ( KERN_DEBUG PRINTK_HEADER x )
|
||||
#endif /* DASD_DEBUG */
|
||||
|
||||
#endif /* DEBUG_H */
|
||||
24
arch/s390/include/asm/delay.h
Normal file
24
arch/s390/include/asm/delay.h
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* S390 version
|
||||
* Copyright IBM Corp. 1999
|
||||
* Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
|
||||
*
|
||||
* Derived from "include/asm-i386/delay.h"
|
||||
* Copyright (C) 1993 Linus Torvalds
|
||||
*
|
||||
* Delay routines calling functions in arch/s390/lib/delay.c
|
||||
*/
|
||||
|
||||
#ifndef _S390_DELAY_H
|
||||
#define _S390_DELAY_H
|
||||
|
||||
void __ndelay(unsigned long long nsecs);
|
||||
void __udelay(unsigned long long usecs);
|
||||
void udelay_simple(unsigned long long usecs);
|
||||
void __delay(unsigned long loops);
|
||||
|
||||
#define ndelay(n) __ndelay((unsigned long long) (n))
|
||||
#define udelay(n) __udelay((unsigned long long) (n))
|
||||
#define mdelay(n) __udelay((unsigned long long) (n) * 1000)
|
||||
|
||||
#endif /* defined(_S390_DELAY_H) */
|
||||
7
arch/s390/include/asm/device.h
Normal file
7
arch/s390/include/asm/device.h
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
/*
|
||||
* Arch specific extensions to struct device
|
||||
*
|
||||
* This file is released under the GPLv2
|
||||
*/
|
||||
#include <asm-generic/device.h>
|
||||
|
||||
52
arch/s390/include/asm/diag.h
Normal file
52
arch/s390/include/asm/diag.h
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* s390 diagnose functions
|
||||
*
|
||||
* Copyright IBM Corp. 2007
|
||||
* Author(s): Michael Holzheu <holzheu@de.ibm.com>
|
||||
*/
|
||||
|
||||
#ifndef _ASM_S390_DIAG_H
|
||||
#define _ASM_S390_DIAG_H
|
||||
|
||||
/*
|
||||
* Diagnose 10: Release page range
|
||||
*/
|
||||
static inline void diag10_range(unsigned long start_pfn, unsigned long num_pfn)
|
||||
{
|
||||
unsigned long start_addr, end_addr;
|
||||
|
||||
start_addr = start_pfn << PAGE_SHIFT;
|
||||
end_addr = (start_pfn + num_pfn - 1) << PAGE_SHIFT;
|
||||
|
||||
asm volatile(
|
||||
"0: diag %0,%1,0x10\n"
|
||||
"1:\n"
|
||||
EX_TABLE(0b, 1b)
|
||||
EX_TABLE(1b, 1b)
|
||||
: : "a" (start_addr), "a" (end_addr));
|
||||
}
|
||||
|
||||
/*
|
||||
* Diagnose 14: Input spool file manipulation
|
||||
*/
|
||||
extern int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode);
|
||||
|
||||
/*
|
||||
* Diagnose 210: Get information about a virtual device
|
||||
*/
|
||||
struct diag210 {
|
||||
u16 vrdcdvno; /* device number (input) */
|
||||
u16 vrdclen; /* data block length (input) */
|
||||
u8 vrdcvcla; /* virtual device class (output) */
|
||||
u8 vrdcvtyp; /* virtual device type (output) */
|
||||
u8 vrdcvsta; /* virtual device status (output) */
|
||||
u8 vrdcvfla; /* virtual device flags (output) */
|
||||
u8 vrdcrccl; /* real device class (output) */
|
||||
u8 vrdccrty; /* real device type (output) */
|
||||
u8 vrdccrmd; /* real device model (output) */
|
||||
u8 vrdccrft; /* real device feature (output) */
|
||||
} __attribute__((packed, aligned(4)));
|
||||
|
||||
extern int diag210(struct diag210 *addr);
|
||||
|
||||
#endif /* _ASM_S390_DIAG_H */
|
||||
53
arch/s390/include/asm/dis.h
Normal file
53
arch/s390/include/asm/dis.h
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Disassemble s390 instructions.
|
||||
*
|
||||
* Copyright IBM Corp. 2007
|
||||
* Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
|
||||
*/
|
||||
|
||||
#ifndef __ASM_S390_DIS_H__
|
||||
#define __ASM_S390_DIS_H__
|
||||
|
||||
/* Type of operand */
|
||||
#define OPERAND_GPR 0x1 /* Operand printed as %rx */
|
||||
#define OPERAND_FPR 0x2 /* Operand printed as %fx */
|
||||
#define OPERAND_AR 0x4 /* Operand printed as %ax */
|
||||
#define OPERAND_CR 0x8 /* Operand printed as %cx */
|
||||
#define OPERAND_VR 0x10 /* Operand printed as %vx */
|
||||
#define OPERAND_DISP 0x20 /* Operand printed as displacement */
|
||||
#define OPERAND_BASE 0x40 /* Operand printed as base register */
|
||||
#define OPERAND_INDEX 0x80 /* Operand printed as index register */
|
||||
#define OPERAND_PCREL 0x100 /* Operand printed as pc-relative symbol */
|
||||
#define OPERAND_SIGNED 0x200 /* Operand printed as signed value */
|
||||
#define OPERAND_LENGTH 0x400 /* Operand printed as length (+1) */
|
||||
|
||||
|
||||
struct s390_operand {
|
||||
int bits; /* The number of bits in the operand. */
|
||||
int shift; /* The number of bits to shift. */
|
||||
int flags; /* One bit syntax flags. */
|
||||
};
|
||||
|
||||
struct s390_insn {
|
||||
const char name[5];
|
||||
unsigned char opfrag;
|
||||
unsigned char format;
|
||||
};
|
||||
|
||||
|
||||
static inline int insn_length(unsigned char code)
|
||||
{
|
||||
return ((((int) code + 64) >> 7) + 1) << 1;
|
||||
}
|
||||
|
||||
void show_code(struct pt_regs *regs);
|
||||
void print_fn_code(unsigned char *code, unsigned long len);
|
||||
int insn_to_mnemonic(unsigned char *instruction, char *buf, unsigned int len);
|
||||
struct s390_insn *find_insn(unsigned char *code);
|
||||
|
||||
static inline int is_known_insn(unsigned char *code)
|
||||
{
|
||||
return !!find_insn(code);
|
||||
}
|
||||
|
||||
#endif /* __ASM_S390_DIS_H__ */
|
||||
1
arch/s390/include/asm/div64.h
Normal file
1
arch/s390/include/asm/div64.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
#include <asm-generic/div64.h>
|
||||
90
arch/s390/include/asm/dma-mapping.h
Normal file
90
arch/s390/include/asm/dma-mapping.h
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
#ifndef _ASM_S390_DMA_MAPPING_H
|
||||
#define _ASM_S390_DMA_MAPPING_H
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/dma-attrs.h>
|
||||
#include <linux/dma-debug.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#define DMA_ERROR_CODE (~(dma_addr_t) 0x0)
|
||||
|
||||
extern struct dma_map_ops s390_dma_ops;
|
||||
|
||||
static inline struct dma_map_ops *get_dma_ops(struct device *dev)
|
||||
{
|
||||
return &s390_dma_ops;
|
||||
}
|
||||
|
||||
extern int dma_set_mask(struct device *dev, u64 mask);
|
||||
|
||||
static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
}
|
||||
|
||||
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
|
||||
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
|
||||
|
||||
#include <asm-generic/dma-mapping-common.h>
|
||||
|
||||
static inline int dma_supported(struct device *dev, u64 mask)
|
||||
{
|
||||
struct dma_map_ops *dma_ops = get_dma_ops(dev);
|
||||
|
||||
if (dma_ops->dma_supported == NULL)
|
||||
return 1;
|
||||
return dma_ops->dma_supported(dev, mask);
|
||||
}
|
||||
|
||||
static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
|
||||
{
|
||||
if (!dev->dma_mask)
|
||||
return 0;
|
||||
return addr + size - 1 <= *dev->dma_mask;
|
||||
}
|
||||
|
||||
static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
|
||||
{
|
||||
struct dma_map_ops *dma_ops = get_dma_ops(dev);
|
||||
|
||||
debug_dma_mapping_error(dev, dma_addr);
|
||||
if (dma_ops->mapping_error)
|
||||
return dma_ops->mapping_error(dev, dma_addr);
|
||||
return dma_addr == DMA_ERROR_CODE;
|
||||
}
|
||||
|
||||
#define dma_alloc_coherent(d, s, h, f) dma_alloc_attrs(d, s, h, f, NULL)
|
||||
|
||||
static inline void *dma_alloc_attrs(struct device *dev, size_t size,
|
||||
dma_addr_t *dma_handle, gfp_t flags,
|
||||
struct dma_attrs *attrs)
|
||||
{
|
||||
struct dma_map_ops *ops = get_dma_ops(dev);
|
||||
void *cpu_addr;
|
||||
|
||||
BUG_ON(!ops);
|
||||
|
||||
cpu_addr = ops->alloc(dev, size, dma_handle, flags, attrs);
|
||||
debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr);
|
||||
|
||||
return cpu_addr;
|
||||
}
|
||||
|
||||
#define dma_free_coherent(d, s, c, h) dma_free_attrs(d, s, c, h, NULL)
|
||||
|
||||
static inline void dma_free_attrs(struct device *dev, size_t size,
|
||||
void *cpu_addr, dma_addr_t dma_handle,
|
||||
struct dma_attrs *attrs)
|
||||
{
|
||||
struct dma_map_ops *ops = get_dma_ops(dev);
|
||||
|
||||
BUG_ON(!ops);
|
||||
|
||||
debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
|
||||
ops->free(dev, size, cpu_addr, dma_handle, attrs);
|
||||
}
|
||||
|
||||
#endif /* _ASM_S390_DMA_MAPPING_H */
|
||||
19
arch/s390/include/asm/dma.h
Normal file
19
arch/s390/include/asm/dma.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef _ASM_S390_DMA_H
|
||||
#define _ASM_S390_DMA_H
|
||||
|
||||
#include <asm/io.h>
|
||||
|
||||
/*
|
||||
* MAX_DMA_ADDRESS is ambiguous because on s390 its completely unrelated
|
||||
* to DMA. It _is_ used for the s390 memory zone split at 2GB caused
|
||||
* by the 31 bit heritage.
|
||||
*/
|
||||
#define MAX_DMA_ADDRESS 0x80000000
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
extern int isa_dma_bridge_buggy;
|
||||
#else
|
||||
#define isa_dma_bridge_buggy (0)
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_S390_DMA_H */
|
||||
117
arch/s390/include/asm/eadm.h
Normal file
117
arch/s390/include/asm/eadm.h
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
#ifndef _ASM_S390_EADM_H
|
||||
#define _ASM_S390_EADM_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/device.h>
|
||||
|
||||
struct arqb {
|
||||
u64 data;
|
||||
u16 fmt:4;
|
||||
u16:12;
|
||||
u16 cmd_code;
|
||||
u16:16;
|
||||
u16 msb_count;
|
||||
u32 reserved[12];
|
||||
} __packed;
|
||||
|
||||
#define ARQB_CMD_MOVE 1
|
||||
|
||||
struct arsb {
|
||||
u16 fmt:4;
|
||||
u32:28;
|
||||
u8 ef;
|
||||
u8:8;
|
||||
u8 ecbi;
|
||||
u8:8;
|
||||
u8 fvf;
|
||||
u16:16;
|
||||
u8 eqc;
|
||||
u32:32;
|
||||
u64 fail_msb;
|
||||
u64 fail_aidaw;
|
||||
u64 fail_ms;
|
||||
u64 fail_scm;
|
||||
u32 reserved[4];
|
||||
} __packed;
|
||||
|
||||
#define EQC_WR_PROHIBIT 22
|
||||
|
||||
struct msb {
|
||||
u8 fmt:4;
|
||||
u8 oc:4;
|
||||
u8 flags;
|
||||
u16:12;
|
||||
u16 bs:4;
|
||||
u32 blk_count;
|
||||
u64 data_addr;
|
||||
u64 scm_addr;
|
||||
u64:64;
|
||||
} __packed;
|
||||
|
||||
struct aidaw {
|
||||
u8 flags;
|
||||
u32 :24;
|
||||
u32 :32;
|
||||
u64 data_addr;
|
||||
} __packed;
|
||||
|
||||
#define MSB_OC_CLEAR 0
|
||||
#define MSB_OC_READ 1
|
||||
#define MSB_OC_WRITE 2
|
||||
#define MSB_OC_RELEASE 3
|
||||
|
||||
#define MSB_FLAG_BNM 0x80
|
||||
#define MSB_FLAG_IDA 0x40
|
||||
|
||||
#define MSB_BS_4K 0
|
||||
#define MSB_BS_1M 1
|
||||
|
||||
#define AOB_NR_MSB 124
|
||||
|
||||
struct aob {
|
||||
struct arqb request;
|
||||
struct arsb response;
|
||||
struct msb msb[AOB_NR_MSB];
|
||||
} __packed __aligned(PAGE_SIZE);
|
||||
|
||||
struct aob_rq_header {
|
||||
struct scm_device *scmdev;
|
||||
char data[0];
|
||||
};
|
||||
|
||||
struct scm_device {
|
||||
u64 address;
|
||||
u64 size;
|
||||
unsigned int nr_max_block;
|
||||
struct device dev;
|
||||
struct {
|
||||
unsigned int persistence:4;
|
||||
unsigned int oper_state:4;
|
||||
unsigned int data_state:4;
|
||||
unsigned int rank:4;
|
||||
unsigned int release:1;
|
||||
unsigned int res_id:8;
|
||||
} __packed attrs;
|
||||
};
|
||||
|
||||
#define OP_STATE_GOOD 1
|
||||
#define OP_STATE_TEMP_ERR 2
|
||||
#define OP_STATE_PERM_ERR 3
|
||||
|
||||
enum scm_event {SCM_CHANGE, SCM_AVAIL};
|
||||
|
||||
struct scm_driver {
|
||||
struct device_driver drv;
|
||||
int (*probe) (struct scm_device *scmdev);
|
||||
int (*remove) (struct scm_device *scmdev);
|
||||
void (*notify) (struct scm_device *scmdev, enum scm_event event);
|
||||
void (*handler) (struct scm_device *scmdev, void *data, int error);
|
||||
};
|
||||
|
||||
int scm_driver_register(struct scm_driver *scmdrv);
|
||||
void scm_driver_unregister(struct scm_driver *scmdrv);
|
||||
|
||||
int eadm_start_aob(struct aob *aob);
|
||||
void scm_irq_handler(struct aob *aob, int error);
|
||||
|
||||
#endif /* _ASM_S390_EADM_H */
|
||||
48
arch/s390/include/asm/ebcdic.h
Normal file
48
arch/s390/include/asm/ebcdic.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* EBCDIC -> ASCII, ASCII -> EBCDIC conversion routines.
|
||||
*
|
||||
* S390 version
|
||||
* Copyright IBM Corp. 1999
|
||||
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
|
||||
*/
|
||||
|
||||
#ifndef _EBCDIC_H
|
||||
#define _EBCDIC_H
|
||||
|
||||
#ifndef _S390_TYPES_H
|
||||
#include <types.h>
|
||||
#endif
|
||||
|
||||
extern __u8 _ascebc_500[256]; /* ASCII -> EBCDIC 500 conversion table */
|
||||
extern __u8 _ebcasc_500[256]; /* EBCDIC 500 -> ASCII conversion table */
|
||||
extern __u8 _ascebc[256]; /* ASCII -> EBCDIC conversion table */
|
||||
extern __u8 _ebcasc[256]; /* EBCDIC -> ASCII conversion table */
|
||||
extern __u8 _ebc_tolower[256]; /* EBCDIC -> lowercase */
|
||||
extern __u8 _ebc_toupper[256]; /* EBCDIC -> uppercase */
|
||||
|
||||
static inline void
|
||||
codepage_convert(const __u8 *codepage, volatile __u8 * addr, unsigned long nr)
|
||||
{
|
||||
if (nr-- <= 0)
|
||||
return;
|
||||
asm volatile(
|
||||
" bras 1,1f\n"
|
||||
" tr 0(1,%0),0(%2)\n"
|
||||
"0: tr 0(256,%0),0(%2)\n"
|
||||
" la %0,256(%0)\n"
|
||||
"1: ahi %1,-256\n"
|
||||
" jnm 0b\n"
|
||||
" ex %1,0(1)"
|
||||
: "+&a" (addr), "+&a" (nr)
|
||||
: "a" (codepage) : "cc", "memory", "1");
|
||||
}
|
||||
|
||||
#define ASCEBC(addr,nr) codepage_convert(_ascebc, addr, nr)
|
||||
#define EBCASC(addr,nr) codepage_convert(_ebcasc, addr, nr)
|
||||
#define ASCEBC_500(addr,nr) codepage_convert(_ascebc_500, addr, nr)
|
||||
#define EBCASC_500(addr,nr) codepage_convert(_ebcasc_500, addr, nr)
|
||||
#define EBC_TOLOWER(addr,nr) codepage_convert(_ebc_tolower, addr, nr)
|
||||
#define EBC_TOUPPER(addr,nr) codepage_convert(_ebc_toupper, addr, nr)
|
||||
|
||||
#endif
|
||||
|
||||
231
arch/s390/include/asm/elf.h
Normal file
231
arch/s390/include/asm/elf.h
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
/*
|
||||
* S390 version
|
||||
*
|
||||
* Derived from "include/asm-i386/elf.h"
|
||||
*/
|
||||
|
||||
#ifndef __ASMS390_ELF_H
|
||||
#define __ASMS390_ELF_H
|
||||
|
||||
/* s390 relocations defined by the ABIs */
|
||||
#define R_390_NONE 0 /* No reloc. */
|
||||
#define R_390_8 1 /* Direct 8 bit. */
|
||||
#define R_390_12 2 /* Direct 12 bit. */
|
||||
#define R_390_16 3 /* Direct 16 bit. */
|
||||
#define R_390_32 4 /* Direct 32 bit. */
|
||||
#define R_390_PC32 5 /* PC relative 32 bit. */
|
||||
#define R_390_GOT12 6 /* 12 bit GOT offset. */
|
||||
#define R_390_GOT32 7 /* 32 bit GOT offset. */
|
||||
#define R_390_PLT32 8 /* 32 bit PC relative PLT address. */
|
||||
#define R_390_COPY 9 /* Copy symbol at runtime. */
|
||||
#define R_390_GLOB_DAT 10 /* Create GOT entry. */
|
||||
#define R_390_JMP_SLOT 11 /* Create PLT entry. */
|
||||
#define R_390_RELATIVE 12 /* Adjust by program base. */
|
||||
#define R_390_GOTOFF32 13 /* 32 bit offset to GOT. */
|
||||
#define R_390_GOTPC 14 /* 32 bit PC rel. offset to GOT. */
|
||||
#define R_390_GOT16 15 /* 16 bit GOT offset. */
|
||||
#define R_390_PC16 16 /* PC relative 16 bit. */
|
||||
#define R_390_PC16DBL 17 /* PC relative 16 bit shifted by 1. */
|
||||
#define R_390_PLT16DBL 18 /* 16 bit PC rel. PLT shifted by 1. */
|
||||
#define R_390_PC32DBL 19 /* PC relative 32 bit shifted by 1. */
|
||||
#define R_390_PLT32DBL 20 /* 32 bit PC rel. PLT shifted by 1. */
|
||||
#define R_390_GOTPCDBL 21 /* 32 bit PC rel. GOT shifted by 1. */
|
||||
#define R_390_64 22 /* Direct 64 bit. */
|
||||
#define R_390_PC64 23 /* PC relative 64 bit. */
|
||||
#define R_390_GOT64 24 /* 64 bit GOT offset. */
|
||||
#define R_390_PLT64 25 /* 64 bit PC relative PLT address. */
|
||||
#define R_390_GOTENT 26 /* 32 bit PC rel. to GOT entry >> 1. */
|
||||
#define R_390_GOTOFF16 27 /* 16 bit offset to GOT. */
|
||||
#define R_390_GOTOFF64 28 /* 64 bit offset to GOT. */
|
||||
#define R_390_GOTPLT12 29 /* 12 bit offset to jump slot. */
|
||||
#define R_390_GOTPLT16 30 /* 16 bit offset to jump slot. */
|
||||
#define R_390_GOTPLT32 31 /* 32 bit offset to jump slot. */
|
||||
#define R_390_GOTPLT64 32 /* 64 bit offset to jump slot. */
|
||||
#define R_390_GOTPLTENT 33 /* 32 bit rel. offset to jump slot. */
|
||||
#define R_390_PLTOFF16 34 /* 16 bit offset from GOT to PLT. */
|
||||
#define R_390_PLTOFF32 35 /* 32 bit offset from GOT to PLT. */
|
||||
#define R_390_PLTOFF64 36 /* 16 bit offset from GOT to PLT. */
|
||||
#define R_390_TLS_LOAD 37 /* Tag for load insn in TLS code. */
|
||||
#define R_390_TLS_GDCALL 38 /* Tag for function call in general
|
||||
dynamic TLS code. */
|
||||
#define R_390_TLS_LDCALL 39 /* Tag for function call in local
|
||||
dynamic TLS code. */
|
||||
#define R_390_TLS_GD32 40 /* Direct 32 bit for general dynamic
|
||||
thread local data. */
|
||||
#define R_390_TLS_GD64 41 /* Direct 64 bit for general dynamic
|
||||
thread local data. */
|
||||
#define R_390_TLS_GOTIE12 42 /* 12 bit GOT offset for static TLS
|
||||
block offset. */
|
||||
#define R_390_TLS_GOTIE32 43 /* 32 bit GOT offset for static TLS
|
||||
block offset. */
|
||||
#define R_390_TLS_GOTIE64 44 /* 64 bit GOT offset for static TLS
|
||||
block offset. */
|
||||
#define R_390_TLS_LDM32 45 /* Direct 32 bit for local dynamic
|
||||
thread local data in LD code. */
|
||||
#define R_390_TLS_LDM64 46 /* Direct 64 bit for local dynamic
|
||||
thread local data in LD code. */
|
||||
#define R_390_TLS_IE32 47 /* 32 bit address of GOT entry for
|
||||
negated static TLS block offset. */
|
||||
#define R_390_TLS_IE64 48 /* 64 bit address of GOT entry for
|
||||
negated static TLS block offset. */
|
||||
#define R_390_TLS_IEENT 49 /* 32 bit rel. offset to GOT entry for
|
||||
negated static TLS block offset. */
|
||||
#define R_390_TLS_LE32 50 /* 32 bit negated offset relative to
|
||||
static TLS block. */
|
||||
#define R_390_TLS_LE64 51 /* 64 bit negated offset relative to
|
||||
static TLS block. */
|
||||
#define R_390_TLS_LDO32 52 /* 32 bit offset relative to TLS
|
||||
block. */
|
||||
#define R_390_TLS_LDO64 53 /* 64 bit offset relative to TLS
|
||||
block. */
|
||||
#define R_390_TLS_DTPMOD 54 /* ID of module containing symbol. */
|
||||
#define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */
|
||||
#define R_390_TLS_TPOFF 56 /* Negate offset in static TLS
|
||||
block. */
|
||||
#define R_390_20 57 /* Direct 20 bit. */
|
||||
#define R_390_GOT20 58 /* 20 bit GOT offset. */
|
||||
#define R_390_GOTPLT20 59 /* 20 bit offset to jump slot. */
|
||||
#define R_390_TLS_GOTIE20 60 /* 20 bit GOT offset for static TLS
|
||||
block offset. */
|
||||
/* Keep this the last entry. */
|
||||
#define R_390_NUM 61
|
||||
|
||||
/* Bits present in AT_HWCAP. */
|
||||
#define HWCAP_S390_ESAN3 1
|
||||
#define HWCAP_S390_ZARCH 2
|
||||
#define HWCAP_S390_STFLE 4
|
||||
#define HWCAP_S390_MSA 8
|
||||
#define HWCAP_S390_LDISP 16
|
||||
#define HWCAP_S390_EIMM 32
|
||||
#define HWCAP_S390_DFP 64
|
||||
#define HWCAP_S390_HPAGE 128
|
||||
#define HWCAP_S390_ETF3EH 256
|
||||
#define HWCAP_S390_HIGH_GPRS 512
|
||||
#define HWCAP_S390_TE 1024
|
||||
#define HWCAP_S390_VXRS 2048
|
||||
|
||||
/*
|
||||
* These are used to set parameters in the core dumps.
|
||||
*/
|
||||
#ifndef CONFIG_64BIT
|
||||
#define ELF_CLASS ELFCLASS32
|
||||
#else /* CONFIG_64BIT */
|
||||
#define ELF_CLASS ELFCLASS64
|
||||
#endif /* CONFIG_64BIT */
|
||||
#define ELF_DATA ELFDATA2MSB
|
||||
#define ELF_ARCH EM_S390
|
||||
|
||||
/*
|
||||
* ELF register definitions..
|
||||
*/
|
||||
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/compat.h>
|
||||
#include <asm/syscall.h>
|
||||
#include <asm/user.h>
|
||||
|
||||
typedef s390_fp_regs elf_fpregset_t;
|
||||
typedef s390_regs elf_gregset_t;
|
||||
|
||||
typedef s390_fp_regs compat_elf_fpregset_t;
|
||||
typedef s390_compat_regs compat_elf_gregset_t;
|
||||
|
||||
#include <linux/sched.h> /* for task_struct */
|
||||
#include <asm/mmu_context.h>
|
||||
|
||||
#include <asm/vdso.h>
|
||||
|
||||
extern unsigned int vdso_enabled;
|
||||
|
||||
/*
|
||||
* This is used to ensure we don't load something for the wrong architecture.
|
||||
*/
|
||||
#define elf_check_arch(x) \
|
||||
(((x)->e_machine == EM_S390 || (x)->e_machine == EM_S390_OLD) \
|
||||
&& (x)->e_ident[EI_CLASS] == ELF_CLASS)
|
||||
#define compat_elf_check_arch(x) \
|
||||
(((x)->e_machine == EM_S390 || (x)->e_machine == EM_S390_OLD) \
|
||||
&& (x)->e_ident[EI_CLASS] == ELF_CLASS)
|
||||
#define compat_start_thread start_thread31
|
||||
|
||||
/* For SVR4/S390 the function pointer to be registered with `atexit` is
|
||||
passed in R14. */
|
||||
#define ELF_PLAT_INIT(_r, load_addr) \
|
||||
do { \
|
||||
_r->gprs[14] = 0; \
|
||||
} while (0)
|
||||
|
||||
#define CORE_DUMP_USE_REGSET
|
||||
#define ELF_EXEC_PAGESIZE 4096
|
||||
|
||||
/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
|
||||
use of this is to invoke "./ld.so someprog" to test out a new version of
|
||||
the loader. We need to make sure that it is out of the way of the program
|
||||
that it will "exec", and that there is sufficient room for the brk. */
|
||||
|
||||
extern unsigned long randomize_et_dyn(unsigned long base);
|
||||
#define ELF_ET_DYN_BASE (randomize_et_dyn(STACK_TOP / 3 * 2))
|
||||
|
||||
/* This yields a mask that user programs can use to figure out what
|
||||
instruction set this CPU supports. */
|
||||
|
||||
extern unsigned long elf_hwcap;
|
||||
#define ELF_HWCAP (elf_hwcap)
|
||||
|
||||
/* This yields a string that ld.so will use to load implementation
|
||||
specific libraries for optimization. This is more specific in
|
||||
intent than poking at uname or /proc/cpuinfo.
|
||||
|
||||
For the moment, we have only optimizations for the Intel generations,
|
||||
but that could change... */
|
||||
|
||||
#define ELF_PLATFORM_SIZE 8
|
||||
extern char elf_platform[];
|
||||
#define ELF_PLATFORM (elf_platform)
|
||||
|
||||
#ifndef CONFIG_COMPAT
|
||||
#define SET_PERSONALITY(ex) \
|
||||
do { \
|
||||
set_personality(PER_LINUX | \
|
||||
(current->personality & (~PER_MASK))); \
|
||||
current_thread_info()->sys_call_table = \
|
||||
(unsigned long) &sys_call_table; \
|
||||
} while (0)
|
||||
#else /* CONFIG_COMPAT */
|
||||
#define SET_PERSONALITY(ex) \
|
||||
do { \
|
||||
if (personality(current->personality) != PER_LINUX32) \
|
||||
set_personality(PER_LINUX | \
|
||||
(current->personality & ~PER_MASK)); \
|
||||
if ((ex).e_ident[EI_CLASS] == ELFCLASS32) { \
|
||||
set_thread_flag(TIF_31BIT); \
|
||||
current_thread_info()->sys_call_table = \
|
||||
(unsigned long) &sys_call_table_emu; \
|
||||
} else { \
|
||||
clear_thread_flag(TIF_31BIT); \
|
||||
current_thread_info()->sys_call_table = \
|
||||
(unsigned long) &sys_call_table; \
|
||||
} \
|
||||
} while (0)
|
||||
#endif /* CONFIG_COMPAT */
|
||||
|
||||
#define STACK_RND_MASK 0x7ffUL
|
||||
|
||||
#define ARCH_DLINFO \
|
||||
do { \
|
||||
if (vdso_enabled) \
|
||||
NEW_AUX_ENT(AT_SYSINFO_EHDR, \
|
||||
(unsigned long)current->mm->context.vdso_base); \
|
||||
} while (0)
|
||||
|
||||
struct linux_binprm;
|
||||
|
||||
#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
|
||||
int arch_setup_additional_pages(struct linux_binprm *, int);
|
||||
|
||||
extern unsigned long arch_randomize_brk(struct mm_struct *mm);
|
||||
#define arch_randomize_brk arch_randomize_brk
|
||||
|
||||
void *fill_cpu_elf_notes(void *ptr, struct save_area *sa, __vector128 *vxrs);
|
||||
|
||||
#endif
|
||||
6
arch/s390/include/asm/emergency-restart.h
Normal file
6
arch/s390/include/asm/emergency-restart.h
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef _ASM_EMERGENCY_RESTART_H
|
||||
#define _ASM_EMERGENCY_RESTART_H
|
||||
|
||||
#include <asm-generic/emergency-restart.h>
|
||||
|
||||
#endif /* _ASM_EMERGENCY_RESTART_H */
|
||||
256
arch/s390/include/asm/etr.h
Normal file
256
arch/s390/include/asm/etr.h
Normal file
|
|
@ -0,0 +1,256 @@
|
|||
/*
|
||||
* Copyright IBM Corp. 2006
|
||||
* Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
|
||||
*/
|
||||
#ifndef __S390_ETR_H
|
||||
#define __S390_ETR_H
|
||||
|
||||
/* ETR attachment control register */
|
||||
struct etr_eacr {
|
||||
unsigned int e0 : 1; /* port 0 stepping control */
|
||||
unsigned int e1 : 1; /* port 1 stepping control */
|
||||
unsigned int _pad0 : 5; /* must be 00100 */
|
||||
unsigned int dp : 1; /* data port control */
|
||||
unsigned int p0 : 1; /* port 0 change recognition control */
|
||||
unsigned int p1 : 1; /* port 1 change recognition control */
|
||||
unsigned int _pad1 : 3; /* must be 000 */
|
||||
unsigned int ea : 1; /* ETR alert control */
|
||||
unsigned int es : 1; /* ETR sync check control */
|
||||
unsigned int sl : 1; /* switch to local control */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Port state returned by steai */
|
||||
enum etr_psc {
|
||||
etr_psc_operational = 0,
|
||||
etr_psc_semi_operational = 1,
|
||||
etr_psc_protocol_error = 4,
|
||||
etr_psc_no_symbols = 8,
|
||||
etr_psc_no_signal = 12,
|
||||
etr_psc_pps_mode = 13
|
||||
};
|
||||
|
||||
/* Logical port state returned by stetr */
|
||||
enum etr_lpsc {
|
||||
etr_lpsc_operational_step = 0,
|
||||
etr_lpsc_operational_alt = 1,
|
||||
etr_lpsc_semi_operational = 2,
|
||||
etr_lpsc_protocol_error = 4,
|
||||
etr_lpsc_no_symbol_sync = 8,
|
||||
etr_lpsc_no_signal = 12,
|
||||
etr_lpsc_pps_mode = 13
|
||||
};
|
||||
|
||||
/* ETR status words */
|
||||
struct etr_esw {
|
||||
struct etr_eacr eacr; /* attachment control register */
|
||||
unsigned int y : 1; /* stepping mode */
|
||||
unsigned int _pad0 : 5; /* must be 00000 */
|
||||
unsigned int p : 1; /* stepping port number */
|
||||
unsigned int q : 1; /* data port number */
|
||||
unsigned int psc0 : 4; /* port 0 state code */
|
||||
unsigned int psc1 : 4; /* port 1 state code */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Second level data register status word */
|
||||
struct etr_slsw {
|
||||
unsigned int vv1 : 1; /* copy of validity bit data frame 1 */
|
||||
unsigned int vv2 : 1; /* copy of validity bit data frame 2 */
|
||||
unsigned int vv3 : 1; /* copy of validity bit data frame 3 */
|
||||
unsigned int vv4 : 1; /* copy of validity bit data frame 4 */
|
||||
unsigned int _pad0 : 19; /* must by all zeroes */
|
||||
unsigned int n : 1; /* EAF port number */
|
||||
unsigned int v1 : 1; /* validity bit ETR data frame 1 */
|
||||
unsigned int v2 : 1; /* validity bit ETR data frame 2 */
|
||||
unsigned int v3 : 1; /* validity bit ETR data frame 3 */
|
||||
unsigned int v4 : 1; /* validity bit ETR data frame 4 */
|
||||
unsigned int _pad1 : 4; /* must be 0000 */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* ETR data frames */
|
||||
struct etr_edf1 {
|
||||
unsigned int u : 1; /* untuned bit */
|
||||
unsigned int _pad0 : 1; /* must be 0 */
|
||||
unsigned int r : 1; /* service request bit */
|
||||
unsigned int _pad1 : 4; /* must be 0000 */
|
||||
unsigned int a : 1; /* time adjustment bit */
|
||||
unsigned int net_id : 8; /* ETR network id */
|
||||
unsigned int etr_id : 8; /* id of ETR which sends data frames */
|
||||
unsigned int etr_pn : 8; /* port number of ETR output port */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct etr_edf2 {
|
||||
unsigned int etv : 32; /* Upper 32 bits of TOD. */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct etr_edf3 {
|
||||
unsigned int rc : 8; /* failure reason code */
|
||||
unsigned int _pad0 : 3; /* must be 000 */
|
||||
unsigned int c : 1; /* ETR coupled bit */
|
||||
unsigned int tc : 4; /* ETR type code */
|
||||
unsigned int blto : 8; /* biased local time offset */
|
||||
/* (blto - 128) * 15 = minutes */
|
||||
unsigned int buo : 8; /* biased utc offset */
|
||||
/* (buo - 128) = leap seconds */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct etr_edf4 {
|
||||
unsigned int ed : 8; /* ETS device dependent data */
|
||||
unsigned int _pad0 : 1; /* must be 0 */
|
||||
unsigned int buc : 5; /* biased ut1 correction */
|
||||
/* (buc - 16) * 0.1 seconds */
|
||||
unsigned int em : 6; /* ETS error magnitude */
|
||||
unsigned int dc : 6; /* ETS drift code */
|
||||
unsigned int sc : 6; /* ETS steering code */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/*
|
||||
* ETR attachment information block, two formats
|
||||
* format 1 has 4 reserved words with a size of 64 bytes
|
||||
* format 2 has 16 reserved words with a size of 96 bytes
|
||||
*/
|
||||
struct etr_aib {
|
||||
struct etr_esw esw;
|
||||
struct etr_slsw slsw;
|
||||
unsigned long long tsp;
|
||||
struct etr_edf1 edf1;
|
||||
struct etr_edf2 edf2;
|
||||
struct etr_edf3 edf3;
|
||||
struct etr_edf4 edf4;
|
||||
unsigned int reserved[16];
|
||||
} __attribute__ ((packed,aligned(8)));
|
||||
|
||||
/* ETR interruption parameter */
|
||||
struct etr_irq_parm {
|
||||
unsigned int _pad0 : 8;
|
||||
unsigned int pc0 : 1; /* port 0 state change */
|
||||
unsigned int pc1 : 1; /* port 1 state change */
|
||||
unsigned int _pad1 : 3;
|
||||
unsigned int eai : 1; /* ETR alert indication */
|
||||
unsigned int _pad2 : 18;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Query TOD offset result */
|
||||
struct etr_ptff_qto {
|
||||
unsigned long long physical_clock;
|
||||
unsigned long long tod_offset;
|
||||
unsigned long long logical_tod_offset;
|
||||
unsigned long long tod_epoch_difference;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Inline assembly helper functions */
|
||||
static inline int etr_setr(struct etr_eacr *ctrl)
|
||||
{
|
||||
int rc = -EOPNOTSUPP;
|
||||
|
||||
asm volatile(
|
||||
" .insn s,0xb2160000,%1\n"
|
||||
"0: la %0,0\n"
|
||||
"1:\n"
|
||||
EX_TABLE(0b,1b)
|
||||
: "+d" (rc) : "Q" (*ctrl));
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Stores a format 1 aib with 64 bytes */
|
||||
static inline int etr_stetr(struct etr_aib *aib)
|
||||
{
|
||||
int rc = -EOPNOTSUPP;
|
||||
|
||||
asm volatile(
|
||||
" .insn s,0xb2170000,%1\n"
|
||||
"0: la %0,0\n"
|
||||
"1:\n"
|
||||
EX_TABLE(0b,1b)
|
||||
: "+d" (rc) : "Q" (*aib));
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Stores a format 2 aib with 96 bytes for specified port */
|
||||
static inline int etr_steai(struct etr_aib *aib, unsigned int func)
|
||||
{
|
||||
register unsigned int reg0 asm("0") = func;
|
||||
int rc = -EOPNOTSUPP;
|
||||
|
||||
asm volatile(
|
||||
" .insn s,0xb2b30000,%1\n"
|
||||
"0: la %0,0\n"
|
||||
"1:\n"
|
||||
EX_TABLE(0b,1b)
|
||||
: "+d" (rc) : "Q" (*aib), "d" (reg0));
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Function codes for the steai instruction. */
|
||||
#define ETR_STEAI_STEPPING_PORT 0x10
|
||||
#define ETR_STEAI_ALTERNATE_PORT 0x11
|
||||
#define ETR_STEAI_PORT_0 0x12
|
||||
#define ETR_STEAI_PORT_1 0x13
|
||||
|
||||
static inline int etr_ptff(void *ptff_block, unsigned int func)
|
||||
{
|
||||
register unsigned int reg0 asm("0") = func;
|
||||
register unsigned long reg1 asm("1") = (unsigned long) ptff_block;
|
||||
int rc = -EOPNOTSUPP;
|
||||
|
||||
asm volatile(
|
||||
" .word 0x0104\n"
|
||||
" ipm %0\n"
|
||||
" srl %0,28\n"
|
||||
: "=d" (rc), "=m" (ptff_block)
|
||||
: "d" (reg0), "d" (reg1), "m" (ptff_block) : "cc");
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Function codes for the ptff instruction. */
|
||||
#define ETR_PTFF_QAF 0x00 /* query available functions */
|
||||
#define ETR_PTFF_QTO 0x01 /* query tod offset */
|
||||
#define ETR_PTFF_QSI 0x02 /* query steering information */
|
||||
#define ETR_PTFF_ATO 0x40 /* adjust tod offset */
|
||||
#define ETR_PTFF_STO 0x41 /* set tod offset */
|
||||
#define ETR_PTFF_SFS 0x42 /* set fine steering rate */
|
||||
#define ETR_PTFF_SGS 0x43 /* set gross steering rate */
|
||||
|
||||
/* Functions needed by the machine check handler */
|
||||
void etr_switch_to_local(void);
|
||||
void etr_sync_check(void);
|
||||
|
||||
/* STP interruption parameter */
|
||||
struct stp_irq_parm {
|
||||
unsigned int _pad0 : 14;
|
||||
unsigned int tsc : 1; /* Timing status change */
|
||||
unsigned int lac : 1; /* Link availability change */
|
||||
unsigned int tcpc : 1; /* Time control parameter change */
|
||||
unsigned int _pad2 : 15;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define STP_OP_SYNC 1
|
||||
#define STP_OP_CTRL 3
|
||||
|
||||
struct stp_sstpi {
|
||||
unsigned int rsvd0;
|
||||
unsigned int rsvd1 : 8;
|
||||
unsigned int stratum : 8;
|
||||
unsigned int vbits : 16;
|
||||
unsigned int leaps : 16;
|
||||
unsigned int tmd : 4;
|
||||
unsigned int ctn : 4;
|
||||
unsigned int rsvd2 : 3;
|
||||
unsigned int c : 1;
|
||||
unsigned int tst : 4;
|
||||
unsigned int tzo : 16;
|
||||
unsigned int dsto : 16;
|
||||
unsigned int ctrl : 16;
|
||||
unsigned int rsvd3 : 16;
|
||||
unsigned int tto;
|
||||
unsigned int rsvd4;
|
||||
unsigned int ctnid[3];
|
||||
unsigned int rsvd5;
|
||||
unsigned int todoff[4];
|
||||
unsigned int rsvd6[48];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Functions needed by the machine check handler */
|
||||
void stp_sync_check(void);
|
||||
void stp_island_check(void);
|
||||
|
||||
#endif /* __S390_ETR_H */
|
||||
12
arch/s390/include/asm/exec.h
Normal file
12
arch/s390/include/asm/exec.h
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* Copyright IBM Corp. 1999, 2009
|
||||
*
|
||||
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
|
||||
*/
|
||||
|
||||
#ifndef __ASM_EXEC_H
|
||||
#define __ASM_EXEC_H
|
||||
|
||||
extern unsigned long arch_align_stack(unsigned long sp);
|
||||
|
||||
#endif /* __ASM_EXEC_H */
|
||||
31
arch/s390/include/asm/extmem.h
Normal file
31
arch/s390/include/asm/extmem.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* definitions for external memory segment support
|
||||
* Copyright IBM Corp. 2003
|
||||
*/
|
||||
|
||||
#ifndef _ASM_S390X_DCSS_H
|
||||
#define _ASM_S390X_DCSS_H
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/* possible values for segment type as returned by segment_info */
|
||||
#define SEG_TYPE_SW 0
|
||||
#define SEG_TYPE_EW 1
|
||||
#define SEG_TYPE_SR 2
|
||||
#define SEG_TYPE_ER 3
|
||||
#define SEG_TYPE_SN 4
|
||||
#define SEG_TYPE_EN 5
|
||||
#define SEG_TYPE_SC 6
|
||||
#define SEG_TYPE_EWEN 7
|
||||
|
||||
#define SEGMENT_SHARED 0
|
||||
#define SEGMENT_EXCLUSIVE 1
|
||||
|
||||
int segment_load (char *name, int segtype, unsigned long *addr, unsigned long *length);
|
||||
void segment_unload(char *name);
|
||||
void segment_save(char *name);
|
||||
int segment_type (char* name);
|
||||
int segment_modify_shared (char *name, int do_nonshared);
|
||||
void segment_warning(int rc, char *seg_name);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
67
arch/s390/include/asm/facility.h
Normal file
67
arch/s390/include/asm/facility.h
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright IBM Corp. 1999, 2009
|
||||
*
|
||||
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
|
||||
*/
|
||||
|
||||
#ifndef __ASM_FACILITY_H
|
||||
#define __ASM_FACILITY_H
|
||||
|
||||
#include <linux/string.h>
|
||||
#include <linux/preempt.h>
|
||||
#include <asm/lowcore.h>
|
||||
|
||||
#define MAX_FACILITY_BIT (256*8) /* stfle_fac_list has 256 bytes */
|
||||
|
||||
static inline int __test_facility(unsigned long nr, void *facilities)
|
||||
{
|
||||
unsigned char *ptr;
|
||||
|
||||
if (nr >= MAX_FACILITY_BIT)
|
||||
return 0;
|
||||
ptr = (unsigned char *) facilities + (nr >> 3);
|
||||
return (*ptr & (0x80 >> (nr & 7))) != 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The test_facility function uses the bit odering where the MSB is bit 0.
|
||||
* That makes it easier to query facility bits with the bit number as
|
||||
* documented in the Principles of Operation.
|
||||
*/
|
||||
static inline int test_facility(unsigned long nr)
|
||||
{
|
||||
return __test_facility(nr, &S390_lowcore.stfle_fac_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* stfle - Store facility list extended
|
||||
* @stfle_fac_list: array where facility list can be stored
|
||||
* @size: size of passed in array in double words
|
||||
*/
|
||||
static inline void stfle(u64 *stfle_fac_list, int size)
|
||||
{
|
||||
unsigned long nr;
|
||||
|
||||
preempt_disable();
|
||||
asm volatile(
|
||||
" .insn s,0xb2b10000,0(0)\n" /* stfl */
|
||||
"0:\n"
|
||||
EX_TABLE(0b, 0b)
|
||||
: "+m" (S390_lowcore.stfl_fac_list));
|
||||
nr = 4; /* bytes stored by stfl */
|
||||
memcpy(stfle_fac_list, &S390_lowcore.stfl_fac_list, 4);
|
||||
if (S390_lowcore.stfl_fac_list & 0x01000000) {
|
||||
/* More facility bits available with stfle */
|
||||
register unsigned long reg0 asm("0") = size - 1;
|
||||
|
||||
asm volatile(".insn s,0xb2b00000,0(%1)" /* stfle */
|
||||
: "+d" (reg0)
|
||||
: "a" (stfle_fac_list)
|
||||
: "memory", "cc");
|
||||
nr = (reg0 + 1) * 8; /* # bytes stored by stfle */
|
||||
}
|
||||
memset((char *) stfle_fac_list + nr, 0, size * 8 - nr);
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
#endif /* __ASM_FACILITY_H */
|
||||
12
arch/s390/include/asm/fb.h
Normal file
12
arch/s390/include/asm/fb.h
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef _ASM_FB_H_
|
||||
#define _ASM_FB_H_
|
||||
#include <linux/fb.h>
|
||||
|
||||
#define fb_pgprotect(...) do {} while (0)
|
||||
|
||||
static inline int fb_is_primary_device(struct fb_info *info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* _ASM_FB_H_ */
|
||||
311
arch/s390/include/asm/fcx.h
Normal file
311
arch/s390/include/asm/fcx.h
Normal file
|
|
@ -0,0 +1,311 @@
|
|||
/*
|
||||
* Functions for assembling fcx enabled I/O control blocks.
|
||||
*
|
||||
* Copyright IBM Corp. 2008
|
||||
* Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
|
||||
*/
|
||||
|
||||
#ifndef _ASM_S390_FCX_H
|
||||
#define _ASM_S390_FCX_H _ASM_S390_FCX_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#define TCW_FORMAT_DEFAULT 0
|
||||
#define TCW_TIDAW_FORMAT_DEFAULT 0
|
||||
#define TCW_FLAGS_INPUT_TIDA (1 << (23 - 5))
|
||||
#define TCW_FLAGS_TCCB_TIDA (1 << (23 - 6))
|
||||
#define TCW_FLAGS_OUTPUT_TIDA (1 << (23 - 7))
|
||||
#define TCW_FLAGS_TIDAW_FORMAT(x) ((x) & 3) << (23 - 9)
|
||||
#define TCW_FLAGS_GET_TIDAW_FORMAT(x) (((x) >> (23 - 9)) & 3)
|
||||
|
||||
/**
|
||||
* struct tcw - Transport Control Word (TCW)
|
||||
* @format: TCW format
|
||||
* @flags: TCW flags
|
||||
* @tccbl: Transport-Command-Control-Block Length
|
||||
* @r: Read Operations
|
||||
* @w: Write Operations
|
||||
* @output: Output-Data Address
|
||||
* @input: Input-Data Address
|
||||
* @tsb: Transport-Status-Block Address
|
||||
* @tccb: Transport-Command-Control-Block Address
|
||||
* @output_count: Output Count
|
||||
* @input_count: Input Count
|
||||
* @intrg: Interrogate TCW Address
|
||||
*/
|
||||
struct tcw {
|
||||
u32 format:2;
|
||||
u32 :6;
|
||||
u32 flags:24;
|
||||
u32 :8;
|
||||
u32 tccbl:6;
|
||||
u32 r:1;
|
||||
u32 w:1;
|
||||
u32 :16;
|
||||
u64 output;
|
||||
u64 input;
|
||||
u64 tsb;
|
||||
u64 tccb;
|
||||
u32 output_count;
|
||||
u32 input_count;
|
||||
u32 :32;
|
||||
u32 :32;
|
||||
u32 :32;
|
||||
u32 intrg;
|
||||
} __attribute__ ((packed, aligned(64)));
|
||||
|
||||
#define TIDAW_FLAGS_LAST (1 << (7 - 0))
|
||||
#define TIDAW_FLAGS_SKIP (1 << (7 - 1))
|
||||
#define TIDAW_FLAGS_DATA_INT (1 << (7 - 2))
|
||||
#define TIDAW_FLAGS_TTIC (1 << (7 - 3))
|
||||
#define TIDAW_FLAGS_INSERT_CBC (1 << (7 - 4))
|
||||
|
||||
/**
|
||||
* struct tidaw - Transport-Indirect-Addressing Word (TIDAW)
|
||||
* @flags: TIDAW flags. Can be an arithmetic OR of the following constants:
|
||||
* %TIDAW_FLAGS_LAST, %TIDAW_FLAGS_SKIP, %TIDAW_FLAGS_DATA_INT,
|
||||
* %TIDAW_FLAGS_TTIC, %TIDAW_FLAGS_INSERT_CBC
|
||||
* @count: Count
|
||||
* @addr: Address
|
||||
*/
|
||||
struct tidaw {
|
||||
u32 flags:8;
|
||||
u32 :24;
|
||||
u32 count;
|
||||
u64 addr;
|
||||
} __attribute__ ((packed, aligned(16)));
|
||||
|
||||
/**
|
||||
* struct tsa_iostat - I/O-Status Transport-Status Area (IO-Stat TSA)
|
||||
* @dev_time: Device Time
|
||||
* @def_time: Defer Time
|
||||
* @queue_time: Queue Time
|
||||
* @dev_busy_time: Device-Busy Time
|
||||
* @dev_act_time: Device-Active-Only Time
|
||||
* @sense: Sense Data (if present)
|
||||
*/
|
||||
struct tsa_iostat {
|
||||
u32 dev_time;
|
||||
u32 def_time;
|
||||
u32 queue_time;
|
||||
u32 dev_busy_time;
|
||||
u32 dev_act_time;
|
||||
u8 sense[32];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/**
|
||||
* struct tsa_ddpcs - Device-Detected-Program-Check Transport-Status Area (DDPC TSA)
|
||||
* @rc: Reason Code
|
||||
* @rcq: Reason Code Qualifier
|
||||
* @sense: Sense Data (if present)
|
||||
*/
|
||||
struct tsa_ddpc {
|
||||
u32 :24;
|
||||
u32 rc:8;
|
||||
u8 rcq[16];
|
||||
u8 sense[32];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define TSA_INTRG_FLAGS_CU_STATE_VALID (1 << (7 - 0))
|
||||
#define TSA_INTRG_FLAGS_DEV_STATE_VALID (1 << (7 - 1))
|
||||
#define TSA_INTRG_FLAGS_OP_STATE_VALID (1 << (7 - 2))
|
||||
|
||||
/**
|
||||
* struct tsa_intrg - Interrogate Transport-Status Area (Intrg. TSA)
|
||||
* @format: Format
|
||||
* @flags: Flags. Can be an arithmetic OR of the following constants:
|
||||
* %TSA_INTRG_FLAGS_CU_STATE_VALID, %TSA_INTRG_FLAGS_DEV_STATE_VALID,
|
||||
* %TSA_INTRG_FLAGS_OP_STATE_VALID
|
||||
* @cu_state: Controle-Unit State
|
||||
* @dev_state: Device State
|
||||
* @op_state: Operation State
|
||||
* @sd_info: State-Dependent Information
|
||||
* @dl_id: Device-Level Identifier
|
||||
* @dd_data: Device-Dependent Data
|
||||
*/
|
||||
struct tsa_intrg {
|
||||
u32 format:8;
|
||||
u32 flags:8;
|
||||
u32 cu_state:8;
|
||||
u32 dev_state:8;
|
||||
u32 op_state:8;
|
||||
u32 :24;
|
||||
u8 sd_info[12];
|
||||
u32 dl_id;
|
||||
u8 dd_data[28];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define TSB_FORMAT_NONE 0
|
||||
#define TSB_FORMAT_IOSTAT 1
|
||||
#define TSB_FORMAT_DDPC 2
|
||||
#define TSB_FORMAT_INTRG 3
|
||||
|
||||
#define TSB_FLAGS_DCW_OFFSET_VALID (1 << (7 - 0))
|
||||
#define TSB_FLAGS_COUNT_VALID (1 << (7 - 1))
|
||||
#define TSB_FLAGS_CACHE_MISS (1 << (7 - 2))
|
||||
#define TSB_FLAGS_TIME_VALID (1 << (7 - 3))
|
||||
#define TSB_FLAGS_FORMAT(x) ((x) & 7)
|
||||
#define TSB_FORMAT(t) ((t)->flags & 7)
|
||||
|
||||
/**
|
||||
* struct tsb - Transport-Status Block (TSB)
|
||||
* @length: Length
|
||||
* @flags: Flags. Can be an arithmetic OR of the following constants:
|
||||
* %TSB_FLAGS_DCW_OFFSET_VALID, %TSB_FLAGS_COUNT_VALID, %TSB_FLAGS_CACHE_MISS,
|
||||
* %TSB_FLAGS_TIME_VALID
|
||||
* @dcw_offset: DCW Offset
|
||||
* @count: Count
|
||||
* @tsa: Transport-Status-Area
|
||||
*/
|
||||
struct tsb {
|
||||
u32 length:8;
|
||||
u32 flags:8;
|
||||
u32 dcw_offset:16;
|
||||
u32 count;
|
||||
u32 :32;
|
||||
union {
|
||||
struct tsa_iostat iostat;
|
||||
struct tsa_ddpc ddpc;
|
||||
struct tsa_intrg intrg;
|
||||
} __attribute__ ((packed)) tsa;
|
||||
} __attribute__ ((packed, aligned(8)));
|
||||
|
||||
#define DCW_INTRG_FORMAT_DEFAULT 0
|
||||
|
||||
#define DCW_INTRG_RC_UNSPECIFIED 0
|
||||
#define DCW_INTRG_RC_TIMEOUT 1
|
||||
|
||||
#define DCW_INTRG_RCQ_UNSPECIFIED 0
|
||||
#define DCW_INTRG_RCQ_PRIMARY 1
|
||||
#define DCW_INTRG_RCQ_SECONDARY 2
|
||||
|
||||
#define DCW_INTRG_FLAGS_MPM (1 << (7 - 0))
|
||||
#define DCW_INTRG_FLAGS_PPR (1 << (7 - 1))
|
||||
#define DCW_INTRG_FLAGS_CRIT (1 << (7 - 2))
|
||||
|
||||
/**
|
||||
* struct dcw_intrg_data - Interrogate DCW data
|
||||
* @format: Format. Should be %DCW_INTRG_FORMAT_DEFAULT
|
||||
* @rc: Reason Code. Can be one of %DCW_INTRG_RC_UNSPECIFIED,
|
||||
* %DCW_INTRG_RC_TIMEOUT
|
||||
* @rcq: Reason Code Qualifier: Can be one of %DCW_INTRG_RCQ_UNSPECIFIED,
|
||||
* %DCW_INTRG_RCQ_PRIMARY, %DCW_INTRG_RCQ_SECONDARY
|
||||
* @lpm: Logical-Path Mask
|
||||
* @pam: Path-Available Mask
|
||||
* @pim: Path-Installed Mask
|
||||
* @timeout: Timeout
|
||||
* @flags: Flags. Can be an arithmetic OR of %DCW_INTRG_FLAGS_MPM,
|
||||
* %DCW_INTRG_FLAGS_PPR, %DCW_INTRG_FLAGS_CRIT
|
||||
* @time: Time
|
||||
* @prog_id: Program Identifier
|
||||
* @prog_data: Program-Dependent Data
|
||||
*/
|
||||
struct dcw_intrg_data {
|
||||
u32 format:8;
|
||||
u32 rc:8;
|
||||
u32 rcq:8;
|
||||
u32 lpm:8;
|
||||
u32 pam:8;
|
||||
u32 pim:8;
|
||||
u32 timeout:16;
|
||||
u32 flags:8;
|
||||
u32 :24;
|
||||
u32 :32;
|
||||
u64 time;
|
||||
u64 prog_id;
|
||||
u8 prog_data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define DCW_FLAGS_CC (1 << (7 - 1))
|
||||
|
||||
#define DCW_CMD_WRITE 0x01
|
||||
#define DCW_CMD_READ 0x02
|
||||
#define DCW_CMD_CONTROL 0x03
|
||||
#define DCW_CMD_SENSE 0x04
|
||||
#define DCW_CMD_SENSE_ID 0xe4
|
||||
#define DCW_CMD_INTRG 0x40
|
||||
|
||||
/**
|
||||
* struct dcw - Device-Command Word (DCW)
|
||||
* @cmd: Command Code. Can be one of %DCW_CMD_WRITE, %DCW_CMD_READ,
|
||||
* %DCW_CMD_CONTROL, %DCW_CMD_SENSE, %DCW_CMD_SENSE_ID, %DCW_CMD_INTRG
|
||||
* @flags: Flags. Can be an arithmetic OR of %DCW_FLAGS_CC
|
||||
* @cd_count: Control-Data Count
|
||||
* @count: Count
|
||||
* @cd: Control Data
|
||||
*/
|
||||
struct dcw {
|
||||
u32 cmd:8;
|
||||
u32 flags:8;
|
||||
u32 :8;
|
||||
u32 cd_count:8;
|
||||
u32 count;
|
||||
u8 cd[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define TCCB_FORMAT_DEFAULT 0x7f
|
||||
#define TCCB_MAX_DCW 30
|
||||
#define TCCB_MAX_SIZE (sizeof(struct tccb_tcah) + \
|
||||
TCCB_MAX_DCW * sizeof(struct dcw) + \
|
||||
sizeof(struct tccb_tcat))
|
||||
#define TCCB_SAC_DEFAULT 0x1ffe
|
||||
#define TCCB_SAC_INTRG 0x1fff
|
||||
|
||||
/**
|
||||
* struct tccb_tcah - Transport-Command-Area Header (TCAH)
|
||||
* @format: Format. Should be %TCCB_FORMAT_DEFAULT
|
||||
* @tcal: Transport-Command-Area Length
|
||||
* @sac: Service-Action Code. Can be one of %TCCB_SAC_DEFAULT, %TCCB_SAC_INTRG
|
||||
* @prio: Priority
|
||||
*/
|
||||
struct tccb_tcah {
|
||||
u32 format:8;
|
||||
u32 :24;
|
||||
u32 :24;
|
||||
u32 tcal:8;
|
||||
u32 sac:16;
|
||||
u32 :8;
|
||||
u32 prio:8;
|
||||
u32 :32;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/**
|
||||
* struct tccb_tcat - Transport-Command-Area Trailer (TCAT)
|
||||
* @count: Transport Count
|
||||
*/
|
||||
struct tccb_tcat {
|
||||
u32 :32;
|
||||
u32 count;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/**
|
||||
* struct tccb - (partial) Transport-Command-Control Block (TCCB)
|
||||
* @tcah: TCAH
|
||||
* @tca: Transport-Command Area
|
||||
*/
|
||||
struct tccb {
|
||||
struct tccb_tcah tcah;
|
||||
u8 tca[0];
|
||||
} __attribute__ ((packed, aligned(8)));
|
||||
|
||||
struct tcw *tcw_get_intrg(struct tcw *tcw);
|
||||
void *tcw_get_data(struct tcw *tcw);
|
||||
struct tccb *tcw_get_tccb(struct tcw *tcw);
|
||||
struct tsb *tcw_get_tsb(struct tcw *tcw);
|
||||
|
||||
void tcw_init(struct tcw *tcw, int r, int w);
|
||||
void tcw_finalize(struct tcw *tcw, int num_tidaws);
|
||||
|
||||
void tcw_set_intrg(struct tcw *tcw, struct tcw *intrg_tcw);
|
||||
void tcw_set_data(struct tcw *tcw, void *data, int use_tidal);
|
||||
void tcw_set_tccb(struct tcw *tcw, struct tccb *tccb);
|
||||
void tcw_set_tsb(struct tcw *tcw, struct tsb *tsb);
|
||||
|
||||
void tccb_init(struct tccb *tccb, size_t tccb_size, u32 sac);
|
||||
void tsb_init(struct tsb *tsb);
|
||||
struct dcw *tccb_add_dcw(struct tccb *tccb, size_t tccb_size, u8 cmd, u8 flags,
|
||||
void *cd, u8 cd_count, u32 count);
|
||||
struct tidaw *tcw_add_tidaw(struct tcw *tcw, int num_tidaws, u8 flags,
|
||||
void *addr, u32 count);
|
||||
|
||||
#endif /* _ASM_S390_FCX_H */
|
||||
25
arch/s390/include/asm/ftrace.h
Normal file
25
arch/s390/include/asm/ftrace.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef _ASM_S390_FTRACE_H
|
||||
#define _ASM_S390_FTRACE_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
extern void _mcount(void);
|
||||
extern char ftrace_graph_caller_end;
|
||||
|
||||
struct dyn_arch_ftrace { };
|
||||
|
||||
#define MCOUNT_ADDR ((long)_mcount)
|
||||
|
||||
|
||||
static inline unsigned long ftrace_call_adjust(unsigned long addr)
|
||||
{
|
||||
return addr;
|
||||
}
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#define MCOUNT_INSN_SIZE 18
|
||||
|
||||
#define ARCH_SUPPORTS_FTRACE_OPS 1
|
||||
|
||||
#endif /* _ASM_S390_FTRACE_H */
|
||||
96
arch/s390/include/asm/futex.h
Normal file
96
arch/s390/include/asm/futex.h
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
#ifndef _ASM_S390_FUTEX_H
|
||||
#define _ASM_S390_FUTEX_H
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/futex.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/errno.h>
|
||||
|
||||
#define __futex_atomic_op(insn, ret, oldval, newval, uaddr, oparg) \
|
||||
asm volatile( \
|
||||
" sacf 256\n" \
|
||||
"0: l %1,0(%6)\n" \
|
||||
"1:"insn \
|
||||
"2: cs %1,%2,0(%6)\n" \
|
||||
"3: jl 1b\n" \
|
||||
" lhi %0,0\n" \
|
||||
"4: sacf 768\n" \
|
||||
EX_TABLE(0b,4b) EX_TABLE(2b,4b) EX_TABLE(3b,4b) \
|
||||
: "=d" (ret), "=&d" (oldval), "=&d" (newval), \
|
||||
"=m" (*uaddr) \
|
||||
: "0" (-EFAULT), "d" (oparg), "a" (uaddr), \
|
||||
"m" (*uaddr) : "cc");
|
||||
|
||||
static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (encoded_op << 8) >> 20;
|
||||
int cmparg = (encoded_op << 20) >> 20;
|
||||
int oldval = 0, newval, ret;
|
||||
|
||||
load_kernel_asce();
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1 << oparg;
|
||||
|
||||
pagefault_disable();
|
||||
switch (op) {
|
||||
case FUTEX_OP_SET:
|
||||
__futex_atomic_op("lr %2,%5\n",
|
||||
ret, oldval, newval, uaddr, oparg);
|
||||
break;
|
||||
case FUTEX_OP_ADD:
|
||||
__futex_atomic_op("lr %2,%1\nar %2,%5\n",
|
||||
ret, oldval, newval, uaddr, oparg);
|
||||
break;
|
||||
case FUTEX_OP_OR:
|
||||
__futex_atomic_op("lr %2,%1\nor %2,%5\n",
|
||||
ret, oldval, newval, uaddr, oparg);
|
||||
break;
|
||||
case FUTEX_OP_ANDN:
|
||||
__futex_atomic_op("lr %2,%1\nnr %2,%5\n",
|
||||
ret, oldval, newval, uaddr, oparg);
|
||||
break;
|
||||
case FUTEX_OP_XOR:
|
||||
__futex_atomic_op("lr %2,%1\nxr %2,%5\n",
|
||||
ret, oldval, newval, uaddr, oparg);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOSYS;
|
||||
}
|
||||
pagefault_enable();
|
||||
|
||||
if (!ret) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
|
||||
case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
|
||||
case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
|
||||
case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
|
||||
case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
|
||||
case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
|
||||
default: ret = -ENOSYS;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
|
||||
u32 oldval, u32 newval)
|
||||
{
|
||||
int ret;
|
||||
|
||||
load_kernel_asce();
|
||||
asm volatile(
|
||||
" sacf 256\n"
|
||||
"0: cs %1,%4,0(%5)\n"
|
||||
"1: la %0,0\n"
|
||||
"2: sacf 768\n"
|
||||
EX_TABLE(0b,2b) EX_TABLE(1b,2b)
|
||||
: "=d" (ret), "+d" (oldval), "=m" (*uaddr)
|
||||
: "0" (-EFAULT), "d" (newval), "a" (uaddr), "m" (*uaddr)
|
||||
: "cc", "memory");
|
||||
*uval = oldval;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* _ASM_S390_FUTEX_H */
|
||||
26
arch/s390/include/asm/hardirq.h
Normal file
26
arch/s390/include/asm/hardirq.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* S390 version
|
||||
* Copyright IBM Corp. 1999, 2000
|
||||
* Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
|
||||
* Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
|
||||
*
|
||||
* Derived from "include/asm-i386/hardirq.h"
|
||||
*/
|
||||
|
||||
#ifndef __ASM_HARDIRQ_H
|
||||
#define __ASM_HARDIRQ_H
|
||||
|
||||
#include <asm/lowcore.h>
|
||||
|
||||
#define local_softirq_pending() (S390_lowcore.softirq_pending)
|
||||
|
||||
#define __ARCH_IRQ_STAT
|
||||
#define __ARCH_HAS_DO_SOFTIRQ
|
||||
#define __ARCH_IRQ_EXIT_IRQS_DISABLED
|
||||
|
||||
static inline void ack_bad_irq(unsigned int irq)
|
||||
{
|
||||
printk(KERN_CRIT "unexpected IRQ trap at vector %02x\n", irq);
|
||||
}
|
||||
|
||||
#endif /* __ASM_HARDIRQ_H */
|
||||
115
arch/s390/include/asm/hugetlb.h
Normal file
115
arch/s390/include/asm/hugetlb.h
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* IBM System z Huge TLB Page Support for Kernel.
|
||||
*
|
||||
* Copyright IBM Corp. 2008
|
||||
* Author(s): Gerald Schaefer <gerald.schaefer@de.ibm.com>
|
||||
*/
|
||||
|
||||
#ifndef _ASM_S390_HUGETLB_H
|
||||
#define _ASM_S390_HUGETLB_H
|
||||
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgtable.h>
|
||||
|
||||
|
||||
#define is_hugepage_only_range(mm, addr, len) 0
|
||||
#define hugetlb_free_pgd_range free_pgd_range
|
||||
|
||||
void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
|
||||
pte_t *ptep, pte_t pte);
|
||||
pte_t huge_ptep_get(pte_t *ptep);
|
||||
pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
|
||||
unsigned long addr, pte_t *ptep);
|
||||
|
||||
/*
|
||||
* If the arch doesn't supply something else, assume that hugepage
|
||||
* size aligned regions are ok without further preparation.
|
||||
*/
|
||||
static inline int prepare_hugepage_range(struct file *file,
|
||||
unsigned long addr, unsigned long len)
|
||||
{
|
||||
if (len & ~HPAGE_MASK)
|
||||
return -EINVAL;
|
||||
if (addr & ~HPAGE_MASK)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define hugetlb_prefault_arch_hook(mm) do { } while (0)
|
||||
#define arch_clear_hugepage_flags(page) do { } while (0)
|
||||
|
||||
int arch_prepare_hugepage(struct page *page);
|
||||
void arch_release_hugepage(struct page *page);
|
||||
|
||||
static inline void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
|
||||
pte_t *ptep)
|
||||
{
|
||||
pte_val(*ptep) = _SEGMENT_ENTRY_EMPTY;
|
||||
}
|
||||
|
||||
static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
|
||||
unsigned long address, pte_t *ptep)
|
||||
{
|
||||
huge_ptep_get_and_clear(vma->vm_mm, address, ptep);
|
||||
}
|
||||
|
||||
static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
|
||||
unsigned long addr, pte_t *ptep,
|
||||
pte_t pte, int dirty)
|
||||
{
|
||||
int changed = !pte_same(huge_ptep_get(ptep), pte);
|
||||
if (changed) {
|
||||
huge_ptep_get_and_clear(vma->vm_mm, addr, ptep);
|
||||
set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
|
||||
unsigned long addr, pte_t *ptep)
|
||||
{
|
||||
pte_t pte = huge_ptep_get_and_clear(mm, addr, ptep);
|
||||
set_huge_pte_at(mm, addr, ptep, pte_wrprotect(pte));
|
||||
}
|
||||
|
||||
static inline pte_t mk_huge_pte(struct page *page, pgprot_t pgprot)
|
||||
{
|
||||
return mk_pte(page, pgprot);
|
||||
}
|
||||
|
||||
static inline int huge_pte_none(pte_t pte)
|
||||
{
|
||||
return pte_none(pte);
|
||||
}
|
||||
|
||||
static inline int huge_pte_write(pte_t pte)
|
||||
{
|
||||
return pte_write(pte);
|
||||
}
|
||||
|
||||
static inline int huge_pte_dirty(pte_t pte)
|
||||
{
|
||||
return pte_dirty(pte);
|
||||
}
|
||||
|
||||
static inline pte_t huge_pte_mkwrite(pte_t pte)
|
||||
{
|
||||
return pte_mkwrite(pte);
|
||||
}
|
||||
|
||||
static inline pte_t huge_pte_mkdirty(pte_t pte)
|
||||
{
|
||||
return pte_mkdirty(pte);
|
||||
}
|
||||
|
||||
static inline pte_t huge_pte_wrprotect(pte_t pte)
|
||||
{
|
||||
return pte_wrprotect(pte);
|
||||
}
|
||||
|
||||
static inline pte_t huge_pte_modify(pte_t pte, pgprot_t newprot)
|
||||
{
|
||||
return pte_modify(pte, newprot);
|
||||
}
|
||||
|
||||
#endif /* _ASM_S390_HUGETLB_H */
|
||||
11
arch/s390/include/asm/hw_irq.h
Normal file
11
arch/s390/include/asm/hw_irq.h
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef _HW_IRQ_H
|
||||
#define _HW_IRQ_H
|
||||
|
||||
#include <linux/msi.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
void __init init_airq_interrupts(void);
|
||||
void __init init_cio_interrupts(void);
|
||||
void __init init_ext_interrupts(void);
|
||||
|
||||
#endif
|
||||
248
arch/s390/include/asm/idals.h
Normal file
248
arch/s390/include/asm/idals.h
Normal file
|
|
@ -0,0 +1,248 @@
|
|||
/*
|
||||
* Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
|
||||
* Martin Schwidefsky <schwidefsky@de.ibm.com>
|
||||
* Bugreports.to..: <Linux390@de.ibm.com>
|
||||
* Copyright IBM Corp. 2000
|
||||
*
|
||||
* History of changes
|
||||
* 07/24/00 new file
|
||||
* 05/04/02 code restructuring.
|
||||
*/
|
||||
|
||||
#ifndef _S390_IDALS_H
|
||||
#define _S390_IDALS_H
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/slab.h>
|
||||
#include <asm/cio.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
#define IDA_SIZE_LOG 12 /* 11 for 2k , 12 for 4k */
|
||||
#else
|
||||
#define IDA_SIZE_LOG 11 /* 11 for 2k , 12 for 4k */
|
||||
#endif
|
||||
#define IDA_BLOCK_SIZE (1L<<IDA_SIZE_LOG)
|
||||
|
||||
/*
|
||||
* Test if an address/length pair needs an idal list.
|
||||
*/
|
||||
static inline int
|
||||
idal_is_needed(void *vaddr, unsigned int length)
|
||||
{
|
||||
#ifdef CONFIG_64BIT
|
||||
return ((__pa(vaddr) + length - 1) >> 31) != 0;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return the number of idal words needed for an address/length pair.
|
||||
*/
|
||||
static inline unsigned int idal_nr_words(void *vaddr, unsigned int length)
|
||||
{
|
||||
return ((__pa(vaddr) & (IDA_BLOCK_SIZE-1)) + length +
|
||||
(IDA_BLOCK_SIZE-1)) >> IDA_SIZE_LOG;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the list of idal words for an address/length pair.
|
||||
*/
|
||||
static inline unsigned long *idal_create_words(unsigned long *idaws,
|
||||
void *vaddr, unsigned int length)
|
||||
{
|
||||
unsigned long paddr;
|
||||
unsigned int cidaw;
|
||||
|
||||
paddr = __pa(vaddr);
|
||||
cidaw = ((paddr & (IDA_BLOCK_SIZE-1)) + length +
|
||||
(IDA_BLOCK_SIZE-1)) >> IDA_SIZE_LOG;
|
||||
*idaws++ = paddr;
|
||||
paddr &= -IDA_BLOCK_SIZE;
|
||||
while (--cidaw > 0) {
|
||||
paddr += IDA_BLOCK_SIZE;
|
||||
*idaws++ = paddr;
|
||||
}
|
||||
return idaws;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the address of the data in CCW.
|
||||
* If necessary it allocates an IDAL and sets the appropriate flags.
|
||||
*/
|
||||
static inline int
|
||||
set_normalized_cda(struct ccw1 * ccw, void *vaddr)
|
||||
{
|
||||
#ifdef CONFIG_64BIT
|
||||
unsigned int nridaws;
|
||||
unsigned long *idal;
|
||||
|
||||
if (ccw->flags & CCW_FLAG_IDA)
|
||||
return -EINVAL;
|
||||
nridaws = idal_nr_words(vaddr, ccw->count);
|
||||
if (nridaws > 0) {
|
||||
idal = kmalloc(nridaws * sizeof(unsigned long),
|
||||
GFP_ATOMIC | GFP_DMA );
|
||||
if (idal == NULL)
|
||||
return -ENOMEM;
|
||||
idal_create_words(idal, vaddr, ccw->count);
|
||||
ccw->flags |= CCW_FLAG_IDA;
|
||||
vaddr = idal;
|
||||
}
|
||||
#endif
|
||||
ccw->cda = (__u32)(unsigned long) vaddr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Releases any allocated IDAL related to the CCW.
|
||||
*/
|
||||
static inline void
|
||||
clear_normalized_cda(struct ccw1 * ccw)
|
||||
{
|
||||
#ifdef CONFIG_64BIT
|
||||
if (ccw->flags & CCW_FLAG_IDA) {
|
||||
kfree((void *)(unsigned long) ccw->cda);
|
||||
ccw->flags &= ~CCW_FLAG_IDA;
|
||||
}
|
||||
#endif
|
||||
ccw->cda = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Idal buffer extension
|
||||
*/
|
||||
struct idal_buffer {
|
||||
size_t size;
|
||||
size_t page_order;
|
||||
void *data[0];
|
||||
};
|
||||
|
||||
/*
|
||||
* Allocate an idal buffer
|
||||
*/
|
||||
static inline struct idal_buffer *
|
||||
idal_buffer_alloc(size_t size, int page_order)
|
||||
{
|
||||
struct idal_buffer *ib;
|
||||
int nr_chunks, nr_ptrs, i;
|
||||
|
||||
nr_ptrs = (size + IDA_BLOCK_SIZE - 1) >> IDA_SIZE_LOG;
|
||||
nr_chunks = (4096 << page_order) >> IDA_SIZE_LOG;
|
||||
ib = kmalloc(sizeof(struct idal_buffer) + nr_ptrs*sizeof(void *),
|
||||
GFP_DMA | GFP_KERNEL);
|
||||
if (ib == NULL)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
ib->size = size;
|
||||
ib->page_order = page_order;
|
||||
for (i = 0; i < nr_ptrs; i++) {
|
||||
if ((i & (nr_chunks - 1)) != 0) {
|
||||
ib->data[i] = ib->data[i-1] + IDA_BLOCK_SIZE;
|
||||
continue;
|
||||
}
|
||||
ib->data[i] = (void *)
|
||||
__get_free_pages(GFP_KERNEL, page_order);
|
||||
if (ib->data[i] != NULL)
|
||||
continue;
|
||||
// Not enough memory
|
||||
while (i >= nr_chunks) {
|
||||
i -= nr_chunks;
|
||||
free_pages((unsigned long) ib->data[i],
|
||||
ib->page_order);
|
||||
}
|
||||
kfree(ib);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
return ib;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free an idal buffer.
|
||||
*/
|
||||
static inline void
|
||||
idal_buffer_free(struct idal_buffer *ib)
|
||||
{
|
||||
int nr_chunks, nr_ptrs, i;
|
||||
|
||||
nr_ptrs = (ib->size + IDA_BLOCK_SIZE - 1) >> IDA_SIZE_LOG;
|
||||
nr_chunks = (4096 << ib->page_order) >> IDA_SIZE_LOG;
|
||||
for (i = 0; i < nr_ptrs; i += nr_chunks)
|
||||
free_pages((unsigned long) ib->data[i], ib->page_order);
|
||||
kfree(ib);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test if a idal list is really needed.
|
||||
*/
|
||||
static inline int
|
||||
__idal_buffer_is_needed(struct idal_buffer *ib)
|
||||
{
|
||||
#ifdef CONFIG_64BIT
|
||||
return ib->size > (4096ul << ib->page_order) ||
|
||||
idal_is_needed(ib->data[0], ib->size);
|
||||
#else
|
||||
return ib->size > (4096ul << ib->page_order);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Set channel data address to idal buffer.
|
||||
*/
|
||||
static inline void
|
||||
idal_buffer_set_cda(struct idal_buffer *ib, struct ccw1 *ccw)
|
||||
{
|
||||
if (__idal_buffer_is_needed(ib)) {
|
||||
// setup idals;
|
||||
ccw->cda = (u32)(addr_t) ib->data;
|
||||
ccw->flags |= CCW_FLAG_IDA;
|
||||
} else
|
||||
// we do not need idals - use direct addressing
|
||||
ccw->cda = (u32)(addr_t) ib->data[0];
|
||||
ccw->count = ib->size;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy count bytes from an idal buffer to user memory
|
||||
*/
|
||||
static inline size_t
|
||||
idal_buffer_to_user(struct idal_buffer *ib, void __user *to, size_t count)
|
||||
{
|
||||
size_t left;
|
||||
int i;
|
||||
|
||||
BUG_ON(count > ib->size);
|
||||
for (i = 0; count > IDA_BLOCK_SIZE; i++) {
|
||||
left = copy_to_user(to, ib->data[i], IDA_BLOCK_SIZE);
|
||||
if (left)
|
||||
return left + count - IDA_BLOCK_SIZE;
|
||||
to = (void __user *) to + IDA_BLOCK_SIZE;
|
||||
count -= IDA_BLOCK_SIZE;
|
||||
}
|
||||
return copy_to_user(to, ib->data[i], count);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy count bytes from user memory to an idal buffer
|
||||
*/
|
||||
static inline size_t
|
||||
idal_buffer_from_user(struct idal_buffer *ib, const void __user *from, size_t count)
|
||||
{
|
||||
size_t left;
|
||||
int i;
|
||||
|
||||
BUG_ON(count > ib->size);
|
||||
for (i = 0; count > IDA_BLOCK_SIZE; i++) {
|
||||
left = copy_from_user(ib->data[i], from, IDA_BLOCK_SIZE);
|
||||
if (left)
|
||||
return left + count - IDA_BLOCK_SIZE;
|
||||
from = (void __user *) from + IDA_BLOCK_SIZE;
|
||||
count -= IDA_BLOCK_SIZE;
|
||||
}
|
||||
return copy_from_user(ib->data[i], from, count);
|
||||
}
|
||||
|
||||
#endif
|
||||
26
arch/s390/include/asm/idle.h
Normal file
26
arch/s390/include/asm/idle.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright IBM Corp. 2014
|
||||
*
|
||||
* Author: Martin Schwidefsky <schwidefsky@de.ibm.com>
|
||||
*/
|
||||
|
||||
#ifndef _S390_IDLE_H
|
||||
#define _S390_IDLE_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/device.h>
|
||||
|
||||
struct s390_idle_data {
|
||||
unsigned int sequence;
|
||||
unsigned long long idle_count;
|
||||
unsigned long long idle_time;
|
||||
unsigned long long clock_idle_enter;
|
||||
unsigned long long clock_idle_exit;
|
||||
unsigned long long timer_idle_enter;
|
||||
unsigned long long timer_idle_exit;
|
||||
};
|
||||
|
||||
extern struct device_attribute dev_attr_idle_count;
|
||||
extern struct device_attribute dev_attr_idle_time_us;
|
||||
|
||||
#endif /* _S390_IDLE_H */
|
||||
72
arch/s390/include/asm/io.h
Normal file
72
arch/s390/include/asm/io.h
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* S390 version
|
||||
* Copyright IBM Corp. 1999
|
||||
* Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
|
||||
*
|
||||
* Derived from "include/asm-i386/io.h"
|
||||
*/
|
||||
|
||||
#ifndef _S390_IO_H
|
||||
#define _S390_IO_H
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/pci_io.h>
|
||||
|
||||
void *xlate_dev_mem_ptr(unsigned long phys);
|
||||
#define xlate_dev_mem_ptr xlate_dev_mem_ptr
|
||||
void unxlate_dev_mem_ptr(unsigned long phys, void *addr);
|
||||
|
||||
/*
|
||||
* Convert a virtual cached pointer to an uncached pointer
|
||||
*/
|
||||
#define xlate_dev_kmem_ptr(p) p
|
||||
|
||||
#define IO_SPACE_LIMIT 0
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
|
||||
#define ioremap_nocache(addr, size) ioremap(addr, size)
|
||||
#define ioremap_wc ioremap_nocache
|
||||
|
||||
static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
|
||||
{
|
||||
return (void __iomem *) offset;
|
||||
}
|
||||
|
||||
static inline void iounmap(volatile void __iomem *addr)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* s390 needs a private implementation of pci_iomap since ioremap with its
|
||||
* offset parameter isn't sufficient. That's because BAR spaces are not
|
||||
* disjunctive on s390 so we need the bar parameter of pci_iomap to find
|
||||
* the corresponding device and create the mapping cookie.
|
||||
*/
|
||||
#define pci_iomap pci_iomap
|
||||
#define pci_iounmap pci_iounmap
|
||||
|
||||
#define memcpy_fromio(dst, src, count) zpci_memcpy_fromio(dst, src, count)
|
||||
#define memcpy_toio(dst, src, count) zpci_memcpy_toio(dst, src, count)
|
||||
#define memset_io(dst, val, count) zpci_memset_io(dst, val, count)
|
||||
|
||||
#define __raw_readb zpci_read_u8
|
||||
#define __raw_readw zpci_read_u16
|
||||
#define __raw_readl zpci_read_u32
|
||||
#define __raw_readq zpci_read_u64
|
||||
#define __raw_writeb zpci_write_u8
|
||||
#define __raw_writew zpci_write_u16
|
||||
#define __raw_writel zpci_write_u32
|
||||
#define __raw_writeq zpci_write_u64
|
||||
|
||||
#define readb_relaxed readb
|
||||
#define readw_relaxed readw
|
||||
#define readl_relaxed readl
|
||||
#define readq_relaxed readq
|
||||
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
#include <asm-generic/io.h>
|
||||
|
||||
#endif
|
||||
182
arch/s390/include/asm/ipl.h
Normal file
182
arch/s390/include/asm/ipl.h
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
* s390 (re)ipl support
|
||||
*
|
||||
* Copyright IBM Corp. 2007
|
||||
*/
|
||||
|
||||
#ifndef _ASM_S390_IPL_H
|
||||
#define _ASM_S390_IPL_H
|
||||
|
||||
#include <asm/lowcore.h>
|
||||
#include <asm/types.h>
|
||||
#include <asm/cio.h>
|
||||
#include <asm/setup.h>
|
||||
|
||||
#define IPL_PARMBLOCK_ORIGIN 0x2000
|
||||
|
||||
#define IPL_PARM_BLK_FCP_LEN (sizeof(struct ipl_list_hdr) + \
|
||||
sizeof(struct ipl_block_fcp))
|
||||
|
||||
#define IPL_PARM_BLK0_FCP_LEN (sizeof(struct ipl_block_fcp) + 16)
|
||||
|
||||
#define IPL_PARM_BLK_CCW_LEN (sizeof(struct ipl_list_hdr) + \
|
||||
sizeof(struct ipl_block_ccw))
|
||||
|
||||
#define IPL_PARM_BLK0_CCW_LEN (sizeof(struct ipl_block_ccw) + 16)
|
||||
|
||||
#define IPL_MAX_SUPPORTED_VERSION (0)
|
||||
|
||||
#define IPL_PARMBLOCK_START ((struct ipl_parameter_block *) \
|
||||
IPL_PARMBLOCK_ORIGIN)
|
||||
#define IPL_PARMBLOCK_SIZE (IPL_PARMBLOCK_START->hdr.len)
|
||||
|
||||
struct ipl_list_hdr {
|
||||
u32 len;
|
||||
u8 reserved1[3];
|
||||
u8 version;
|
||||
u32 blk0_len;
|
||||
u8 pbt;
|
||||
u8 flags;
|
||||
u16 reserved2;
|
||||
u8 loadparm[8];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct ipl_block_fcp {
|
||||
u8 reserved1[305-1];
|
||||
u8 opt;
|
||||
u8 reserved2[3];
|
||||
u16 reserved3;
|
||||
u16 devno;
|
||||
u8 reserved4[4];
|
||||
u64 wwpn;
|
||||
u64 lun;
|
||||
u32 bootprog;
|
||||
u8 reserved5[12];
|
||||
u64 br_lba;
|
||||
u32 scp_data_len;
|
||||
u8 reserved6[260];
|
||||
u8 scp_data[];
|
||||
} __attribute__((packed));
|
||||
|
||||
#define DIAG308_VMPARM_SIZE 64
|
||||
#define DIAG308_SCPDATA_SIZE (PAGE_SIZE - (sizeof(struct ipl_list_hdr) + \
|
||||
offsetof(struct ipl_block_fcp, scp_data)))
|
||||
|
||||
struct ipl_block_ccw {
|
||||
u8 reserved1[84];
|
||||
u8 reserved2[2];
|
||||
u16 devno;
|
||||
u8 vm_flags;
|
||||
u8 reserved3[3];
|
||||
u32 vm_parm_len;
|
||||
u8 nss_name[8];
|
||||
u8 vm_parm[DIAG308_VMPARM_SIZE];
|
||||
u8 reserved4[8];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct ipl_parameter_block {
|
||||
struct ipl_list_hdr hdr;
|
||||
union {
|
||||
struct ipl_block_fcp fcp;
|
||||
struct ipl_block_ccw ccw;
|
||||
} ipl_info;
|
||||
} __attribute__((packed,aligned(4096)));
|
||||
|
||||
/*
|
||||
* IPL validity flags
|
||||
*/
|
||||
extern u32 ipl_flags;
|
||||
extern u32 dump_prefix_page;
|
||||
|
||||
struct dump_save_areas {
|
||||
struct save_area_ext **areas;
|
||||
int count;
|
||||
};
|
||||
|
||||
extern struct dump_save_areas dump_save_areas;
|
||||
struct save_area_ext *dump_save_area_create(int cpu);
|
||||
|
||||
extern void do_reipl(void);
|
||||
extern void do_halt(void);
|
||||
extern void do_poff(void);
|
||||
extern void ipl_save_parameters(void);
|
||||
extern void ipl_update_parameters(void);
|
||||
extern size_t append_ipl_vmparm(char *, size_t);
|
||||
extern size_t append_ipl_scpdata(char *, size_t);
|
||||
|
||||
enum {
|
||||
IPL_DEVNO_VALID = 1,
|
||||
IPL_PARMBLOCK_VALID = 2,
|
||||
IPL_NSS_VALID = 4,
|
||||
};
|
||||
|
||||
enum ipl_type {
|
||||
IPL_TYPE_UNKNOWN = 1,
|
||||
IPL_TYPE_CCW = 2,
|
||||
IPL_TYPE_FCP = 4,
|
||||
IPL_TYPE_FCP_DUMP = 8,
|
||||
IPL_TYPE_NSS = 16,
|
||||
};
|
||||
|
||||
struct ipl_info
|
||||
{
|
||||
enum ipl_type type;
|
||||
union {
|
||||
struct {
|
||||
struct ccw_dev_id dev_id;
|
||||
} ccw;
|
||||
struct {
|
||||
struct ccw_dev_id dev_id;
|
||||
u64 wwpn;
|
||||
u64 lun;
|
||||
} fcp;
|
||||
struct {
|
||||
char name[NSS_NAME_SIZE + 1];
|
||||
} nss;
|
||||
} data;
|
||||
};
|
||||
|
||||
extern struct ipl_info ipl_info;
|
||||
extern void setup_ipl(void);
|
||||
|
||||
/*
|
||||
* DIAG 308 support
|
||||
*/
|
||||
enum diag308_subcode {
|
||||
DIAG308_REL_HSA = 2,
|
||||
DIAG308_IPL = 3,
|
||||
DIAG308_DUMP = 4,
|
||||
DIAG308_SET = 5,
|
||||
DIAG308_STORE = 6,
|
||||
};
|
||||
|
||||
enum diag308_ipl_type {
|
||||
DIAG308_IPL_TYPE_FCP = 0,
|
||||
DIAG308_IPL_TYPE_CCW = 2,
|
||||
};
|
||||
|
||||
enum diag308_opt {
|
||||
DIAG308_IPL_OPT_IPL = 0x10,
|
||||
DIAG308_IPL_OPT_DUMP = 0x20,
|
||||
};
|
||||
|
||||
enum diag308_flags {
|
||||
DIAG308_FLAGS_LP_VALID = 0x80,
|
||||
};
|
||||
|
||||
enum diag308_vm_flags {
|
||||
DIAG308_VM_FLAGS_NSS_VALID = 0x80,
|
||||
DIAG308_VM_FLAGS_VP_VALID = 0x40,
|
||||
};
|
||||
|
||||
enum diag308_rc {
|
||||
DIAG308_RC_OK = 0x0001,
|
||||
DIAG308_RC_NOCONFIG = 0x0102,
|
||||
};
|
||||
|
||||
extern int diag308(unsigned long subcode, void *addr);
|
||||
extern void diag308_reset(void);
|
||||
extern void store_status(void);
|
||||
extern void lgr_info_log(void);
|
||||
|
||||
#endif /* _ASM_S390_IPL_H */
|
||||
110
arch/s390/include/asm/irq.h
Normal file
110
arch/s390/include/asm/irq.h
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
#ifndef _ASM_IRQ_H
|
||||
#define _ASM_IRQ_H
|
||||
|
||||
#define EXT_INTERRUPT 1
|
||||
#define IO_INTERRUPT 2
|
||||
#define THIN_INTERRUPT 3
|
||||
|
||||
#define NR_IRQS_BASE 4
|
||||
|
||||
#ifdef CONFIG_PCI_NR_MSI
|
||||
# define NR_IRQS (NR_IRQS_BASE + CONFIG_PCI_NR_MSI)
|
||||
#else
|
||||
# define NR_IRQS NR_IRQS_BASE
|
||||
#endif
|
||||
|
||||
/* This number is used when no interrupt has been assigned */
|
||||
#define NO_IRQ 0
|
||||
|
||||
/* External interruption codes */
|
||||
#define EXT_IRQ_INTERRUPT_KEY 0x0040
|
||||
#define EXT_IRQ_CLK_COMP 0x1004
|
||||
#define EXT_IRQ_CPU_TIMER 0x1005
|
||||
#define EXT_IRQ_WARNING_TRACK 0x1007
|
||||
#define EXT_IRQ_MALFUNC_ALERT 0x1200
|
||||
#define EXT_IRQ_EMERGENCY_SIG 0x1201
|
||||
#define EXT_IRQ_EXTERNAL_CALL 0x1202
|
||||
#define EXT_IRQ_TIMING_ALERT 0x1406
|
||||
#define EXT_IRQ_MEASURE_ALERT 0x1407
|
||||
#define EXT_IRQ_SERVICE_SIG 0x2401
|
||||
#define EXT_IRQ_CP_SERVICE 0x2603
|
||||
#define EXT_IRQ_IUCV 0x4000
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/hardirq.h>
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/cache.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
enum interruption_class {
|
||||
IRQEXT_CLK,
|
||||
IRQEXT_EXC,
|
||||
IRQEXT_EMS,
|
||||
IRQEXT_TMR,
|
||||
IRQEXT_TLA,
|
||||
IRQEXT_PFL,
|
||||
IRQEXT_DSD,
|
||||
IRQEXT_VRT,
|
||||
IRQEXT_SCP,
|
||||
IRQEXT_IUC,
|
||||
IRQEXT_CMS,
|
||||
IRQEXT_CMC,
|
||||
IRQEXT_CMR,
|
||||
IRQEXT_FTP,
|
||||
IRQIO_CIO,
|
||||
IRQIO_QAI,
|
||||
IRQIO_DAS,
|
||||
IRQIO_C15,
|
||||
IRQIO_C70,
|
||||
IRQIO_TAP,
|
||||
IRQIO_VMR,
|
||||
IRQIO_LCS,
|
||||
IRQIO_CLW,
|
||||
IRQIO_CTC,
|
||||
IRQIO_APB,
|
||||
IRQIO_ADM,
|
||||
IRQIO_CSC,
|
||||
IRQIO_PCI,
|
||||
IRQIO_MSI,
|
||||
IRQIO_VIR,
|
||||
IRQIO_VAI,
|
||||
NMI_NMI,
|
||||
CPU_RST,
|
||||
NR_ARCH_IRQS
|
||||
};
|
||||
|
||||
struct irq_stat {
|
||||
unsigned int irqs[NR_ARCH_IRQS];
|
||||
};
|
||||
|
||||
DECLARE_PER_CPU_SHARED_ALIGNED(struct irq_stat, irq_stat);
|
||||
|
||||
static __always_inline void inc_irq_stat(enum interruption_class irq)
|
||||
{
|
||||
__this_cpu_inc(irq_stat.irqs[irq]);
|
||||
}
|
||||
|
||||
struct ext_code {
|
||||
unsigned short subcode;
|
||||
unsigned short code;
|
||||
};
|
||||
|
||||
typedef void (*ext_int_handler_t)(struct ext_code, unsigned int, unsigned long);
|
||||
|
||||
int register_external_irq(u16 code, ext_int_handler_t handler);
|
||||
int unregister_external_irq(u16 code, ext_int_handler_t handler);
|
||||
|
||||
enum irq_subclass {
|
||||
IRQ_SUBCLASS_MEASUREMENT_ALERT = 5,
|
||||
IRQ_SUBCLASS_SERVICE_SIGNAL = 9,
|
||||
};
|
||||
|
||||
void irq_subclass_register(enum irq_subclass subclass);
|
||||
void irq_subclass_unregister(enum irq_subclass subclass);
|
||||
|
||||
#define irq_canonicalize(irq) (irq)
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* _ASM_IRQ_H */
|
||||
1
arch/s390/include/asm/irq_regs.h
Normal file
1
arch/s390/include/asm/irq_regs.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
#include <asm-generic/irq_regs.h>
|
||||
72
arch/s390/include/asm/irqflags.h
Normal file
72
arch/s390/include/asm/irqflags.h
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright IBM Corp. 2006, 2010
|
||||
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
|
||||
*/
|
||||
|
||||
#ifndef __ASM_IRQFLAGS_H
|
||||
#define __ASM_IRQFLAGS_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/* store then OR system mask. */
|
||||
#define __arch_local_irq_stosm(__or) \
|
||||
({ \
|
||||
unsigned long __mask; \
|
||||
asm volatile( \
|
||||
" stosm %0,%1" \
|
||||
: "=Q" (__mask) : "i" (__or) : "memory"); \
|
||||
__mask; \
|
||||
})
|
||||
|
||||
/* store then AND system mask. */
|
||||
#define __arch_local_irq_stnsm(__and) \
|
||||
({ \
|
||||
unsigned long __mask; \
|
||||
asm volatile( \
|
||||
" stnsm %0,%1" \
|
||||
: "=Q" (__mask) : "i" (__and) : "memory"); \
|
||||
__mask; \
|
||||
})
|
||||
|
||||
/* set system mask. */
|
||||
static inline notrace void __arch_local_irq_ssm(unsigned long flags)
|
||||
{
|
||||
asm volatile("ssm %0" : : "Q" (flags) : "memory");
|
||||
}
|
||||
|
||||
static inline notrace unsigned long arch_local_save_flags(void)
|
||||
{
|
||||
return __arch_local_irq_stosm(0x00);
|
||||
}
|
||||
|
||||
static inline notrace unsigned long arch_local_irq_save(void)
|
||||
{
|
||||
return __arch_local_irq_stnsm(0xfc);
|
||||
}
|
||||
|
||||
static inline notrace void arch_local_irq_disable(void)
|
||||
{
|
||||
arch_local_irq_save();
|
||||
}
|
||||
|
||||
static inline notrace void arch_local_irq_enable(void)
|
||||
{
|
||||
__arch_local_irq_stosm(0x03);
|
||||
}
|
||||
|
||||
static inline notrace void arch_local_irq_restore(unsigned long flags)
|
||||
{
|
||||
__arch_local_irq_ssm(flags);
|
||||
}
|
||||
|
||||
static inline notrace bool arch_irqs_disabled_flags(unsigned long flags)
|
||||
{
|
||||
return !(flags & (3UL << (BITS_PER_LONG - 8)));
|
||||
}
|
||||
|
||||
static inline notrace bool arch_irqs_disabled(void)
|
||||
{
|
||||
return arch_irqs_disabled_flags(arch_local_save_flags());
|
||||
}
|
||||
|
||||
#endif /* __ASM_IRQFLAGS_H */
|
||||
28
arch/s390/include/asm/isc.h
Normal file
28
arch/s390/include/asm/isc.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef _ASM_S390_ISC_H
|
||||
#define _ASM_S390_ISC_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/*
|
||||
* I/O interruption subclasses used by drivers.
|
||||
* Please add all used iscs here so that it is possible to distribute
|
||||
* isc usage between drivers.
|
||||
* Reminder: 0 is highest priority, 7 lowest.
|
||||
*/
|
||||
#define MAX_ISC 7
|
||||
|
||||
/* Regular I/O interrupts. */
|
||||
#define IO_SCH_ISC 3 /* regular I/O subchannels */
|
||||
#define CONSOLE_ISC 1 /* console I/O subchannel */
|
||||
#define EADM_SCH_ISC 4 /* EADM subchannels */
|
||||
#define CHSC_SCH_ISC 7 /* CHSC subchannels */
|
||||
/* Adapter interrupts. */
|
||||
#define QDIO_AIRQ_ISC IO_SCH_ISC /* I/O subchannel in qdio mode */
|
||||
#define PCI_ISC 2 /* PCI I/O subchannels */
|
||||
#define AP_ISC 6 /* adjunct processor (crypto) devices */
|
||||
|
||||
/* Functions for registration of I/O interruption subclasses */
|
||||
void isc_register(unsigned int isc);
|
||||
void isc_unregister(unsigned int isc);
|
||||
|
||||
#endif /* _ASM_S390_ISC_H */
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue