linux/arch/s390/kvm/diag.c
<<
>>
Prefs
   1/*
   2 * diag.c - handling diagnose instructions
   3 *
   4 * Copyright IBM Corp. 2008
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License (version 2 only)
   8 * as published by the Free Software Foundation.
   9 *
  10 *    Author(s): Carsten Otte <cotte@de.ibm.com>
  11 *               Christian Borntraeger <borntraeger@de.ibm.com>
  12 */
  13
  14#include <linux/kvm.h>
  15#include <linux/kvm_host.h>
  16#include "kvm-s390.h"
  17
  18static int __diag_time_slice_end(struct kvm_vcpu *vcpu)
  19{
  20        VCPU_EVENT(vcpu, 5, "%s", "diag time slice end");
  21        vcpu->stat.diagnose_44++;
  22        vcpu_put(vcpu);
  23        yield();
  24        vcpu_load(vcpu);
  25        return 0;
  26}
  27
  28static int __diag_ipl_functions(struct kvm_vcpu *vcpu)
  29{
  30        unsigned int reg = vcpu->arch.sie_block->ipa & 0xf;
  31        unsigned long subcode = vcpu->arch.guest_gprs[reg] & 0xffff;
  32
  33        VCPU_EVENT(vcpu, 5, "diag ipl functions, subcode %lx", subcode);
  34        switch (subcode) {
  35        case 3:
  36                vcpu->run->s390_reset_flags = KVM_S390_RESET_CLEAR;
  37                break;
  38        case 4:
  39                vcpu->run->s390_reset_flags = 0;
  40                break;
  41        default:
  42                return -ENOTSUPP;
  43        }
  44
  45        atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
  46        vcpu->run->s390_reset_flags |= KVM_S390_RESET_SUBSYSTEM;
  47        vcpu->run->s390_reset_flags |= KVM_S390_RESET_IPL;
  48        vcpu->run->s390_reset_flags |= KVM_S390_RESET_CPU_INIT;
  49        vcpu->run->exit_reason = KVM_EXIT_S390_RESET;
  50        VCPU_EVENT(vcpu, 3, "requesting userspace resets %lx",
  51          vcpu->run->s390_reset_flags);
  52        return -EREMOTE;
  53}
  54
  55int kvm_s390_handle_diag(struct kvm_vcpu *vcpu)
  56{
  57        int code = (vcpu->arch.sie_block->ipb & 0xfff0000) >> 16;
  58
  59        switch (code) {
  60        case 0x44:
  61                return __diag_time_slice_end(vcpu);
  62        case 0x308:
  63                return __diag_ipl_functions(vcpu);
  64        default:
  65                return -ENOTSUPP;
  66        }
  67}
  68