From mboxrd@z Thu Jan 1 00:00:00 1970 From: Carsten Otte Subject: [patch 03/12] [PATCH] kvm-s390-ucontrol: export page faults to user Date: Thu, 01 Dec 2011 13:57:35 +0100 Message-ID: <20111201130409.114036900@de.ibm.com> References: <20111201125732.085553111@de.ibm.com> Cc: Christian Borntraeger , Heiko Carstens , Martin Schwidefsky , Cornelia Huck , KVM , Joachim von Buttlar , Jens Freimann , Constantin Werner To: Avi Kivity , Marcelo Tossati Return-path: Received: from e06smtp15.uk.ibm.com ([195.75.94.111]:51667 "EHLO e06smtp15.uk.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754036Ab1LANE1 (ORCPT ); Thu, 1 Dec 2011 08:04:27 -0500 Received: from /spool/local by e06smtp15.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 1 Dec 2011 13:04:26 -0000 Received: from d06av02.portsmouth.uk.ibm.com (d06av02.portsmouth.uk.ibm.com [9.149.37.228]) by d06nrmr1806.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id pB1D4As42207830 for ; Thu, 1 Dec 2011 13:04:10 GMT Received: from d06av02.portsmouth.uk.ibm.com (loopback [127.0.0.1]) by d06av02.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id pB1D49nC023077 for ; Thu, 1 Dec 2011 06:04:09 -0700 Content-Disposition: inline; filename=page-fault-exit.patch Sender: kvm-owner@vger.kernel.org List-ID: This patch introduces a new exit reason in the kvm_run structure named KVM_EXIT_UCONTROL. This exit indicates, that a virtual cpu has regognized a fault on the host page table. The idea is that userspace can handle this fault by mapping memory at the fault location into the cpu's address space and then continue to run the virtual cpu. Signed-off-by: Carsten Otte --- Index: linux-2.5-cecsim/arch/s390/kvm/kvm-s390.c =================================================================== --- linux-2.5-cecsim.orig/arch/s390/kvm/kvm-s390.c +++ linux-2.5-cecsim/arch/s390/kvm/kvm-s390.c @@ -509,8 +509,10 @@ int kvm_arch_vcpu_ioctl_set_mpstate(stru 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()) @@ -527,9 +529,15 @@ static void __vcpu_run(struct kvm_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); @@ -538,6 +546,7 @@ static void __vcpu_run(struct kvm_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) @@ -558,6 +567,7 @@ rerun_vcpu: case KVM_EXIT_UNKNOWN: case KVM_EXIT_INTR: case KVM_EXIT_S390_RESET: + case KVM_EXIT_UCONTROL: break; default: BUG(); @@ -569,7 +579,9 @@ rerun_vcpu: might_fault(); do { - __vcpu_run(vcpu); + rc = __vcpu_run(vcpu); + if (rc) + break; rc = kvm_handle_sie_intercept(vcpu); } while (!signal_pending(current) && !rc); @@ -581,6 +593,16 @@ rerun_vcpu: rc = -EINTR; } +#ifdef CONFIG_KVM_UCONTROL + if (rc == SIE_INTERCEPT_UCONTROL) { + kvm_run->exit_reason = KVM_EXIT_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; Index: linux-2.5-cecsim/arch/s390/kvm/kvm-s390.h =================================================================== --- linux-2.5-cecsim.orig/arch/s390/kvm/kvm-s390.h +++ linux-2.5-cecsim/arch/s390/kvm/kvm-s390.h @@ -26,6 +26,7 @@ typedef int (*intercept_handler_t)(struc /* 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...)\ Index: linux-2.5-cecsim/include/linux/kvm.h =================================================================== --- linux-2.5-cecsim.orig/include/linux/kvm.h +++ linux-2.5-cecsim/include/linux/kvm.h @@ -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_UCONTROL 20 /* For KVM_EXIT_INTERNAL_ERROR */ #define KVM_INTERNAL_ERROR_EMULATION 1 @@ -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_UCONTROL */ + struct { + __u64 trans_exc_code; + __u32 pgm_code; + } s390_ucontrol; /* KVM_EXIT_DCR */ struct { __u32 dcrn;