KVM: s390: add 'pgm' member to kvm_vcpu_arch and helper function
authorHeiko Carstens <heiko.carstens@de.ibm.com>
Wed, 1 Jan 2014 15:31:49 +0000 (16:31 +0100)
committerChristian Borntraeger <borntraeger@de.ibm.com>
Tue, 22 Apr 2014 11:24:37 +0000 (13:24 +0200)
Add a 'struct kvm_s390_pgm_info pgm' member to kvm_vcpu_arch. This
structure will be used if during instruction emulation in the context
of a vcpu exception data needs to be stored somewhere.

Also add a helper function kvm_s390_inject_prog_cond() which can inject
vcpu's last exception if needed.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
arch/s390/include/asm/kvm_host.h
arch/s390/kvm/kvm-s390.h

index 90905ca9372507804149a111ef6c6725e572ba98..c290d443d2c11fd173122d2743e934796bc727e0 100644 (file)
@@ -286,6 +286,7 @@ struct kvm_vcpu_arch {
        struct kvm_s390_local_interrupt local_int;
        struct hrtimer    ckc_timer;
        struct tasklet_struct tasklet;
+       struct kvm_s390_pgm_info pgm;
        union  {
                struct cpuid    cpu_id;
                u64             stidp_data;
index f3ab9fcad4961ed4d45b1ad77a8a96cbce031b38..11ed0a596b5a49061ad6d3f1cf9bc0554cd2e3e6 100644 (file)
@@ -170,6 +170,39 @@ int kvm_s390_handle_diag(struct kvm_vcpu *vcpu);
 int kvm_s390_inject_prog_irq(struct kvm_vcpu *vcpu,
                             struct kvm_s390_pgm_info *pgm_info);
 
+/**
+ * kvm_s390_inject_prog_cond - conditionally inject a program check
+ * @vcpu: virtual cpu
+ * @rc: original return/error code
+ *
+ * This function is supposed to be used after regular guest access functions
+ * failed, to conditionally inject a program check to a vcpu. The typical
+ * pattern would look like
+ *
+ * rc = write_guest(vcpu, addr, data, len);
+ * if (rc)
+ *     return kvm_s390_inject_prog_cond(vcpu, rc);
+ *
+ * A negative return code from guest access functions implies an internal error
+ * like e.g. out of memory. In these cases no program check should be injected
+ * to the guest.
+ * A positive value implies that an exception happened while accessing a guest's
+ * memory. In this case all data belonging to the corresponding program check
+ * has been stored in vcpu->arch.pgm and can be injected with
+ * kvm_s390_inject_prog_irq().
+ *
+ * Returns: - the original @rc value if @rc was negative (internal error)
+ *         - zero if @rc was already zero
+ *         - zero or error code from injecting if @rc was positive
+ *           (program check injected to @vcpu)
+ */
+static inline int kvm_s390_inject_prog_cond(struct kvm_vcpu *vcpu, int rc)
+{
+       if (rc <= 0)
+               return rc;
+       return kvm_s390_inject_prog_irq(vcpu, &vcpu->arch.pgm);
+}
+
 /* implemented in interrupt.c */
 int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu);
 int psw_extint_disabled(struct kvm_vcpu *vcpu);