mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 03:36:19 +00:00
KVM: s390: Allow stfle instruction in the guest
2.6.31-rc introduced an architecture level set checker based on facility bits. e.g. if the kernel is compiled to run only on z9, several facility bits are checked very early and the kernel refuses to boot if a z9 specific facility is missing. Until now kvm on s390 did not implement the store facility extended (STFLE) instruction. A 2.6.31-rc kernel that was compiled for z9 or higher did not boot in kvm. This patch implements stfle. This patch should go in before 2.6.31. Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> Signed-off-by: Avi Kivity <avi@redhat.com>
This commit is contained in:
parent
a3f9d3981c
commit
ef50f7ac7e
3 changed files with 26 additions and 3 deletions
|
@ -99,7 +99,9 @@ struct kvm_s390_sie_block {
|
|||
__u8 reservedd0[48]; /* 0x00d0 */
|
||||
__u64 gcr[16]; /* 0x0100 */
|
||||
__u64 gbea; /* 0x0180 */
|
||||
__u8 reserved188[120]; /* 0x0188 */
|
||||
__u8 reserved188[24]; /* 0x0188 */
|
||||
__u32 fac; /* 0x01a0 */
|
||||
__u8 reserved1a4[92]; /* 0x01a4 */
|
||||
} __attribute__((packed));
|
||||
|
||||
struct kvm_vcpu_stat {
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <asm/lowcore.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/nmi.h>
|
||||
#include <asm/system.h>
|
||||
#include "kvm-s390.h"
|
||||
#include "gaccess.h"
|
||||
|
||||
|
@ -69,6 +70,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
|
|||
{ NULL }
|
||||
};
|
||||
|
||||
static unsigned long long *facilities;
|
||||
|
||||
/* Section: not file related */
|
||||
void kvm_arch_hardware_enable(void *garbage)
|
||||
|
@ -288,6 +290,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
|
|||
vcpu->arch.sie_block->gmsor = vcpu->kvm->arch.guest_origin;
|
||||
vcpu->arch.sie_block->ecb = 2;
|
||||
vcpu->arch.sie_block->eca = 0xC1002001U;
|
||||
vcpu->arch.sie_block->fac = (int) (long) facilities;
|
||||
hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
|
||||
tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet,
|
||||
(unsigned long) vcpu);
|
||||
|
@ -739,11 +742,29 @@ gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn)
|
|||
|
||||
static int __init kvm_s390_init(void)
|
||||
{
|
||||
return kvm_init(NULL, sizeof(struct kvm_vcpu), THIS_MODULE);
|
||||
int ret;
|
||||
ret = kvm_init(NULL, sizeof(struct kvm_vcpu), THIS_MODULE);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* guests can ask for up to 255+1 double words, we need a full page
|
||||
* to hold the maximum amount of facilites. On the other hand, we
|
||||
* only set facilities that are known to work in KVM.
|
||||
*/
|
||||
facilities = (unsigned long long *) get_zeroed_page(GFP_DMA);
|
||||
if (!facilities) {
|
||||
kvm_exit();
|
||||
return -ENOMEM;
|
||||
}
|
||||
stfle(facilities, 1);
|
||||
facilities[0] &= 0xff00fff3f0700000ULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit kvm_s390_exit(void)
|
||||
{
|
||||
free_page((unsigned long) facilities);
|
||||
kvm_exit();
|
||||
}
|
||||
|
||||
|
|
|
@ -158,7 +158,7 @@ static int handle_stfl(struct kvm_vcpu *vcpu)
|
|||
|
||||
vcpu->stat.instruction_stfl++;
|
||||
/* only pass the facility bits, which we can handle */
|
||||
facility_list &= 0xfe00fff3;
|
||||
facility_list &= 0xff00fff3;
|
||||
|
||||
rc = copy_to_guest(vcpu, offsetof(struct _lowcore, stfl_fac_list),
|
||||
&facility_list, sizeof(facility_list));
|
||||
|
|
Loading…
Reference in a new issue