diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2013-12-12 05:41:33 -0500 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2013-12-12 05:41:33 -0500 |
commit | 6bb05ef78553491b2e2e0710dde364331dc3cdd2 (patch) | |
tree | 02e15152f1fa25c21155d1e021d20972ac57ea36 | |
parent | 6dfacadd5858882eee1983995854d4e1fb1b966e (diff) | |
parent | ff1f3cb4b3ac5d039f02679f34cb1498d110d241 (diff) |
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.
-rw-r--r-- | Documentation/virtual/kvm/hypercalls.txt | 3 | ||||
-rw-r--r-- | Documentation/virtual/kvm/s390-diag.txt | 80 | ||||
-rw-r--r-- | arch/s390/include/asm/sigp.h | 2 | ||||
-rw-r--r-- | arch/s390/kvm/diag.c | 2 | ||||
-rw-r--r-- | arch/s390/kvm/sigp.c | 64 |
5 files changed, 139 insertions, 12 deletions
diff --git a/Documentation/virtual/kvm/hypercalls.txt b/Documentation/virtual/kvm/hypercalls.txt index 022198e389d7..d922d73efa7b 100644 --- a/Documentation/virtual/kvm/hypercalls.txt +++ b/Documentation/virtual/kvm/hypercalls.txt | |||
@@ -17,6 +17,9 @@ S390: | |||
17 | S390 uses diagnose instruction as hypercall (0x500) along with hypercall | 17 | S390 uses diagnose instruction as hypercall (0x500) along with hypercall |
18 | number in R1. | 18 | number in R1. |
19 | 19 | ||
20 | For further information on the S390 diagnose call as supported by KVM, | ||
21 | refer to Documentation/virtual/kvm/s390-diag.txt. | ||
22 | |||
20 | PowerPC: | 23 | PowerPC: |
21 | It uses R3-R10 and hypercall number in R11. R4-R11 are used as output registers. | 24 | It uses R3-R10 and hypercall number in R11. R4-R11 are used as output registers. |
22 | Return value is placed in R3. | 25 | Return value is placed in R3. |
diff --git a/Documentation/virtual/kvm/s390-diag.txt b/Documentation/virtual/kvm/s390-diag.txt new file mode 100644 index 000000000000..f1de4fbade15 --- /dev/null +++ b/Documentation/virtual/kvm/s390-diag.txt | |||
@@ -0,0 +1,80 @@ | |||
1 | The s390 DIAGNOSE call on KVM | ||
2 | ============================= | ||
3 | |||
4 | KVM on s390 supports the DIAGNOSE call for making hypercalls, both for | ||
5 | native hypercalls and for selected hypercalls found on other s390 | ||
6 | hypervisors. | ||
7 | |||
8 | Note that bits are numbered as by the usual s390 convention (most significant | ||
9 | bit on the left). | ||
10 | |||
11 | |||
12 | General remarks | ||
13 | --------------- | ||
14 | |||
15 | DIAGNOSE calls by the guest cause a mandatory intercept. This implies | ||
16 | all supported DIAGNOSE calls need to be handled by either KVM or its | ||
17 | userspace. | ||
18 | |||
19 | All DIAGNOSE calls supported by KVM use the RS-a format: | ||
20 | |||
21 | -------------------------------------- | ||
22 | | '83' | R1 | R3 | B2 | D2 | | ||
23 | -------------------------------------- | ||
24 | 0 8 12 16 20 31 | ||
25 | |||
26 | The second-operand address (obtained by the base/displacement calculation) | ||
27 | is not used to address data. Instead, bits 48-63 of this address specify | ||
28 | the function code, and bits 0-47 are ignored. | ||
29 | |||
30 | The supported DIAGNOSE function codes vary by the userspace used. For | ||
31 | DIAGNOSE function codes not specific to KVM, please refer to the | ||
32 | documentation for the s390 hypervisors defining them. | ||
33 | |||
34 | |||
35 | DIAGNOSE function code 'X'500' - KVM virtio functions | ||
36 | ----------------------------------------------------- | ||
37 | |||
38 | If the function code specifies 0x500, various virtio-related functions | ||
39 | are performed. | ||
40 | |||
41 | General register 1 contains the virtio subfunction code. Supported | ||
42 | virtio subfunctions depend on KVM's userspace. Generally, userspace | ||
43 | provides either s390-virtio (subcodes 0-2) or virtio-ccw (subcode 3). | ||
44 | |||
45 | Upon completion of the DIAGNOSE instruction, general register 2 contains | ||
46 | the function's return code, which is either a return code or a subcode | ||
47 | specific value. | ||
48 | |||
49 | Subcode 0 - s390-virtio notification and early console printk | ||
50 | Handled by userspace. | ||
51 | |||
52 | Subcode 1 - s390-virtio reset | ||
53 | Handled by userspace. | ||
54 | |||
55 | Subcode 2 - s390-virtio set status | ||
56 | Handled by userspace. | ||
57 | |||
58 | Subcode 3 - virtio-ccw notification | ||
59 | Handled by either userspace or KVM (ioeventfd case). | ||
60 | |||
61 | General register 2 contains a subchannel-identification word denoting | ||
62 | the subchannel of the virtio-ccw proxy device to be notified. | ||
63 | |||
64 | General register 3 contains the number of the virtqueue to be notified. | ||
65 | |||
66 | General register 4 contains a 64bit identifier for KVM usage (the | ||
67 | kvm_io_bus cookie). If general register 4 does not contain a valid | ||
68 | identifier, it is ignored. | ||
69 | |||
70 | After completion of the DIAGNOSE call, general register 2 may contain | ||
71 | a 64bit identifier (in the kvm_io_bus cookie case). | ||
72 | |||
73 | See also the virtio standard for a discussion of this hypercall. | ||
74 | |||
75 | |||
76 | DIAGNOSE function code 'X'501 - KVM breakpoint | ||
77 | ---------------------------------------------- | ||
78 | |||
79 | If the function code specifies 0x501, breakpoint functions may be performed. | ||
80 | This function code is handled by userspace. | ||
diff --git a/arch/s390/include/asm/sigp.h b/arch/s390/include/asm/sigp.h index 5a87d16d3e7c..d091aa1aaf11 100644 --- a/arch/s390/include/asm/sigp.h +++ b/arch/s390/include/asm/sigp.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #define SIGP_SENSE 1 | 5 | #define SIGP_SENSE 1 |
6 | #define SIGP_EXTERNAL_CALL 2 | 6 | #define SIGP_EXTERNAL_CALL 2 |
7 | #define SIGP_EMERGENCY_SIGNAL 3 | 7 | #define SIGP_EMERGENCY_SIGNAL 3 |
8 | #define SIGP_START 4 | ||
8 | #define SIGP_STOP 5 | 9 | #define SIGP_STOP 5 |
9 | #define SIGP_RESTART 6 | 10 | #define SIGP_RESTART 6 |
10 | #define SIGP_STOP_AND_STORE_STATUS 9 | 11 | #define SIGP_STOP_AND_STORE_STATUS 9 |
@@ -12,6 +13,7 @@ | |||
12 | #define SIGP_SET_PREFIX 13 | 13 | #define SIGP_SET_PREFIX 13 |
13 | #define SIGP_STORE_STATUS_AT_ADDRESS 14 | 14 | #define SIGP_STORE_STATUS_AT_ADDRESS 14 |
14 | #define SIGP_SET_ARCHITECTURE 18 | 15 | #define SIGP_SET_ARCHITECTURE 18 |
16 | #define SIGP_COND_EMERGENCY_SIGNAL 19 | ||
15 | #define SIGP_SENSE_RUNNING 21 | 17 | #define SIGP_SENSE_RUNNING 21 |
16 | 18 | ||
17 | /* SIGP condition codes */ | 19 | /* SIGP condition codes */ |
diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c index 5ff29be7d87a..8216c0e0b2e2 100644 --- a/arch/s390/kvm/diag.c +++ b/arch/s390/kvm/diag.c | |||
@@ -121,7 +121,7 @@ static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu) | |||
121 | * - gpr 4 contains the index on the bus (optionally) | 121 | * - gpr 4 contains the index on the bus (optionally) |
122 | */ | 122 | */ |
123 | ret = kvm_io_bus_write_cookie(vcpu->kvm, KVM_VIRTIO_CCW_NOTIFY_BUS, | 123 | ret = kvm_io_bus_write_cookie(vcpu->kvm, KVM_VIRTIO_CCW_NOTIFY_BUS, |
124 | vcpu->run->s.regs.gprs[2], | 124 | vcpu->run->s.regs.gprs[2] & 0xffffffff, |
125 | 8, &vcpu->run->s.regs.gprs[3], | 125 | 8, &vcpu->run->s.regs.gprs[3], |
126 | vcpu->run->s.regs.gprs[4]); | 126 | vcpu->run->s.regs.gprs[4]); |
127 | 127 | ||
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index c3700585b4bb..87c2b3a3bd3e 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * handling interprocessor communication | 2 | * handling interprocessor communication |
3 | * | 3 | * |
4 | * Copyright IBM Corp. 2008, 2009 | 4 | * Copyright IBM Corp. 2008, 2013 |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 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) | 7 | * it under the terms of the GNU General Public License (version 2 only) |
@@ -89,6 +89,37 @@ unlock: | |||
89 | return rc; | 89 | return rc; |
90 | } | 90 | } |
91 | 91 | ||
92 | static int __sigp_conditional_emergency(struct kvm_vcpu *vcpu, u16 cpu_addr, | ||
93 | u16 asn, u64 *reg) | ||
94 | { | ||
95 | struct kvm_vcpu *dst_vcpu = NULL; | ||
96 | const u64 psw_int_mask = PSW_MASK_IO | PSW_MASK_EXT; | ||
97 | u16 p_asn, s_asn; | ||
98 | psw_t *psw; | ||
99 | u32 flags; | ||
100 | |||
101 | if (cpu_addr < KVM_MAX_VCPUS) | ||
102 | dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); | ||
103 | if (!dst_vcpu) | ||
104 | return SIGP_CC_NOT_OPERATIONAL; | ||
105 | flags = atomic_read(&dst_vcpu->arch.sie_block->cpuflags); | ||
106 | psw = &dst_vcpu->arch.sie_block->gpsw; | ||
107 | p_asn = dst_vcpu->arch.sie_block->gcr[4] & 0xffff; /* Primary ASN */ | ||
108 | s_asn = dst_vcpu->arch.sie_block->gcr[3] & 0xffff; /* Secondary ASN */ | ||
109 | |||
110 | /* Deliver the emergency signal? */ | ||
111 | if (!(flags & CPUSTAT_STOPPED) | ||
112 | || (psw->mask & psw_int_mask) != psw_int_mask | ||
113 | || ((flags & CPUSTAT_WAIT) && psw->addr != 0) | ||
114 | || (!(flags & CPUSTAT_WAIT) && (asn == p_asn || asn == s_asn))) { | ||
115 | return __sigp_emergency(vcpu, cpu_addr); | ||
116 | } else { | ||
117 | *reg &= 0xffffffff00000000UL; | ||
118 | *reg |= SIGP_STATUS_INCORRECT_STATE; | ||
119 | return SIGP_CC_STATUS_STORED; | ||
120 | } | ||
121 | } | ||
122 | |||
92 | static int __sigp_external_call(struct kvm_vcpu *vcpu, u16 cpu_addr) | 123 | static int __sigp_external_call(struct kvm_vcpu *vcpu, u16 cpu_addr) |
93 | { | 124 | { |
94 | struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; | 125 | 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, | |||
332 | return rc; | 363 | return rc; |
333 | } | 364 | } |
334 | 365 | ||
335 | static int __sigp_restart(struct kvm_vcpu *vcpu, u16 cpu_addr) | 366 | /* Test whether the destination CPU is available and not busy */ |
367 | static int sigp_check_callable(struct kvm_vcpu *vcpu, u16 cpu_addr) | ||
336 | { | 368 | { |
337 | struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; | 369 | struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; |
338 | struct kvm_s390_local_interrupt *li; | 370 | struct kvm_s390_local_interrupt *li; |
@@ -351,9 +383,6 @@ static int __sigp_restart(struct kvm_vcpu *vcpu, u16 cpu_addr) | |||
351 | spin_lock_bh(&li->lock); | 383 | spin_lock_bh(&li->lock); |
352 | if (li->action_bits & ACTION_STOP_ON_STOP) | 384 | if (li->action_bits & ACTION_STOP_ON_STOP) |
353 | rc = SIGP_CC_BUSY; | 385 | rc = SIGP_CC_BUSY; |
354 | else | ||
355 | VCPU_EVENT(vcpu, 4, "sigp restart %x to handle userspace", | ||
356 | cpu_addr); | ||
357 | spin_unlock_bh(&li->lock); | 386 | spin_unlock_bh(&li->lock); |
358 | out: | 387 | out: |
359 | spin_unlock(&fi->lock); | 388 | spin_unlock(&fi->lock); |
@@ -417,17 +446,31 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu) | |||
417 | rc = __sigp_set_prefix(vcpu, cpu_addr, parameter, | 446 | rc = __sigp_set_prefix(vcpu, cpu_addr, parameter, |
418 | &vcpu->run->s.regs.gprs[r1]); | 447 | &vcpu->run->s.regs.gprs[r1]); |
419 | break; | 448 | break; |
449 | case SIGP_COND_EMERGENCY_SIGNAL: | ||
450 | rc = __sigp_conditional_emergency(vcpu, cpu_addr, parameter, | ||
451 | &vcpu->run->s.regs.gprs[r1]); | ||
452 | break; | ||
420 | case SIGP_SENSE_RUNNING: | 453 | case SIGP_SENSE_RUNNING: |
421 | vcpu->stat.instruction_sigp_sense_running++; | 454 | vcpu->stat.instruction_sigp_sense_running++; |
422 | rc = __sigp_sense_running(vcpu, cpu_addr, | 455 | rc = __sigp_sense_running(vcpu, cpu_addr, |
423 | &vcpu->run->s.regs.gprs[r1]); | 456 | &vcpu->run->s.regs.gprs[r1]); |
424 | break; | 457 | break; |
458 | case SIGP_START: | ||
459 | rc = sigp_check_callable(vcpu, cpu_addr); | ||
460 | if (rc == SIGP_CC_ORDER_CODE_ACCEPTED) | ||
461 | rc = -EOPNOTSUPP; /* Handle START in user space */ | ||
462 | break; | ||
425 | case SIGP_RESTART: | 463 | case SIGP_RESTART: |
426 | vcpu->stat.instruction_sigp_restart++; | 464 | vcpu->stat.instruction_sigp_restart++; |
427 | rc = __sigp_restart(vcpu, cpu_addr); | 465 | rc = sigp_check_callable(vcpu, cpu_addr); |
428 | if (rc == SIGP_CC_BUSY) | 466 | if (rc == SIGP_CC_ORDER_CODE_ACCEPTED) { |
429 | break; | 467 | VCPU_EVENT(vcpu, 4, |
430 | /* user space must know about restart */ | 468 | "sigp restart %x to handle userspace", |
469 | cpu_addr); | ||
470 | /* user space must know about restart */ | ||
471 | rc = -EOPNOTSUPP; | ||
472 | } | ||
473 | break; | ||
431 | default: | 474 | default: |
432 | return -EOPNOTSUPP; | 475 | return -EOPNOTSUPP; |
433 | } | 476 | } |
@@ -435,7 +478,6 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu) | |||
435 | if (rc < 0) | 478 | if (rc < 0) |
436 | return rc; | 479 | return rc; |
437 | 480 | ||
438 | vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44); | 481 | kvm_s390_set_psw_cc(vcpu, rc); |
439 | vcpu->arch.sie_block->gpsw.mask |= (rc & 3ul) << 44; | ||
440 | return 0; | 482 | return 0; |
441 | } | 483 | } |