forked from Minki/linux
Some further s390 patches for kvm-next.
Various improvements and bugfixes in the signal processor handling. Document kvm support for diagnose (s390 hypercalls). And last but not least, fix a bug in the s390 ioeventfd backend that was causing us grief in scenarios with 4G+ memory. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABAgAGBQJSqLJhAAoJEN7Pa5PG8C+vfdgP/3TzhJDOlQQBUSrmgE7TzaXR qHXMVDsWRzrpkrXXjLnHrmwTl5+d5y6yz4TQGhpDEQsMSzTHtv0xq+2qdED92P5P L2RNTBFeilRMke1j71uWYszJBiiEoyePg1Cj0rJ84fGJobc6NgXIjX+pftvtsMpC Xid54/m3DmBKJBHIIQKz2EwUHc3/TQj3wnIPjK5f6Lb7d231131fn5heEQj9TVCh Vc2Ei/c/KGf8afgzPtA29zIQX8y2KuPcbh5ouGI9bHIgBuLN9FbYV3V9CsDNc2lM rKSCeXwExdaZbtQ/kStbIKRFLR6D7JFSjUZORGgOq03wMvGUztckJ1WhbAw+ufef vPDtKY4h9Jl1tEuErmnuecspJafjrsY3q1d1quxOOl+anU6CfX8DZ/4xbXtU8XYd CRHEsxvJNXKPge4jpCmukJP8iJ4HaGdZYeiy9mdNEAhQZhmeuPdIzt+DtJjNZpup C1ofz3a7mz5c+lTMWC2xOwLmqpPCioIqYUSKYmzWimWBXmpRqoJtOmZAvT+BqDY2 +GTTk4JJoj4vhxQNRFROuvZ710H/NNF/Nm8Mex776IDXg3vNuPuxu9yFtf8k8fiY UcIZ8Y8PEYhpm4VN/fdFM6pwTvHqFHtAhqaofp3Tb6wE0JCiVZ7b2E5jJuIYE6wS EP+r1TCuGi5OH02doEKH =/dj0 -----END PGP SIGNATURE----- Merge tag 'kvm-s390-20131211' of git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux into kvm-next Some further s390 patches for kvm-next. Various improvements and bugfixes in the signal processor handling. Document kvm support for diagnose (s390 hypercalls). And last but not least, fix a bug in the s390 ioeventfd backend that was causing us grief in scenarios with 4G+ memory.
This commit is contained in:
commit
6bb05ef785
@ -17,6 +17,9 @@ S390:
|
||||
S390 uses diagnose instruction as hypercall (0x500) along with hypercall
|
||||
number in R1.
|
||||
|
||||
For further information on the S390 diagnose call as supported by KVM,
|
||||
refer to Documentation/virtual/kvm/s390-diag.txt.
|
||||
|
||||
PowerPC:
|
||||
It uses R3-R10 and hypercall number in R11. R4-R11 are used as output registers.
|
||||
Return value is placed in R3.
|
||||
|
80
Documentation/virtual/kvm/s390-diag.txt
Normal file
80
Documentation/virtual/kvm/s390-diag.txt
Normal file
@ -0,0 +1,80 @@
|
||||
The s390 DIAGNOSE call on KVM
|
||||
=============================
|
||||
|
||||
KVM on s390 supports the DIAGNOSE call for making hypercalls, both for
|
||||
native hypercalls and for selected hypercalls found on other s390
|
||||
hypervisors.
|
||||
|
||||
Note that bits are numbered as by the usual s390 convention (most significant
|
||||
bit on the left).
|
||||
|
||||
|
||||
General remarks
|
||||
---------------
|
||||
|
||||
DIAGNOSE calls by the guest cause a mandatory intercept. This implies
|
||||
all supported DIAGNOSE calls need to be handled by either KVM or its
|
||||
userspace.
|
||||
|
||||
All DIAGNOSE calls supported by KVM use the RS-a format:
|
||||
|
||||
--------------------------------------
|
||||
| '83' | R1 | R3 | B2 | D2 |
|
||||
--------------------------------------
|
||||
0 8 12 16 20 31
|
||||
|
||||
The second-operand address (obtained by the base/displacement calculation)
|
||||
is not used to address data. Instead, bits 48-63 of this address specify
|
||||
the function code, and bits 0-47 are ignored.
|
||||
|
||||
The supported DIAGNOSE function codes vary by the userspace used. For
|
||||
DIAGNOSE function codes not specific to KVM, please refer to the
|
||||
documentation for the s390 hypervisors defining them.
|
||||
|
||||
|
||||
DIAGNOSE function code 'X'500' - KVM virtio functions
|
||||
-----------------------------------------------------
|
||||
|
||||
If the function code specifies 0x500, various virtio-related functions
|
||||
are performed.
|
||||
|
||||
General register 1 contains the virtio subfunction code. Supported
|
||||
virtio subfunctions depend on KVM's userspace. Generally, userspace
|
||||
provides either s390-virtio (subcodes 0-2) or virtio-ccw (subcode 3).
|
||||
|
||||
Upon completion of the DIAGNOSE instruction, general register 2 contains
|
||||
the function's return code, which is either a return code or a subcode
|
||||
specific value.
|
||||
|
||||
Subcode 0 - s390-virtio notification and early console printk
|
||||
Handled by userspace.
|
||||
|
||||
Subcode 1 - s390-virtio reset
|
||||
Handled by userspace.
|
||||
|
||||
Subcode 2 - s390-virtio set status
|
||||
Handled by userspace.
|
||||
|
||||
Subcode 3 - virtio-ccw notification
|
||||
Handled by either userspace or KVM (ioeventfd case).
|
||||
|
||||
General register 2 contains a subchannel-identification word denoting
|
||||
the subchannel of the virtio-ccw proxy device to be notified.
|
||||
|
||||
General register 3 contains the number of the virtqueue to be notified.
|
||||
|
||||
General register 4 contains a 64bit identifier for KVM usage (the
|
||||
kvm_io_bus cookie). If general register 4 does not contain a valid
|
||||
identifier, it is ignored.
|
||||
|
||||
After completion of the DIAGNOSE call, general register 2 may contain
|
||||
a 64bit identifier (in the kvm_io_bus cookie case).
|
||||
|
||||
See also the virtio standard for a discussion of this hypercall.
|
||||
|
||||
|
||||
DIAGNOSE function code 'X'501 - KVM breakpoint
|
||||
----------------------------------------------
|
||||
|
||||
If the function code specifies 0x501, breakpoint functions may be performed.
|
||||
This function code is handled by userspace.
|
@ -5,6 +5,7 @@
|
||||
#define SIGP_SENSE 1
|
||||
#define SIGP_EXTERNAL_CALL 2
|
||||
#define SIGP_EMERGENCY_SIGNAL 3
|
||||
#define SIGP_START 4
|
||||
#define SIGP_STOP 5
|
||||
#define SIGP_RESTART 6
|
||||
#define SIGP_STOP_AND_STORE_STATUS 9
|
||||
@ -12,6 +13,7 @@
|
||||
#define SIGP_SET_PREFIX 13
|
||||
#define SIGP_STORE_STATUS_AT_ADDRESS 14
|
||||
#define SIGP_SET_ARCHITECTURE 18
|
||||
#define SIGP_COND_EMERGENCY_SIGNAL 19
|
||||
#define SIGP_SENSE_RUNNING 21
|
||||
|
||||
/* SIGP condition codes */
|
||||
|
@ -121,7 +121,7 @@ static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu)
|
||||
* - gpr 4 contains the index on the bus (optionally)
|
||||
*/
|
||||
ret = kvm_io_bus_write_cookie(vcpu->kvm, KVM_VIRTIO_CCW_NOTIFY_BUS,
|
||||
vcpu->run->s.regs.gprs[2],
|
||||
vcpu->run->s.regs.gprs[2] & 0xffffffff,
|
||||
8, &vcpu->run->s.regs.gprs[3],
|
||||
vcpu->run->s.regs.gprs[4]);
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* handling interprocessor communication
|
||||
*
|
||||
* Copyright IBM Corp. 2008, 2009
|
||||
* Copyright IBM Corp. 2008, 2013
|
||||
*
|
||||
* 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)
|
||||
@ -89,6 +89,37 @@ unlock:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __sigp_conditional_emergency(struct kvm_vcpu *vcpu, u16 cpu_addr,
|
||||
u16 asn, u64 *reg)
|
||||
{
|
||||
struct kvm_vcpu *dst_vcpu = NULL;
|
||||
const u64 psw_int_mask = PSW_MASK_IO | PSW_MASK_EXT;
|
||||
u16 p_asn, s_asn;
|
||||
psw_t *psw;
|
||||
u32 flags;
|
||||
|
||||
if (cpu_addr < KVM_MAX_VCPUS)
|
||||
dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr);
|
||||
if (!dst_vcpu)
|
||||
return SIGP_CC_NOT_OPERATIONAL;
|
||||
flags = atomic_read(&dst_vcpu->arch.sie_block->cpuflags);
|
||||
psw = &dst_vcpu->arch.sie_block->gpsw;
|
||||
p_asn = dst_vcpu->arch.sie_block->gcr[4] & 0xffff; /* Primary ASN */
|
||||
s_asn = dst_vcpu->arch.sie_block->gcr[3] & 0xffff; /* Secondary ASN */
|
||||
|
||||
/* Deliver the emergency signal? */
|
||||
if (!(flags & CPUSTAT_STOPPED)
|
||||
|| (psw->mask & psw_int_mask) != psw_int_mask
|
||||
|| ((flags & CPUSTAT_WAIT) && psw->addr != 0)
|
||||
|| (!(flags & CPUSTAT_WAIT) && (asn == p_asn || asn == s_asn))) {
|
||||
return __sigp_emergency(vcpu, cpu_addr);
|
||||
} else {
|
||||
*reg &= 0xffffffff00000000UL;
|
||||
*reg |= SIGP_STATUS_INCORRECT_STATE;
|
||||
return SIGP_CC_STATUS_STORED;
|
||||
}
|
||||
}
|
||||
|
||||
static int __sigp_external_call(struct kvm_vcpu *vcpu, u16 cpu_addr)
|
||||
{
|
||||
struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int;
|
||||
@ -332,7 +363,8 @@ static int __sigp_sense_running(struct kvm_vcpu *vcpu, u16 cpu_addr,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __sigp_restart(struct kvm_vcpu *vcpu, u16 cpu_addr)
|
||||
/* Test whether the destination CPU is available and not busy */
|
||||
static int sigp_check_callable(struct kvm_vcpu *vcpu, u16 cpu_addr)
|
||||
{
|
||||
struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int;
|
||||
struct kvm_s390_local_interrupt *li;
|
||||
@ -351,9 +383,6 @@ static int __sigp_restart(struct kvm_vcpu *vcpu, u16 cpu_addr)
|
||||
spin_lock_bh(&li->lock);
|
||||
if (li->action_bits & ACTION_STOP_ON_STOP)
|
||||
rc = SIGP_CC_BUSY;
|
||||
else
|
||||
VCPU_EVENT(vcpu, 4, "sigp restart %x to handle userspace",
|
||||
cpu_addr);
|
||||
spin_unlock_bh(&li->lock);
|
||||
out:
|
||||
spin_unlock(&fi->lock);
|
||||
@ -417,17 +446,31 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
|
||||
rc = __sigp_set_prefix(vcpu, cpu_addr, parameter,
|
||||
&vcpu->run->s.regs.gprs[r1]);
|
||||
break;
|
||||
case SIGP_COND_EMERGENCY_SIGNAL:
|
||||
rc = __sigp_conditional_emergency(vcpu, cpu_addr, parameter,
|
||||
&vcpu->run->s.regs.gprs[r1]);
|
||||
break;
|
||||
case SIGP_SENSE_RUNNING:
|
||||
vcpu->stat.instruction_sigp_sense_running++;
|
||||
rc = __sigp_sense_running(vcpu, cpu_addr,
|
||||
&vcpu->run->s.regs.gprs[r1]);
|
||||
break;
|
||||
case SIGP_START:
|
||||
rc = sigp_check_callable(vcpu, cpu_addr);
|
||||
if (rc == SIGP_CC_ORDER_CODE_ACCEPTED)
|
||||
rc = -EOPNOTSUPP; /* Handle START in user space */
|
||||
break;
|
||||
case SIGP_RESTART:
|
||||
vcpu->stat.instruction_sigp_restart++;
|
||||
rc = __sigp_restart(vcpu, cpu_addr);
|
||||
if (rc == SIGP_CC_BUSY)
|
||||
break;
|
||||
/* user space must know about restart */
|
||||
rc = sigp_check_callable(vcpu, cpu_addr);
|
||||
if (rc == SIGP_CC_ORDER_CODE_ACCEPTED) {
|
||||
VCPU_EVENT(vcpu, 4,
|
||||
"sigp restart %x to handle userspace",
|
||||
cpu_addr);
|
||||
/* user space must know about restart */
|
||||
rc = -EOPNOTSUPP;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
@ -435,7 +478,6 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44);
|
||||
vcpu->arch.sie_block->gpsw.mask |= (rc & 3ul) << 44;
|
||||
kvm_s390_set_psw_cc(vcpu, rc);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user