Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 297050
b: refs/heads/master
c: e168bf8
h: refs/heads/master
v: v3
  • Loading branch information
Carsten Otte authored and Avi Kivity committed Mar 5, 2012
1 parent 29ecf6a commit e461413
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 6 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 27e0393f15fc8bc855c6a888387ff5ffd2181089
refs/heads/master: e168bf8de33e16a909df2401af1f7d419c5780de
14 changes: 14 additions & 0 deletions trunk/Documentation/virtual/kvm/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1694,6 +1694,20 @@ s390 specific.

s390 specific.

/* KVM_EXIT_S390_UCONTROL */
struct {
__u64 trans_exc_code;
__u32 pgm_code;
} s390_ucontrol;

s390 specific. A page fault has occurred for a user controlled virtual
machine (KVM_VM_S390_UNCONTROL) on it's host page table that cannot be
resolved by the kernel.
The program code and the translation exception code that were placed
in the cpu's lowcore are presented here as defined by the z Architecture
Principles of Operation Book in the Chapter for Dynamic Address Translation
(DAT)

/* KVM_EXIT_DCR */
struct {
__u32 dcrn;
Expand Down
32 changes: 27 additions & 5 deletions trunk/arch/s390/kvm/kvm-s390.c
Original file line number Diff line number Diff line change
Expand Up @@ -493,8 +493,10 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
return -EINVAL; /* not implemented yet */
}

static void __vcpu_run(struct kvm_vcpu *vcpu)
static int __vcpu_run(struct kvm_vcpu *vcpu)
{
int rc;

memcpy(&vcpu->arch.sie_block->gg14, &vcpu->arch.guest_gprs[14], 16);

if (need_resched())
Expand All @@ -511,9 +513,15 @@ static void __vcpu_run(struct kvm_vcpu *vcpu)
local_irq_enable();
VCPU_EVENT(vcpu, 6, "entering sie flags %x",
atomic_read(&vcpu->arch.sie_block->cpuflags));
if (sie64a(vcpu->arch.sie_block, vcpu->arch.guest_gprs)) {
VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
rc = sie64a(vcpu->arch.sie_block, vcpu->arch.guest_gprs);
if (rc) {
if (kvm_is_ucontrol(vcpu->kvm)) {
rc = SIE_INTERCEPT_UCONTROL;
} else {
VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
rc = 0;
}
}
VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
vcpu->arch.sie_block->icptcode);
Expand All @@ -522,6 +530,7 @@ static void __vcpu_run(struct kvm_vcpu *vcpu)
local_irq_enable();

memcpy(&vcpu->arch.guest_gprs[14], &vcpu->arch.sie_block->gg14, 16);
return rc;
}

int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
Expand All @@ -542,6 +551,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
case KVM_EXIT_UNKNOWN:
case KVM_EXIT_INTR:
case KVM_EXIT_S390_RESET:
case KVM_EXIT_S390_UCONTROL:
break;
default:
BUG();
Expand All @@ -553,7 +563,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
might_fault();

do {
__vcpu_run(vcpu);
rc = __vcpu_run(vcpu);
if (rc)
break;
rc = kvm_handle_sie_intercept(vcpu);
} while (!signal_pending(current) && !rc);

Expand All @@ -565,6 +577,16 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
rc = -EINTR;
}

#ifdef CONFIG_KVM_S390_UCONTROL
if (rc == SIE_INTERCEPT_UCONTROL) {
kvm_run->exit_reason = KVM_EXIT_S390_UCONTROL;
kvm_run->s390_ucontrol.trans_exc_code =
current->thread.gmap_addr;
kvm_run->s390_ucontrol.pgm_code = 0x10;
rc = 0;
}
#endif

if (rc == -EOPNOTSUPP) {
/* intercept cannot be handled in-kernel, prepare kvm-run */
kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/s390/kvm/kvm-s390.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ typedef int (*intercept_handler_t)(struct kvm_vcpu *vcpu);

/* negativ values are error codes, positive values for internal conditions */
#define SIE_INTERCEPT_RERUNVCPU (1<<0)
#define SIE_INTERCEPT_UCONTROL (1<<1)
int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu);

#define VM_EVENT(d_kvm, d_loglevel, d_string, d_args...)\
Expand Down
6 changes: 6 additions & 0 deletions trunk/include/linux/kvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ struct kvm_pit_config {
#define KVM_EXIT_INTERNAL_ERROR 17
#define KVM_EXIT_OSI 18
#define KVM_EXIT_PAPR_HCALL 19
#define KVM_EXIT_S390_UCONTROL 20

/* For KVM_EXIT_INTERNAL_ERROR */
#define KVM_INTERNAL_ERROR_EMULATION 1
Expand Down Expand Up @@ -249,6 +250,11 @@ struct kvm_run {
#define KVM_S390_RESET_CPU_INIT 8
#define KVM_S390_RESET_IPL 16
__u64 s390_reset_flags;
/* KVM_EXIT_S390_UCONTROL */
struct {
__u64 trans_exc_code;
__u32 pgm_code;
} s390_ucontrol;
/* KVM_EXIT_DCR */
struct {
__u32 dcrn;
Expand Down

0 comments on commit e461413

Please sign in to comment.