aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDominik Dingel <dingel@linux.vnet.ibm.com>2014-01-14 12:11:14 -0500
committerChristian Borntraeger <borntraeger@de.ibm.com>2014-04-22 03:36:26 -0400
commit693ffc0802db41911ada95a3e77546f0ed1e7d00 (patch)
treee9de97bef94041a578e84f30fbbfddfb355b3aea
parent934bc131efc3e4be6a52f7dd6c4dbf99635e381a (diff)
KVM: s390: Don't enable skeys by default
The first invocation of storage key operations on a given cpu will be intercepted. On these intercepts we will enable storage keys for the guest and remove the previously added intercepts. Signed-off-by: Dominik Dingel <dingel@linux.vnet.ibm.com> Acked-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
-rw-r--r--arch/s390/include/asm/kvm_host.h3
-rw-r--r--arch/s390/include/asm/mmu_context.h2
-rw-r--r--arch/s390/kvm/kvm-s390.c1
-rw-r--r--arch/s390/kvm/priv.c14
-rw-r--r--arch/s390/kvm/trace.h14
5 files changed, 33 insertions, 1 deletions
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index 154b60089be9..a993b6f3429f 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -89,6 +89,9 @@ struct kvm_s390_sie_block {
89 __u16 lctl; /* 0x0044 */ 89 __u16 lctl; /* 0x0044 */
90 __s16 icpua; /* 0x0046 */ 90 __s16 icpua; /* 0x0046 */
91#define ICTL_LPSW 0x00400000 91#define ICTL_LPSW 0x00400000
92#define ICTL_ISKE 0x00004000
93#define ICTL_SSKE 0x00002000
94#define ICTL_RRBE 0x00001000
92 __u32 ictl; /* 0x0048 */ 95 __u32 ictl; /* 0x0048 */
93 __u32 eca; /* 0x004c */ 96 __u32 eca; /* 0x004c */
94 __u8 icptcode; /* 0x0050 */ 97 __u8 icptcode; /* 0x0050 */
diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h
index 05925ead0748..d42fb1b728d8 100644
--- a/arch/s390/include/asm/mmu_context.h
+++ b/arch/s390/include/asm/mmu_context.h
@@ -23,7 +23,7 @@ static inline int init_new_context(struct task_struct *tsk,
23 mm->context.asce_bits |= _ASCE_TYPE_REGION3; 23 mm->context.asce_bits |= _ASCE_TYPE_REGION3;
24#endif 24#endif
25 mm->context.has_pgste = 0; 25 mm->context.has_pgste = 0;
26 mm->context.use_skey = 1; 26 mm->context.use_skey = 0;
27 mm->context.asce_limit = STACK_TOP_MAX; 27 mm->context.asce_limit = STACK_TOP_MAX;
28 crst_table_init((unsigned long *) mm->pgd, pgd_entry_type(mm)); 28 crst_table_init((unsigned long *) mm->pgd, pgd_entry_type(mm));
29 return 0; 29 return 0;
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index b3ecb8f5b6ce..b767ec97368a 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -465,6 +465,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
465 vcpu->arch.sie_block->ecb2 = 8; 465 vcpu->arch.sie_block->ecb2 = 8;
466 vcpu->arch.sie_block->eca = 0xC1002001U; 466 vcpu->arch.sie_block->eca = 0xC1002001U;
467 vcpu->arch.sie_block->fac = (int) (long) vfacilities; 467 vcpu->arch.sie_block->fac = (int) (long) vfacilities;
468 vcpu->arch.sie_block->ictl |= ICTL_ISKE | ICTL_SSKE | ICTL_RRBE;
468 if (kvm_enabled_cmma()) { 469 if (kvm_enabled_cmma()) {
469 cbrl = alloc_page(GFP_KERNEL | __GFP_ZERO); 470 cbrl = alloc_page(GFP_KERNEL | __GFP_ZERO);
470 if (cbrl) { 471 if (cbrl) {
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index 476e9e218f43..8a63e992936b 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -147,8 +147,21 @@ static int handle_store_cpu_address(struct kvm_vcpu *vcpu)
147 return 0; 147 return 0;
148} 148}
149 149
150static void __skey_check_enable(struct kvm_vcpu *vcpu)
151{
152 if (!(vcpu->arch.sie_block->ictl & (ICTL_ISKE | ICTL_SSKE | ICTL_RRBE)))
153 return;
154
155 s390_enable_skey();
156 trace_kvm_s390_skey_related_inst(vcpu);
157 vcpu->arch.sie_block->ictl &= ~(ICTL_ISKE | ICTL_SSKE | ICTL_RRBE);
158}
159
160
150static int handle_skey(struct kvm_vcpu *vcpu) 161static int handle_skey(struct kvm_vcpu *vcpu)
151{ 162{
163 __skey_check_enable(vcpu);
164
152 vcpu->stat.instruction_storage_key++; 165 vcpu->stat.instruction_storage_key++;
153 166
154 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) 167 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
@@ -618,6 +631,7 @@ static int handle_pfmf(struct kvm_vcpu *vcpu)
618 } 631 }
619 632
620 if (vcpu->run->s.regs.gprs[reg1] & PFMF_SK) { 633 if (vcpu->run->s.regs.gprs[reg1] & PFMF_SK) {
634 __skey_check_enable(vcpu);
621 if (set_guest_storage_key(current->mm, useraddr, 635 if (set_guest_storage_key(current->mm, useraddr,
622 vcpu->run->s.regs.gprs[reg1] & PFMF_KEY, 636 vcpu->run->s.regs.gprs[reg1] & PFMF_KEY,
623 vcpu->run->s.regs.gprs[reg1] & PFMF_NQ)) 637 vcpu->run->s.regs.gprs[reg1] & PFMF_NQ))
diff --git a/arch/s390/kvm/trace.h b/arch/s390/kvm/trace.h
index e8e7213d4cc5..a4bf7d78a0db 100644
--- a/arch/s390/kvm/trace.h
+++ b/arch/s390/kvm/trace.h
@@ -30,6 +30,20 @@
30 TP_printk("%02d[%016lx-%016lx]: " p_str, __entry->id, \ 30 TP_printk("%02d[%016lx-%016lx]: " p_str, __entry->id, \
31 __entry->pswmask, __entry->pswaddr, p_args) 31 __entry->pswmask, __entry->pswaddr, p_args)
32 32
33TRACE_EVENT(kvm_s390_skey_related_inst,
34 TP_PROTO(VCPU_PROTO_COMMON),
35 TP_ARGS(VCPU_ARGS_COMMON),
36
37 TP_STRUCT__entry(
38 VCPU_FIELD_COMMON
39 ),
40
41 TP_fast_assign(
42 VCPU_ASSIGN_COMMON
43 ),
44 VCPU_TP_PRINTK("%s", "first instruction related to skeys on vcpu")
45 );
46
33TRACE_EVENT(kvm_s390_major_guest_pfault, 47TRACE_EVENT(kvm_s390_major_guest_pfault,
34 TP_PROTO(VCPU_PROTO_COMMON), 48 TP_PROTO(VCPU_PROTO_COMMON),
35 TP_ARGS(VCPU_ARGS_COMMON), 49 TP_ARGS(VCPU_ARGS_COMMON),