diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2015-02-09 07:34:43 -0500 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2015-02-09 07:34:43 -0500 |
commit | ccd9e785ea174a1c21d4c63a2afaacd6ef31d56d (patch) | |
tree | 33413aecd118bb8342e95ad3297a06ce322c07a0 | |
parent | f7819512996361280b86259222456fcf15aad926 (diff) | |
parent | de8e5d744051568c8aad35c1c2dcf8fd137d10c9 (diff) |
Merge tag 'kvm-s390-next-20150209' of git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux into HEAD
KVM: s390: fixes and features for kvm/next (3.20)
1. Fixes
- Fix user triggerable endless loop
- reenable LPP facility
- disable KVM compat ioctl on s390 (untested and broken)
2. cpu models for s390
- provide facilities and instruction blocking per VM
- add s390 specific vm attributes for setting values
3. crypto
- toleration patch for z13 support
4. add uuid and long name to /proc/sysinfo (stsi 322)
- patch Acked by Heiko Carstens (touches non-kvm s390 code)
-rw-r--r-- | Documentation/virtual/kvm/devices/vm.txt | 45 | ||||
-rw-r--r-- | arch/s390/include/asm/kvm_host.h | 27 | ||||
-rw-r--r-- | arch/s390/include/asm/sysinfo.h | 10 | ||||
-rw-r--r-- | arch/s390/include/uapi/asm/kvm.h | 21 | ||||
-rw-r--r-- | arch/s390/kernel/sysinfo.c | 29 | ||||
-rw-r--r-- | arch/s390/kvm/gaccess.c | 4 | ||||
-rw-r--r-- | arch/s390/kvm/interrupt.c | 2 | ||||
-rw-r--r-- | arch/s390/kvm/kvm-s390.c | 273 | ||||
-rw-r--r-- | arch/s390/kvm/kvm-s390.h | 13 | ||||
-rw-r--r-- | arch/s390/kvm/priv.c | 13 | ||||
-rw-r--r-- | virt/kvm/Kconfig | 4 | ||||
-rw-r--r-- | virt/kvm/kvm_main.c | 12 |
12 files changed, 397 insertions, 56 deletions
diff --git a/Documentation/virtual/kvm/devices/vm.txt b/Documentation/virtual/kvm/devices/vm.txt index c3b17c61b7dd..5542c4641a3c 100644 --- a/Documentation/virtual/kvm/devices/vm.txt +++ b/Documentation/virtual/kvm/devices/vm.txt | |||
@@ -38,3 +38,48 @@ Allows userspace to query the actual limit and set a new limit for | |||
38 | the maximum guest memory size. The limit will be rounded up to | 38 | the maximum guest memory size. The limit will be rounded up to |
39 | 2048 MB, 4096 GB, 8192 TB respectively, as this limit is governed by | 39 | 2048 MB, 4096 GB, 8192 TB respectively, as this limit is governed by |
40 | the number of page table levels. | 40 | the number of page table levels. |
41 | |||
42 | 2. GROUP: KVM_S390_VM_CPU_MODEL | ||
43 | Architectures: s390 | ||
44 | |||
45 | 2.1. ATTRIBUTE: KVM_S390_VM_CPU_MACHINE (r/o) | ||
46 | |||
47 | Allows user space to retrieve machine and kvm specific cpu related information: | ||
48 | |||
49 | struct kvm_s390_vm_cpu_machine { | ||
50 | __u64 cpuid; # CPUID of host | ||
51 | __u32 ibc; # IBC level range offered by host | ||
52 | __u8 pad[4]; | ||
53 | __u64 fac_mask[256]; # set of cpu facilities enabled by KVM | ||
54 | __u64 fac_list[256]; # set of cpu facilities offered by host | ||
55 | } | ||
56 | |||
57 | Parameters: address of buffer to store the machine related cpu data | ||
58 | of type struct kvm_s390_vm_cpu_machine* | ||
59 | Returns: -EFAULT if the given address is not accessible from kernel space | ||
60 | -ENOMEM if not enough memory is available to process the ioctl | ||
61 | 0 in case of success | ||
62 | |||
63 | 2.2. ATTRIBUTE: KVM_S390_VM_CPU_PROCESSOR (r/w) | ||
64 | |||
65 | Allows user space to retrieve or request to change cpu related information for a vcpu: | ||
66 | |||
67 | struct kvm_s390_vm_cpu_processor { | ||
68 | __u64 cpuid; # CPUID currently (to be) used by this vcpu | ||
69 | __u16 ibc; # IBC level currently (to be) used by this vcpu | ||
70 | __u8 pad[6]; | ||
71 | __u64 fac_list[256]; # set of cpu facilities currently (to be) used | ||
72 | # by this vcpu | ||
73 | } | ||
74 | |||
75 | KVM does not enforce or limit the cpu model data in any form. Take the information | ||
76 | retrieved by means of KVM_S390_VM_CPU_MACHINE as hint for reasonable configuration | ||
77 | setups. Instruction interceptions triggered by additionally set facilitiy bits that | ||
78 | are not handled by KVM need to by imlemented in the VM driver code. | ||
79 | |||
80 | Parameters: address of buffer to store/set the processor related cpu | ||
81 | data of type struct kvm_s390_vm_cpu_processor*. | ||
82 | Returns: -EBUSY in case 1 or more vcpus are already activated (only in write case) | ||
83 | -EFAULT if the given address is not accessible from kernel space | ||
84 | -ENOMEM if not enough memory is available to process the ioctl | ||
85 | 0 in case of success | ||
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index f79058e3fd98..d84559e31f32 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h | |||
@@ -89,7 +89,8 @@ struct kvm_s390_sie_block { | |||
89 | atomic_t cpuflags; /* 0x0000 */ | 89 | atomic_t cpuflags; /* 0x0000 */ |
90 | __u32 : 1; /* 0x0004 */ | 90 | __u32 : 1; /* 0x0004 */ |
91 | __u32 prefix : 18; | 91 | __u32 prefix : 18; |
92 | __u32 : 13; | 92 | __u32 : 1; |
93 | __u32 ibc : 12; | ||
93 | __u8 reserved08[4]; /* 0x0008 */ | 94 | __u8 reserved08[4]; /* 0x0008 */ |
94 | #define PROG_IN_SIE (1<<0) | 95 | #define PROG_IN_SIE (1<<0) |
95 | __u32 prog0c; /* 0x000c */ | 96 | __u32 prog0c; /* 0x000c */ |
@@ -163,6 +164,7 @@ struct kvm_s390_sie_block { | |||
163 | __u64 tecmc; /* 0x00e8 */ | 164 | __u64 tecmc; /* 0x00e8 */ |
164 | __u8 reservedf0[12]; /* 0x00f0 */ | 165 | __u8 reservedf0[12]; /* 0x00f0 */ |
165 | #define CRYCB_FORMAT1 0x00000001 | 166 | #define CRYCB_FORMAT1 0x00000001 |
167 | #define CRYCB_FORMAT2 0x00000003 | ||
166 | __u32 crycbd; /* 0x00fc */ | 168 | __u32 crycbd; /* 0x00fc */ |
167 | __u64 gcr[16]; /* 0x0100 */ | 169 | __u64 gcr[16]; /* 0x0100 */ |
168 | __u64 gbea; /* 0x0180 */ | 170 | __u64 gbea; /* 0x0180 */ |
@@ -505,6 +507,27 @@ struct s390_io_adapter { | |||
505 | #define MAX_S390_IO_ADAPTERS ((MAX_ISC + 1) * 8) | 507 | #define MAX_S390_IO_ADAPTERS ((MAX_ISC + 1) * 8) |
506 | #define MAX_S390_ADAPTER_MAPS 256 | 508 | #define MAX_S390_ADAPTER_MAPS 256 |
507 | 509 | ||
510 | /* maximum size of facilities and facility mask is 2k bytes */ | ||
511 | #define S390_ARCH_FAC_LIST_SIZE_BYTE (1<<11) | ||
512 | #define S390_ARCH_FAC_LIST_SIZE_U64 \ | ||
513 | (S390_ARCH_FAC_LIST_SIZE_BYTE / sizeof(u64)) | ||
514 | #define S390_ARCH_FAC_MASK_SIZE_BYTE S390_ARCH_FAC_LIST_SIZE_BYTE | ||
515 | #define S390_ARCH_FAC_MASK_SIZE_U64 \ | ||
516 | (S390_ARCH_FAC_MASK_SIZE_BYTE / sizeof(u64)) | ||
517 | |||
518 | struct s390_model_fac { | ||
519 | /* facilities used in SIE context */ | ||
520 | __u64 sie[S390_ARCH_FAC_LIST_SIZE_U64]; | ||
521 | /* subset enabled by kvm */ | ||
522 | __u64 kvm[S390_ARCH_FAC_LIST_SIZE_U64]; | ||
523 | }; | ||
524 | |||
525 | struct kvm_s390_cpu_model { | ||
526 | struct s390_model_fac *fac; | ||
527 | struct cpuid cpu_id; | ||
528 | unsigned short ibc; | ||
529 | }; | ||
530 | |||
508 | struct kvm_s390_crypto { | 531 | struct kvm_s390_crypto { |
509 | struct kvm_s390_crypto_cb *crycb; | 532 | struct kvm_s390_crypto_cb *crycb; |
510 | __u32 crycbd; | 533 | __u32 crycbd; |
@@ -516,6 +539,7 @@ struct kvm_s390_crypto_cb { | |||
516 | __u8 reserved00[72]; /* 0x0000 */ | 539 | __u8 reserved00[72]; /* 0x0000 */ |
517 | __u8 dea_wrapping_key_mask[24]; /* 0x0048 */ | 540 | __u8 dea_wrapping_key_mask[24]; /* 0x0048 */ |
518 | __u8 aes_wrapping_key_mask[32]; /* 0x0060 */ | 541 | __u8 aes_wrapping_key_mask[32]; /* 0x0060 */ |
542 | __u8 reserved80[128]; /* 0x0080 */ | ||
519 | }; | 543 | }; |
520 | 544 | ||
521 | struct kvm_arch{ | 545 | struct kvm_arch{ |
@@ -534,6 +558,7 @@ struct kvm_arch{ | |||
534 | int ipte_lock_count; | 558 | int ipte_lock_count; |
535 | struct mutex ipte_mutex; | 559 | struct mutex ipte_mutex; |
536 | spinlock_t start_stop_lock; | 560 | spinlock_t start_stop_lock; |
561 | struct kvm_s390_cpu_model model; | ||
537 | struct kvm_s390_crypto crypto; | 562 | struct kvm_s390_crypto crypto; |
538 | u64 epoch; | 563 | u64 epoch; |
539 | }; | 564 | }; |
diff --git a/arch/s390/include/asm/sysinfo.h b/arch/s390/include/asm/sysinfo.h index f92428e459f8..9f8f2b5c8d6c 100644 --- a/arch/s390/include/asm/sysinfo.h +++ b/arch/s390/include/asm/sysinfo.h | |||
@@ -15,6 +15,7 @@ | |||
15 | #define __ASM_S390_SYSINFO_H | 15 | #define __ASM_S390_SYSINFO_H |
16 | 16 | ||
17 | #include <asm/bitsperlong.h> | 17 | #include <asm/bitsperlong.h> |
18 | #include <linux/uuid.h> | ||
18 | 19 | ||
19 | struct sysinfo_1_1_1 { | 20 | struct sysinfo_1_1_1 { |
20 | unsigned char p:1; | 21 | unsigned char p:1; |
@@ -112,10 +113,13 @@ struct sysinfo_3_2_2 { | |||
112 | char name[8]; | 113 | char name[8]; |
113 | unsigned int caf; | 114 | unsigned int caf; |
114 | char cpi[16]; | 115 | char cpi[16]; |
115 | char reserved_1[24]; | 116 | char reserved_1[3]; |
116 | 117 | char ext_name_encoding; | |
118 | unsigned int reserved_2; | ||
119 | uuid_be uuid; | ||
117 | } vm[8]; | 120 | } vm[8]; |
118 | char reserved_544[3552]; | 121 | char reserved_3[1504]; |
122 | char ext_names[8][256]; | ||
119 | }; | 123 | }; |
120 | 124 | ||
121 | extern int topology_max_mnest; | 125 | extern int topology_max_mnest; |
diff --git a/arch/s390/include/uapi/asm/kvm.h b/arch/s390/include/uapi/asm/kvm.h index 546fc3a302e5..9c77e60b9a26 100644 --- a/arch/s390/include/uapi/asm/kvm.h +++ b/arch/s390/include/uapi/asm/kvm.h | |||
@@ -59,6 +59,7 @@ struct kvm_s390_io_adapter_req { | |||
59 | #define KVM_S390_VM_MEM_CTRL 0 | 59 | #define KVM_S390_VM_MEM_CTRL 0 |
60 | #define KVM_S390_VM_TOD 1 | 60 | #define KVM_S390_VM_TOD 1 |
61 | #define KVM_S390_VM_CRYPTO 2 | 61 | #define KVM_S390_VM_CRYPTO 2 |
62 | #define KVM_S390_VM_CPU_MODEL 3 | ||
62 | 63 | ||
63 | /* kvm attributes for mem_ctrl */ | 64 | /* kvm attributes for mem_ctrl */ |
64 | #define KVM_S390_VM_MEM_ENABLE_CMMA 0 | 65 | #define KVM_S390_VM_MEM_ENABLE_CMMA 0 |
@@ -69,6 +70,26 @@ struct kvm_s390_io_adapter_req { | |||
69 | #define KVM_S390_VM_TOD_LOW 0 | 70 | #define KVM_S390_VM_TOD_LOW 0 |
70 | #define KVM_S390_VM_TOD_HIGH 1 | 71 | #define KVM_S390_VM_TOD_HIGH 1 |
71 | 72 | ||
73 | /* kvm attributes for KVM_S390_VM_CPU_MODEL */ | ||
74 | /* processor related attributes are r/w */ | ||
75 | #define KVM_S390_VM_CPU_PROCESSOR 0 | ||
76 | struct kvm_s390_vm_cpu_processor { | ||
77 | __u64 cpuid; | ||
78 | __u16 ibc; | ||
79 | __u8 pad[6]; | ||
80 | __u64 fac_list[256]; | ||
81 | }; | ||
82 | |||
83 | /* machine related attributes are r/o */ | ||
84 | #define KVM_S390_VM_CPU_MACHINE 1 | ||
85 | struct kvm_s390_vm_cpu_machine { | ||
86 | __u64 cpuid; | ||
87 | __u32 ibc; | ||
88 | __u8 pad[4]; | ||
89 | __u64 fac_mask[256]; | ||
90 | __u64 fac_list[256]; | ||
91 | }; | ||
92 | |||
72 | /* kvm attributes for crypto */ | 93 | /* kvm attributes for crypto */ |
73 | #define KVM_S390_VM_CRYPTO_ENABLE_AES_KW 0 | 94 | #define KVM_S390_VM_CRYPTO_ENABLE_AES_KW 0 |
74 | #define KVM_S390_VM_CRYPTO_ENABLE_DEA_KW 1 | 95 | #define KVM_S390_VM_CRYPTO_ENABLE_DEA_KW 1 |
diff --git a/arch/s390/kernel/sysinfo.c b/arch/s390/kernel/sysinfo.c index 811f542b8ed4..cebab77c138c 100644 --- a/arch/s390/kernel/sysinfo.c +++ b/arch/s390/kernel/sysinfo.c | |||
@@ -196,6 +196,33 @@ static void stsi_2_2_2(struct seq_file *m, struct sysinfo_2_2_2 *info) | |||
196 | seq_printf(m, "LPAR CPUs Shared: %d\n", info->cpus_shared); | 196 | seq_printf(m, "LPAR CPUs Shared: %d\n", info->cpus_shared); |
197 | } | 197 | } |
198 | 198 | ||
199 | static void print_ext_name(struct seq_file *m, int lvl, | ||
200 | struct sysinfo_3_2_2 *info) | ||
201 | { | ||
202 | if (info->vm[lvl].ext_name_encoding == 0) | ||
203 | return; | ||
204 | if (info->ext_names[lvl][0] == 0) | ||
205 | return; | ||
206 | switch (info->vm[lvl].ext_name_encoding) { | ||
207 | case 1: /* EBCDIC */ | ||
208 | EBCASC(info->ext_names[lvl], sizeof(info->ext_names[lvl])); | ||
209 | break; | ||
210 | case 2: /* UTF-8 */ | ||
211 | break; | ||
212 | default: | ||
213 | return; | ||
214 | } | ||
215 | seq_printf(m, "VM%02d Extended Name: %-.256s\n", lvl, | ||
216 | info->ext_names[lvl]); | ||
217 | } | ||
218 | |||
219 | static void print_uuid(struct seq_file *m, int i, struct sysinfo_3_2_2 *info) | ||
220 | { | ||
221 | if (!memcmp(&info->vm[i].uuid, &NULL_UUID_BE, sizeof(uuid_be))) | ||
222 | return; | ||
223 | seq_printf(m, "VM%02d UUID: %pUb\n", i, &info->vm[i].uuid); | ||
224 | } | ||
225 | |||
199 | static void stsi_3_2_2(struct seq_file *m, struct sysinfo_3_2_2 *info) | 226 | static void stsi_3_2_2(struct seq_file *m, struct sysinfo_3_2_2 *info) |
200 | { | 227 | { |
201 | int i; | 228 | int i; |
@@ -213,6 +240,8 @@ static void stsi_3_2_2(struct seq_file *m, struct sysinfo_3_2_2 *info) | |||
213 | seq_printf(m, "VM%02d CPUs Configured: %d\n", i, info->vm[i].cpus_configured); | 240 | seq_printf(m, "VM%02d CPUs Configured: %d\n", i, info->vm[i].cpus_configured); |
214 | seq_printf(m, "VM%02d CPUs Standby: %d\n", i, info->vm[i].cpus_standby); | 241 | seq_printf(m, "VM%02d CPUs Standby: %d\n", i, info->vm[i].cpus_standby); |
215 | seq_printf(m, "VM%02d CPUs Reserved: %d\n", i, info->vm[i].cpus_reserved); | 242 | seq_printf(m, "VM%02d CPUs Reserved: %d\n", i, info->vm[i].cpus_reserved); |
243 | print_ext_name(m, i, info); | ||
244 | print_uuid(m, i, info); | ||
216 | } | 245 | } |
217 | } | 246 | } |
218 | 247 | ||
diff --git a/arch/s390/kvm/gaccess.c b/arch/s390/kvm/gaccess.c index 8a1be9017730..267523cac6de 100644 --- a/arch/s390/kvm/gaccess.c +++ b/arch/s390/kvm/gaccess.c | |||
@@ -357,8 +357,8 @@ static unsigned long guest_translate(struct kvm_vcpu *vcpu, unsigned long gva, | |||
357 | union asce asce; | 357 | union asce asce; |
358 | 358 | ||
359 | ctlreg0.val = vcpu->arch.sie_block->gcr[0]; | 359 | ctlreg0.val = vcpu->arch.sie_block->gcr[0]; |
360 | edat1 = ctlreg0.edat && test_vfacility(8); | 360 | edat1 = ctlreg0.edat && test_kvm_facility(vcpu->kvm, 8); |
361 | edat2 = edat1 && test_vfacility(78); | 361 | edat2 = edat1 && test_kvm_facility(vcpu->kvm, 78); |
362 | asce.val = get_vcpu_asce(vcpu); | 362 | asce.val = get_vcpu_asce(vcpu); |
363 | if (asce.r) | 363 | if (asce.r) |
364 | goto real_address; | 364 | goto real_address; |
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index c34e1d904ff6..073b5f387d1d 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c | |||
@@ -1244,6 +1244,8 @@ static int __inject_vm(struct kvm *kvm, struct kvm_s390_interrupt_info *inti) | |||
1244 | list_add_tail(&inti->list, &iter->list); | 1244 | list_add_tail(&inti->list, &iter->list); |
1245 | } | 1245 | } |
1246 | atomic_set(&fi->active, 1); | 1246 | atomic_set(&fi->active, 1); |
1247 | if (atomic_read(&kvm->online_vcpus) == 0) | ||
1248 | goto unlock_fi; | ||
1247 | sigcpu = find_first_bit(fi->idle_mask, KVM_MAX_VCPUS); | 1249 | sigcpu = find_first_bit(fi->idle_mask, KVM_MAX_VCPUS); |
1248 | if (sigcpu == KVM_MAX_VCPUS) { | 1250 | if (sigcpu == KVM_MAX_VCPUS) { |
1249 | do { | 1251 | do { |
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 1dbab2340a66..0c3623927563 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <asm/pgtable.h> | 30 | #include <asm/pgtable.h> |
31 | #include <asm/nmi.h> | 31 | #include <asm/nmi.h> |
32 | #include <asm/switch_to.h> | 32 | #include <asm/switch_to.h> |
33 | #include <asm/facility.h> | ||
34 | #include <asm/sclp.h> | 33 | #include <asm/sclp.h> |
35 | #include "kvm-s390.h" | 34 | #include "kvm-s390.h" |
36 | #include "gaccess.h" | 35 | #include "gaccess.h" |
@@ -100,15 +99,20 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { | |||
100 | { NULL } | 99 | { NULL } |
101 | }; | 100 | }; |
102 | 101 | ||
103 | unsigned long *vfacilities; | 102 | /* upper facilities limit for kvm */ |
104 | static struct gmap_notifier gmap_notifier; | 103 | unsigned long kvm_s390_fac_list_mask[] = { |
104 | 0xff82fffbf4fc2000UL, | ||
105 | 0x005c000000000000UL, | ||
106 | }; | ||
105 | 107 | ||
106 | /* test availability of vfacility */ | 108 | unsigned long kvm_s390_fac_list_mask_size(void) |
107 | int test_vfacility(unsigned long nr) | ||
108 | { | 109 | { |
109 | return __test_facility(nr, (void *) vfacilities); | 110 | BUILD_BUG_ON(ARRAY_SIZE(kvm_s390_fac_list_mask) > S390_ARCH_FAC_MASK_SIZE_U64); |
111 | return ARRAY_SIZE(kvm_s390_fac_list_mask); | ||
110 | } | 112 | } |
111 | 113 | ||
114 | static struct gmap_notifier gmap_notifier; | ||
115 | |||
112 | /* Section: not file related */ | 116 | /* Section: not file related */ |
113 | int kvm_arch_hardware_enable(void) | 117 | int kvm_arch_hardware_enable(void) |
114 | { | 118 | { |
@@ -351,7 +355,7 @@ static int kvm_s390_vm_set_crypto(struct kvm *kvm, struct kvm_device_attr *attr) | |||
351 | struct kvm_vcpu *vcpu; | 355 | struct kvm_vcpu *vcpu; |
352 | int i; | 356 | int i; |
353 | 357 | ||
354 | if (!test_vfacility(76)) | 358 | if (!test_kvm_facility(kvm, 76)) |
355 | return -EINVAL; | 359 | return -EINVAL; |
356 | 360 | ||
357 | mutex_lock(&kvm->lock); | 361 | mutex_lock(&kvm->lock); |
@@ -498,6 +502,106 @@ static int kvm_s390_get_tod(struct kvm *kvm, struct kvm_device_attr *attr) | |||
498 | return ret; | 502 | return ret; |
499 | } | 503 | } |
500 | 504 | ||
505 | static int kvm_s390_set_processor(struct kvm *kvm, struct kvm_device_attr *attr) | ||
506 | { | ||
507 | struct kvm_s390_vm_cpu_processor *proc; | ||
508 | int ret = 0; | ||
509 | |||
510 | mutex_lock(&kvm->lock); | ||
511 | if (atomic_read(&kvm->online_vcpus)) { | ||
512 | ret = -EBUSY; | ||
513 | goto out; | ||
514 | } | ||
515 | proc = kzalloc(sizeof(*proc), GFP_KERNEL); | ||
516 | if (!proc) { | ||
517 | ret = -ENOMEM; | ||
518 | goto out; | ||
519 | } | ||
520 | if (!copy_from_user(proc, (void __user *)attr->addr, | ||
521 | sizeof(*proc))) { | ||
522 | memcpy(&kvm->arch.model.cpu_id, &proc->cpuid, | ||
523 | sizeof(struct cpuid)); | ||
524 | kvm->arch.model.ibc = proc->ibc; | ||
525 | memcpy(kvm->arch.model.fac->kvm, proc->fac_list, | ||
526 | S390_ARCH_FAC_LIST_SIZE_BYTE); | ||
527 | } else | ||
528 | ret = -EFAULT; | ||
529 | kfree(proc); | ||
530 | out: | ||
531 | mutex_unlock(&kvm->lock); | ||
532 | return ret; | ||
533 | } | ||
534 | |||
535 | static int kvm_s390_set_cpu_model(struct kvm *kvm, struct kvm_device_attr *attr) | ||
536 | { | ||
537 | int ret = -ENXIO; | ||
538 | |||
539 | switch (attr->attr) { | ||
540 | case KVM_S390_VM_CPU_PROCESSOR: | ||
541 | ret = kvm_s390_set_processor(kvm, attr); | ||
542 | break; | ||
543 | } | ||
544 | return ret; | ||
545 | } | ||
546 | |||
547 | static int kvm_s390_get_processor(struct kvm *kvm, struct kvm_device_attr *attr) | ||
548 | { | ||
549 | struct kvm_s390_vm_cpu_processor *proc; | ||
550 | int ret = 0; | ||
551 | |||
552 | proc = kzalloc(sizeof(*proc), GFP_KERNEL); | ||
553 | if (!proc) { | ||
554 | ret = -ENOMEM; | ||
555 | goto out; | ||
556 | } | ||
557 | memcpy(&proc->cpuid, &kvm->arch.model.cpu_id, sizeof(struct cpuid)); | ||
558 | proc->ibc = kvm->arch.model.ibc; | ||
559 | memcpy(&proc->fac_list, kvm->arch.model.fac->kvm, S390_ARCH_FAC_LIST_SIZE_BYTE); | ||
560 | if (copy_to_user((void __user *)attr->addr, proc, sizeof(*proc))) | ||
561 | ret = -EFAULT; | ||
562 | kfree(proc); | ||
563 | out: | ||
564 | return ret; | ||
565 | } | ||
566 | |||
567 | static int kvm_s390_get_machine(struct kvm *kvm, struct kvm_device_attr *attr) | ||
568 | { | ||
569 | struct kvm_s390_vm_cpu_machine *mach; | ||
570 | int ret = 0; | ||
571 | |||
572 | mach = kzalloc(sizeof(*mach), GFP_KERNEL); | ||
573 | if (!mach) { | ||
574 | ret = -ENOMEM; | ||
575 | goto out; | ||
576 | } | ||
577 | get_cpu_id((struct cpuid *) &mach->cpuid); | ||
578 | mach->ibc = sclp_get_ibc(); | ||
579 | memcpy(&mach->fac_mask, kvm_s390_fac_list_mask, | ||
580 | kvm_s390_fac_list_mask_size() * sizeof(u64)); | ||
581 | memcpy((unsigned long *)&mach->fac_list, S390_lowcore.stfle_fac_list, | ||
582 | S390_ARCH_FAC_LIST_SIZE_U64); | ||
583 | if (copy_to_user((void __user *)attr->addr, mach, sizeof(*mach))) | ||
584 | ret = -EFAULT; | ||
585 | kfree(mach); | ||
586 | out: | ||
587 | return ret; | ||
588 | } | ||
589 | |||
590 | static int kvm_s390_get_cpu_model(struct kvm *kvm, struct kvm_device_attr *attr) | ||
591 | { | ||
592 | int ret = -ENXIO; | ||
593 | |||
594 | switch (attr->attr) { | ||
595 | case KVM_S390_VM_CPU_PROCESSOR: | ||
596 | ret = kvm_s390_get_processor(kvm, attr); | ||
597 | break; | ||
598 | case KVM_S390_VM_CPU_MACHINE: | ||
599 | ret = kvm_s390_get_machine(kvm, attr); | ||
600 | break; | ||
601 | } | ||
602 | return ret; | ||
603 | } | ||
604 | |||
501 | static int kvm_s390_vm_set_attr(struct kvm *kvm, struct kvm_device_attr *attr) | 605 | static int kvm_s390_vm_set_attr(struct kvm *kvm, struct kvm_device_attr *attr) |
502 | { | 606 | { |
503 | int ret; | 607 | int ret; |
@@ -509,6 +613,9 @@ static int kvm_s390_vm_set_attr(struct kvm *kvm, struct kvm_device_attr *attr) | |||
509 | case KVM_S390_VM_TOD: | 613 | case KVM_S390_VM_TOD: |
510 | ret = kvm_s390_set_tod(kvm, attr); | 614 | ret = kvm_s390_set_tod(kvm, attr); |
511 | break; | 615 | break; |
616 | case KVM_S390_VM_CPU_MODEL: | ||
617 | ret = kvm_s390_set_cpu_model(kvm, attr); | ||
618 | break; | ||
512 | case KVM_S390_VM_CRYPTO: | 619 | case KVM_S390_VM_CRYPTO: |
513 | ret = kvm_s390_vm_set_crypto(kvm, attr); | 620 | ret = kvm_s390_vm_set_crypto(kvm, attr); |
514 | break; | 621 | break; |
@@ -531,6 +638,9 @@ static int kvm_s390_vm_get_attr(struct kvm *kvm, struct kvm_device_attr *attr) | |||
531 | case KVM_S390_VM_TOD: | 638 | case KVM_S390_VM_TOD: |
532 | ret = kvm_s390_get_tod(kvm, attr); | 639 | ret = kvm_s390_get_tod(kvm, attr); |
533 | break; | 640 | break; |
641 | case KVM_S390_VM_CPU_MODEL: | ||
642 | ret = kvm_s390_get_cpu_model(kvm, attr); | ||
643 | break; | ||
534 | default: | 644 | default: |
535 | ret = -ENXIO; | 645 | ret = -ENXIO; |
536 | break; | 646 | break; |
@@ -567,6 +677,17 @@ static int kvm_s390_vm_has_attr(struct kvm *kvm, struct kvm_device_attr *attr) | |||
567 | break; | 677 | break; |
568 | } | 678 | } |
569 | break; | 679 | break; |
680 | case KVM_S390_VM_CPU_MODEL: | ||
681 | switch (attr->attr) { | ||
682 | case KVM_S390_VM_CPU_PROCESSOR: | ||
683 | case KVM_S390_VM_CPU_MACHINE: | ||
684 | ret = 0; | ||
685 | break; | ||
686 | default: | ||
687 | ret = -ENXIO; | ||
688 | break; | ||
689 | } | ||
690 | break; | ||
570 | case KVM_S390_VM_CRYPTO: | 691 | case KVM_S390_VM_CRYPTO: |
571 | switch (attr->attr) { | 692 | switch (attr->attr) { |
572 | case KVM_S390_VM_CRYPTO_ENABLE_AES_KW: | 693 | case KVM_S390_VM_CRYPTO_ENABLE_AES_KW: |
@@ -654,9 +775,61 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
654 | return r; | 775 | return r; |
655 | } | 776 | } |
656 | 777 | ||
778 | static int kvm_s390_query_ap_config(u8 *config) | ||
779 | { | ||
780 | u32 fcn_code = 0x04000000UL; | ||
781 | u32 cc; | ||
782 | |||
783 | asm volatile( | ||
784 | "lgr 0,%1\n" | ||
785 | "lgr 2,%2\n" | ||
786 | ".long 0xb2af0000\n" /* PQAP(QCI) */ | ||
787 | "ipm %0\n" | ||
788 | "srl %0,28\n" | ||
789 | : "=r" (cc) | ||
790 | : "r" (fcn_code), "r" (config) | ||
791 | : "cc", "0", "2", "memory" | ||
792 | ); | ||
793 | |||
794 | return cc; | ||
795 | } | ||
796 | |||
797 | static int kvm_s390_apxa_installed(void) | ||
798 | { | ||
799 | u8 config[128]; | ||
800 | int cc; | ||
801 | |||
802 | if (test_facility(2) && test_facility(12)) { | ||
803 | cc = kvm_s390_query_ap_config(config); | ||
804 | |||
805 | if (cc) | ||
806 | pr_err("PQAP(QCI) failed with cc=%d", cc); | ||
807 | else | ||
808 | return config[0] & 0x40; | ||
809 | } | ||
810 | |||
811 | return 0; | ||
812 | } | ||
813 | |||
814 | static void kvm_s390_set_crycb_format(struct kvm *kvm) | ||
815 | { | ||
816 | kvm->arch.crypto.crycbd = (__u32)(unsigned long) kvm->arch.crypto.crycb; | ||
817 | |||
818 | if (kvm_s390_apxa_installed()) | ||
819 | kvm->arch.crypto.crycbd |= CRYCB_FORMAT2; | ||
820 | else | ||
821 | kvm->arch.crypto.crycbd |= CRYCB_FORMAT1; | ||
822 | } | ||
823 | |||
824 | static void kvm_s390_get_cpu_id(struct cpuid *cpu_id) | ||
825 | { | ||
826 | get_cpu_id(cpu_id); | ||
827 | cpu_id->version = 0xff; | ||
828 | } | ||
829 | |||
657 | static int kvm_s390_crypto_init(struct kvm *kvm) | 830 | static int kvm_s390_crypto_init(struct kvm *kvm) |
658 | { | 831 | { |
659 | if (!test_vfacility(76)) | 832 | if (!test_kvm_facility(kvm, 76)) |
660 | return 0; | 833 | return 0; |
661 | 834 | ||
662 | kvm->arch.crypto.crycb = kzalloc(sizeof(*kvm->arch.crypto.crycb), | 835 | kvm->arch.crypto.crycb = kzalloc(sizeof(*kvm->arch.crypto.crycb), |
@@ -664,8 +837,7 @@ static int kvm_s390_crypto_init(struct kvm *kvm) | |||
664 | if (!kvm->arch.crypto.crycb) | 837 | if (!kvm->arch.crypto.crycb) |
665 | return -ENOMEM; | 838 | return -ENOMEM; |
666 | 839 | ||
667 | kvm->arch.crypto.crycbd = (__u32) (unsigned long) kvm->arch.crypto.crycb | | 840 | kvm_s390_set_crycb_format(kvm); |
668 | CRYCB_FORMAT1; | ||
669 | 841 | ||
670 | /* Disable AES/DEA protected key functions by default */ | 842 | /* Disable AES/DEA protected key functions by default */ |
671 | kvm->arch.crypto.aes_kw = 0; | 843 | kvm->arch.crypto.aes_kw = 0; |
@@ -676,7 +848,7 @@ static int kvm_s390_crypto_init(struct kvm *kvm) | |||
676 | 848 | ||
677 | int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) | 849 | int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) |
678 | { | 850 | { |
679 | int rc; | 851 | int i, rc; |
680 | char debug_name[16]; | 852 | char debug_name[16]; |
681 | static unsigned long sca_offset; | 853 | static unsigned long sca_offset; |
682 | 854 | ||
@@ -711,6 +883,46 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) | |||
711 | if (!kvm->arch.dbf) | 883 | if (!kvm->arch.dbf) |
712 | goto out_nodbf; | 884 | goto out_nodbf; |
713 | 885 | ||
886 | /* | ||
887 | * The architectural maximum amount of facilities is 16 kbit. To store | ||
888 | * this amount, 2 kbyte of memory is required. Thus we need a full | ||
889 | * page to hold the active copy (arch.model.fac->sie) and the current | ||
890 | * facilities set (arch.model.fac->kvm). Its address size has to be | ||
891 | * 31 bits and word aligned. | ||
892 | */ | ||
893 | kvm->arch.model.fac = | ||
894 | (struct s390_model_fac *) get_zeroed_page(GFP_KERNEL | GFP_DMA); | ||
895 | if (!kvm->arch.model.fac) | ||
896 | goto out_nofac; | ||
897 | |||
898 | memcpy(kvm->arch.model.fac->kvm, S390_lowcore.stfle_fac_list, | ||
899 | S390_ARCH_FAC_LIST_SIZE_U64); | ||
900 | |||
901 | /* | ||
902 | * If this KVM host runs *not* in a LPAR, relax the facility bits | ||
903 | * of the kvm facility mask by all missing facilities. This will allow | ||
904 | * to determine the right CPU model by means of the remaining facilities. | ||
905 | * Live guest migration must prohibit the migration of KVMs running in | ||
906 | * a LPAR to non LPAR hosts. | ||
907 | */ | ||
908 | if (!MACHINE_IS_LPAR) | ||
909 | for (i = 0; i < kvm_s390_fac_list_mask_size(); i++) | ||
910 | kvm_s390_fac_list_mask[i] &= kvm->arch.model.fac->kvm[i]; | ||
911 | |||
912 | /* | ||
913 | * Apply the kvm facility mask to limit the kvm supported/tolerated | ||
914 | * facility list. | ||
915 | */ | ||
916 | for (i = 0; i < S390_ARCH_FAC_LIST_SIZE_U64; i++) { | ||
917 | if (i < kvm_s390_fac_list_mask_size()) | ||
918 | kvm->arch.model.fac->kvm[i] &= kvm_s390_fac_list_mask[i]; | ||
919 | else | ||
920 | kvm->arch.model.fac->kvm[i] = 0UL; | ||
921 | } | ||
922 | |||
923 | kvm_s390_get_cpu_id(&kvm->arch.model.cpu_id); | ||
924 | kvm->arch.model.ibc = sclp_get_ibc() & 0x0fff; | ||
925 | |||
714 | if (kvm_s390_crypto_init(kvm) < 0) | 926 | if (kvm_s390_crypto_init(kvm) < 0) |
715 | goto out_crypto; | 927 | goto out_crypto; |
716 | 928 | ||
@@ -742,6 +954,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) | |||
742 | out_nogmap: | 954 | out_nogmap: |
743 | kfree(kvm->arch.crypto.crycb); | 955 | kfree(kvm->arch.crypto.crycb); |
744 | out_crypto: | 956 | out_crypto: |
957 | free_page((unsigned long)kvm->arch.model.fac); | ||
958 | out_nofac: | ||
745 | debug_unregister(kvm->arch.dbf); | 959 | debug_unregister(kvm->arch.dbf); |
746 | out_nodbf: | 960 | out_nodbf: |
747 | free_page((unsigned long)(kvm->arch.sca)); | 961 | free_page((unsigned long)(kvm->arch.sca)); |
@@ -794,6 +1008,7 @@ static void kvm_free_vcpus(struct kvm *kvm) | |||
794 | void kvm_arch_destroy_vm(struct kvm *kvm) | 1008 | void kvm_arch_destroy_vm(struct kvm *kvm) |
795 | { | 1009 | { |
796 | kvm_free_vcpus(kvm); | 1010 | kvm_free_vcpus(kvm); |
1011 | free_page((unsigned long)kvm->arch.model.fac); | ||
797 | free_page((unsigned long)(kvm->arch.sca)); | 1012 | free_page((unsigned long)(kvm->arch.sca)); |
798 | debug_unregister(kvm->arch.dbf); | 1013 | debug_unregister(kvm->arch.dbf); |
799 | kfree(kvm->arch.crypto.crycb); | 1014 | kfree(kvm->arch.crypto.crycb); |
@@ -889,7 +1104,7 @@ void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) | |||
889 | 1104 | ||
890 | static void kvm_s390_vcpu_crypto_setup(struct kvm_vcpu *vcpu) | 1105 | static void kvm_s390_vcpu_crypto_setup(struct kvm_vcpu *vcpu) |
891 | { | 1106 | { |
892 | if (!test_vfacility(76)) | 1107 | if (!test_kvm_facility(vcpu->kvm, 76)) |
893 | return; | 1108 | return; |
894 | 1109 | ||
895 | vcpu->arch.sie_block->ecb3 &= ~(ECB3_AES | ECB3_DEA); | 1110 | vcpu->arch.sie_block->ecb3 &= ~(ECB3_AES | ECB3_DEA); |
@@ -928,7 +1143,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) | |||
928 | CPUSTAT_STOPPED | | 1143 | CPUSTAT_STOPPED | |
929 | CPUSTAT_GED); | 1144 | CPUSTAT_GED); |
930 | vcpu->arch.sie_block->ecb = 6; | 1145 | vcpu->arch.sie_block->ecb = 6; |
931 | if (test_vfacility(50) && test_vfacility(73)) | 1146 | if (test_kvm_facility(vcpu->kvm, 50) && test_kvm_facility(vcpu->kvm, 73)) |
932 | vcpu->arch.sie_block->ecb |= 0x10; | 1147 | vcpu->arch.sie_block->ecb |= 0x10; |
933 | 1148 | ||
934 | vcpu->arch.sie_block->ecb2 = 8; | 1149 | vcpu->arch.sie_block->ecb2 = 8; |
@@ -937,7 +1152,6 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) | |||
937 | vcpu->arch.sie_block->eca |= 1; | 1152 | vcpu->arch.sie_block->eca |= 1; |
938 | if (sclp_has_sigpif()) | 1153 | if (sclp_has_sigpif()) |
939 | vcpu->arch.sie_block->eca |= 0x10000000U; | 1154 | vcpu->arch.sie_block->eca |= 0x10000000U; |
940 | vcpu->arch.sie_block->fac = (int) (long) vfacilities; | ||
941 | vcpu->arch.sie_block->ictl |= ICTL_ISKE | ICTL_SSKE | ICTL_RRBE | | 1155 | vcpu->arch.sie_block->ictl |= ICTL_ISKE | ICTL_SSKE | ICTL_RRBE | |
942 | ICTL_TPROT; | 1156 | ICTL_TPROT; |
943 | 1157 | ||
@@ -948,8 +1162,13 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) | |||
948 | } | 1162 | } |
949 | hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | 1163 | hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
950 | vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup; | 1164 | vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup; |
951 | get_cpu_id(&vcpu->arch.cpu_id); | 1165 | |
952 | vcpu->arch.cpu_id.version = 0xff; | 1166 | mutex_lock(&vcpu->kvm->lock); |
1167 | vcpu->arch.cpu_id = vcpu->kvm->arch.model.cpu_id; | ||
1168 | memcpy(vcpu->kvm->arch.model.fac->sie, vcpu->kvm->arch.model.fac->kvm, | ||
1169 | S390_ARCH_FAC_LIST_SIZE_BYTE); | ||
1170 | vcpu->arch.sie_block->ibc = vcpu->kvm->arch.model.ibc; | ||
1171 | mutex_unlock(&vcpu->kvm->lock); | ||
953 | 1172 | ||
954 | kvm_s390_vcpu_crypto_setup(vcpu); | 1173 | kvm_s390_vcpu_crypto_setup(vcpu); |
955 | 1174 | ||
@@ -993,6 +1212,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, | |||
993 | vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca; | 1212 | vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca; |
994 | set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn); | 1213 | set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn); |
995 | } | 1214 | } |
1215 | vcpu->arch.sie_block->fac = (int) (long) kvm->arch.model.fac->sie; | ||
996 | 1216 | ||
997 | spin_lock_init(&vcpu->arch.local_int.lock); | 1217 | spin_lock_init(&vcpu->arch.local_int.lock); |
998 | vcpu->arch.local_int.float_int = &kvm->arch.float_int; | 1218 | vcpu->arch.local_int.float_int = &kvm->arch.float_int; |
@@ -2058,30 +2278,11 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, | |||
2058 | 2278 | ||
2059 | static int __init kvm_s390_init(void) | 2279 | static int __init kvm_s390_init(void) |
2060 | { | 2280 | { |
2061 | int ret; | 2281 | return kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE); |
2062 | ret = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE); | ||
2063 | if (ret) | ||
2064 | return ret; | ||
2065 | |||
2066 | /* | ||
2067 | * guests can ask for up to 255+1 double words, we need a full page | ||
2068 | * to hold the maximum amount of facilities. On the other hand, we | ||
2069 | * only set facilities that are known to work in KVM. | ||
2070 | */ | ||
2071 | vfacilities = (unsigned long *) get_zeroed_page(GFP_KERNEL|GFP_DMA); | ||
2072 | if (!vfacilities) { | ||
2073 | kvm_exit(); | ||
2074 | return -ENOMEM; | ||
2075 | } | ||
2076 | memcpy(vfacilities, S390_lowcore.stfle_fac_list, 16); | ||
2077 | vfacilities[0] &= 0xff82fffbf47c2000UL; | ||
2078 | vfacilities[1] &= 0x005c000000000000UL; | ||
2079 | return 0; | ||
2080 | } | 2282 | } |
2081 | 2283 | ||
2082 | static void __exit kvm_s390_exit(void) | 2284 | static void __exit kvm_s390_exit(void) |
2083 | { | 2285 | { |
2084 | free_page((unsigned long) vfacilities); | ||
2085 | kvm_exit(); | 2286 | kvm_exit(); |
2086 | } | 2287 | } |
2087 | 2288 | ||
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h index c22dce8a7536..985c2114d7ef 100644 --- a/arch/s390/kvm/kvm-s390.h +++ b/arch/s390/kvm/kvm-s390.h | |||
@@ -18,12 +18,10 @@ | |||
18 | #include <linux/hrtimer.h> | 18 | #include <linux/hrtimer.h> |
19 | #include <linux/kvm.h> | 19 | #include <linux/kvm.h> |
20 | #include <linux/kvm_host.h> | 20 | #include <linux/kvm_host.h> |
21 | #include <asm/facility.h> | ||
21 | 22 | ||
22 | typedef int (*intercept_handler_t)(struct kvm_vcpu *vcpu); | 23 | typedef int (*intercept_handler_t)(struct kvm_vcpu *vcpu); |
23 | 24 | ||
24 | /* declare vfacilities extern */ | ||
25 | extern unsigned long *vfacilities; | ||
26 | |||
27 | /* Transactional Memory Execution related macros */ | 25 | /* Transactional Memory Execution related macros */ |
28 | #define IS_TE_ENABLED(vcpu) ((vcpu->arch.sie_block->ecb & 0x10)) | 26 | #define IS_TE_ENABLED(vcpu) ((vcpu->arch.sie_block->ecb & 0x10)) |
29 | #define TDB_FORMAT1 1 | 27 | #define TDB_FORMAT1 1 |
@@ -127,6 +125,12 @@ static inline void kvm_s390_set_psw_cc(struct kvm_vcpu *vcpu, unsigned long cc) | |||
127 | vcpu->arch.sie_block->gpsw.mask |= cc << 44; | 125 | vcpu->arch.sie_block->gpsw.mask |= cc << 44; |
128 | } | 126 | } |
129 | 127 | ||
128 | /* test availability of facility in a kvm intance */ | ||
129 | static inline int test_kvm_facility(struct kvm *kvm, unsigned long nr) | ||
130 | { | ||
131 | return __test_facility(nr, kvm->arch.model.fac->kvm); | ||
132 | } | ||
133 | |||
130 | /* are cpu states controlled by user space */ | 134 | /* are cpu states controlled by user space */ |
131 | static inline int kvm_s390_user_cpu_state_ctrl(struct kvm *kvm) | 135 | static inline int kvm_s390_user_cpu_state_ctrl(struct kvm *kvm) |
132 | { | 136 | { |
@@ -183,7 +187,8 @@ int kvm_s390_vcpu_setup_cmma(struct kvm_vcpu *vcpu); | |||
183 | void kvm_s390_vcpu_unsetup_cmma(struct kvm_vcpu *vcpu); | 187 | void kvm_s390_vcpu_unsetup_cmma(struct kvm_vcpu *vcpu); |
184 | /* is cmma enabled */ | 188 | /* is cmma enabled */ |
185 | bool kvm_s390_cmma_enabled(struct kvm *kvm); | 189 | bool kvm_s390_cmma_enabled(struct kvm *kvm); |
186 | int test_vfacility(unsigned long nr); | 190 | unsigned long kvm_s390_fac_list_mask_size(void); |
191 | extern unsigned long kvm_s390_fac_list_mask[]; | ||
187 | 192 | ||
188 | /* implemented in diag.c */ | 193 | /* implemented in diag.c */ |
189 | int kvm_s390_handle_diag(struct kvm_vcpu *vcpu); | 194 | int kvm_s390_handle_diag(struct kvm_vcpu *vcpu); |
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index 1be578d64dfc..bdd9b5b17e03 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c | |||
@@ -337,19 +337,24 @@ static int handle_io_inst(struct kvm_vcpu *vcpu) | |||
337 | static int handle_stfl(struct kvm_vcpu *vcpu) | 337 | static int handle_stfl(struct kvm_vcpu *vcpu) |
338 | { | 338 | { |
339 | int rc; | 339 | int rc; |
340 | unsigned int fac; | ||
340 | 341 | ||
341 | vcpu->stat.instruction_stfl++; | 342 | vcpu->stat.instruction_stfl++; |
342 | 343 | ||
343 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) | 344 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) |
344 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); | 345 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); |
345 | 346 | ||
347 | /* | ||
348 | * We need to shift the lower 32 facility bits (bit 0-31) from a u64 | ||
349 | * into a u32 memory representation. They will remain bits 0-31. | ||
350 | */ | ||
351 | fac = *vcpu->kvm->arch.model.fac->sie >> 32; | ||
346 | rc = write_guest_lc(vcpu, offsetof(struct _lowcore, stfl_fac_list), | 352 | rc = write_guest_lc(vcpu, offsetof(struct _lowcore, stfl_fac_list), |
347 | vfacilities, 4); | 353 | &fac, sizeof(fac)); |
348 | if (rc) | 354 | if (rc) |
349 | return rc; | 355 | return rc; |
350 | VCPU_EVENT(vcpu, 5, "store facility list value %x", | 356 | VCPU_EVENT(vcpu, 5, "store facility list value %x", fac); |
351 | *(unsigned int *) vfacilities); | 357 | trace_kvm_s390_handle_stfl(vcpu, fac); |
352 | trace_kvm_s390_handle_stfl(vcpu, *(unsigned int *) vfacilities); | ||
353 | return 0; | 358 | return 0; |
354 | } | 359 | } |
355 | 360 | ||
diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig index 50d110654b42..e2c876d5a03b 100644 --- a/virt/kvm/Kconfig +++ b/virt/kvm/Kconfig | |||
@@ -43,3 +43,7 @@ config HAVE_KVM_ARCH_TLB_FLUSH_ALL | |||
43 | 43 | ||
44 | config KVM_GENERIC_DIRTYLOG_READ_PROTECT | 44 | config KVM_GENERIC_DIRTYLOG_READ_PROTECT |
45 | bool | 45 | bool |
46 | |||
47 | config KVM_COMPAT | ||
48 | def_bool y | ||
49 | depends on COMPAT && !S390 | ||
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 32449e0e9aa8..8579f1876e5a 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -92,7 +92,7 @@ struct dentry *kvm_debugfs_dir; | |||
92 | 92 | ||
93 | static long kvm_vcpu_ioctl(struct file *file, unsigned int ioctl, | 93 | static long kvm_vcpu_ioctl(struct file *file, unsigned int ioctl, |
94 | unsigned long arg); | 94 | unsigned long arg); |
95 | #ifdef CONFIG_COMPAT | 95 | #ifdef CONFIG_KVM_COMPAT |
96 | static long kvm_vcpu_compat_ioctl(struct file *file, unsigned int ioctl, | 96 | static long kvm_vcpu_compat_ioctl(struct file *file, unsigned int ioctl, |
97 | unsigned long arg); | 97 | unsigned long arg); |
98 | #endif | 98 | #endif |
@@ -2052,7 +2052,7 @@ static int kvm_vcpu_release(struct inode *inode, struct file *filp) | |||
2052 | static struct file_operations kvm_vcpu_fops = { | 2052 | static struct file_operations kvm_vcpu_fops = { |
2053 | .release = kvm_vcpu_release, | 2053 | .release = kvm_vcpu_release, |
2054 | .unlocked_ioctl = kvm_vcpu_ioctl, | 2054 | .unlocked_ioctl = kvm_vcpu_ioctl, |
2055 | #ifdef CONFIG_COMPAT | 2055 | #ifdef CONFIG_KVM_COMPAT |
2056 | .compat_ioctl = kvm_vcpu_compat_ioctl, | 2056 | .compat_ioctl = kvm_vcpu_compat_ioctl, |
2057 | #endif | 2057 | #endif |
2058 | .mmap = kvm_vcpu_mmap, | 2058 | .mmap = kvm_vcpu_mmap, |
@@ -2342,7 +2342,7 @@ out: | |||
2342 | return r; | 2342 | return r; |
2343 | } | 2343 | } |
2344 | 2344 | ||
2345 | #ifdef CONFIG_COMPAT | 2345 | #ifdef CONFIG_KVM_COMPAT |
2346 | static long kvm_vcpu_compat_ioctl(struct file *filp, | 2346 | static long kvm_vcpu_compat_ioctl(struct file *filp, |
2347 | unsigned int ioctl, unsigned long arg) | 2347 | unsigned int ioctl, unsigned long arg) |
2348 | { | 2348 | { |
@@ -2434,7 +2434,7 @@ static int kvm_device_release(struct inode *inode, struct file *filp) | |||
2434 | 2434 | ||
2435 | static const struct file_operations kvm_device_fops = { | 2435 | static const struct file_operations kvm_device_fops = { |
2436 | .unlocked_ioctl = kvm_device_ioctl, | 2436 | .unlocked_ioctl = kvm_device_ioctl, |
2437 | #ifdef CONFIG_COMPAT | 2437 | #ifdef CONFIG_KVM_COMPAT |
2438 | .compat_ioctl = kvm_device_ioctl, | 2438 | .compat_ioctl = kvm_device_ioctl, |
2439 | #endif | 2439 | #endif |
2440 | .release = kvm_device_release, | 2440 | .release = kvm_device_release, |
@@ -2721,7 +2721,7 @@ out: | |||
2721 | return r; | 2721 | return r; |
2722 | } | 2722 | } |
2723 | 2723 | ||
2724 | #ifdef CONFIG_COMPAT | 2724 | #ifdef CONFIG_KVM_COMPAT |
2725 | struct compat_kvm_dirty_log { | 2725 | struct compat_kvm_dirty_log { |
2726 | __u32 slot; | 2726 | __u32 slot; |
2727 | __u32 padding1; | 2727 | __u32 padding1; |
@@ -2768,7 +2768,7 @@ out: | |||
2768 | static struct file_operations kvm_vm_fops = { | 2768 | static struct file_operations kvm_vm_fops = { |
2769 | .release = kvm_vm_release, | 2769 | .release = kvm_vm_release, |
2770 | .unlocked_ioctl = kvm_vm_ioctl, | 2770 | .unlocked_ioctl = kvm_vm_ioctl, |
2771 | #ifdef CONFIG_COMPAT | 2771 | #ifdef CONFIG_KVM_COMPAT |
2772 | .compat_ioctl = kvm_vm_compat_ioctl, | 2772 | .compat_ioctl = kvm_vm_compat_ioctl, |
2773 | #endif | 2773 | #endif |
2774 | .llseek = noop_llseek, | 2774 | .llseek = noop_llseek, |