diff options
Diffstat (limited to 'arch/s390')
| -rw-r--r-- | arch/s390/include/asm/kvm_host.h | 11 | ||||
| -rw-r--r-- | arch/s390/include/asm/sclp.h | 1 | ||||
| -rw-r--r-- | arch/s390/include/asm/sigp.h | 1 | ||||
| -rw-r--r-- | arch/s390/include/uapi/asm/kvm.h | 1 | ||||
| -rw-r--r-- | arch/s390/include/uapi/asm/sie.h | 7 | ||||
| -rw-r--r-- | arch/s390/kvm/Kconfig | 1 | ||||
| -rw-r--r-- | arch/s390/kvm/interrupt.c | 47 | ||||
| -rw-r--r-- | arch/s390/kvm/kvm-s390.c | 61 | ||||
| -rw-r--r-- | arch/s390/kvm/priv.c | 21 | ||||
| -rw-r--r-- | arch/s390/kvm/sigp.c | 6 |
10 files changed, 122 insertions, 35 deletions
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index 6da41fab70fb..37b9017c6a96 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h | |||
| @@ -38,7 +38,7 @@ | |||
| 38 | */ | 38 | */ |
| 39 | #define KVM_NR_IRQCHIPS 1 | 39 | #define KVM_NR_IRQCHIPS 1 |
| 40 | #define KVM_IRQCHIP_NUM_PINS 4096 | 40 | #define KVM_IRQCHIP_NUM_PINS 4096 |
| 41 | #define KVM_HALT_POLL_NS_DEFAULT 0 | 41 | #define KVM_HALT_POLL_NS_DEFAULT 80000 |
| 42 | 42 | ||
| 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 |
| @@ -247,6 +247,7 @@ struct kvm_vcpu_stat { | |||
| 247 | u32 exit_instruction; | 247 | u32 exit_instruction; |
| 248 | u32 halt_successful_poll; | 248 | u32 halt_successful_poll; |
| 249 | u32 halt_attempted_poll; | 249 | u32 halt_attempted_poll; |
| 250 | u32 halt_poll_invalid; | ||
| 250 | u32 halt_wakeup; | 251 | u32 halt_wakeup; |
| 251 | u32 instruction_lctl; | 252 | u32 instruction_lctl; |
| 252 | u32 instruction_lctlg; | 253 | u32 instruction_lctlg; |
| @@ -544,10 +545,6 @@ struct kvm_vcpu_arch { | |||
| 544 | struct kvm_s390_local_interrupt local_int; | 545 | struct kvm_s390_local_interrupt local_int; |
| 545 | struct hrtimer ckc_timer; | 546 | struct hrtimer ckc_timer; |
| 546 | struct kvm_s390_pgm_info pgm; | 547 | struct kvm_s390_pgm_info pgm; |
| 547 | union { | ||
| 548 | struct cpuid cpu_id; | ||
| 549 | u64 stidp_data; | ||
| 550 | }; | ||
| 551 | struct gmap *gmap; | 548 | struct gmap *gmap; |
| 552 | struct kvm_guestdbg_info_arch guestdbg; | 549 | struct kvm_guestdbg_info_arch guestdbg; |
| 553 | unsigned long pfault_token; | 550 | unsigned long pfault_token; |
| @@ -605,7 +602,7 @@ struct kvm_s390_cpu_model { | |||
| 605 | __u64 fac_mask[S390_ARCH_FAC_LIST_SIZE_U64]; | 602 | __u64 fac_mask[S390_ARCH_FAC_LIST_SIZE_U64]; |
| 606 | /* facility list requested by guest (in dma page) */ | 603 | /* facility list requested by guest (in dma page) */ |
| 607 | __u64 *fac_list; | 604 | __u64 *fac_list; |
| 608 | struct cpuid cpu_id; | 605 | u64 cpuid; |
| 609 | unsigned short ibc; | 606 | unsigned short ibc; |
| 610 | }; | 607 | }; |
| 611 | 608 | ||
| @@ -700,4 +697,6 @@ static inline void kvm_arch_flush_shadow_memslot(struct kvm *kvm, | |||
| 700 | static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {} | 697 | static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {} |
| 701 | static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {} | 698 | static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {} |
| 702 | 699 | ||
| 700 | void kvm_arch_vcpu_block_finish(struct kvm_vcpu *vcpu); | ||
| 701 | |||
| 703 | #endif | 702 | #endif |
diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h index bd7893d274fa..e4f6f73afe2f 100644 --- a/arch/s390/include/asm/sclp.h +++ b/arch/s390/include/asm/sclp.h | |||
| @@ -69,6 +69,7 @@ struct sclp_info { | |||
| 69 | unsigned int max_cores; | 69 | unsigned int max_cores; |
| 70 | unsigned long hsa_size; | 70 | unsigned long hsa_size; |
| 71 | unsigned long facilities; | 71 | unsigned long facilities; |
| 72 | unsigned int hmfai; | ||
| 72 | }; | 73 | }; |
| 73 | extern struct sclp_info sclp; | 74 | extern struct sclp_info sclp; |
| 74 | 75 | ||
diff --git a/arch/s390/include/asm/sigp.h b/arch/s390/include/asm/sigp.h index ec60cf7fa0a2..1c8f33fca356 100644 --- a/arch/s390/include/asm/sigp.h +++ b/arch/s390/include/asm/sigp.h | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | 27 | ||
| 28 | /* SIGP cpu status bits */ | 28 | /* SIGP cpu status bits */ |
| 29 | 29 | ||
| 30 | #define SIGP_STATUS_INVALID_ORDER 0x00000002UL | ||
| 30 | #define SIGP_STATUS_CHECK_STOP 0x00000010UL | 31 | #define SIGP_STATUS_CHECK_STOP 0x00000010UL |
| 31 | #define SIGP_STATUS_STOPPED 0x00000040UL | 32 | #define SIGP_STATUS_STOPPED 0x00000040UL |
| 32 | #define SIGP_STATUS_EXT_CALL_PENDING 0x00000080UL | 33 | #define SIGP_STATUS_EXT_CALL_PENDING 0x00000080UL |
diff --git a/arch/s390/include/uapi/asm/kvm.h b/arch/s390/include/uapi/asm/kvm.h index 347fe5afa419..3b8e99ef9d58 100644 --- a/arch/s390/include/uapi/asm/kvm.h +++ b/arch/s390/include/uapi/asm/kvm.h | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #define KVM_DEV_FLIC_APF_DISABLE_WAIT 5 | 25 | #define KVM_DEV_FLIC_APF_DISABLE_WAIT 5 |
| 26 | #define KVM_DEV_FLIC_ADAPTER_REGISTER 6 | 26 | #define KVM_DEV_FLIC_ADAPTER_REGISTER 6 |
| 27 | #define KVM_DEV_FLIC_ADAPTER_MODIFY 7 | 27 | #define KVM_DEV_FLIC_ADAPTER_MODIFY 7 |
| 28 | #define KVM_DEV_FLIC_CLEAR_IO_IRQ 8 | ||
| 28 | /* | 29 | /* |
| 29 | * We can have up to 4*64k pending subchannels + 8 adapter interrupts, | 30 | * We can have up to 4*64k pending subchannels + 8 adapter interrupts, |
| 30 | * as well as up to ASYNC_PF_PER_VCPU*KVM_MAX_VCPUS pfault done interrupts. | 31 | * as well as up to ASYNC_PF_PER_VCPU*KVM_MAX_VCPUS pfault done interrupts. |
diff --git a/arch/s390/include/uapi/asm/sie.h b/arch/s390/include/uapi/asm/sie.h index 5dbaa72baa64..8fb5d4a6dd25 100644 --- a/arch/s390/include/uapi/asm/sie.h +++ b/arch/s390/include/uapi/asm/sie.h | |||
| @@ -16,14 +16,19 @@ | |||
| 16 | { 0x01, "SIGP sense" }, \ | 16 | { 0x01, "SIGP sense" }, \ |
| 17 | { 0x02, "SIGP external call" }, \ | 17 | { 0x02, "SIGP external call" }, \ |
| 18 | { 0x03, "SIGP emergency signal" }, \ | 18 | { 0x03, "SIGP emergency signal" }, \ |
| 19 | { 0x04, "SIGP start" }, \ | ||
| 19 | { 0x05, "SIGP stop" }, \ | 20 | { 0x05, "SIGP stop" }, \ |
| 20 | { 0x06, "SIGP restart" }, \ | 21 | { 0x06, "SIGP restart" }, \ |
| 21 | { 0x09, "SIGP stop and store status" }, \ | 22 | { 0x09, "SIGP stop and store status" }, \ |
| 22 | { 0x0b, "SIGP initial cpu reset" }, \ | 23 | { 0x0b, "SIGP initial cpu reset" }, \ |
| 24 | { 0x0c, "SIGP cpu reset" }, \ | ||
| 23 | { 0x0d, "SIGP set prefix" }, \ | 25 | { 0x0d, "SIGP set prefix" }, \ |
| 24 | { 0x0e, "SIGP store status at address" }, \ | 26 | { 0x0e, "SIGP store status at address" }, \ |
| 25 | { 0x12, "SIGP set architecture" }, \ | 27 | { 0x12, "SIGP set architecture" }, \ |
| 26 | { 0x15, "SIGP sense running" } | 28 | { 0x13, "SIGP conditional emergency signal" }, \ |
| 29 | { 0x15, "SIGP sense running" }, \ | ||
| 30 | { 0x16, "SIGP set multithreading"}, \ | ||
| 31 | { 0x17, "SIGP store additional status ait address"} | ||
| 27 | 32 | ||
| 28 | #define icpt_prog_codes \ | 33 | #define icpt_prog_codes \ |
| 29 | { 0x0001, "Prog Operation" }, \ | 34 | { 0x0001, "Prog Operation" }, \ |
diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig index 5ea5af3c7db7..b1900239b0ab 100644 --- a/arch/s390/kvm/Kconfig +++ b/arch/s390/kvm/Kconfig | |||
| @@ -28,6 +28,7 @@ config KVM | |||
| 28 | select HAVE_KVM_IRQCHIP | 28 | select HAVE_KVM_IRQCHIP |
| 29 | select HAVE_KVM_IRQFD | 29 | select HAVE_KVM_IRQFD |
| 30 | select HAVE_KVM_IRQ_ROUTING | 30 | select HAVE_KVM_IRQ_ROUTING |
| 31 | select HAVE_KVM_INVALID_WAKEUPS | ||
| 31 | select SRCU | 32 | select SRCU |
| 32 | select KVM_VFIO | 33 | select KVM_VFIO |
| 33 | ---help--- | 34 | ---help--- |
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 84efc2ba6a90..5a80af740d3e 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c | |||
| @@ -977,6 +977,11 @@ no_timer: | |||
| 977 | 977 | ||
| 978 | void kvm_s390_vcpu_wakeup(struct kvm_vcpu *vcpu) | 978 | void kvm_s390_vcpu_wakeup(struct kvm_vcpu *vcpu) |
| 979 | { | 979 | { |
| 980 | /* | ||
| 981 | * We cannot move this into the if, as the CPU might be already | ||
| 982 | * in kvm_vcpu_block without having the waitqueue set (polling) | ||
| 983 | */ | ||
| 984 | vcpu->valid_wakeup = true; | ||
| 980 | if (swait_active(&vcpu->wq)) { | 985 | if (swait_active(&vcpu->wq)) { |
| 981 | /* | 986 | /* |
| 982 | * The vcpu gave up the cpu voluntarily, mark it as a good | 987 | * The vcpu gave up the cpu voluntarily, mark it as a good |
| @@ -2034,6 +2039,27 @@ static int modify_io_adapter(struct kvm_device *dev, | |||
| 2034 | return ret; | 2039 | return ret; |
| 2035 | } | 2040 | } |
| 2036 | 2041 | ||
| 2042 | static int clear_io_irq(struct kvm *kvm, struct kvm_device_attr *attr) | ||
| 2043 | |||
| 2044 | { | ||
| 2045 | const u64 isc_mask = 0xffUL << 24; /* all iscs set */ | ||
| 2046 | u32 schid; | ||
| 2047 | |||
| 2048 | if (attr->flags) | ||
| 2049 | return -EINVAL; | ||
| 2050 | if (attr->attr != sizeof(schid)) | ||
| 2051 | return -EINVAL; | ||
| 2052 | if (copy_from_user(&schid, (void __user *) attr->addr, sizeof(schid))) | ||
| 2053 | return -EFAULT; | ||
| 2054 | kfree(kvm_s390_get_io_int(kvm, isc_mask, schid)); | ||
| 2055 | /* | ||
| 2056 | * If userspace is conforming to the architecture, we can have at most | ||
| 2057 | * one pending I/O interrupt per subchannel, so this is effectively a | ||
| 2058 | * clear all. | ||
| 2059 | */ | ||
| 2060 | return 0; | ||
| 2061 | } | ||
| 2062 | |||
| 2037 | static int flic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr) | 2063 | static int flic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr) |
| 2038 | { | 2064 | { |
| 2039 | int r = 0; | 2065 | int r = 0; |
| @@ -2067,6 +2093,9 @@ static int flic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr) | |||
| 2067 | case KVM_DEV_FLIC_ADAPTER_MODIFY: | 2093 | case KVM_DEV_FLIC_ADAPTER_MODIFY: |
| 2068 | r = modify_io_adapter(dev, attr); | 2094 | r = modify_io_adapter(dev, attr); |
| 2069 | break; | 2095 | break; |
| 2096 | case KVM_DEV_FLIC_CLEAR_IO_IRQ: | ||
| 2097 | r = clear_io_irq(dev->kvm, attr); | ||
| 2098 | break; | ||
| 2070 | default: | 2099 | default: |
| 2071 | r = -EINVAL; | 2100 | r = -EINVAL; |
| 2072 | } | 2101 | } |
| @@ -2074,6 +2103,23 @@ static int flic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr) | |||
| 2074 | return r; | 2103 | return r; |
| 2075 | } | 2104 | } |
| 2076 | 2105 | ||
| 2106 | static int flic_has_attr(struct kvm_device *dev, | ||
| 2107 | struct kvm_device_attr *attr) | ||
| 2108 | { | ||
| 2109 | switch (attr->group) { | ||
| 2110 | case KVM_DEV_FLIC_GET_ALL_IRQS: | ||
| 2111 | case KVM_DEV_FLIC_ENQUEUE: | ||
| 2112 | case KVM_DEV_FLIC_CLEAR_IRQS: | ||
| 2113 | case KVM_DEV_FLIC_APF_ENABLE: | ||
| 2114 | case KVM_DEV_FLIC_APF_DISABLE_WAIT: | ||
| 2115 | case KVM_DEV_FLIC_ADAPTER_REGISTER: | ||
| 2116 | case KVM_DEV_FLIC_ADAPTER_MODIFY: | ||
| 2117 | case KVM_DEV_FLIC_CLEAR_IO_IRQ: | ||
| 2118 | return 0; | ||
| 2119 | } | ||
| 2120 | return -ENXIO; | ||
| 2121 | } | ||
| 2122 | |||
| 2077 | static int flic_create(struct kvm_device *dev, u32 type) | 2123 | static int flic_create(struct kvm_device *dev, u32 type) |
| 2078 | { | 2124 | { |
| 2079 | if (!dev) | 2125 | if (!dev) |
| @@ -2095,6 +2141,7 @@ struct kvm_device_ops kvm_flic_ops = { | |||
| 2095 | .name = "kvm-flic", | 2141 | .name = "kvm-flic", |
| 2096 | .get_attr = flic_get_attr, | 2142 | .get_attr = flic_get_attr, |
| 2097 | .set_attr = flic_set_attr, | 2143 | .set_attr = flic_set_attr, |
| 2144 | .has_attr = flic_has_attr, | ||
| 2098 | .create = flic_create, | 2145 | .create = flic_create, |
| 2099 | .destroy = flic_destroy, | 2146 | .destroy = flic_destroy, |
| 2100 | }; | 2147 | }; |
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 668c087513e5..6d8ec3ac9dd8 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
| @@ -65,6 +65,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { | |||
| 65 | { "exit_instr_and_program_int", VCPU_STAT(exit_instr_and_program) }, | 65 | { "exit_instr_and_program_int", VCPU_STAT(exit_instr_and_program) }, |
| 66 | { "halt_successful_poll", VCPU_STAT(halt_successful_poll) }, | 66 | { "halt_successful_poll", VCPU_STAT(halt_successful_poll) }, |
| 67 | { "halt_attempted_poll", VCPU_STAT(halt_attempted_poll) }, | 67 | { "halt_attempted_poll", VCPU_STAT(halt_attempted_poll) }, |
| 68 | { "halt_poll_invalid", VCPU_STAT(halt_poll_invalid) }, | ||
| 68 | { "halt_wakeup", VCPU_STAT(halt_wakeup) }, | 69 | { "halt_wakeup", VCPU_STAT(halt_wakeup) }, |
| 69 | { "instruction_lctlg", VCPU_STAT(instruction_lctlg) }, | 70 | { "instruction_lctlg", VCPU_STAT(instruction_lctlg) }, |
| 70 | { "instruction_lctl", VCPU_STAT(instruction_lctl) }, | 71 | { "instruction_lctl", VCPU_STAT(instruction_lctl) }, |
| @@ -118,9 +119,9 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { | |||
| 118 | }; | 119 | }; |
| 119 | 120 | ||
| 120 | /* upper facilities limit for kvm */ | 121 | /* upper facilities limit for kvm */ |
| 121 | unsigned long kvm_s390_fac_list_mask[] = { | 122 | unsigned long kvm_s390_fac_list_mask[16] = { |
| 122 | 0xffe6fffbfcfdfc40UL, | 123 | 0xffe6000000000000UL, |
| 123 | 0x005e800000000000UL, | 124 | 0x005e000000000000UL, |
| 124 | }; | 125 | }; |
| 125 | 126 | ||
| 126 | unsigned long kvm_s390_fac_list_mask_size(void) | 127 | unsigned long kvm_s390_fac_list_mask_size(void) |
| @@ -638,6 +639,7 @@ static int kvm_s390_get_tod(struct kvm *kvm, struct kvm_device_attr *attr) | |||
| 638 | static int kvm_s390_set_processor(struct kvm *kvm, struct kvm_device_attr *attr) | 639 | static int kvm_s390_set_processor(struct kvm *kvm, struct kvm_device_attr *attr) |
| 639 | { | 640 | { |
| 640 | struct kvm_s390_vm_cpu_processor *proc; | 641 | struct kvm_s390_vm_cpu_processor *proc; |
| 642 | u16 lowest_ibc, unblocked_ibc; | ||
| 641 | int ret = 0; | 643 | int ret = 0; |
| 642 | 644 | ||
| 643 | mutex_lock(&kvm->lock); | 645 | mutex_lock(&kvm->lock); |
| @@ -652,9 +654,17 @@ static int kvm_s390_set_processor(struct kvm *kvm, struct kvm_device_attr *attr) | |||
| 652 | } | 654 | } |
| 653 | if (!copy_from_user(proc, (void __user *)attr->addr, | 655 | if (!copy_from_user(proc, (void __user *)attr->addr, |
| 654 | sizeof(*proc))) { | 656 | sizeof(*proc))) { |
| 655 | memcpy(&kvm->arch.model.cpu_id, &proc->cpuid, | 657 | kvm->arch.model.cpuid = proc->cpuid; |
| 656 | sizeof(struct cpuid)); | 658 | lowest_ibc = sclp.ibc >> 16 & 0xfff; |
| 657 | kvm->arch.model.ibc = proc->ibc; | 659 | unblocked_ibc = sclp.ibc & 0xfff; |
| 660 | if (lowest_ibc) { | ||
| 661 | if (proc->ibc > unblocked_ibc) | ||
| 662 | kvm->arch.model.ibc = unblocked_ibc; | ||
| 663 | else if (proc->ibc < lowest_ibc) | ||
| 664 | kvm->arch.model.ibc = lowest_ibc; | ||
| 665 | else | ||
| 666 | kvm->arch.model.ibc = proc->ibc; | ||
| 667 | } | ||
| 658 | memcpy(kvm->arch.model.fac_list, proc->fac_list, | 668 | memcpy(kvm->arch.model.fac_list, proc->fac_list, |
| 659 | S390_ARCH_FAC_LIST_SIZE_BYTE); | 669 | S390_ARCH_FAC_LIST_SIZE_BYTE); |
| 660 | } else | 670 | } else |
| @@ -687,7 +697,7 @@ static int kvm_s390_get_processor(struct kvm *kvm, struct kvm_device_attr *attr) | |||
| 687 | ret = -ENOMEM; | 697 | ret = -ENOMEM; |
| 688 | goto out; | 698 | goto out; |
| 689 | } | 699 | } |
| 690 | memcpy(&proc->cpuid, &kvm->arch.model.cpu_id, sizeof(struct cpuid)); | 700 | proc->cpuid = kvm->arch.model.cpuid; |
| 691 | proc->ibc = kvm->arch.model.ibc; | 701 | proc->ibc = kvm->arch.model.ibc; |
| 692 | memcpy(&proc->fac_list, kvm->arch.model.fac_list, | 702 | memcpy(&proc->fac_list, kvm->arch.model.fac_list, |
| 693 | S390_ARCH_FAC_LIST_SIZE_BYTE); | 703 | S390_ARCH_FAC_LIST_SIZE_BYTE); |
| @@ -1081,10 +1091,13 @@ static void kvm_s390_set_crycb_format(struct kvm *kvm) | |||
| 1081 | kvm->arch.crypto.crycbd |= CRYCB_FORMAT1; | 1091 | kvm->arch.crypto.crycbd |= CRYCB_FORMAT1; |
| 1082 | } | 1092 | } |
| 1083 | 1093 | ||
| 1084 | static void kvm_s390_get_cpu_id(struct cpuid *cpu_id) | 1094 | static u64 kvm_s390_get_initial_cpuid(void) |
| 1085 | { | 1095 | { |
| 1086 | get_cpu_id(cpu_id); | 1096 | struct cpuid cpuid; |
| 1087 | cpu_id->version = 0xff; | 1097 | |
| 1098 | get_cpu_id(&cpuid); | ||
| 1099 | cpuid.version = 0xff; | ||
| 1100 | return *((u64 *) &cpuid); | ||
| 1088 | } | 1101 | } |
| 1089 | 1102 | ||
| 1090 | static void kvm_s390_crypto_init(struct kvm *kvm) | 1103 | static void kvm_s390_crypto_init(struct kvm *kvm) |
| @@ -1175,7 +1188,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) | |||
| 1175 | memcpy(kvm->arch.model.fac_list, kvm->arch.model.fac_mask, | 1188 | memcpy(kvm->arch.model.fac_list, kvm->arch.model.fac_mask, |
| 1176 | S390_ARCH_FAC_LIST_SIZE_BYTE); | 1189 | S390_ARCH_FAC_LIST_SIZE_BYTE); |
| 1177 | 1190 | ||
| 1178 | kvm_s390_get_cpu_id(&kvm->arch.model.cpu_id); | 1191 | kvm->arch.model.cpuid = kvm_s390_get_initial_cpuid(); |
| 1179 | kvm->arch.model.ibc = sclp.ibc & 0x0fff; | 1192 | kvm->arch.model.ibc = sclp.ibc & 0x0fff; |
| 1180 | 1193 | ||
| 1181 | kvm_s390_crypto_init(kvm); | 1194 | kvm_s390_crypto_init(kvm); |
| @@ -1624,7 +1637,6 @@ static void kvm_s390_vcpu_setup_model(struct kvm_vcpu *vcpu) | |||
| 1624 | { | 1637 | { |
| 1625 | struct kvm_s390_cpu_model *model = &vcpu->kvm->arch.model; | 1638 | struct kvm_s390_cpu_model *model = &vcpu->kvm->arch.model; |
| 1626 | 1639 | ||
| 1627 | vcpu->arch.cpu_id = model->cpu_id; | ||
| 1628 | vcpu->arch.sie_block->ibc = model->ibc; | 1640 | vcpu->arch.sie_block->ibc = model->ibc; |
| 1629 | if (test_kvm_facility(vcpu->kvm, 7)) | 1641 | if (test_kvm_facility(vcpu->kvm, 7)) |
| 1630 | vcpu->arch.sie_block->fac = (u32)(u64) model->fac_list; | 1642 | vcpu->arch.sie_block->fac = (u32)(u64) model->fac_list; |
| @@ -1645,11 +1657,14 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) | |||
| 1645 | 1657 | ||
| 1646 | kvm_s390_vcpu_setup_model(vcpu); | 1658 | kvm_s390_vcpu_setup_model(vcpu); |
| 1647 | 1659 | ||
| 1648 | vcpu->arch.sie_block->ecb = 6; | 1660 | vcpu->arch.sie_block->ecb = 0x02; |
| 1661 | if (test_kvm_facility(vcpu->kvm, 9)) | ||
| 1662 | vcpu->arch.sie_block->ecb |= 0x04; | ||
| 1649 | if (test_kvm_facility(vcpu->kvm, 50) && test_kvm_facility(vcpu->kvm, 73)) | 1663 | if (test_kvm_facility(vcpu->kvm, 50) && test_kvm_facility(vcpu->kvm, 73)) |
| 1650 | vcpu->arch.sie_block->ecb |= 0x10; | 1664 | vcpu->arch.sie_block->ecb |= 0x10; |
| 1651 | 1665 | ||
| 1652 | vcpu->arch.sie_block->ecb2 = 8; | 1666 | if (test_kvm_facility(vcpu->kvm, 8)) |
| 1667 | vcpu->arch.sie_block->ecb2 |= 0x08; | ||
| 1653 | vcpu->arch.sie_block->eca = 0xC1002000U; | 1668 | vcpu->arch.sie_block->eca = 0xC1002000U; |
| 1654 | if (sclp.has_siif) | 1669 | if (sclp.has_siif) |
| 1655 | vcpu->arch.sie_block->eca |= 1; | 1670 | vcpu->arch.sie_block->eca |= 1; |
| @@ -2971,13 +2986,31 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, | |||
| 2971 | return; | 2986 | return; |
| 2972 | } | 2987 | } |
| 2973 | 2988 | ||
| 2989 | static inline unsigned long nonhyp_mask(int i) | ||
| 2990 | { | ||
| 2991 | unsigned int nonhyp_fai = (sclp.hmfai << i * 2) >> 30; | ||
| 2992 | |||
| 2993 | return 0x0000ffffffffffffUL >> (nonhyp_fai << 4); | ||
| 2994 | } | ||
| 2995 | |||
| 2996 | void kvm_arch_vcpu_block_finish(struct kvm_vcpu *vcpu) | ||
| 2997 | { | ||
| 2998 | vcpu->valid_wakeup = false; | ||
| 2999 | } | ||
| 3000 | |||
| 2974 | static int __init kvm_s390_init(void) | 3001 | static int __init kvm_s390_init(void) |
| 2975 | { | 3002 | { |
| 3003 | int i; | ||
| 3004 | |||
| 2976 | if (!sclp.has_sief2) { | 3005 | if (!sclp.has_sief2) { |
| 2977 | pr_info("SIE not available\n"); | 3006 | pr_info("SIE not available\n"); |
| 2978 | return -ENODEV; | 3007 | return -ENODEV; |
| 2979 | } | 3008 | } |
| 2980 | 3009 | ||
| 3010 | for (i = 0; i < 16; i++) | ||
| 3011 | kvm_s390_fac_list_mask[i] |= | ||
| 3012 | S390_lowcore.stfle_fac_list[i] & nonhyp_mask(i); | ||
| 3013 | |||
| 2981 | return kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE); | 3014 | return kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE); |
| 2982 | } | 3015 | } |
| 2983 | 3016 | ||
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index 0a1591d3d25d..95916fa7c670 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c | |||
| @@ -439,7 +439,7 @@ static int handle_lpswe(struct kvm_vcpu *vcpu) | |||
| 439 | 439 | ||
| 440 | static int handle_stidp(struct kvm_vcpu *vcpu) | 440 | static int handle_stidp(struct kvm_vcpu *vcpu) |
| 441 | { | 441 | { |
| 442 | u64 stidp_data = vcpu->arch.stidp_data; | 442 | u64 stidp_data = vcpu->kvm->arch.model.cpuid; |
| 443 | u64 operand2; | 443 | u64 operand2; |
| 444 | int rc; | 444 | int rc; |
| 445 | ar_t ar; | 445 | ar_t ar; |
| @@ -670,8 +670,9 @@ static int handle_pfmf(struct kvm_vcpu *vcpu) | |||
| 670 | if (vcpu->run->s.regs.gprs[reg1] & PFMF_RESERVED) | 670 | if (vcpu->run->s.regs.gprs[reg1] & PFMF_RESERVED) |
| 671 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); | 671 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); |
| 672 | 672 | ||
| 673 | /* Only provide non-quiescing support if the host supports it */ | 673 | /* Only provide non-quiescing support if enabled for the guest */ |
| 674 | if (vcpu->run->s.regs.gprs[reg1] & PFMF_NQ && !test_facility(14)) | 674 | if (vcpu->run->s.regs.gprs[reg1] & PFMF_NQ && |
| 675 | !test_kvm_facility(vcpu->kvm, 14)) | ||
| 675 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); | 676 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); |
| 676 | 677 | ||
| 677 | /* No support for conditional-SSKE */ | 678 | /* No support for conditional-SSKE */ |
| @@ -744,7 +745,7 @@ static int handle_essa(struct kvm_vcpu *vcpu) | |||
| 744 | { | 745 | { |
| 745 | /* entries expected to be 1FF */ | 746 | /* entries expected to be 1FF */ |
| 746 | int entries = (vcpu->arch.sie_block->cbrlo & ~PAGE_MASK) >> 3; | 747 | int entries = (vcpu->arch.sie_block->cbrlo & ~PAGE_MASK) >> 3; |
| 747 | unsigned long *cbrlo, cbrle; | 748 | unsigned long *cbrlo; |
| 748 | struct gmap *gmap; | 749 | struct gmap *gmap; |
| 749 | int i; | 750 | int i; |
| 750 | 751 | ||
| @@ -765,17 +766,9 @@ static int handle_essa(struct kvm_vcpu *vcpu) | |||
| 765 | vcpu->arch.sie_block->cbrlo &= PAGE_MASK; /* reset nceo */ | 766 | vcpu->arch.sie_block->cbrlo &= PAGE_MASK; /* reset nceo */ |
| 766 | cbrlo = phys_to_virt(vcpu->arch.sie_block->cbrlo); | 767 | cbrlo = phys_to_virt(vcpu->arch.sie_block->cbrlo); |
| 767 | down_read(&gmap->mm->mmap_sem); | 768 | down_read(&gmap->mm->mmap_sem); |
| 768 | for (i = 0; i < entries; ++i) { | 769 | for (i = 0; i < entries; ++i) |
| 769 | cbrle = cbrlo[i]; | 770 | __gmap_zap(gmap, cbrlo[i]); |
| 770 | if (unlikely(cbrle & ~PAGE_MASK || cbrle < 2 * PAGE_SIZE)) | ||
| 771 | /* invalid entry */ | ||
| 772 | break; | ||
| 773 | /* try to free backing */ | ||
| 774 | __gmap_zap(gmap, cbrle); | ||
| 775 | } | ||
| 776 | up_read(&gmap->mm->mmap_sem); | 771 | up_read(&gmap->mm->mmap_sem); |
| 777 | if (i < entries) | ||
| 778 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); | ||
| 779 | return 0; | 772 | return 0; |
| 780 | } | 773 | } |
| 781 | 774 | ||
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index 77c22d685c7a..28ea0cab1f1b 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c | |||
| @@ -240,6 +240,12 @@ static int __sigp_sense_running(struct kvm_vcpu *vcpu, | |||
| 240 | struct kvm_s390_local_interrupt *li; | 240 | struct kvm_s390_local_interrupt *li; |
| 241 | int rc; | 241 | int rc; |
| 242 | 242 | ||
| 243 | if (!test_kvm_facility(vcpu->kvm, 9)) { | ||
| 244 | *reg &= 0xffffffff00000000UL; | ||
| 245 | *reg |= SIGP_STATUS_INVALID_ORDER; | ||
| 246 | return SIGP_CC_STATUS_STORED; | ||
| 247 | } | ||
| 248 | |||
| 243 | li = &dst_vcpu->arch.local_int; | 249 | li = &dst_vcpu->arch.local_int; |
| 244 | if (atomic_read(li->cpuflags) & CPUSTAT_RUNNING) { | 250 | if (atomic_read(li->cpuflags) & CPUSTAT_RUNNING) { |
| 245 | /* running */ | 251 | /* running */ |
