aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Hildenbrand <dahi@linux.vnet.ibm.com>2016-06-21 08:19:51 -0400
committerChristian Borntraeger <borntraeger@de.ibm.com>2016-07-18 08:15:00 -0400
commit6502a34cfd6695929086187f63fe670cc3050e68 (patch)
tree774e386aac358c15baeeba02a38bb8b080e3887d
parentaf1bae5497b98cb99d6b0492e6981f060420a00c (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.txt13
-rw-r--r--arch/s390/include/asm/kvm_host.h2
-rw-r--r--arch/s390/kvm/intercept.c3
-rw-r--r--arch/s390/kvm/kvm-s390.c26
-rw-r--r--include/uapi/linux/kvm.h1
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
3857without interrupt remapping. This is undesirable in logical mode, 3857without interrupt remapping. This is undesirable in logical mode,
3858where 0xff represents CPUs 0-7 in cluster 0. 3858where 0xff represents CPUs 0-7 in cluster 0.
3859 3859
38607.8 KVM_CAP_S390_USER_INSTR0
3861
3862Architectures: s390
3863Parameters: none
3864
3865With this capability enabled, all illegal instructions 0x0000 (2 bytes) will
3866be intercepted and forwarded to user space. User space can use this
3867mechanism e.g. to realize 2-byte software breakpoints. The kernel will
3868not inject an operating exception for these instructions, user space has
3869to take care of that.
3870
3871This capability can be enabled dynamically even if VCPUs were already
3872created and are running.
3860 3873
38618. Other capabilities. 38748. 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
460static 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
459static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap) 470static 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