]> git.karo-electronics.de Git - linux-beck.git/commitdiff
KVM: s390: vsie: support setting the ibc
authorDavid Hildenbrand <dahi@linux.vnet.ibm.com>
Fri, 19 Feb 2016 09:11:24 +0000 (10:11 +0100)
committerChristian Borntraeger <borntraeger@de.ibm.com>
Tue, 21 Jun 2016 07:43:34 +0000 (09:43 +0200)
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>
arch/s390/kvm/vsie.c

index 2839efcfc5ffec2e0c93d8b63e432ccf976cf9cd..1165baf78535322e93a10e848da4b0a2e21bf456 100644 (file)
@@ -102,6 +102,26 @@ static int prepare_cpuflags(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
        return 0;
 }
 
+/* shadow (round up/down) the ibc to avoid validity icpt */
+static void prepare_ibc(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
+{
+       struct kvm_s390_sie_block *scb_s = &vsie_page->scb_s;
+       struct kvm_s390_sie_block *scb_o = vsie_page->scb_o;
+       __u64 min_ibc = (sclp.ibc >> 16) & 0x0fffU;
+
+       scb_s->ibc = 0;
+       /* ibc installed in g2 and requested for g3 */
+       if (vcpu->kvm->arch.model.ibc && (scb_o->ibc & 0x0fffU)) {
+               scb_s->ibc = scb_o->ibc & 0x0fffU;
+               /* takte care of the minimum ibc level of the machine */
+               if (scb_s->ibc < min_ibc)
+                       scb_s->ibc = min_ibc;
+               /* take care of the maximum ibc level set for the guest */
+               if (scb_s->ibc > vcpu->kvm->arch.model.ibc)
+                       scb_s->ibc = vcpu->kvm->arch.model.ibc;
+       }
+}
+
 /* unshadow the scb, copying parameters back to the real scb */
 static void unshadow_scb(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
 {
@@ -214,6 +234,7 @@ static int shadow_scb(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
        /* MVPG and Protection Exception Interpretation are always available */
        scb_s->eca |= scb_o->eca & 0x01002000U;
 
+       prepare_ibc(vcpu, vsie_page);
 out:
        if (rc)
                unshadow_scb(vcpu, vsie_page);