You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6: (48 commits) [S390] topology: export cpu topology via proc/sysinfo [S390] topology: move topology sysinfo code [S390] topology: clean up facility detection [S390] cleanup facility list handling [S390] enable ARCH_DMA_ADDR_T_64BIT with 64BIT [S390] dasd: ignore unsolicited interrupts for DIAG [S390] kvm: Enable z196 instruction facilities [S390] dasd: fix unsolicited interrupt recognition [S390] dasd: fix use after free in dbf [S390] kvm: Fix badness at include/asm/mmu_context.h:83 [S390] cio: fix I/O cancel function [S390] topology: change default [S390] smp: use correct cpu address in print_cpu_info() [S390] remove ieee_instruction_pointer from thread_struct [S390] cleanup system call parameter setup [S390] correct alignment of cpuid structure [S390] cleanup lowcore access from external interrupts [S390] cleanup lowcore access from program checks [S390] pgtable: move pte_mkhuge() from hugetlb.h to pgtable.h [S390] fix SIGBUS handling ...
This commit is contained in:
@@ -2438,7 +2438,7 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||
topology informations if the hardware supports these.
|
||||
The scheduler will make use of these informations and
|
||||
e.g. base its process migration decisions on it.
|
||||
Default is off.
|
||||
Default is on.
|
||||
|
||||
tp720= [HW,PS2]
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
obj-y += kernel/
|
||||
obj-y += mm/
|
||||
obj-y += crypto/
|
||||
obj-y += appldata/
|
||||
obj-y += hypfs/
|
||||
obj-y += kvm/
|
||||
@@ -60,6 +60,9 @@ config NO_IOMEM
|
||||
config NO_DMA
|
||||
def_bool y
|
||||
|
||||
config ARCH_DMA_ADDR_T_64BIT
|
||||
def_bool 64BIT
|
||||
|
||||
config GENERIC_LOCKBREAK
|
||||
bool
|
||||
default y
|
||||
@@ -101,6 +104,7 @@ config S390
|
||||
select HAVE_KERNEL_BZIP2
|
||||
select HAVE_KERNEL_LZMA
|
||||
select HAVE_KERNEL_LZO
|
||||
select HAVE_GET_USER_PAGES_FAST
|
||||
select ARCH_INLINE_SPIN_TRYLOCK
|
||||
select ARCH_INLINE_SPIN_TRYLOCK_BH
|
||||
select ARCH_INLINE_SPIN_LOCK
|
||||
@@ -286,6 +290,14 @@ config MARCH_Z10
|
||||
machines such as the z990, z890, z900, z800, z9-109, z9-ec
|
||||
and z9-bc.
|
||||
|
||||
config MARCH_Z196
|
||||
bool "IBM zEnterprise 196"
|
||||
help
|
||||
Select this to enable optimizations for IBM zEnterprise 196.
|
||||
The kernel will be slightly faster but will not work on older
|
||||
machines such as the z990, z890, z900, z800, z9-109, z9-ec,
|
||||
z9-bc, z10-ec and z10-bc.
|
||||
|
||||
endchoice
|
||||
|
||||
config PACK_STACK
|
||||
|
||||
+3
-2
@@ -40,6 +40,7 @@ cflags-$(CONFIG_MARCH_Z900) += $(call cc-option,-march=z900)
|
||||
cflags-$(CONFIG_MARCH_Z990) += $(call cc-option,-march=z990)
|
||||
cflags-$(CONFIG_MARCH_Z9_109) += $(call cc-option,-march=z9-109)
|
||||
cflags-$(CONFIG_MARCH_Z10) += $(call cc-option,-march=z10)
|
||||
cflags-$(CONFIG_MARCH_Z196) += $(call cc-option,-march=z196)
|
||||
|
||||
#KBUILD_IMAGE is necessary for make rpm
|
||||
KBUILD_IMAGE :=arch/s390/boot/image
|
||||
@@ -94,8 +95,8 @@ head-y := arch/s390/kernel/head.o
|
||||
head-y += arch/s390/kernel/$(if $(CONFIG_64BIT),head64.o,head31.o)
|
||||
head-y += arch/s390/kernel/init_task.o
|
||||
|
||||
core-y += arch/s390/mm/ arch/s390/kernel/ arch/s390/crypto/ \
|
||||
arch/s390/appldata/ arch/s390/hypfs/ arch/s390/kvm/
|
||||
# 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/
|
||||
|
||||
@@ -297,7 +297,7 @@ static inline int crypt_s390_func_available(int func)
|
||||
int ret;
|
||||
|
||||
/* check if CPACF facility (bit 17) is available */
|
||||
if (!(stfl() & 1ULL << (31 - 17)))
|
||||
if (!test_facility(17))
|
||||
return 0;
|
||||
|
||||
switch (func & CRYPT_S390_OP_MASK) {
|
||||
|
||||
@@ -91,6 +91,16 @@ struct ccw_device {
|
||||
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.
|
||||
*/
|
||||
@@ -109,6 +119,7 @@ enum uc_todo {
|
||||
* @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
|
||||
@@ -127,6 +138,7 @@ struct ccw_driver {
|
||||
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 *);
|
||||
|
||||
@@ -20,7 +20,7 @@ struct cpuid
|
||||
unsigned int ident : 24;
|
||||
unsigned int machine : 16;
|
||||
unsigned int unused : 16;
|
||||
} __packed;
|
||||
} __attribute__ ((packed, aligned(8)));
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* _ASM_S390_CPU_H */
|
||||
|
||||
@@ -37,32 +37,6 @@ static inline int prepare_hugepage_range(struct file *file,
|
||||
int arch_prepare_hugepage(struct page *page);
|
||||
void arch_release_hugepage(struct page *page);
|
||||
|
||||
static inline pte_t pte_mkhuge(pte_t pte)
|
||||
{
|
||||
/*
|
||||
* PROT_NONE needs to be remapped from the pte type to the ste type.
|
||||
* The HW invalid bit is also different for pte and ste. The pte
|
||||
* invalid bit happens to be the same as the ste _SEGMENT_ENTRY_LARGE
|
||||
* bit, so we don't have to clear it.
|
||||
*/
|
||||
if (pte_val(pte) & _PAGE_INVALID) {
|
||||
if (pte_val(pte) & _PAGE_SWT)
|
||||
pte_val(pte) |= _HPAGE_TYPE_NONE;
|
||||
pte_val(pte) |= _SEGMENT_ENTRY_INV;
|
||||
}
|
||||
/*
|
||||
* Clear SW pte bits SWT and SWX, there are no SW bits in a segment
|
||||
* table entry.
|
||||
*/
|
||||
pte_val(pte) &= ~(_PAGE_SWT | _PAGE_SWX);
|
||||
/*
|
||||
* Also set the change-override bit because we don't need dirty bit
|
||||
* tracking for hugetlbfs pages.
|
||||
*/
|
||||
pte_val(pte) |= (_SEGMENT_ENTRY_LARGE | _SEGMENT_ENTRY_CO);
|
||||
return pte;
|
||||
}
|
||||
|
||||
static inline pte_t huge_pte_wrprotect(pte_t pte)
|
||||
{
|
||||
pte_val(pte) |= _PAGE_RO;
|
||||
|
||||
@@ -150,9 +150,10 @@ struct _lowcore {
|
||||
*/
|
||||
__u32 ipib; /* 0x0e00 */
|
||||
__u32 ipib_checksum; /* 0x0e04 */
|
||||
__u8 pad_0x0e08[0x0f00-0x0e08]; /* 0x0e08 */
|
||||
|
||||
/* Align to the top 1k of prefix area */
|
||||
__u8 pad_0x0e08[0x1000-0x0e08]; /* 0x0e08 */
|
||||
/* Extended facility list */
|
||||
__u64 stfle_fac_list[32]; /* 0x0f00 */
|
||||
} __packed;
|
||||
|
||||
#else /* CONFIG_32BIT */
|
||||
@@ -285,7 +286,11 @@ struct _lowcore {
|
||||
*/
|
||||
__u64 ipib; /* 0x0e00 */
|
||||
__u32 ipib_checksum; /* 0x0e08 */
|
||||
__u8 pad_0x0e0c[0x11b8-0x0e0c]; /* 0x0e0c */
|
||||
__u8 pad_0x0e0c[0x0f00-0x0e0c]; /* 0x0e0c */
|
||||
|
||||
/* Extended facility list */
|
||||
__u64 stfle_fac_list[32]; /* 0x0f00 */
|
||||
__u8 pad_0x1000[0x11b8-0x1000]; /* 0x1000 */
|
||||
|
||||
/* 64 bit extparam used for pfault/diag 250: defined by architecture */
|
||||
__u64 ext_params2; /* 0x11B8 */
|
||||
|
||||
@@ -108,9 +108,13 @@ typedef pte_t *pgtable_t;
|
||||
#define __pgprot(x) ((pgprot_t) { (x) } )
|
||||
|
||||
static inline void
|
||||
page_set_storage_key(unsigned long addr, unsigned int skey)
|
||||
page_set_storage_key(unsigned long addr, unsigned int skey, int mapped)
|
||||
{
|
||||
asm volatile("sske %0,%1" : : "d" (skey), "a" (addr));
|
||||
if (!mapped)
|
||||
asm volatile(".insn rrf,0xb22b0000,%0,%1,8,0"
|
||||
: : "d" (skey), "a" (addr));
|
||||
else
|
||||
asm volatile("sske %0,%1" : : "d" (skey), "a" (addr));
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
|
||||
@@ -21,9 +21,11 @@
|
||||
|
||||
unsigned long *crst_table_alloc(struct mm_struct *, int);
|
||||
void crst_table_free(struct mm_struct *, unsigned long *);
|
||||
void crst_table_free_rcu(struct mm_struct *, unsigned long *);
|
||||
|
||||
unsigned long *page_table_alloc(struct mm_struct *);
|
||||
void page_table_free(struct mm_struct *, unsigned long *);
|
||||
void page_table_free_rcu(struct mm_struct *, unsigned long *);
|
||||
void disable_noexec(struct mm_struct *, struct task_struct *);
|
||||
|
||||
static inline void clear_table(unsigned long *s, unsigned long val, size_t n)
|
||||
@@ -176,4 +178,6 @@ static inline void pmd_populate(struct mm_struct *mm,
|
||||
#define pte_free_kernel(mm, pte) page_table_free(mm, (unsigned long *) pte)
|
||||
#define pte_free(mm, pte) page_table_free(mm, (unsigned long *) pte)
|
||||
|
||||
extern void rcu_table_freelist_finish(void);
|
||||
|
||||
#endif /* _S390_PGALLOC_H */
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
extern pgd_t swapper_pg_dir[] __attribute__ ((aligned (4096)));
|
||||
extern void paging_init(void);
|
||||
extern void vmem_map_init(void);
|
||||
extern void fault_init(void);
|
||||
|
||||
/*
|
||||
* The S390 doesn't have any external MMU info: the kernel page
|
||||
@@ -46,11 +47,27 @@ extern void vmem_map_init(void);
|
||||
#define update_mmu_cache(vma, address, ptep) do { } while (0)
|
||||
|
||||
/*
|
||||
* ZERO_PAGE is a global shared page that is always zero: used
|
||||
* ZERO_PAGE is a global shared page that is always zero; used
|
||||
* for zero-mapped memory areas etc..
|
||||
*/
|
||||
extern char empty_zero_page[PAGE_SIZE];
|
||||
#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
|
||||
|
||||
extern unsigned long empty_zero_page;
|
||||
extern unsigned long zero_page_mask;
|
||||
|
||||
#define ZERO_PAGE(vaddr) \
|
||||
(virt_to_page((void *)(empty_zero_page + \
|
||||
(((unsigned long)(vaddr)) &zero_page_mask))))
|
||||
|
||||
#define is_zero_pfn is_zero_pfn
|
||||
static inline int is_zero_pfn(unsigned long pfn)
|
||||
{
|
||||
extern unsigned long zero_pfn;
|
||||
unsigned long offset_from_zero_pfn = pfn - zero_pfn;
|
||||
return offset_from_zero_pfn <= (zero_page_mask >> PAGE_SHIFT);
|
||||
}
|
||||
|
||||
#define my_zero_pfn(addr) page_to_pfn(ZERO_PAGE(addr))
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
/*
|
||||
@@ -300,6 +317,7 @@ extern unsigned long VMALLOC_START;
|
||||
|
||||
/* Bits in the segment table entry */
|
||||
#define _SEGMENT_ENTRY_ORIGIN 0x7fffffc0UL /* page table origin */
|
||||
#define _SEGMENT_ENTRY_RO 0x200 /* page protection bit */
|
||||
#define _SEGMENT_ENTRY_INV 0x20 /* invalid segment table entry */
|
||||
#define _SEGMENT_ENTRY_COMMON 0x10 /* common segment bit */
|
||||
#define _SEGMENT_ENTRY_PTL 0x0f /* page table length */
|
||||
@@ -572,7 +590,7 @@ static inline void rcp_unlock(pte_t *ptep)
|
||||
}
|
||||
|
||||
/* forward declaration for SetPageUptodate in page-flags.h*/
|
||||
static inline void page_clear_dirty(struct page *page);
|
||||
static inline void page_clear_dirty(struct page *page, int mapped);
|
||||
#include <linux/page-flags.h>
|
||||
|
||||
static inline void ptep_rcp_copy(pte_t *ptep)
|
||||
@@ -754,6 +772,34 @@ static inline pte_t pte_mkspecial(pte_t pte)
|
||||
return pte;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HUGETLB_PAGE
|
||||
static inline pte_t pte_mkhuge(pte_t pte)
|
||||
{
|
||||
/*
|
||||
* PROT_NONE needs to be remapped from the pte type to the ste type.
|
||||
* The HW invalid bit is also different for pte and ste. The pte
|
||||
* invalid bit happens to be the same as the ste _SEGMENT_ENTRY_LARGE
|
||||
* bit, so we don't have to clear it.
|
||||
*/
|
||||
if (pte_val(pte) & _PAGE_INVALID) {
|
||||
if (pte_val(pte) & _PAGE_SWT)
|
||||
pte_val(pte) |= _HPAGE_TYPE_NONE;
|
||||
pte_val(pte) |= _SEGMENT_ENTRY_INV;
|
||||
}
|
||||
/*
|
||||
* Clear SW pte bits SWT and SWX, there are no SW bits in a segment
|
||||
* table entry.
|
||||
*/
|
||||
pte_val(pte) &= ~(_PAGE_SWT | _PAGE_SWX);
|
||||
/*
|
||||
* Also set the change-override bit because we don't need dirty bit
|
||||
* tracking for hugetlbfs pages.
|
||||
*/
|
||||
pte_val(pte) |= (_SEGMENT_ENTRY_LARGE | _SEGMENT_ENTRY_CO);
|
||||
return pte;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PGSTE
|
||||
/*
|
||||
* Get (and clear) the user dirty bit for a PTE.
|
||||
@@ -782,7 +828,7 @@ static inline int kvm_s390_test_and_clear_page_dirty(struct mm_struct *mm,
|
||||
}
|
||||
dirty = test_and_clear_bit_simple(KVM_UD_BIT, pgste);
|
||||
if (skey & _PAGE_CHANGED)
|
||||
page_clear_dirty(page);
|
||||
page_clear_dirty(page, 1);
|
||||
rcp_unlock(ptep);
|
||||
return dirty;
|
||||
}
|
||||
@@ -957,9 +1003,9 @@ static inline int page_test_dirty(struct page *page)
|
||||
}
|
||||
|
||||
#define __HAVE_ARCH_PAGE_CLEAR_DIRTY
|
||||
static inline void page_clear_dirty(struct page *page)
|
||||
static inline void page_clear_dirty(struct page *page, int mapped)
|
||||
{
|
||||
page_set_storage_key(page_to_phys(page), PAGE_DEFAULT_KEY);
|
||||
page_set_storage_key(page_to_phys(page), PAGE_DEFAULT_KEY, mapped);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -82,8 +82,6 @@ struct thread_struct {
|
||||
unsigned long prot_addr; /* address of protection-excep. */
|
||||
unsigned int trap_no;
|
||||
per_struct per_info;
|
||||
/* Used to give failing instruction back to user for ieee exceptions */
|
||||
unsigned long ieee_instruction_pointer;
|
||||
/* pfault_wait is used to block the process on a pfault event */
|
||||
unsigned long pfault_wait;
|
||||
};
|
||||
|
||||
@@ -481,8 +481,7 @@ struct user_regs_struct
|
||||
* watchpoints. This is the way intel does it.
|
||||
*/
|
||||
per_struct per_info;
|
||||
unsigned long ieee_instruction_pointer;
|
||||
/* Used to give failing instruction back to user for ieee exceptions */
|
||||
unsigned long ieee_instruction_pointer; /* obsolete, always 0 */
|
||||
};
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
typedef void (*ext_int_handler_t)(__u16 code);
|
||||
typedef void (*ext_int_handler_t)(unsigned int, unsigned int, unsigned long);
|
||||
|
||||
typedef struct ext_int_info_t {
|
||||
struct ext_int_info_t *next;
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
#include <asm-generic/scatterlist.h>
|
||||
|
||||
#define ARCH_HAS_SG_CHAIN
|
||||
|
||||
@@ -73,6 +73,7 @@ extern unsigned int user_mode;
|
||||
#define MACHINE_FLAG_PFMF (1UL << 11)
|
||||
#define MACHINE_FLAG_LPAR (1UL << 12)
|
||||
#define MACHINE_FLAG_SPP (1UL << 13)
|
||||
#define MACHINE_FLAG_TOPOLOGY (1UL << 14)
|
||||
|
||||
#define MACHINE_IS_VM (S390_lowcore.machine_flags & MACHINE_FLAG_VM)
|
||||
#define MACHINE_IS_KVM (S390_lowcore.machine_flags & MACHINE_FLAG_KVM)
|
||||
@@ -90,6 +91,7 @@ extern unsigned int user_mode;
|
||||
#define MACHINE_HAS_HPAGE (0)
|
||||
#define MACHINE_HAS_PFMF (0)
|
||||
#define MACHINE_HAS_SPP (0)
|
||||
#define MACHINE_HAS_TOPOLOGY (0)
|
||||
#else /* __s390x__ */
|
||||
#define MACHINE_HAS_IEEE (1)
|
||||
#define MACHINE_HAS_CSP (1)
|
||||
@@ -100,6 +102,7 @@ extern unsigned int user_mode;
|
||||
#define MACHINE_HAS_HPAGE (S390_lowcore.machine_flags & MACHINE_FLAG_HPAGE)
|
||||
#define MACHINE_HAS_PFMF (S390_lowcore.machine_flags & MACHINE_FLAG_PFMF)
|
||||
#define MACHINE_HAS_SPP (S390_lowcore.machine_flags & MACHINE_FLAG_SPP)
|
||||
#define MACHINE_HAS_TOPOLOGY (S390_lowcore.machine_flags & MACHINE_FLAG_TOPOLOGY)
|
||||
#endif /* __s390x__ */
|
||||
|
||||
#define ZFCPDUMP_HSA_SIZE (32UL<<20)
|
||||
|
||||
@@ -65,8 +65,6 @@ static inline void syscall_get_arguments(struct task_struct *task,
|
||||
if (test_tsk_thread_flag(task, TIF_31BIT))
|
||||
mask = 0xffffffff;
|
||||
#endif
|
||||
if (i + n == 6)
|
||||
args[--n] = regs->args[0] & mask;
|
||||
while (n-- > 0)
|
||||
if (i + n > 0)
|
||||
args[n] = regs->gprs[2 + i + n] & mask;
|
||||
@@ -80,8 +78,6 @@ static inline void syscall_set_arguments(struct task_struct *task,
|
||||
const unsigned long *args)
|
||||
{
|
||||
BUG_ON(i + n > 6);
|
||||
if (i + n == 6)
|
||||
regs->args[0] = args[--n];
|
||||
while (n-- > 0)
|
||||
if (i + n > 0)
|
||||
regs->gprs[2 + i + n] = args[n];
|
||||
|
||||
@@ -14,8 +14,13 @@
|
||||
#ifndef __ASM_S390_SYSINFO_H
|
||||
#define __ASM_S390_SYSINFO_H
|
||||
|
||||
#include <asm/bitsperlong.h>
|
||||
|
||||
struct sysinfo_1_1_1 {
|
||||
char reserved_0[32];
|
||||
unsigned short :16;
|
||||
unsigned char ccr;
|
||||
unsigned char cai;
|
||||
char reserved_0[28];
|
||||
char manufacturer[16];
|
||||
char type[4];
|
||||
char reserved_1[12];
|
||||
@@ -104,6 +109,39 @@ struct sysinfo_3_2_2 {
|
||||
char reserved_544[3552];
|
||||
};
|
||||
|
||||
#define TOPOLOGY_CPU_BITS 64
|
||||
#define TOPOLOGY_NR_MAG 6
|
||||
|
||||
struct topology_cpu {
|
||||
unsigned char reserved0[4];
|
||||
unsigned char :6;
|
||||
unsigned char pp:2;
|
||||
unsigned char reserved1;
|
||||
unsigned short origin;
|
||||
unsigned long mask[TOPOLOGY_CPU_BITS / BITS_PER_LONG];
|
||||
};
|
||||
|
||||
struct topology_container {
|
||||
unsigned char reserved[7];
|
||||
unsigned char id;
|
||||
};
|
||||
|
||||
union topology_entry {
|
||||
unsigned char nl;
|
||||
struct topology_cpu cpu;
|
||||
struct topology_container container;
|
||||
};
|
||||
|
||||
struct sysinfo_15_1_x {
|
||||
unsigned char reserved0[2];
|
||||
unsigned short length;
|
||||
unsigned char mag[TOPOLOGY_NR_MAG];
|
||||
unsigned char reserved1;
|
||||
unsigned char mnest;
|
||||
unsigned char reserved2[4];
|
||||
union topology_entry tle[0];
|
||||
};
|
||||
|
||||
static inline int stsi(void *sysinfo, int fc, int sel1, int sel2)
|
||||
{
|
||||
register int r0 asm("0") = (fc << 28) | sel1;
|
||||
|
||||
@@ -85,14 +85,16 @@ static inline void restore_access_regs(unsigned int *acrs)
|
||||
asm volatile("lam 0,15,%0" : : "Q" (*acrs));
|
||||
}
|
||||
|
||||
#define switch_to(prev,next,last) do { \
|
||||
if (prev == next) \
|
||||
break; \
|
||||
save_fp_regs(&prev->thread.fp_regs); \
|
||||
restore_fp_regs(&next->thread.fp_regs); \
|
||||
save_access_regs(&prev->thread.acrs[0]); \
|
||||
restore_access_regs(&next->thread.acrs[0]); \
|
||||
prev = __switch_to(prev,next); \
|
||||
#define switch_to(prev,next,last) do { \
|
||||
if (prev->mm) { \
|
||||
save_fp_regs(&prev->thread.fp_regs); \
|
||||
save_access_regs(&prev->thread.acrs[0]); \
|
||||
} \
|
||||
if (next->mm) { \
|
||||
restore_fp_regs(&next->thread.fp_regs); \
|
||||
restore_access_regs(&next->thread.acrs[0]); \
|
||||
} \
|
||||
prev = __switch_to(prev,next); \
|
||||
} while (0)
|
||||
|
||||
extern void account_vtime(struct task_struct *, struct task_struct *);
|
||||
@@ -418,30 +420,21 @@ extern void smp_ctl_clear_bit(int cr, int bit);
|
||||
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
static inline unsigned int stfl(void)
|
||||
{
|
||||
asm volatile(
|
||||
" .insn s,0xb2b10000,0(0)\n" /* stfl */
|
||||
"0:\n"
|
||||
EX_TABLE(0b,0b));
|
||||
return S390_lowcore.stfl_fac_list;
|
||||
}
|
||||
#define MAX_FACILITY_BIT (256*8) /* stfle_fac_list has 256 bytes */
|
||||
|
||||
static inline int __stfle(unsigned long long *list, int doublewords)
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
typedef struct { unsigned long long _[doublewords]; } addrtype;
|
||||
register unsigned long __nr asm("0") = doublewords - 1;
|
||||
unsigned char *ptr;
|
||||
|
||||
asm volatile(".insn s,0xb2b00000,%0" /* stfle */
|
||||
: "=m" (*(addrtype *) list), "+d" (__nr) : : "cc");
|
||||
return __nr + 1;
|
||||
}
|
||||
|
||||
static inline int stfle(unsigned long long *list, int doublewords)
|
||||
{
|
||||
if (!(stfl() & (1UL << 24)))
|
||||
return -EOPNOTSUPP;
|
||||
return __stfle(list, doublewords);
|
||||
if (nr >= MAX_FACILITY_BIT)
|
||||
return 0;
|
||||
ptr = (unsigned char *) &S390_lowcore.stfle_fac_list + (nr >> 3);
|
||||
return (*ptr & (0x80 >> (nr & 7))) != 0;
|
||||
}
|
||||
|
||||
static inline unsigned short stap(void)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user