Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/virt/kvm/kvm
Browse files Browse the repository at this point in the history
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
  • Loading branch information
torvalds committed Mar 10, 2015
2 parents ec0e6bd + bfb8fb4 commit affb817
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 45 deletions.
12 changes: 6 additions & 6 deletions arch/s390/include/asm/kvm_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -515,15 +515,15 @@ struct s390_io_adapter {
#define S390_ARCH_FAC_MASK_SIZE_U64 \
(S390_ARCH_FAC_MASK_SIZE_BYTE / sizeof(u64))

struct s390_model_fac {
/* facilities used in SIE context */
__u64 sie[S390_ARCH_FAC_LIST_SIZE_U64];
/* subset enabled by kvm */
__u64 kvm[S390_ARCH_FAC_LIST_SIZE_U64];
struct kvm_s390_fac {
/* facility list requested by guest */
__u64 list[S390_ARCH_FAC_LIST_SIZE_U64];
/* facility mask supported by kvm & hosting machine */
__u64 mask[S390_ARCH_FAC_LIST_SIZE_U64];
};

struct kvm_s390_cpu_model {
struct s390_model_fac *fac;
struct kvm_s390_fac *fac;
struct cpuid cpu_id;
unsigned short ibc;
};
Expand Down
68 changes: 31 additions & 37 deletions arch/s390/kvm/kvm-s390.c
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ static int kvm_s390_set_processor(struct kvm *kvm, struct kvm_device_attr *attr)
memcpy(&kvm->arch.model.cpu_id, &proc->cpuid,
sizeof(struct cpuid));
kvm->arch.model.ibc = proc->ibc;
memcpy(kvm->arch.model.fac->kvm, proc->fac_list,
memcpy(kvm->arch.model.fac->list, proc->fac_list,
S390_ARCH_FAC_LIST_SIZE_BYTE);
} else
ret = -EFAULT;
Expand Down Expand Up @@ -556,7 +556,7 @@ static int kvm_s390_get_processor(struct kvm *kvm, struct kvm_device_attr *attr)
}
memcpy(&proc->cpuid, &kvm->arch.model.cpu_id, sizeof(struct cpuid));
proc->ibc = kvm->arch.model.ibc;
memcpy(&proc->fac_list, kvm->arch.model.fac->kvm, S390_ARCH_FAC_LIST_SIZE_BYTE);
memcpy(&proc->fac_list, kvm->arch.model.fac->list, S390_ARCH_FAC_LIST_SIZE_BYTE);
if (copy_to_user((void __user *)attr->addr, proc, sizeof(*proc)))
ret = -EFAULT;
kfree(proc);
Expand All @@ -576,10 +576,10 @@ static int kvm_s390_get_machine(struct kvm *kvm, struct kvm_device_attr *attr)
}
get_cpu_id((struct cpuid *) &mach->cpuid);
mach->ibc = sclp_get_ibc();
memcpy(&mach->fac_mask, kvm_s390_fac_list_mask,
kvm_s390_fac_list_mask_size() * sizeof(u64));
memcpy(&mach->fac_mask, kvm->arch.model.fac->mask,
S390_ARCH_FAC_LIST_SIZE_BYTE);
memcpy((unsigned long *)&mach->fac_list, S390_lowcore.stfle_fac_list,
S390_ARCH_FAC_LIST_SIZE_U64);
S390_ARCH_FAC_LIST_SIZE_BYTE);
if (copy_to_user((void __user *)attr->addr, mach, sizeof(*mach)))
ret = -EFAULT;
kfree(mach);
Expand Down Expand Up @@ -778,15 +778,18 @@ long kvm_arch_vm_ioctl(struct file *filp,
static int kvm_s390_query_ap_config(u8 *config)
{
u32 fcn_code = 0x04000000UL;
u32 cc;
u32 cc = 0;

memset(config, 0, 128);
asm volatile(
"lgr 0,%1\n"
"lgr 2,%2\n"
".long 0xb2af0000\n" /* PQAP(QCI) */
"ipm %0\n"
"0: ipm %0\n"
"srl %0,28\n"
: "=r" (cc)
"1:\n"
EX_TABLE(0b, 1b)
: "+r" (cc)
: "r" (fcn_code), "r" (config)
: "cc", "0", "2", "memory"
);
Expand Down Expand Up @@ -839,9 +842,13 @@ static int kvm_s390_crypto_init(struct kvm *kvm)

kvm_s390_set_crycb_format(kvm);

/* Disable AES/DEA protected key functions by default */
kvm->arch.crypto.aes_kw = 0;
kvm->arch.crypto.dea_kw = 0;
/* Enable AES/DEA protected key functions by default */
kvm->arch.crypto.aes_kw = 1;
kvm->arch.crypto.dea_kw = 1;
get_random_bytes(kvm->arch.crypto.crycb->aes_wrapping_key_mask,
sizeof(kvm->arch.crypto.crycb->aes_wrapping_key_mask));
get_random_bytes(kvm->arch.crypto.crycb->dea_wrapping_key_mask,
sizeof(kvm->arch.crypto.crycb->dea_wrapping_key_mask));

return 0;
}
Expand Down Expand Up @@ -886,40 +893,29 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
/*
* The architectural maximum amount of facilities is 16 kbit. To store
* this amount, 2 kbyte of memory is required. Thus we need a full
* page to hold the active copy (arch.model.fac->sie) and the current
* facilities set (arch.model.fac->kvm). Its address size has to be
* page to hold the guest facility list (arch.model.fac->list) and the
* facility mask (arch.model.fac->mask). Its address size has to be
* 31 bits and word aligned.
*/
kvm->arch.model.fac =
(struct s390_model_fac *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
(struct kvm_s390_fac *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
if (!kvm->arch.model.fac)
goto out_nofac;

memcpy(kvm->arch.model.fac->kvm, S390_lowcore.stfle_fac_list,
S390_ARCH_FAC_LIST_SIZE_U64);

/*
* If this KVM host runs *not* in a LPAR, relax the facility bits
* of the kvm facility mask by all missing facilities. This will allow
* to determine the right CPU model by means of the remaining facilities.
* Live guest migration must prohibit the migration of KVMs running in
* a LPAR to non LPAR hosts.
*/
if (!MACHINE_IS_LPAR)
for (i = 0; i < kvm_s390_fac_list_mask_size(); i++)
kvm_s390_fac_list_mask[i] &= kvm->arch.model.fac->kvm[i];

/*
* Apply the kvm facility mask to limit the kvm supported/tolerated
* facility list.
*/
/* Populate the facility mask initially. */
memcpy(kvm->arch.model.fac->mask, S390_lowcore.stfle_fac_list,
S390_ARCH_FAC_LIST_SIZE_BYTE);
for (i = 0; i < S390_ARCH_FAC_LIST_SIZE_U64; i++) {
if (i < kvm_s390_fac_list_mask_size())
kvm->arch.model.fac->kvm[i] &= kvm_s390_fac_list_mask[i];
kvm->arch.model.fac->mask[i] &= kvm_s390_fac_list_mask[i];
else
kvm->arch.model.fac->kvm[i] = 0UL;
kvm->arch.model.fac->mask[i] = 0UL;
}

/* Populate the facility list initially. */
memcpy(kvm->arch.model.fac->list, kvm->arch.model.fac->mask,
S390_ARCH_FAC_LIST_SIZE_BYTE);

kvm_s390_get_cpu_id(&kvm->arch.model.cpu_id);
kvm->arch.model.ibc = sclp_get_ibc() & 0x0fff;

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

mutex_lock(&vcpu->kvm->lock);
vcpu->arch.cpu_id = vcpu->kvm->arch.model.cpu_id;
memcpy(vcpu->kvm->arch.model.fac->sie, vcpu->kvm->arch.model.fac->kvm,
S390_ARCH_FAC_LIST_SIZE_BYTE);
vcpu->arch.sie_block->ibc = vcpu->kvm->arch.model.ibc;
mutex_unlock(&vcpu->kvm->lock);

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

spin_lock_init(&vcpu->arch.local_int.lock);
vcpu->arch.local_int.float_int = &kvm->arch.float_int;
Expand Down
3 changes: 2 additions & 1 deletion arch/s390/kvm/kvm-s390.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ static inline void kvm_s390_set_psw_cc(struct kvm_vcpu *vcpu, unsigned long cc)
/* test availability of facility in a kvm intance */
static inline int test_kvm_facility(struct kvm *kvm, unsigned long nr)
{
return __test_facility(nr, kvm->arch.model.fac->kvm);
return __test_facility(nr, kvm->arch.model.fac->mask) &&
__test_facility(nr, kvm->arch.model.fac->list);
}

/* are cpu states controlled by user space */
Expand Down
2 changes: 1 addition & 1 deletion arch/s390/kvm/priv.c
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ static int handle_stfl(struct kvm_vcpu *vcpu)
* We need to shift the lower 32 facility bits (bit 0-31) from a u64
* into a u32 memory representation. They will remain bits 0-31.
*/
fac = *vcpu->kvm->arch.model.fac->sie >> 32;
fac = *vcpu->kvm->arch.model.fac->list >> 32;
rc = write_guest_lc(vcpu, offsetof(struct _lowcore, stfl_fac_list),
&fac, sizeof(fac));
if (rc)
Expand Down

0 comments on commit affb817

Please sign in to comment.