diff options
Diffstat (limited to 'arch/s390/kvm')
| -rw-r--r-- | arch/s390/kvm/diag.c | 4 | ||||
| -rw-r--r-- | arch/s390/kvm/gaccess.h | 4 | ||||
| -rw-r--r-- | arch/s390/kvm/intercept.c | 4 | ||||
| -rw-r--r-- | arch/s390/kvm/interrupt.c | 2 | ||||
| -rw-r--r-- | arch/s390/kvm/kvm-s390.c | 5 | ||||
| -rw-r--r-- | arch/s390/kvm/kvm-s390.h | 4 | ||||
| -rw-r--r-- | arch/s390/kvm/priv.c | 2 | ||||
| -rw-r--r-- | arch/s390/kvm/sigp.c | 121 | 
8 files changed, 63 insertions, 83 deletions
diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c index b23d9ac77df..c88bb779339 100644 --- a/arch/s390/kvm/diag.c +++ b/arch/s390/kvm/diag.c @@ -1,7 +1,7 @@  /* - * diag.c - handling diagnose instructions + * handling diagnose instructions   * - * Copyright IBM Corp. 2008,2011 + * Copyright IBM Corp. 2008, 2011   *   * This program is free software; you can redistribute it and/or modify   * it under the terms of the GNU General Public License (version 2 only) diff --git a/arch/s390/kvm/gaccess.h b/arch/s390/kvm/gaccess.h index c86f6ae43f7..4703f129e95 100644 --- a/arch/s390/kvm/gaccess.h +++ b/arch/s390/kvm/gaccess.h @@ -1,7 +1,7 @@  /* - * access.h -  access guest memory + * access guest memory   * - * Copyright IBM Corp. 2008,2009 + * Copyright IBM Corp. 2008, 2009   *   * This program is free software; you can redistribute it and/or modify   * it under the terms of the GNU General Public License (version 2 only) diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c index 979cbe55bf5..adae539f12e 100644 --- a/arch/s390/kvm/intercept.c +++ b/arch/s390/kvm/intercept.c @@ -1,7 +1,7 @@  /* - * intercept.c - in-kernel handling for sie intercepts + * in-kernel handling for sie intercepts   * - * Copyright IBM Corp. 2008,2009 + * Copyright IBM Corp. 2008, 2009   *   * This program is free software; you can redistribute it and/or modify   * it under the terms of the GNU General Public License (version 2 only) diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 2d9f9a72bb8..b7bc1aac8ed 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -1,5 +1,5 @@  /* - * interrupt.c - handling kvm guest interrupts + * handling kvm guest interrupts   *   * Copyright IBM Corp. 2008   * diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 664766d0c83..d470ccbfaba 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -1,7 +1,7 @@  /* - * s390host.c --  hosting zSeries kernel virtual machines + * hosting zSeries kernel virtual machines   * - * Copyright IBM Corp. 2008,2009 + * Copyright IBM Corp. 2008, 2009   *   * This program is free software; you can redistribute it and/or modify   * it under the terms of the GNU General Public License (version 2 only) @@ -347,6 +347,7 @@ static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)  	vcpu->arch.guest_fpregs.fpc = 0;  	asm volatile("lfpc %0" : : "Q" (vcpu->arch.guest_fpregs.fpc));  	vcpu->arch.sie_block->gbea = 1; +	atomic_set_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags);  }  int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h index 2294377975e..d75bc5e92c5 100644 --- a/arch/s390/kvm/kvm-s390.h +++ b/arch/s390/kvm/kvm-s390.h @@ -1,7 +1,7 @@  /* - * kvm_s390.h -  definition for kvm on s390 + * definition for kvm on s390   * - * Copyright IBM Corp. 2008,2009 + * Copyright IBM Corp. 2008, 2009   *   * This program is free software; you can redistribute it and/or modify   * it under the terms of the GNU General Public License (version 2 only) diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index 68a6b2ed16b..60da903d6f3 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c @@ -1,5 +1,5 @@  /* - * priv.c - handling privileged instructions + * handling privileged instructions   *   * Copyright IBM Corp. 2008   * diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index 0ad4cf23839..56f80e1f98f 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c @@ -1,7 +1,7 @@  /* - * sigp.c - handlinge interprocessor communication + * handling interprocessor communication   * - * Copyright IBM Corp. 2008,2009 + * Copyright IBM Corp. 2008, 2009   *   * This program is free software; you can redistribute it and/or modify   * it under the terms of the GNU General Public License (version 2 only) @@ -15,38 +15,10 @@  #include <linux/kvm.h>  #include <linux/kvm_host.h>  #include <linux/slab.h> +#include <asm/sigp.h>  #include "gaccess.h"  #include "kvm-s390.h" -/* sigp order codes */ -#define SIGP_SENSE             0x01 -#define SIGP_EXTERNAL_CALL     0x02 -#define SIGP_EMERGENCY         0x03 -#define SIGP_START             0x04 -#define SIGP_STOP              0x05 -#define SIGP_RESTART           0x06 -#define SIGP_STOP_STORE_STATUS 0x09 -#define SIGP_INITIAL_CPU_RESET 0x0b -#define SIGP_CPU_RESET         0x0c -#define SIGP_SET_PREFIX        0x0d -#define SIGP_STORE_STATUS_ADDR 0x0e -#define SIGP_SET_ARCH          0x12 -#define SIGP_SENSE_RUNNING     0x15 - -/* cpu status bits */ -#define SIGP_STAT_EQUIPMENT_CHECK   0x80000000UL -#define SIGP_STAT_NOT_RUNNING	    0x00000400UL -#define SIGP_STAT_INCORRECT_STATE   0x00000200UL -#define SIGP_STAT_INVALID_PARAMETER 0x00000100UL -#define SIGP_STAT_EXT_CALL_PENDING  0x00000080UL -#define SIGP_STAT_STOPPED           0x00000040UL -#define SIGP_STAT_OPERATOR_INTERV   0x00000020UL -#define SIGP_STAT_CHECK_STOP        0x00000010UL -#define SIGP_STAT_INOPERATIVE       0x00000004UL -#define SIGP_STAT_INVALID_ORDER     0x00000002UL -#define SIGP_STAT_RECEIVER_CHECK    0x00000001UL - -  static int __sigp_sense(struct kvm_vcpu *vcpu, u16 cpu_addr,  			u64 *reg)  { @@ -54,19 +26,23 @@ static int __sigp_sense(struct kvm_vcpu *vcpu, u16 cpu_addr,  	int rc;  	if (cpu_addr >= KVM_MAX_VCPUS) -		return 3; /* not operational */ +		return SIGP_CC_NOT_OPERATIONAL;  	spin_lock(&fi->lock);  	if (fi->local_int[cpu_addr] == NULL) -		rc = 3; /* not operational */ +		rc = SIGP_CC_NOT_OPERATIONAL;  	else if (!(atomic_read(fi->local_int[cpu_addr]->cpuflags) -		  & CPUSTAT_STOPPED)) { -		*reg &= 0xffffffff00000000UL; -		rc = 1; /* status stored */ -	} else { +		   & (CPUSTAT_ECALL_PEND | CPUSTAT_STOPPED))) +		rc = SIGP_CC_ORDER_CODE_ACCEPTED; +	else {  		*reg &= 0xffffffff00000000UL; -		*reg |= SIGP_STAT_STOPPED; -		rc = 1; /* status stored */ +		if (atomic_read(fi->local_int[cpu_addr]->cpuflags) +		    & CPUSTAT_ECALL_PEND) +			*reg |= SIGP_STATUS_EXT_CALL_PENDING; +		if (atomic_read(fi->local_int[cpu_addr]->cpuflags) +		    & CPUSTAT_STOPPED) +			*reg |= SIGP_STATUS_STOPPED; +		rc = SIGP_CC_STATUS_STORED;  	}  	spin_unlock(&fi->lock); @@ -82,7 +58,7 @@ static int __sigp_emergency(struct kvm_vcpu *vcpu, u16 cpu_addr)  	int rc;  	if (cpu_addr >= KVM_MAX_VCPUS) -		return 3; /* not operational */ +		return SIGP_CC_NOT_OPERATIONAL;  	inti = kzalloc(sizeof(*inti), GFP_KERNEL);  	if (!inti) @@ -94,7 +70,7 @@ static int __sigp_emergency(struct kvm_vcpu *vcpu, u16 cpu_addr)  	spin_lock(&fi->lock);  	li = fi->local_int[cpu_addr];  	if (li == NULL) { -		rc = 3; /* not operational */ +		rc = SIGP_CC_NOT_OPERATIONAL;  		kfree(inti);  		goto unlock;  	} @@ -105,7 +81,7 @@ static int __sigp_emergency(struct kvm_vcpu *vcpu, u16 cpu_addr)  	if (waitqueue_active(&li->wq))  		wake_up_interruptible(&li->wq);  	spin_unlock_bh(&li->lock); -	rc = 0; /* order accepted */ +	rc = SIGP_CC_ORDER_CODE_ACCEPTED;  	VCPU_EVENT(vcpu, 4, "sent sigp emerg to cpu %x", cpu_addr);  unlock:  	spin_unlock(&fi->lock); @@ -120,7 +96,7 @@ static int __sigp_external_call(struct kvm_vcpu *vcpu, u16 cpu_addr)  	int rc;  	if (cpu_addr >= KVM_MAX_VCPUS) -		return 3; /* not operational */ +		return SIGP_CC_NOT_OPERATIONAL;  	inti = kzalloc(sizeof(*inti), GFP_KERNEL);  	if (!inti) @@ -132,7 +108,7 @@ static int __sigp_external_call(struct kvm_vcpu *vcpu, u16 cpu_addr)  	spin_lock(&fi->lock);  	li = fi->local_int[cpu_addr];  	if (li == NULL) { -		rc = 3; /* not operational */ +		rc = SIGP_CC_NOT_OPERATIONAL;  		kfree(inti);  		goto unlock;  	} @@ -143,7 +119,7 @@ static int __sigp_external_call(struct kvm_vcpu *vcpu, u16 cpu_addr)  	if (waitqueue_active(&li->wq))  		wake_up_interruptible(&li->wq);  	spin_unlock_bh(&li->lock); -	rc = 0; /* order accepted */ +	rc = SIGP_CC_ORDER_CODE_ACCEPTED;  	VCPU_EVENT(vcpu, 4, "sent sigp ext call to cpu %x", cpu_addr);  unlock:  	spin_unlock(&fi->lock); @@ -171,7 +147,7 @@ static int __inject_sigp_stop(struct kvm_s390_local_interrupt *li, int action)  out:  	spin_unlock_bh(&li->lock); -	return 0; /* order accepted */ +	return SIGP_CC_ORDER_CODE_ACCEPTED;  }  static int __sigp_stop(struct kvm_vcpu *vcpu, u16 cpu_addr, int action) @@ -181,12 +157,12 @@ static int __sigp_stop(struct kvm_vcpu *vcpu, u16 cpu_addr, int action)  	int rc;  	if (cpu_addr >= KVM_MAX_VCPUS) -		return 3; /* not operational */ +		return SIGP_CC_NOT_OPERATIONAL;  	spin_lock(&fi->lock);  	li = fi->local_int[cpu_addr];  	if (li == NULL) { -		rc = 3; /* not operational */ +		rc = SIGP_CC_NOT_OPERATIONAL;  		goto unlock;  	} @@ -210,11 +186,11 @@ static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter)  	switch (parameter & 0xff) {  	case 0: -		rc = 3; /* not operational */ +		rc = SIGP_CC_NOT_OPERATIONAL;  		break;  	case 1:  	case 2: -		rc = 0; /* order accepted */ +		rc = SIGP_CC_ORDER_CODE_ACCEPTED;  		break;  	default:  		rc = -EOPNOTSUPP; @@ -235,21 +211,23 @@ static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address,  	address = address & 0x7fffe000u;  	if (copy_from_guest_absolute(vcpu, &tmp, address, 1) ||  	   copy_from_guest_absolute(vcpu, &tmp, address + PAGE_SIZE, 1)) { -		*reg |= SIGP_STAT_INVALID_PARAMETER; -		return 1; /* invalid parameter */ +		*reg &= 0xffffffff00000000UL; +		*reg |= SIGP_STATUS_INVALID_PARAMETER; +		return SIGP_CC_STATUS_STORED;  	}  	inti = kzalloc(sizeof(*inti), GFP_KERNEL);  	if (!inti) -		return 2; /* busy */ +		return SIGP_CC_BUSY;  	spin_lock(&fi->lock);  	if (cpu_addr < KVM_MAX_VCPUS)  		li = fi->local_int[cpu_addr];  	if (li == NULL) { -		rc = 1; /* incorrect state */ -		*reg &= SIGP_STAT_INCORRECT_STATE; +		*reg &= 0xffffffff00000000UL; +		*reg |= SIGP_STATUS_INCORRECT_STATE; +		rc = SIGP_CC_STATUS_STORED;  		kfree(inti);  		goto out_fi;  	} @@ -257,8 +235,9 @@ static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address,  	spin_lock_bh(&li->lock);  	/* cpu must be in stopped state */  	if (!(atomic_read(li->cpuflags) & CPUSTAT_STOPPED)) { -		rc = 1; /* incorrect state */ -		*reg &= SIGP_STAT_INCORRECT_STATE; +		*reg &= 0xffffffff00000000UL; +		*reg |= SIGP_STATUS_INCORRECT_STATE; +		rc = SIGP_CC_STATUS_STORED;  		kfree(inti);  		goto out_li;  	} @@ -270,7 +249,7 @@ static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address,  	atomic_set(&li->active, 1);  	if (waitqueue_active(&li->wq))  		wake_up_interruptible(&li->wq); -	rc = 0; /* order accepted */ +	rc = SIGP_CC_ORDER_CODE_ACCEPTED;  	VCPU_EVENT(vcpu, 4, "set prefix of cpu %02x to %x", cpu_addr, address);  out_li: @@ -287,21 +266,21 @@ static int __sigp_sense_running(struct kvm_vcpu *vcpu, u16 cpu_addr,  	struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int;  	if (cpu_addr >= KVM_MAX_VCPUS) -		return 3; /* not operational */ +		return SIGP_CC_NOT_OPERATIONAL;  	spin_lock(&fi->lock);  	if (fi->local_int[cpu_addr] == NULL) -		rc = 3; /* not operational */ +		rc = SIGP_CC_NOT_OPERATIONAL;  	else {  		if (atomic_read(fi->local_int[cpu_addr]->cpuflags)  		    & CPUSTAT_RUNNING) {  			/* running */ -			rc = 1; +			rc = SIGP_CC_ORDER_CODE_ACCEPTED;  		} else {  			/* not running */  			*reg &= 0xffffffff00000000UL; -			*reg |= SIGP_STAT_NOT_RUNNING; -			rc = 0; +			*reg |= SIGP_STATUS_NOT_RUNNING; +			rc = SIGP_CC_STATUS_STORED;  		}  	}  	spin_unlock(&fi->lock); @@ -314,23 +293,23 @@ static int __sigp_sense_running(struct kvm_vcpu *vcpu, u16 cpu_addr,  static int __sigp_restart(struct kvm_vcpu *vcpu, u16 cpu_addr)  { -	int rc = 0;  	struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int;  	struct kvm_s390_local_interrupt *li; +	int rc = SIGP_CC_ORDER_CODE_ACCEPTED;  	if (cpu_addr >= KVM_MAX_VCPUS) -		return 3; /* not operational */ +		return SIGP_CC_NOT_OPERATIONAL;  	spin_lock(&fi->lock);  	li = fi->local_int[cpu_addr];  	if (li == NULL) { -		rc = 3; /* not operational */ +		rc = SIGP_CC_NOT_OPERATIONAL;  		goto out;  	}  	spin_lock_bh(&li->lock);  	if (li->action_bits & ACTION_STOP_ON_STOP) -		rc = 2; /* busy */ +		rc = SIGP_CC_BUSY;  	else  		VCPU_EVENT(vcpu, 4, "sigp restart %x to handle userspace",  			cpu_addr); @@ -375,7 +354,7 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)  		vcpu->stat.instruction_sigp_external_call++;  		rc = __sigp_external_call(vcpu, cpu_addr);  		break; -	case SIGP_EMERGENCY: +	case SIGP_EMERGENCY_SIGNAL:  		vcpu->stat.instruction_sigp_emergency++;  		rc = __sigp_emergency(vcpu, cpu_addr);  		break; @@ -383,12 +362,12 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)  		vcpu->stat.instruction_sigp_stop++;  		rc = __sigp_stop(vcpu, cpu_addr, ACTION_STOP_ON_STOP);  		break; -	case SIGP_STOP_STORE_STATUS: +	case SIGP_STOP_AND_STORE_STATUS:  		vcpu->stat.instruction_sigp_stop++;  		rc = __sigp_stop(vcpu, cpu_addr, ACTION_STORE_ON_STOP |  						 ACTION_STOP_ON_STOP);  		break; -	case SIGP_SET_ARCH: +	case SIGP_SET_ARCHITECTURE:  		vcpu->stat.instruction_sigp_arch++;  		rc = __sigp_set_arch(vcpu, parameter);  		break; @@ -405,7 +384,7 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)  	case SIGP_RESTART:  		vcpu->stat.instruction_sigp_restart++;  		rc = __sigp_restart(vcpu, cpu_addr); -		if (rc == 2) /* busy */ +		if (rc == SIGP_CC_BUSY)  			break;  		/* user space must know about restart */  	default:  |