Skip to content

Commit affb817

Browse files
committed
Merge git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull kvm/s390 bugfixes from Marcelo Tosatti. * git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: s390: non-LPAR case obsolete during facilities mask init KVM: s390: include guest facilities in kvm facility test KVM: s390: fix in memory copy of facility lists KVM: s390/cpacf: Fix kernel bug under z/VM KVM: s390/cpacf: Enable key wrapping by default
2 parents ec0e6bd + bfb8fb4 commit affb817

File tree

4 files changed

+40
-45
lines changed

4 files changed

+40
-45
lines changed

arch/s390/include/asm/kvm_host.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -515,15 +515,15 @@ struct s390_io_adapter {
515515
#define S390_ARCH_FAC_MASK_SIZE_U64 \
516516
(S390_ARCH_FAC_MASK_SIZE_BYTE / sizeof(u64))
517517

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];
518+
struct kvm_s390_fac {
519+
/* facility list requested by guest */
520+
__u64 list[S390_ARCH_FAC_LIST_SIZE_U64];
521+
/* facility mask supported by kvm & hosting machine */
522+
__u64 mask[S390_ARCH_FAC_LIST_SIZE_U64];
523523
};
524524

525525
struct kvm_s390_cpu_model {
526-
struct s390_model_fac *fac;
526+
struct kvm_s390_fac *fac;
527527
struct cpuid cpu_id;
528528
unsigned short ibc;
529529
};

arch/s390/kvm/kvm-s390.c

Lines changed: 31 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,7 @@ static int kvm_s390_set_processor(struct kvm *kvm, struct kvm_device_attr *attr)
522522
memcpy(&kvm->arch.model.cpu_id, &proc->cpuid,
523523
sizeof(struct cpuid));
524524
kvm->arch.model.ibc = proc->ibc;
525-
memcpy(kvm->arch.model.fac->kvm, proc->fac_list,
525+
memcpy(kvm->arch.model.fac->list, proc->fac_list,
526526
S390_ARCH_FAC_LIST_SIZE_BYTE);
527527
} else
528528
ret = -EFAULT;
@@ -556,7 +556,7 @@ static int kvm_s390_get_processor(struct kvm *kvm, struct kvm_device_attr *attr)
556556
}
557557
memcpy(&proc->cpuid, &kvm->arch.model.cpu_id, sizeof(struct cpuid));
558558
proc->ibc = kvm->arch.model.ibc;
559-
memcpy(&proc->fac_list, kvm->arch.model.fac->kvm, S390_ARCH_FAC_LIST_SIZE_BYTE);
559+
memcpy(&proc->fac_list, kvm->arch.model.fac->list, S390_ARCH_FAC_LIST_SIZE_BYTE);
560560
if (copy_to_user((void __user *)attr->addr, proc, sizeof(*proc)))
561561
ret = -EFAULT;
562562
kfree(proc);
@@ -576,10 +576,10 @@ static int kvm_s390_get_machine(struct kvm *kvm, struct kvm_device_attr *attr)
576576
}
577577
get_cpu_id((struct cpuid *) &mach->cpuid);
578578
mach->ibc = sclp_get_ibc();
579-
memcpy(&mach->fac_mask, kvm_s390_fac_list_mask,
580-
kvm_s390_fac_list_mask_size() * sizeof(u64));
579+
memcpy(&mach->fac_mask, kvm->arch.model.fac->mask,
580+
S390_ARCH_FAC_LIST_SIZE_BYTE);
581581
memcpy((unsigned long *)&mach->fac_list, S390_lowcore.stfle_fac_list,
582-
S390_ARCH_FAC_LIST_SIZE_U64);
582+
S390_ARCH_FAC_LIST_SIZE_BYTE);
583583
if (copy_to_user((void __user *)attr->addr, mach, sizeof(*mach)))
584584
ret = -EFAULT;
585585
kfree(mach);
@@ -778,15 +778,18 @@ long kvm_arch_vm_ioctl(struct file *filp,
778778
static int kvm_s390_query_ap_config(u8 *config)
779779
{
780780
u32 fcn_code = 0x04000000UL;
781-
u32 cc;
781+
u32 cc = 0;
782782

783+
memset(config, 0, 128);
783784
asm volatile(
784785
"lgr 0,%1\n"
785786
"lgr 2,%2\n"
786787
".long 0xb2af0000\n" /* PQAP(QCI) */
787-
"ipm %0\n"
788+
"0: ipm %0\n"
788789
"srl %0,28\n"
789-
: "=r" (cc)
790+
"1:\n"
791+
EX_TABLE(0b, 1b)
792+
: "+r" (cc)
790793
: "r" (fcn_code), "r" (config)
791794
: "cc", "0", "2", "memory"
792795
);
@@ -839,9 +842,13 @@ static int kvm_s390_crypto_init(struct kvm *kvm)
839842

840843
kvm_s390_set_crycb_format(kvm);
841844

842-
/* Disable AES/DEA protected key functions by default */
843-
kvm->arch.crypto.aes_kw = 0;
844-
kvm->arch.crypto.dea_kw = 0;
845+
/* Enable AES/DEA protected key functions by default */
846+
kvm->arch.crypto.aes_kw = 1;
847+
kvm->arch.crypto.dea_kw = 1;
848+
get_random_bytes(kvm->arch.crypto.crycb->aes_wrapping_key_mask,
849+
sizeof(kvm->arch.crypto.crycb->aes_wrapping_key_mask));
850+
get_random_bytes(kvm->arch.crypto.crycb->dea_wrapping_key_mask,
851+
sizeof(kvm->arch.crypto.crycb->dea_wrapping_key_mask));
845852

846853
return 0;
847854
}
@@ -886,40 +893,29 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
886893
/*
887894
* The architectural maximum amount of facilities is 16 kbit. To store
888895
* 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
896+
* page to hold the guest facility list (arch.model.fac->list) and the
897+
* facility mask (arch.model.fac->mask). Its address size has to be
891898
* 31 bits and word aligned.
892899
*/
893900
kvm->arch.model.fac =
894-
(struct s390_model_fac *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
901+
(struct kvm_s390_fac *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
895902
if (!kvm->arch.model.fac)
896903
goto out_nofac;
897904

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-
*/
905+
/* Populate the facility mask initially. */
906+
memcpy(kvm->arch.model.fac->mask, S390_lowcore.stfle_fac_list,
907+
S390_ARCH_FAC_LIST_SIZE_BYTE);
916908
for (i = 0; i < S390_ARCH_FAC_LIST_SIZE_U64; i++) {
917909
if (i < kvm_s390_fac_list_mask_size())
918-
kvm->arch.model.fac->kvm[i] &= kvm_s390_fac_list_mask[i];
910+
kvm->arch.model.fac->mask[i] &= kvm_s390_fac_list_mask[i];
919911
else
920-
kvm->arch.model.fac->kvm[i] = 0UL;
912+
kvm->arch.model.fac->mask[i] = 0UL;
921913
}
922914

915+
/* Populate the facility list initially. */
916+
memcpy(kvm->arch.model.fac->list, kvm->arch.model.fac->mask,
917+
S390_ARCH_FAC_LIST_SIZE_BYTE);
918+
923919
kvm_s390_get_cpu_id(&kvm->arch.model.cpu_id);
924920
kvm->arch.model.ibc = sclp_get_ibc() & 0x0fff;
925921

@@ -1165,8 +1161,6 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
11651161

11661162
mutex_lock(&vcpu->kvm->lock);
11671163
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);
11701164
vcpu->arch.sie_block->ibc = vcpu->kvm->arch.model.ibc;
11711165
mutex_unlock(&vcpu->kvm->lock);
11721166

@@ -1212,7 +1206,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
12121206
vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca;
12131207
set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn);
12141208
}
1215-
vcpu->arch.sie_block->fac = (int) (long) kvm->arch.model.fac->sie;
1209+
vcpu->arch.sie_block->fac = (int) (long) kvm->arch.model.fac->list;
12161210

12171211
spin_lock_init(&vcpu->arch.local_int.lock);
12181212
vcpu->arch.local_int.float_int = &kvm->arch.float_int;

arch/s390/kvm/kvm-s390.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,8 @@ static inline void kvm_s390_set_psw_cc(struct kvm_vcpu *vcpu, unsigned long cc)
128128
/* test availability of facility in a kvm intance */
129129
static inline int test_kvm_facility(struct kvm *kvm, unsigned long nr)
130130
{
131-
return __test_facility(nr, kvm->arch.model.fac->kvm);
131+
return __test_facility(nr, kvm->arch.model.fac->mask) &&
132+
__test_facility(nr, kvm->arch.model.fac->list);
132133
}
133134

134135
/* are cpu states controlled by user space */

arch/s390/kvm/priv.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ static int handle_stfl(struct kvm_vcpu *vcpu)
348348
* We need to shift the lower 32 facility bits (bit 0-31) from a u64
349349
* into a u32 memory representation. They will remain bits 0-31.
350350
*/
351-
fac = *vcpu->kvm->arch.model.fac->sie >> 32;
351+
fac = *vcpu->kvm->arch.model.fac->list >> 32;
352352
rc = write_guest_lc(vcpu, offsetof(struct _lowcore, stfl_fac_list),
353353
&fac, sizeof(fac));
354354
if (rc)

0 commit comments

Comments
 (0)