diff options
author | David Hildenbrand <dahi@linux.vnet.ibm.com> | 2016-02-19 04:11:24 -0500 |
---|---|---|
committer | Christian Borntraeger <borntraeger@de.ibm.com> | 2016-06-21 03:43:34 -0400 |
commit | 3573602b20b061030c34b04f206b781857f155df (patch) | |
tree | 8a5a1fc849a89f6f08c7448578f195594eef3108 /arch/s390/kvm | |
parent | 06d68a6c85d95515533663ff002d06753fd772aa (diff) |
KVM: s390: vsie: support setting the ibc
As soon as we forward an ibc to guest 2 (indicated via
kvm->arch.model.ibc), he can also use it for guest 3. Let's properly round
the ibc up/down, so we avoid any potential validity icpts from the
underlying SIE, if it doesn't simply round the values.
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'arch/s390/kvm')
-rw-r--r-- | arch/s390/kvm/vsie.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/arch/s390/kvm/vsie.c b/arch/s390/kvm/vsie.c index 2839efcfc5ff..1165baf78535 100644 --- a/arch/s390/kvm/vsie.c +++ b/arch/s390/kvm/vsie.c | |||
@@ -102,6 +102,26 @@ static int prepare_cpuflags(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page) | |||
102 | return 0; | 102 | return 0; |
103 | } | 103 | } |
104 | 104 | ||
105 | /* shadow (round up/down) the ibc to avoid validity icpt */ | ||
106 | static void prepare_ibc(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page) | ||
107 | { | ||
108 | struct kvm_s390_sie_block *scb_s = &vsie_page->scb_s; | ||
109 | struct kvm_s390_sie_block *scb_o = vsie_page->scb_o; | ||
110 | __u64 min_ibc = (sclp.ibc >> 16) & 0x0fffU; | ||
111 | |||
112 | scb_s->ibc = 0; | ||
113 | /* ibc installed in g2 and requested for g3 */ | ||
114 | if (vcpu->kvm->arch.model.ibc && (scb_o->ibc & 0x0fffU)) { | ||
115 | scb_s->ibc = scb_o->ibc & 0x0fffU; | ||
116 | /* takte care of the minimum ibc level of the machine */ | ||
117 | if (scb_s->ibc < min_ibc) | ||
118 | scb_s->ibc = min_ibc; | ||
119 | /* take care of the maximum ibc level set for the guest */ | ||
120 | if (scb_s->ibc > vcpu->kvm->arch.model.ibc) | ||
121 | scb_s->ibc = vcpu->kvm->arch.model.ibc; | ||
122 | } | ||
123 | } | ||
124 | |||
105 | /* unshadow the scb, copying parameters back to the real scb */ | 125 | /* unshadow the scb, copying parameters back to the real scb */ |
106 | static void unshadow_scb(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page) | 126 | static void unshadow_scb(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page) |
107 | { | 127 | { |
@@ -214,6 +234,7 @@ static int shadow_scb(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page) | |||
214 | /* MVPG and Protection Exception Interpretation are always available */ | 234 | /* MVPG and Protection Exception Interpretation are always available */ |
215 | scb_s->eca |= scb_o->eca & 0x01002000U; | 235 | scb_s->eca |= scb_o->eca & 0x01002000U; |
216 | 236 | ||
237 | prepare_ibc(vcpu, vsie_page); | ||
217 | out: | 238 | out: |
218 | if (rc) | 239 | if (rc) |
219 | unshadow_scb(vcpu, vsie_page); | 240 | unshadow_scb(vcpu, vsie_page); |