diff options
author | Michael Mueller <mimu@linux.vnet.ibm.com> | 2015-02-02 09:42:51 -0500 |
---|---|---|
committer | Christian Borntraeger <borntraeger@de.ibm.com> | 2015-02-09 06:44:12 -0500 |
commit | 9d8d578605b4fca37bd2230bbacb3ad0ee48e7e4 (patch) | |
tree | 4d0af38197c3f4350b49cbd2c5bd6fc303b89377 /arch/s390 | |
parent | 45c9b47c5883d02abab6c7c7788e3d97a2f158e1 (diff) |
KVM: s390: use facilities and cpu_id per KVM
The patch introduces facilities and cpu_ids per virtual machine.
Different virtual machines may want to expose different facilities and
cpu ids to the guest, so let's make them per-vm instead of global.
Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/include/asm/kvm_host.h | 21 | ||||
-rw-r--r-- | arch/s390/kvm/gaccess.c | 4 | ||||
-rw-r--r-- | arch/s390/kvm/kvm-s390.c | 92 | ||||
-rw-r--r-- | arch/s390/kvm/kvm-s390.h | 13 | ||||
-rw-r--r-- | arch/s390/kvm/priv.c | 13 |
5 files changed, 99 insertions, 44 deletions
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index 77ae01444e98..79dc3b0aa65f 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h | |||
@@ -506,6 +506,26 @@ struct s390_io_adapter { | |||
506 | #define MAX_S390_IO_ADAPTERS ((MAX_ISC + 1) * 8) | 506 | #define MAX_S390_IO_ADAPTERS ((MAX_ISC + 1) * 8) |
507 | #define MAX_S390_ADAPTER_MAPS 256 | 507 | #define MAX_S390_ADAPTER_MAPS 256 |
508 | 508 | ||
509 | /* maximum size of facilities and facility mask is 2k bytes */ | ||
510 | #define S390_ARCH_FAC_LIST_SIZE_BYTE (1<<11) | ||
511 | #define S390_ARCH_FAC_LIST_SIZE_U64 \ | ||
512 | (S390_ARCH_FAC_LIST_SIZE_BYTE / sizeof(u64)) | ||
513 | #define S390_ARCH_FAC_MASK_SIZE_BYTE S390_ARCH_FAC_LIST_SIZE_BYTE | ||
514 | #define S390_ARCH_FAC_MASK_SIZE_U64 \ | ||
515 | (S390_ARCH_FAC_MASK_SIZE_BYTE / sizeof(u64)) | ||
516 | |||
517 | struct s390_model_fac { | ||
518 | /* facilities used in SIE context */ | ||
519 | __u64 sie[S390_ARCH_FAC_LIST_SIZE_U64]; | ||
520 | /* subset enabled by kvm */ | ||
521 | __u64 kvm[S390_ARCH_FAC_LIST_SIZE_U64]; | ||
522 | }; | ||
523 | |||
524 | struct kvm_s390_cpu_model { | ||
525 | struct s390_model_fac *fac; | ||
526 | struct cpuid cpu_id; | ||
527 | }; | ||
528 | |||
509 | struct kvm_s390_crypto { | 529 | struct kvm_s390_crypto { |
510 | struct kvm_s390_crypto_cb *crycb; | 530 | struct kvm_s390_crypto_cb *crycb; |
511 | __u32 crycbd; | 531 | __u32 crycbd; |
@@ -536,6 +556,7 @@ struct kvm_arch{ | |||
536 | int ipte_lock_count; | 556 | int ipte_lock_count; |
537 | struct mutex ipte_mutex; | 557 | struct mutex ipte_mutex; |
538 | spinlock_t start_stop_lock; | 558 | spinlock_t start_stop_lock; |
559 | struct kvm_s390_cpu_model model; | ||
539 | struct kvm_s390_crypto crypto; | 560 | struct kvm_s390_crypto crypto; |
540 | u64 epoch; | 561 | u64 epoch; |
541 | }; | 562 | }; |
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/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index deac47378f77..8c538a1a23c1 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); |
@@ -700,9 +704,15 @@ static void kvm_s390_set_crycb_format(struct kvm *kvm) | |||
700 | kvm->arch.crypto.crycbd |= CRYCB_FORMAT1; | 704 | kvm->arch.crypto.crycbd |= CRYCB_FORMAT1; |
701 | } | 705 | } |
702 | 706 | ||
707 | static void kvm_s390_get_cpu_id(struct cpuid *cpu_id) | ||
708 | { | ||
709 | get_cpu_id(cpu_id); | ||
710 | cpu_id->version = 0xff; | ||
711 | } | ||
712 | |||
703 | static int kvm_s390_crypto_init(struct kvm *kvm) | 713 | static int kvm_s390_crypto_init(struct kvm *kvm) |
704 | { | 714 | { |
705 | if (!test_vfacility(76)) | 715 | if (!test_kvm_facility(kvm, 76)) |
706 | return 0; | 716 | return 0; |
707 | 717 | ||
708 | kvm->arch.crypto.crycb = kzalloc(sizeof(*kvm->arch.crypto.crycb), | 718 | kvm->arch.crypto.crycb = kzalloc(sizeof(*kvm->arch.crypto.crycb), |
@@ -721,7 +731,7 @@ static int kvm_s390_crypto_init(struct kvm *kvm) | |||
721 | 731 | ||
722 | int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) | 732 | int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) |
723 | { | 733 | { |
724 | int rc; | 734 | int i, rc; |
725 | char debug_name[16]; | 735 | char debug_name[16]; |
726 | static unsigned long sca_offset; | 736 | static unsigned long sca_offset; |
727 | 737 | ||
@@ -756,6 +766,34 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) | |||
756 | if (!kvm->arch.dbf) | 766 | if (!kvm->arch.dbf) |
757 | goto out_nodbf; | 767 | goto out_nodbf; |
758 | 768 | ||
769 | /* | ||
770 | * The architectural maximum amount of facilities is 16 kbit. To store | ||
771 | * this amount, 2 kbyte of memory is required. Thus we need a full | ||
772 | * page to hold the active copy (arch.model.fac->sie) and the current | ||
773 | * facilities set (arch.model.fac->kvm). Its address size has to be | ||
774 | * 31 bits and word aligned. | ||
775 | */ | ||
776 | kvm->arch.model.fac = | ||
777 | (struct s390_model_fac *) get_zeroed_page(GFP_KERNEL | GFP_DMA); | ||
778 | if (!kvm->arch.model.fac) | ||
779 | goto out_nofac; | ||
780 | |||
781 | memcpy(kvm->arch.model.fac->kvm, S390_lowcore.stfle_fac_list, | ||
782 | S390_ARCH_FAC_LIST_SIZE_U64); | ||
783 | |||
784 | /* | ||
785 | * Apply the kvm facility mask to limit the kvm supported/tolerated | ||
786 | * facility list. | ||
787 | */ | ||
788 | for (i = 0; i < S390_ARCH_FAC_LIST_SIZE_U64; i++) { | ||
789 | if (i < kvm_s390_fac_list_mask_size()) | ||
790 | kvm->arch.model.fac->kvm[i] &= kvm_s390_fac_list_mask[i]; | ||
791 | else | ||
792 | kvm->arch.model.fac->kvm[i] = 0UL; | ||
793 | } | ||
794 | |||
795 | kvm_s390_get_cpu_id(&kvm->arch.model.cpu_id); | ||
796 | |||
759 | if (kvm_s390_crypto_init(kvm) < 0) | 797 | if (kvm_s390_crypto_init(kvm) < 0) |
760 | goto out_crypto; | 798 | goto out_crypto; |
761 | 799 | ||
@@ -787,6 +825,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) | |||
787 | out_nogmap: | 825 | out_nogmap: |
788 | kfree(kvm->arch.crypto.crycb); | 826 | kfree(kvm->arch.crypto.crycb); |
789 | out_crypto: | 827 | out_crypto: |
828 | free_page((unsigned long)kvm->arch.model.fac); | ||
829 | out_nofac: | ||
790 | debug_unregister(kvm->arch.dbf); | 830 | debug_unregister(kvm->arch.dbf); |
791 | out_nodbf: | 831 | out_nodbf: |
792 | free_page((unsigned long)(kvm->arch.sca)); | 832 | free_page((unsigned long)(kvm->arch.sca)); |
@@ -839,6 +879,7 @@ static void kvm_free_vcpus(struct kvm *kvm) | |||
839 | void kvm_arch_destroy_vm(struct kvm *kvm) | 879 | void kvm_arch_destroy_vm(struct kvm *kvm) |
840 | { | 880 | { |
841 | kvm_free_vcpus(kvm); | 881 | kvm_free_vcpus(kvm); |
882 | free_page((unsigned long)kvm->arch.model.fac); | ||
842 | free_page((unsigned long)(kvm->arch.sca)); | 883 | free_page((unsigned long)(kvm->arch.sca)); |
843 | debug_unregister(kvm->arch.dbf); | 884 | debug_unregister(kvm->arch.dbf); |
844 | kfree(kvm->arch.crypto.crycb); | 885 | kfree(kvm->arch.crypto.crycb); |
@@ -934,7 +975,7 @@ void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) | |||
934 | 975 | ||
935 | static void kvm_s390_vcpu_crypto_setup(struct kvm_vcpu *vcpu) | 976 | static void kvm_s390_vcpu_crypto_setup(struct kvm_vcpu *vcpu) |
936 | { | 977 | { |
937 | if (!test_vfacility(76)) | 978 | if (!test_kvm_facility(vcpu->kvm, 76)) |
938 | return; | 979 | return; |
939 | 980 | ||
940 | vcpu->arch.sie_block->ecb3 &= ~(ECB3_AES | ECB3_DEA); | 981 | vcpu->arch.sie_block->ecb3 &= ~(ECB3_AES | ECB3_DEA); |
@@ -973,7 +1014,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) | |||
973 | CPUSTAT_STOPPED | | 1014 | CPUSTAT_STOPPED | |
974 | CPUSTAT_GED); | 1015 | CPUSTAT_GED); |
975 | vcpu->arch.sie_block->ecb = 6; | 1016 | vcpu->arch.sie_block->ecb = 6; |
976 | if (test_vfacility(50) && test_vfacility(73)) | 1017 | if (test_kvm_facility(vcpu->kvm, 50) && test_kvm_facility(vcpu->kvm, 73)) |
977 | vcpu->arch.sie_block->ecb |= 0x10; | 1018 | vcpu->arch.sie_block->ecb |= 0x10; |
978 | 1019 | ||
979 | vcpu->arch.sie_block->ecb2 = 8; | 1020 | vcpu->arch.sie_block->ecb2 = 8; |
@@ -982,7 +1023,6 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) | |||
982 | vcpu->arch.sie_block->eca |= 1; | 1023 | vcpu->arch.sie_block->eca |= 1; |
983 | if (sclp_has_sigpif()) | 1024 | if (sclp_has_sigpif()) |
984 | vcpu->arch.sie_block->eca |= 0x10000000U; | 1025 | vcpu->arch.sie_block->eca |= 0x10000000U; |
985 | vcpu->arch.sie_block->fac = (int) (long) vfacilities; | ||
986 | vcpu->arch.sie_block->ictl |= ICTL_ISKE | ICTL_SSKE | ICTL_RRBE | | 1026 | vcpu->arch.sie_block->ictl |= ICTL_ISKE | ICTL_SSKE | ICTL_RRBE | |
987 | ICTL_TPROT; | 1027 | ICTL_TPROT; |
988 | 1028 | ||
@@ -993,8 +1033,10 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) | |||
993 | } | 1033 | } |
994 | hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | 1034 | hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
995 | vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup; | 1035 | vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup; |
996 | get_cpu_id(&vcpu->arch.cpu_id); | 1036 | |
997 | vcpu->arch.cpu_id.version = 0xff; | 1037 | vcpu->arch.cpu_id = vcpu->kvm->arch.model.cpu_id; |
1038 | memcpy(vcpu->kvm->arch.model.fac->sie, vcpu->kvm->arch.model.fac->kvm, | ||
1039 | S390_ARCH_FAC_LIST_SIZE_BYTE); | ||
998 | 1040 | ||
999 | kvm_s390_vcpu_crypto_setup(vcpu); | 1041 | kvm_s390_vcpu_crypto_setup(vcpu); |
1000 | 1042 | ||
@@ -1038,6 +1080,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, | |||
1038 | vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca; | 1080 | vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca; |
1039 | set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn); | 1081 | set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn); |
1040 | } | 1082 | } |
1083 | vcpu->arch.sie_block->fac = (int) (long) kvm->arch.model.fac->sie; | ||
1041 | 1084 | ||
1042 | spin_lock_init(&vcpu->arch.local_int.lock); | 1085 | spin_lock_init(&vcpu->arch.local_int.lock); |
1043 | vcpu->arch.local_int.float_int = &kvm->arch.float_int; | 1086 | vcpu->arch.local_int.float_int = &kvm->arch.float_int; |
@@ -2103,30 +2146,11 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, | |||
2103 | 2146 | ||
2104 | static int __init kvm_s390_init(void) | 2147 | static int __init kvm_s390_init(void) |
2105 | { | 2148 | { |
2106 | int ret; | 2149 | return kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE); |
2107 | ret = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE); | ||
2108 | if (ret) | ||
2109 | return ret; | ||
2110 | |||
2111 | /* | ||
2112 | * guests can ask for up to 255+1 double words, we need a full page | ||
2113 | * to hold the maximum amount of facilities. On the other hand, we | ||
2114 | * only set facilities that are known to work in KVM. | ||
2115 | */ | ||
2116 | vfacilities = (unsigned long *) get_zeroed_page(GFP_KERNEL|GFP_DMA); | ||
2117 | if (!vfacilities) { | ||
2118 | kvm_exit(); | ||
2119 | return -ENOMEM; | ||
2120 | } | ||
2121 | memcpy(vfacilities, S390_lowcore.stfle_fac_list, 16); | ||
2122 | vfacilities[0] &= 0xff82fffbf4fc2000UL; | ||
2123 | vfacilities[1] &= 0x005c000000000000UL; | ||
2124 | return 0; | ||
2125 | } | 2150 | } |
2126 | 2151 | ||
2127 | static void __exit kvm_s390_exit(void) | 2152 | static void __exit kvm_s390_exit(void) |
2128 | { | 2153 | { |
2129 | free_page((unsigned long) vfacilities); | ||
2130 | kvm_exit(); | 2154 | kvm_exit(); |
2131 | } | 2155 | } |
2132 | 2156 | ||
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 | ||