diff options
| -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, |
