diff options
| -rw-r--r-- | arch/s390/include/asm/pgtable.h | 2 | ||||
| -rw-r--r-- | arch/s390/kernel/asm-offsets.c | 3 | ||||
| -rw-r--r-- | arch/s390/kernel/entry64.S | 6 | ||||
| -rw-r--r-- | arch/s390/kvm/kvm-s390.c | 4 | ||||
| -rw-r--r-- | arch/s390/mm/pgtable.c | 10 |
5 files changed, 15 insertions, 10 deletions
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 519eb5f187ef..c0cb794bb365 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h | |||
| @@ -658,12 +658,14 @@ static inline void pgste_set_pte(pte_t *ptep, pgste_t pgste) | |||
| 658 | * struct gmap_struct - guest address space | 658 | * struct gmap_struct - guest address space |
| 659 | * @mm: pointer to the parent mm_struct | 659 | * @mm: pointer to the parent mm_struct |
| 660 | * @table: pointer to the page directory | 660 | * @table: pointer to the page directory |
| 661 | * @asce: address space control element for gmap page table | ||
| 661 | * @crst_list: list of all crst tables used in the guest address space | 662 | * @crst_list: list of all crst tables used in the guest address space |
| 662 | */ | 663 | */ |
| 663 | struct gmap { | 664 | struct gmap { |
| 664 | struct list_head list; | 665 | struct list_head list; |
| 665 | struct mm_struct *mm; | 666 | struct mm_struct *mm; |
| 666 | unsigned long *table; | 667 | unsigned long *table; |
| 668 | unsigned long asce; | ||
| 667 | struct list_head crst_list; | 669 | struct list_head crst_list; |
| 668 | }; | 670 | }; |
| 669 | 671 | ||
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index 532fd4322156..2b45591e1582 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | #include <linux/sched.h> | 10 | #include <linux/sched.h> |
| 11 | #include <asm/vdso.h> | 11 | #include <asm/vdso.h> |
| 12 | #include <asm/sigp.h> | 12 | #include <asm/sigp.h> |
| 13 | #include <asm/pgtable.h> | ||
| 13 | 14 | ||
| 14 | /* | 15 | /* |
| 15 | * Make sure that the compiler is new enough. We want a compiler that | 16 | * Make sure that the compiler is new enough. We want a compiler that |
| @@ -126,6 +127,7 @@ int main(void) | |||
| 126 | DEFINE(__LC_KERNEL_STACK, offsetof(struct _lowcore, kernel_stack)); | 127 | DEFINE(__LC_KERNEL_STACK, offsetof(struct _lowcore, kernel_stack)); |
| 127 | DEFINE(__LC_ASYNC_STACK, offsetof(struct _lowcore, async_stack)); | 128 | DEFINE(__LC_ASYNC_STACK, offsetof(struct _lowcore, async_stack)); |
| 128 | DEFINE(__LC_PANIC_STACK, offsetof(struct _lowcore, panic_stack)); | 129 | DEFINE(__LC_PANIC_STACK, offsetof(struct _lowcore, panic_stack)); |
| 130 | DEFINE(__LC_USER_ASCE, offsetof(struct _lowcore, user_asce)); | ||
| 129 | DEFINE(__LC_INT_CLOCK, offsetof(struct _lowcore, int_clock)); | 131 | DEFINE(__LC_INT_CLOCK, offsetof(struct _lowcore, int_clock)); |
| 130 | DEFINE(__LC_MCCK_CLOCK, offsetof(struct _lowcore, mcck_clock)); | 132 | DEFINE(__LC_MCCK_CLOCK, offsetof(struct _lowcore, mcck_clock)); |
| 131 | DEFINE(__LC_MACHINE_FLAGS, offsetof(struct _lowcore, machine_flags)); | 133 | DEFINE(__LC_MACHINE_FLAGS, offsetof(struct _lowcore, machine_flags)); |
| @@ -151,6 +153,7 @@ int main(void) | |||
| 151 | DEFINE(__LC_VDSO_PER_CPU, offsetof(struct _lowcore, vdso_per_cpu_data)); | 153 | DEFINE(__LC_VDSO_PER_CPU, offsetof(struct _lowcore, vdso_per_cpu_data)); |
| 152 | DEFINE(__LC_GMAP, offsetof(struct _lowcore, gmap)); | 154 | DEFINE(__LC_GMAP, offsetof(struct _lowcore, gmap)); |
| 153 | DEFINE(__LC_CMF_HPP, offsetof(struct _lowcore, cmf_hpp)); | 155 | DEFINE(__LC_CMF_HPP, offsetof(struct _lowcore, cmf_hpp)); |
| 156 | DEFINE(__GMAP_ASCE, offsetof(struct gmap, asce)); | ||
| 154 | #endif /* CONFIG_32BIT */ | 157 | #endif /* CONFIG_32BIT */ |
| 155 | return 0; | 158 | return 0; |
| 156 | } | 159 | } |
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 5f729d627cef..713da0760538 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S | |||
| @@ -1076,6 +1076,11 @@ sie_loop: | |||
| 1076 | lg %r14,__LC_THREAD_INFO # pointer thread_info struct | 1076 | lg %r14,__LC_THREAD_INFO # pointer thread_info struct |
| 1077 | tm __TI_flags+7(%r14),_TIF_EXIT_SIE | 1077 | tm __TI_flags+7(%r14),_TIF_EXIT_SIE |
| 1078 | jnz sie_exit | 1078 | jnz sie_exit |
| 1079 | lg %r14,__LC_GMAP # get gmap pointer | ||
| 1080 | ltgr %r14,%r14 | ||
| 1081 | jz sie_gmap | ||
| 1082 | lctlg %c1,%c1,__GMAP_ASCE(%r14) # load primary asce | ||
| 1083 | sie_gmap: | ||
| 1079 | lg %r14,__SF_EMPTY(%r15) # get control block pointer | 1084 | lg %r14,__SF_EMPTY(%r15) # get control block pointer |
| 1080 | SPP __SF_EMPTY(%r15) # set guest id | 1085 | SPP __SF_EMPTY(%r15) # set guest id |
| 1081 | sie 0(%r14) | 1086 | sie 0(%r14) |
| @@ -1083,6 +1088,7 @@ sie_done: | |||
| 1083 | SPP __LC_CMF_HPP # set host id | 1088 | SPP __LC_CMF_HPP # set host id |
| 1084 | lg %r14,__LC_THREAD_INFO # pointer thread_info struct | 1089 | lg %r14,__LC_THREAD_INFO # pointer thread_info struct |
| 1085 | sie_exit: | 1090 | sie_exit: |
| 1091 | lctlg %c1,%c1,__LC_USER_ASCE # load primary asce | ||
| 1086 | ni __TI_flags+6(%r14),255-(_TIF_SIE>>8) | 1092 | ni __TI_flags+6(%r14),255-(_TIF_SIE>>8) |
| 1087 | lg %r14,__SF_EMPTY+8(%r15) # load guest register save area | 1093 | lg %r14,__SF_EMPTY+8(%r15) # load guest register save area |
| 1088 | stmg %r0,%r13,0(%r14) # save guest gprs 0-13 | 1094 | stmg %r0,%r13,0(%r14) # save guest gprs 0-13 |
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index f17296e4fc89..b4eced131e5c 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
| @@ -263,10 +263,12 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | |||
| 263 | vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK; | 263 | vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK; |
| 264 | restore_fp_regs(&vcpu->arch.guest_fpregs); | 264 | restore_fp_regs(&vcpu->arch.guest_fpregs); |
| 265 | restore_access_regs(vcpu->arch.guest_acrs); | 265 | restore_access_regs(vcpu->arch.guest_acrs); |
| 266 | gmap_enable(vcpu->arch.gmap); | ||
| 266 | } | 267 | } |
| 267 | 268 | ||
| 268 | void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) | 269 | void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) |
| 269 | { | 270 | { |
| 271 | gmap_disable(vcpu->arch.gmap); | ||
| 270 | save_fp_regs(&vcpu->arch.guest_fpregs); | 272 | save_fp_regs(&vcpu->arch.guest_fpregs); |
| 271 | save_access_regs(vcpu->arch.guest_acrs); | 273 | save_access_regs(vcpu->arch.guest_acrs); |
| 272 | restore_fp_regs(&vcpu->arch.host_fpregs); | 274 | restore_fp_regs(&vcpu->arch.host_fpregs); |
| @@ -461,7 +463,6 @@ static void __vcpu_run(struct kvm_vcpu *vcpu) | |||
| 461 | local_irq_disable(); | 463 | local_irq_disable(); |
| 462 | kvm_guest_enter(); | 464 | kvm_guest_enter(); |
| 463 | local_irq_enable(); | 465 | local_irq_enable(); |
| 464 | gmap_enable(vcpu->arch.gmap); | ||
| 465 | VCPU_EVENT(vcpu, 6, "entering sie flags %x", | 466 | VCPU_EVENT(vcpu, 6, "entering sie flags %x", |
| 466 | atomic_read(&vcpu->arch.sie_block->cpuflags)); | 467 | atomic_read(&vcpu->arch.sie_block->cpuflags)); |
| 467 | if (sie64a(vcpu->arch.sie_block, vcpu->arch.guest_gprs)) { | 468 | if (sie64a(vcpu->arch.sie_block, vcpu->arch.guest_gprs)) { |
| @@ -470,7 +471,6 @@ static void __vcpu_run(struct kvm_vcpu *vcpu) | |||
| 470 | } | 471 | } |
| 471 | VCPU_EVENT(vcpu, 6, "exit sie icptcode %d", | 472 | VCPU_EVENT(vcpu, 6, "exit sie icptcode %d", |
| 472 | vcpu->arch.sie_block->icptcode); | 473 | vcpu->arch.sie_block->icptcode); |
| 473 | gmap_disable(vcpu->arch.gmap); | ||
| 474 | local_irq_disable(); | 474 | local_irq_disable(); |
| 475 | kvm_guest_exit(); | 475 | kvm_guest_exit(); |
| 476 | local_irq_enable(); | 476 | local_irq_enable(); |
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 4d1f2bce87b3..f69ff3c13496 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c | |||
| @@ -160,6 +160,8 @@ struct gmap *gmap_alloc(struct mm_struct *mm) | |||
| 160 | table = (unsigned long *) page_to_phys(page); | 160 | table = (unsigned long *) page_to_phys(page); |
| 161 | crst_table_init(table, _REGION1_ENTRY_EMPTY); | 161 | crst_table_init(table, _REGION1_ENTRY_EMPTY); |
| 162 | gmap->table = table; | 162 | gmap->table = table; |
| 163 | gmap->asce = _ASCE_TYPE_REGION1 | _ASCE_TABLE_LENGTH | | ||
| 164 | _ASCE_USER_BITS | __pa(table); | ||
| 163 | list_add(&gmap->list, &mm->context.gmap_list); | 165 | list_add(&gmap->list, &mm->context.gmap_list); |
| 164 | return gmap; | 166 | return gmap; |
| 165 | 167 | ||
| @@ -240,10 +242,6 @@ EXPORT_SYMBOL_GPL(gmap_free); | |||
| 240 | */ | 242 | */ |
| 241 | void gmap_enable(struct gmap *gmap) | 243 | void gmap_enable(struct gmap *gmap) |
| 242 | { | 244 | { |
| 243 | /* Load primary space page table origin. */ | ||
| 244 | S390_lowcore.user_asce = _ASCE_TYPE_REGION1 | _ASCE_TABLE_LENGTH | | ||
| 245 | _ASCE_USER_BITS | __pa(gmap->table); | ||
| 246 | asm volatile("lctlg 1,1,%0\n" : : "m" (S390_lowcore.user_asce) ); | ||
| 247 | S390_lowcore.gmap = (unsigned long) gmap; | 245 | S390_lowcore.gmap = (unsigned long) gmap; |
| 248 | } | 246 | } |
| 249 | EXPORT_SYMBOL_GPL(gmap_enable); | 247 | EXPORT_SYMBOL_GPL(gmap_enable); |
| @@ -254,10 +252,6 @@ EXPORT_SYMBOL_GPL(gmap_enable); | |||
| 254 | */ | 252 | */ |
| 255 | void gmap_disable(struct gmap *gmap) | 253 | void gmap_disable(struct gmap *gmap) |
| 256 | { | 254 | { |
| 257 | /* Load primary space page table origin. */ | ||
| 258 | S390_lowcore.user_asce = | ||
| 259 | gmap->mm->context.asce_bits | __pa(gmap->mm->pgd); | ||
| 260 | asm volatile("lctlg 1,1,%0\n" : : "m" (S390_lowcore.user_asce) ); | ||
| 261 | S390_lowcore.gmap = 0UL; | 255 | S390_lowcore.gmap = 0UL; |
| 262 | } | 256 | } |
| 263 | EXPORT_SYMBOL_GPL(gmap_disable); | 257 | EXPORT_SYMBOL_GPL(gmap_disable); |
