KVM: s390: : Feature and fix for kvm/next (4.8) part 4

1. Provide an exit to userspace for the invalid opcode 0 (used for
    software breakpoints)
 2. "Fix" (by returning condition code 3) some unhandled PTFF subcodes
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.14 (GNU/Linux)
 
 iQIcBAABAgAGBQJXjMzCAAoJEBF7vIC1phx8yrsP/2mM7YC/kJLHMwbWJeRF8nCa
 Du8ah4x0ocadlMkXzo/uzTl7+TIFZq0UsqN6XYp3TO1R3Z6fkbZ8RHnAd0dIwAhe
 GJl3a+L1L8dDkAhVFIxkTpS/lcpaQb6HL9PmBzprscm42nt88Cb9GUNWwhL5EwXv
 lYNUpS03VK7V/JsemeuYMfwyMtP6VNAD80LazVCoS7gboqaaAaZNMEuwEaiNcwk3
 NjdynA1mk9fpEash3p0ESCtgRwP8vytgVLLctArXOIFVuDdT0obbSmBikUiNPY5f
 7nl0yzaAkynRrzwWnZ6kBdDR1s61GsS+zZ8q4scXp7bW7TrsK7j4dlYMFQQKKvAO
 LSOS4DfNgUQ/4Z4un04PWcRjQ0kmWQFluLXyOW3SYg0ft6N8B6ujsXWui4rN3d5W
 sKAw4lnUHyKsjBKQ3zIX2YoYZXrJavxgGyQ1m91iT6oyjm0D6Ip821eAq02I9RPi
 lZRoe5rbqYxbN4485cNy81V2v3VgNOs5rsLOXwDio+U9DxvxE0uNIGKAoK6d2Nqn
 EFSlPc8SvOyvQVAFzeMBERQ4cUSAQ9p+BtBw4pr3y6Mm1AzenUCq5yLNID1oNfYq
 U5vIBIL8rVj8ffW1HRrfM3pnWwcVKAhsm5ssQxfHNYXNJ2LA5aV6LGAsdfoN+lP+
 faVW07AcCwYrKpK4TQVb
 =/3KO
 -----END PGP SIGNATURE-----

Merge tag 'kvm-s390-next-4.8-4' of git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux into next

KVM: s390: : Feature and fix for kvm/next (4.8) part 4

1. Provide an exit to userspace for the invalid opcode 0 (used for
   software breakpoints)
2. "Fix" (by returning condition code 3) some unhandled PTFF subcodes
This commit is contained in:
Radim Krčmář 2016-07-21 14:20:42 +02:00
commit 61f5dea179
6 changed files with 51 additions and 2 deletions

View File

@ -3857,6 +3857,19 @@ as a broadcast even in x2APIC mode in order to support physical x2APIC
without interrupt remapping. This is undesirable in logical mode,
where 0xff represents CPUs 0-7 in cluster 0.
7.8 KVM_CAP_S390_USER_INSTR0
Architectures: s390
Parameters: none
With this capability enabled, all illegal instructions 0x0000 (2 bytes) will
be intercepted and forwarded to user space. User space can use this
mechanism e.g. to realize 2-byte software breakpoints. The kernel will
not inject an operating exception for these instructions, user space has
to take care of that.
This capability can be enabled dynamically even if VCPUs were already
created and are running.
8. Other capabilities.
----------------------

View File

@ -43,6 +43,7 @@
/* s390-specific vcpu->requests bit members */
#define KVM_REQ_ENABLE_IBS 8
#define KVM_REQ_DISABLE_IBS 9
#define KVM_REQ_ICPT_OPEREXC 10
#define SIGP_CTRL_C 0x80
#define SIGP_CTRL_SCN_MASK 0x3f
@ -666,6 +667,7 @@ struct kvm_arch{
int user_cpu_state_ctrl;
int user_sigp;
int user_stsi;
int user_instr0;
struct s390_io_adapter *adapters[MAX_S390_IO_ADAPTERS];
wait_queue_head_t ipte_wq;
int ipte_lock_count;

View File

@ -359,6 +359,9 @@ static int handle_operexc(struct kvm_vcpu *vcpu)
test_kvm_facility(vcpu->kvm, 74))
return handle_sthyi(vcpu);
if (vcpu->arch.sie_block->ipa == 0 && vcpu->kvm->arch.user_instr0)
return -EOPNOTSUPP;
return kvm_s390_inject_program_int(vcpu, PGM_OPERATION);
}

View File

@ -364,6 +364,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
case KVM_CAP_S390_USER_STSI:
case KVM_CAP_S390_SKEYS:
case KVM_CAP_S390_IRQ_STATE:
case KVM_CAP_S390_USER_INSTR0:
r = 1;
break;
case KVM_CAP_S390_MEM_OP:
@ -456,6 +457,16 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
return r;
}
static void icpt_operexc_on_all_vcpus(struct kvm *kvm)
{
unsigned int i;
struct kvm_vcpu *vcpu;
kvm_for_each_vcpu(i, vcpu, kvm) {
kvm_s390_sync_request(KVM_REQ_ICPT_OPEREXC, vcpu);
}
}
static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap)
{
int r;
@ -507,6 +518,12 @@ static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap)
kvm->arch.user_stsi = 1;
r = 0;
break;
case KVM_CAP_S390_USER_INSTR0:
VM_EVENT(kvm, 3, "%s", "ENABLE: CAP_S390_USER_INSTR0");
kvm->arch.user_instr0 = 1;
icpt_operexc_on_all_vcpus(kvm);
r = 0;
break;
default:
r = -EINVAL;
break;
@ -1836,6 +1853,8 @@ void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
vcpu->arch.gmap = vcpu->kvm->arch.gmap;
sca_add_vcpu(vcpu);
}
if (test_kvm_facility(vcpu->kvm, 74) || vcpu->kvm->arch.user_instr0)
vcpu->arch.sie_block->ictl |= ICTL_OPEREXC;
/* make vcpu_load load the right gmap on the first trigger */
vcpu->arch.enabled_gmap = vcpu->arch.gmap;
}
@ -1923,8 +1942,6 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
}
vcpu->arch.sie_block->riccbd = (unsigned long) &vcpu->run->s.regs.riccb;
vcpu->arch.sie_block->ictl |= ICTL_ISKE | ICTL_SSKE | ICTL_RRBE;
if (test_kvm_facility(vcpu->kvm, 74))
vcpu->arch.sie_block->ictl |= ICTL_OPEREXC;
if (vcpu->kvm->arch.use_cmma) {
rc = kvm_s390_vcpu_setup_cmma(vcpu);
@ -2369,6 +2386,11 @@ static int kvm_s390_handle_requests(struct kvm_vcpu *vcpu)
goto retry;
}
if (kvm_check_request(KVM_REQ_ICPT_OPEREXC, vcpu)) {
vcpu->arch.sie_block->ictl |= ICTL_OPEREXC;
goto retry;
}
/* nothing to do, just clear the request */
clear_bit(KVM_REQ_UNHALT, &vcpu->requests);

View File

@ -1185,7 +1185,15 @@ static int handle_sckpf(struct kvm_vcpu *vcpu)
return 0;
}
static int handle_ptff(struct kvm_vcpu *vcpu)
{
/* we don't emulate any control instructions yet */
kvm_s390_set_psw_cc(vcpu, 3);
return 0;
}
static const intercept_handler_t x01_handlers[256] = {
[0x04] = handle_ptff,
[0x07] = handle_sckpf,
};

View File

@ -867,6 +867,7 @@ struct kvm_ppc_smmu_info {
#define KVM_CAP_VCPU_ATTRIBUTES 127
#define KVM_CAP_MAX_VCPU_ID 128
#define KVM_CAP_X2APIC_API 129
#define KVM_CAP_S390_USER_INSTR0 130
#ifdef KVM_CAP_IRQ_ROUTING