diff options
author | Dominik Dingel <dingel@linux.vnet.ibm.com> | 2014-01-14 12:11:14 -0500 |
---|---|---|
committer | Christian Borntraeger <borntraeger@de.ibm.com> | 2014-04-22 03:36:26 -0400 |
commit | 693ffc0802db41911ada95a3e77546f0ed1e7d00 (patch) | |
tree | e9de97bef94041a578e84f30fbbfddfb355b3aea | |
parent | 934bc131efc3e4be6a52f7dd6c4dbf99635e381a (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.h | 3 | ||||
-rw-r--r-- | arch/s390/include/asm/mmu_context.h | 2 | ||||
-rw-r--r-- | arch/s390/kvm/kvm-s390.c | 1 | ||||
-rw-r--r-- | arch/s390/kvm/priv.c | 14 | ||||
-rw-r--r-- | arch/s390/kvm/trace.h | 14 |
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 | ||
150 | static 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 | |||
150 | static int handle_skey(struct kvm_vcpu *vcpu) | 161 | static 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 | ||
33 | TRACE_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 | |||
33 | TRACE_EVENT(kvm_s390_major_guest_pfault, | 47 | TRACE_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), |