mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 09:19:51 +00:00
This deals with 2 guest features that need enablement in the kvm host:
- transactional execution - lpp sampling support In addition there is also a fix to the virtio-ccw guest driver. This will enable future features -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABAgAGBQJS2SgQAAoJEBF7vIC1phx8f48P/Rfb/Gg6YT8impCxUr9xaCBM X5lI48HbY7o/b3pQ624VlBUTuv6Hwo0HTVwNExKK0XzS/e9LXFch5dZ03EvFnVYX 3KcAOQ1mlJwYz2At8WdIHj+UHWSiVtNSq6T/rFILMBXqQw/d20NBG2t6J79Pa84G /WkexHv3Q9VKTWZUl05fmbnYTDtEPbVfTt85EbjaHxuUS8ahibYws+GSWcH2eDYe NYtXjrnDJwpoNM0OsyyGItiwNnIQ0ISzxwCzgtu97re9VTKEUoCqkEsMEf1lYr2+ t35RKzuPSvIrVufYf1+L553n9RRAckdHyq/trV70QNj69RoVA8qBii8HuQhN+2WP z+GzCqFv5mMFG2dzoBnrKG77cMXuKFvV9AjyaKPKHg/sty18jXFWzl8YFHVIwngV /KvQx5/+GznsETI5mHAn7BHlOWm1+Wk+I9Mkh6XySlglxlDvH0LTybJDnehhTotX wqPj6X+Qjq1AytDCpExQzDNfeLZx8jYbus4KOo8vptXNRKEyWY2yg5XJxjyjbyp4 0JOorFgl0zrV04+JMhWkLZY5sPzH7/tHe0hJ8VDzow2+IRwhEu31zLmAwFvsb/Ih 6XL1ioncWpCFDGwLcayNMHKAU/k4C5jDxzFJHrLvK8qKMM/SA7LLkaPUhsuUr+oX SlO7Pk859ckzjc5xfCzd =GbUg -----END PGP SIGNATURE----- Merge tag 'kvm-s390-20140117' of git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux into kvm-queue This deals with 2 guest features that need enablement in the kvm host: - transactional execution - lpp sampling support In addition there is also a fix to the virtio-ccw guest driver. This will enable future features
This commit is contained in:
commit
c760f5e29d
5 changed files with 51 additions and 9 deletions
|
@ -106,9 +106,22 @@ struct kvm_s390_sie_block {
|
|||
__u64 gbea; /* 0x0180 */
|
||||
__u8 reserved188[24]; /* 0x0188 */
|
||||
__u32 fac; /* 0x01a0 */
|
||||
__u8 reserved1a4[92]; /* 0x01a4 */
|
||||
__u8 reserved1a4[68]; /* 0x01a4 */
|
||||
__u64 itdba; /* 0x01e8 */
|
||||
__u8 reserved1f0[16]; /* 0x01f0 */
|
||||
} __attribute__((packed));
|
||||
|
||||
struct kvm_s390_itdb {
|
||||
__u8 data[256];
|
||||
} __packed;
|
||||
|
||||
struct sie_page {
|
||||
struct kvm_s390_sie_block sie_block;
|
||||
__u8 reserved200[1024]; /* 0x0200 */
|
||||
struct kvm_s390_itdb itdb; /* 0x0600 */
|
||||
__u8 reserved700[2304]; /* 0x0700 */
|
||||
} __packed;
|
||||
|
||||
struct kvm_vcpu_stat {
|
||||
u32 exit_userspace;
|
||||
u32 exit_null;
|
||||
|
|
|
@ -112,6 +112,17 @@ static int handle_instruction(struct kvm_vcpu *vcpu)
|
|||
static int handle_prog(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
vcpu->stat.exit_program_interruption++;
|
||||
|
||||
/* Restore ITDB to Program-Interruption TDB in guest memory */
|
||||
if (IS_TE_ENABLED(vcpu) &&
|
||||
!(current->thread.per_flags & PER_FLAG_NO_TE) &&
|
||||
IS_ITDB_VALID(vcpu)) {
|
||||
copy_to_guest(vcpu, TDB_ADDR, vcpu->arch.sie_block->itdba,
|
||||
sizeof(struct kvm_s390_itdb));
|
||||
memset((void *) vcpu->arch.sie_block->itdba, 0,
|
||||
sizeof(struct kvm_s390_itdb));
|
||||
}
|
||||
|
||||
trace_kvm_s390_intercept_prog(vcpu, vcpu->arch.sie_block->iprcc);
|
||||
return kvm_s390_inject_program_int(vcpu, vcpu->arch.sie_block->iprcc);
|
||||
}
|
||||
|
|
|
@ -395,6 +395,9 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
|
|||
CPUSTAT_STOPPED |
|
||||
CPUSTAT_GED);
|
||||
vcpu->arch.sie_block->ecb = 6;
|
||||
if (test_vfacility(50) && test_vfacility(73))
|
||||
vcpu->arch.sie_block->ecb |= 0x10;
|
||||
|
||||
vcpu->arch.sie_block->ecb2 = 8;
|
||||
vcpu->arch.sie_block->eca = 0xC1002001U;
|
||||
vcpu->arch.sie_block->fac = (int) (long) vfacilities;
|
||||
|
@ -411,6 +414,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
|
|||
unsigned int id)
|
||||
{
|
||||
struct kvm_vcpu *vcpu;
|
||||
struct sie_page *sie_page;
|
||||
int rc = -EINVAL;
|
||||
|
||||
if (id >= KVM_MAX_VCPUS)
|
||||
|
@ -422,12 +426,13 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
|
|||
if (!vcpu)
|
||||
goto out;
|
||||
|
||||
vcpu->arch.sie_block = (struct kvm_s390_sie_block *)
|
||||
get_zeroed_page(GFP_KERNEL);
|
||||
|
||||
if (!vcpu->arch.sie_block)
|
||||
sie_page = (struct sie_page *) get_zeroed_page(GFP_KERNEL);
|
||||
if (!sie_page)
|
||||
goto out_free_cpu;
|
||||
|
||||
vcpu->arch.sie_block = &sie_page->sie_block;
|
||||
vcpu->arch.sie_block->itdba = (unsigned long) &sie_page->itdb;
|
||||
|
||||
vcpu->arch.sie_block->icpua = id;
|
||||
if (!kvm_is_ucontrol(kvm)) {
|
||||
if (!kvm->arch.sca) {
|
||||
|
@ -1182,8 +1187,8 @@ static int __init kvm_s390_init(void)
|
|||
return -ENOMEM;
|
||||
}
|
||||
memcpy(vfacilities, S390_lowcore.stfle_fac_list, 16);
|
||||
vfacilities[0] &= 0xff82fff3f47c0000UL;
|
||||
vfacilities[1] &= 0x001c000000000000UL;
|
||||
vfacilities[0] &= 0xff82fff3f4fc2000UL;
|
||||
vfacilities[1] &= 0x005c000000000000UL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,12 @@ extern unsigned long *vfacilities;
|
|||
|
||||
int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu);
|
||||
|
||||
/* Transactional Memory Execution related macros */
|
||||
#define IS_TE_ENABLED(vcpu) ((vcpu->arch.sie_block->ecb & 0x10))
|
||||
#define TDB_ADDR 0x1800UL
|
||||
#define TDB_FORMAT1 1
|
||||
#define IS_ITDB_VALID(vcpu) ((*(char *)vcpu->arch.sie_block->itdba == TDB_FORMAT1))
|
||||
|
||||
#define VM_EVENT(d_kvm, d_loglevel, d_string, d_args...)\
|
||||
do { \
|
||||
debug_sprintf_event(d_kvm->arch.dbf, d_loglevel, d_string "\n", \
|
||||
|
|
|
@ -642,8 +642,15 @@ static void virtio_ccw_int_handler(struct ccw_device *cdev,
|
|||
(SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND))) {
|
||||
/* OK */
|
||||
}
|
||||
if (irb_is_error(irb))
|
||||
vcdev->err = -EIO; /* XXX - use real error */
|
||||
if (irb_is_error(irb)) {
|
||||
/* Command reject? */
|
||||
if ((scsw_dstat(&irb->scsw) & DEV_STAT_UNIT_CHECK) &&
|
||||
(irb->ecw[0] & SNS0_CMD_REJECT))
|
||||
vcdev->err = -EOPNOTSUPP;
|
||||
else
|
||||
/* Map everything else to -EIO. */
|
||||
vcdev->err = -EIO;
|
||||
}
|
||||
if (vcdev->curr_io & activity) {
|
||||
switch (activity) {
|
||||
case VIRTIO_CCW_DOING_READ_FEAT:
|
||||
|
|
Loading…
Reference in a new issue