diff options
author | David Hildenbrand <dahi@linux.vnet.ibm.com> | 2016-06-21 08:19:51 -0400 |
---|---|---|
committer | Christian Borntraeger <borntraeger@de.ibm.com> | 2016-07-18 08:15:00 -0400 |
commit | 6502a34cfd6695929086187f63fe670cc3050e68 (patch) | |
tree | 774e386aac358c15baeeba02a38bb8b080e3887d | |
parent | af1bae5497b98cb99d6b0492e6981f060420a00c (diff) |
KVM: s390: allow user space to handle instr 0x0000
We will use illegal instruction 0x0000 for handling 2 byte sw breakpoints
from user space. As it can be enabled dynamically via a capability,
let's move setting of ICTL_OPEREXC to the post creation step, so we avoid
any races when enabling that capability just while adding new cpus.
Acked-by: Janosch Frank <frankja@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
-rw-r--r-- | Documentation/virtual/kvm/api.txt | 13 | ||||
-rw-r--r-- | arch/s390/include/asm/kvm_host.h | 2 | ||||
-rw-r--r-- | arch/s390/kvm/intercept.c | 3 | ||||
-rw-r--r-- | arch/s390/kvm/kvm-s390.c | 26 | ||||
-rw-r--r-- | include/uapi/linux/kvm.h | 1 |
5 files changed, 43 insertions, 2 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index c4d2fb0e28de..299306db5d84 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt | |||
@@ -3857,6 +3857,19 @@ as a broadcast even in x2APIC mode in order to support physical x2APIC | |||
3857 | without interrupt remapping. This is undesirable in logical mode, | 3857 | without interrupt remapping. This is undesirable in logical mode, |
3858 | where 0xff represents CPUs 0-7 in cluster 0. | 3858 | where 0xff represents CPUs 0-7 in cluster 0. |
3859 | 3859 | ||
3860 | 7.8 KVM_CAP_S390_USER_INSTR0 | ||
3861 | |||
3862 | Architectures: s390 | ||
3863 | Parameters: none | ||
3864 | |||
3865 | With this capability enabled, all illegal instructions 0x0000 (2 bytes) will | ||
3866 | be intercepted and forwarded to user space. User space can use this | ||
3867 | mechanism e.g. to realize 2-byte software breakpoints. The kernel will | ||
3868 | not inject an operating exception for these instructions, user space has | ||
3869 | to take care of that. | ||
3870 | |||
3871 | This capability can be enabled dynamically even if VCPUs were already | ||
3872 | created and are running. | ||
3860 | 3873 | ||
3861 | 8. Other capabilities. | 3874 | 8. Other capabilities. |
3862 | ---------------------- | 3875 | ---------------------- |
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index 946fc86202fd..183b01727de4 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h | |||
@@ -43,6 +43,7 @@ | |||
43 | /* s390-specific vcpu->requests bit members */ | 43 | /* s390-specific vcpu->requests bit members */ |
44 | #define KVM_REQ_ENABLE_IBS 8 | 44 | #define KVM_REQ_ENABLE_IBS 8 |
45 | #define KVM_REQ_DISABLE_IBS 9 | 45 | #define KVM_REQ_DISABLE_IBS 9 |
46 | #define KVM_REQ_ICPT_OPEREXC 10 | ||
46 | 47 | ||
47 | #define SIGP_CTRL_C 0x80 | 48 | #define SIGP_CTRL_C 0x80 |
48 | #define SIGP_CTRL_SCN_MASK 0x3f | 49 | #define SIGP_CTRL_SCN_MASK 0x3f |
@@ -666,6 +667,7 @@ struct kvm_arch{ | |||
666 | int user_cpu_state_ctrl; | 667 | int user_cpu_state_ctrl; |
667 | int user_sigp; | 668 | int user_sigp; |
668 | int user_stsi; | 669 | int user_stsi; |
670 | int user_instr0; | ||
669 | struct s390_io_adapter *adapters[MAX_S390_IO_ADAPTERS]; | 671 | struct s390_io_adapter *adapters[MAX_S390_IO_ADAPTERS]; |
670 | wait_queue_head_t ipte_wq; | 672 | wait_queue_head_t ipte_wq; |
671 | int ipte_lock_count; | 673 | int ipte_lock_count; |
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c index 850be47c4cc9..7a2f1551bc39 100644 --- a/arch/s390/kvm/intercept.c +++ b/arch/s390/kvm/intercept.c | |||
@@ -359,6 +359,9 @@ static int handle_operexc(struct kvm_vcpu *vcpu) | |||
359 | test_kvm_facility(vcpu->kvm, 74)) | 359 | test_kvm_facility(vcpu->kvm, 74)) |
360 | return handle_sthyi(vcpu); | 360 | return handle_sthyi(vcpu); |
361 | 361 | ||
362 | if (vcpu->arch.sie_block->ipa == 0 && vcpu->kvm->arch.user_instr0) | ||
363 | return -EOPNOTSUPP; | ||
364 | |||
362 | return kvm_s390_inject_program_int(vcpu, PGM_OPERATION); | 365 | return kvm_s390_inject_program_int(vcpu, PGM_OPERATION); |
363 | } | 366 | } |
364 | 367 | ||
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index d42428c11794..63ac7c1641a7 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
@@ -364,6 +364,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) | |||
364 | case KVM_CAP_S390_USER_STSI: | 364 | case KVM_CAP_S390_USER_STSI: |
365 | case KVM_CAP_S390_SKEYS: | 365 | case KVM_CAP_S390_SKEYS: |
366 | case KVM_CAP_S390_IRQ_STATE: | 366 | case KVM_CAP_S390_IRQ_STATE: |
367 | case KVM_CAP_S390_USER_INSTR0: | ||
367 | r = 1; | 368 | r = 1; |
368 | break; | 369 | break; |
369 | case KVM_CAP_S390_MEM_OP: | 370 | case KVM_CAP_S390_MEM_OP: |
@@ -456,6 +457,16 @@ out: | |||
456 | return r; | 457 | return r; |
457 | } | 458 | } |
458 | 459 | ||
460 | static void icpt_operexc_on_all_vcpus(struct kvm *kvm) | ||
461 | { | ||
462 | unsigned int i; | ||
463 | struct kvm_vcpu *vcpu; | ||
464 | |||
465 | kvm_for_each_vcpu(i, vcpu, kvm) { | ||
466 | kvm_s390_sync_request(KVM_REQ_ICPT_OPEREXC, vcpu); | ||
467 | } | ||
468 | } | ||
469 | |||
459 | static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap) | 470 | static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap) |
460 | { | 471 | { |
461 | int r; | 472 | int r; |
@@ -507,6 +518,12 @@ static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap) | |||
507 | kvm->arch.user_stsi = 1; | 518 | kvm->arch.user_stsi = 1; |
508 | r = 0; | 519 | r = 0; |
509 | break; | 520 | break; |
521 | case KVM_CAP_S390_USER_INSTR0: | ||
522 | VM_EVENT(kvm, 3, "%s", "ENABLE: CAP_S390_USER_INSTR0"); | ||
523 | kvm->arch.user_instr0 = 1; | ||
524 | icpt_operexc_on_all_vcpus(kvm); | ||
525 | r = 0; | ||
526 | break; | ||
510 | default: | 527 | default: |
511 | r = -EINVAL; | 528 | r = -EINVAL; |
512 | break; | 529 | break; |
@@ -1836,6 +1853,8 @@ void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) | |||
1836 | vcpu->arch.gmap = vcpu->kvm->arch.gmap; | 1853 | vcpu->arch.gmap = vcpu->kvm->arch.gmap; |
1837 | sca_add_vcpu(vcpu); | 1854 | sca_add_vcpu(vcpu); |
1838 | } | 1855 | } |
1856 | if (test_kvm_facility(vcpu->kvm, 74) || vcpu->kvm->arch.user_instr0) | ||
1857 | vcpu->arch.sie_block->ictl |= ICTL_OPEREXC; | ||
1839 | /* make vcpu_load load the right gmap on the first trigger */ | 1858 | /* make vcpu_load load the right gmap on the first trigger */ |
1840 | vcpu->arch.enabled_gmap = vcpu->arch.gmap; | 1859 | vcpu->arch.enabled_gmap = vcpu->arch.gmap; |
1841 | } | 1860 | } |
@@ -1923,8 +1942,6 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) | |||
1923 | } | 1942 | } |
1924 | vcpu->arch.sie_block->riccbd = (unsigned long) &vcpu->run->s.regs.riccb; | 1943 | vcpu->arch.sie_block->riccbd = (unsigned long) &vcpu->run->s.regs.riccb; |
1925 | vcpu->arch.sie_block->ictl |= ICTL_ISKE | ICTL_SSKE | ICTL_RRBE; | 1944 | vcpu->arch.sie_block->ictl |= ICTL_ISKE | ICTL_SSKE | ICTL_RRBE; |
1926 | if (test_kvm_facility(vcpu->kvm, 74)) | ||
1927 | vcpu->arch.sie_block->ictl |= ICTL_OPEREXC; | ||
1928 | 1945 | ||
1929 | if (vcpu->kvm->arch.use_cmma) { | 1946 | if (vcpu->kvm->arch.use_cmma) { |
1930 | rc = kvm_s390_vcpu_setup_cmma(vcpu); | 1947 | rc = kvm_s390_vcpu_setup_cmma(vcpu); |
@@ -2369,6 +2386,11 @@ retry: | |||
2369 | goto retry; | 2386 | goto retry; |
2370 | } | 2387 | } |
2371 | 2388 | ||
2389 | if (kvm_check_request(KVM_REQ_ICPT_OPEREXC, vcpu)) { | ||
2390 | vcpu->arch.sie_block->ictl |= ICTL_OPEREXC; | ||
2391 | goto retry; | ||
2392 | } | ||
2393 | |||
2372 | /* nothing to do, just clear the request */ | 2394 | /* nothing to do, just clear the request */ |
2373 | clear_bit(KVM_REQ_UNHALT, &vcpu->requests); | 2395 | clear_bit(KVM_REQ_UNHALT, &vcpu->requests); |
2374 | 2396 | ||
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 4f8030e5b05d..70941f4ab6d8 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h | |||
@@ -867,6 +867,7 @@ struct kvm_ppc_smmu_info { | |||
867 | #define KVM_CAP_VCPU_ATTRIBUTES 127 | 867 | #define KVM_CAP_VCPU_ATTRIBUTES 127 |
868 | #define KVM_CAP_MAX_VCPU_ID 128 | 868 | #define KVM_CAP_MAX_VCPU_ID 128 |
869 | #define KVM_CAP_X2APIC_API 129 | 869 | #define KVM_CAP_X2APIC_API 129 |
870 | #define KVM_CAP_S390_USER_INSTR0 130 | ||
870 | 871 | ||
871 | #ifdef KVM_CAP_IRQ_ROUTING | 872 | #ifdef KVM_CAP_IRQ_ROUTING |
872 | 873 | ||