forked from Minki/linux
KVM: s390: Fixes and features for 4.16
- add the virtio-ccw transport for kvmconfig - more debug tracing for cpu model - cleanups and fixes -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJaXhcpAAoJEBF7vIC1phx8YdwP/1FYC24FZVqKZ3NO4ItSh7xc QdithL2dqfeudmwc/nU6AilMbvgTdR6QmWOICh7fc2HklrIxqkFcjZeHDe2mp5NB aI1WVtt3EpqZWsimXUkWYUY0Az3DF36Yc/vYw7ubUvPzb5aN9c7G666ADfUwgIjP IgFgqyEKeT7uP5KVF5Ysz/WaYSGY1BsbwfNfWWjWYQgcj77cA4FkBrM4Krq7GYsO sGI/IeI9RjtNyExLljpV/eg1rfO6iV+9k8QR4DOYccHooG3tZNhRTbOWTIbvDQir ryoDeAe2ndDa6BpWDPWRjsricq53+hXuDhx344hro15Uiv949cNMS5d6UFsAnuHR JYoX/TLmqaETTEC2krn0OgviEU7RcEUAaiEbdegHRTgCNVsYnxoqO91OMudaiyml zyzUKQYt73t2rBsciRPi3p+nSe6i56uE2yvAi1HtKSM5JMJweVp0VYsQB/0MTFnz 8VIrQjWhj/GEbUufHwWTTwPvEy1Aj9yr4xM6Jxe+C0hnFnB9n2BQQr89QWLkLt2L 0YGviq17Xbk3dgvhp28wY6kPTYipY3VJy2MiyH5DZDY9+5MsMo2VY/y6GyXEe4HZ ycGyRdvyyNxwiAOI7NVHQYufiVjcdX4kV9uKC6VcfB2tcJF16l3s3u60EE324+t5 lf1LrFVP0xgBrKfAA8SV =Cc57 -----END PGP SIGNATURE----- Merge tag 'kvm-s390-next-4.16-1' of git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux KVM: s390: Fixes and features for 4.16 - add the virtio-ccw transport for kvmconfig - more debug tracing for cpu model - cleanups and fixes
This commit is contained in:
commit
7cd918047a
@ -515,9 +515,6 @@ struct kvm_s390_irq_payload {
|
||||
|
||||
struct kvm_s390_local_interrupt {
|
||||
spinlock_t lock;
|
||||
struct kvm_s390_float_interrupt *float_int;
|
||||
struct swait_queue_head *wq;
|
||||
atomic_t *cpuflags;
|
||||
DECLARE_BITMAP(sigp_emerg_pending, KVM_MAX_VCPUS);
|
||||
struct kvm_s390_irq_payload irq;
|
||||
unsigned long pending_irqs;
|
||||
|
@ -107,12 +107,11 @@ static int sca_inject_ext_call(struct kvm_vcpu *vcpu, int src_id)
|
||||
|
||||
static void sca_clear_ext_call(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
|
||||
int rc, expect;
|
||||
|
||||
if (!kvm_s390_use_sca_entries())
|
||||
return;
|
||||
atomic_andnot(CPUSTAT_ECALL_PEND, li->cpuflags);
|
||||
atomic_andnot(CPUSTAT_ECALL_PEND, &vcpu->arch.sie_block->cpuflags);
|
||||
read_lock(&vcpu->kvm->arch.sca_lock);
|
||||
if (vcpu->kvm->arch.use_esca) {
|
||||
struct esca_block *sca = vcpu->kvm->arch.sca;
|
||||
@ -279,13 +278,13 @@ static unsigned long deliverable_irqs(struct kvm_vcpu *vcpu)
|
||||
static void __set_cpu_idle(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
atomic_or(CPUSTAT_WAIT, &vcpu->arch.sie_block->cpuflags);
|
||||
set_bit(vcpu->vcpu_id, vcpu->arch.local_int.float_int->idle_mask);
|
||||
set_bit(vcpu->vcpu_id, vcpu->kvm->arch.float_int.idle_mask);
|
||||
}
|
||||
|
||||
static void __unset_cpu_idle(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
atomic_andnot(CPUSTAT_WAIT, &vcpu->arch.sie_block->cpuflags);
|
||||
clear_bit(vcpu->vcpu_id, vcpu->arch.local_int.float_int->idle_mask);
|
||||
clear_bit(vcpu->vcpu_id, vcpu->kvm->arch.float_int.idle_mask);
|
||||
}
|
||||
|
||||
static void __reset_intercept_indicators(struct kvm_vcpu *vcpu)
|
||||
@ -1228,7 +1227,7 @@ static int __inject_pfault_init(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
|
||||
|
||||
li->irq.ext = irq->u.ext;
|
||||
set_bit(IRQ_PEND_PFAULT_INIT, &li->pending_irqs);
|
||||
atomic_or(CPUSTAT_EXT_INT, li->cpuflags);
|
||||
__set_cpuflag(vcpu, CPUSTAT_EXT_INT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1253,7 +1252,7 @@ static int __inject_extcall(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
|
||||
if (test_and_set_bit(IRQ_PEND_EXT_EXTERNAL, &li->pending_irqs))
|
||||
return -EBUSY;
|
||||
*extcall = irq->u.extcall;
|
||||
atomic_or(CPUSTAT_EXT_INT, li->cpuflags);
|
||||
__set_cpuflag(vcpu, CPUSTAT_EXT_INT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1329,7 +1328,7 @@ static int __inject_sigp_emergency(struct kvm_vcpu *vcpu,
|
||||
|
||||
set_bit(irq->u.emerg.code, li->sigp_emerg_pending);
|
||||
set_bit(IRQ_PEND_EXT_EMERGENCY, &li->pending_irqs);
|
||||
atomic_or(CPUSTAT_EXT_INT, li->cpuflags);
|
||||
__set_cpuflag(vcpu, CPUSTAT_EXT_INT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1373,7 +1372,7 @@ static int __inject_ckc(struct kvm_vcpu *vcpu)
|
||||
0, 0);
|
||||
|
||||
set_bit(IRQ_PEND_EXT_CLOCK_COMP, &li->pending_irqs);
|
||||
atomic_or(CPUSTAT_EXT_INT, li->cpuflags);
|
||||
__set_cpuflag(vcpu, CPUSTAT_EXT_INT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1386,7 +1385,7 @@ static int __inject_cpu_timer(struct kvm_vcpu *vcpu)
|
||||
0, 0);
|
||||
|
||||
set_bit(IRQ_PEND_EXT_CPU_TIMER, &li->pending_irqs);
|
||||
atomic_or(CPUSTAT_EXT_INT, li->cpuflags);
|
||||
__set_cpuflag(vcpu, CPUSTAT_EXT_INT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1546,7 +1545,6 @@ static int __inject_io(struct kvm *kvm, struct kvm_s390_interrupt_info *inti)
|
||||
static void __floating_irq_kick(struct kvm *kvm, u64 type)
|
||||
{
|
||||
struct kvm_s390_float_interrupt *fi = &kvm->arch.float_int;
|
||||
struct kvm_s390_local_interrupt *li;
|
||||
struct kvm_vcpu *dst_vcpu;
|
||||
int sigcpu, online_vcpus, nr_tries = 0;
|
||||
|
||||
@ -1568,20 +1566,17 @@ static void __floating_irq_kick(struct kvm *kvm, u64 type)
|
||||
dst_vcpu = kvm_get_vcpu(kvm, sigcpu);
|
||||
|
||||
/* make the VCPU drop out of the SIE, or wake it up if sleeping */
|
||||
li = &dst_vcpu->arch.local_int;
|
||||
spin_lock(&li->lock);
|
||||
switch (type) {
|
||||
case KVM_S390_MCHK:
|
||||
atomic_or(CPUSTAT_STOP_INT, li->cpuflags);
|
||||
__set_cpuflag(dst_vcpu, CPUSTAT_STOP_INT);
|
||||
break;
|
||||
case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX:
|
||||
atomic_or(CPUSTAT_IO_INT, li->cpuflags);
|
||||
__set_cpuflag(dst_vcpu, CPUSTAT_IO_INT);
|
||||
break;
|
||||
default:
|
||||
atomic_or(CPUSTAT_EXT_INT, li->cpuflags);
|
||||
__set_cpuflag(dst_vcpu, CPUSTAT_EXT_INT);
|
||||
break;
|
||||
}
|
||||
spin_unlock(&li->lock);
|
||||
kvm_s390_vcpu_wakeup(dst_vcpu);
|
||||
}
|
||||
|
||||
|
@ -573,7 +573,7 @@ static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap)
|
||||
case KVM_CAP_S390_GS:
|
||||
r = -EINVAL;
|
||||
mutex_lock(&kvm->lock);
|
||||
if (atomic_read(&kvm->online_vcpus)) {
|
||||
if (kvm->created_vcpus) {
|
||||
r = -EBUSY;
|
||||
} else if (test_facility(133)) {
|
||||
set_kvm_facility(kvm->arch.model.fac_mask, 133);
|
||||
@ -1084,7 +1084,6 @@ static int kvm_s390_set_processor_feat(struct kvm *kvm,
|
||||
struct kvm_device_attr *attr)
|
||||
{
|
||||
struct kvm_s390_vm_cpu_feat data;
|
||||
int ret = -EBUSY;
|
||||
|
||||
if (copy_from_user(&data, (void __user *)attr->addr, sizeof(data)))
|
||||
return -EFAULT;
|
||||
@ -1094,13 +1093,18 @@ static int kvm_s390_set_processor_feat(struct kvm *kvm,
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&kvm->lock);
|
||||
if (!atomic_read(&kvm->online_vcpus)) {
|
||||
bitmap_copy(kvm->arch.cpu_feat, (unsigned long *) data.feat,
|
||||
KVM_S390_VM_CPU_FEAT_NR_BITS);
|
||||
ret = 0;
|
||||
if (kvm->created_vcpus) {
|
||||
mutex_unlock(&kvm->lock);
|
||||
return -EBUSY;
|
||||
}
|
||||
bitmap_copy(kvm->arch.cpu_feat, (unsigned long *) data.feat,
|
||||
KVM_S390_VM_CPU_FEAT_NR_BITS);
|
||||
mutex_unlock(&kvm->lock);
|
||||
return ret;
|
||||
VM_EVENT(kvm, 3, "SET: guest feat: 0x%16.16llx.0x%16.16llx.0x%16.16llx",
|
||||
data.feat[0],
|
||||
data.feat[1],
|
||||
data.feat[2]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kvm_s390_set_processor_subfunc(struct kvm *kvm,
|
||||
@ -1202,6 +1206,10 @@ static int kvm_s390_get_processor_feat(struct kvm *kvm,
|
||||
KVM_S390_VM_CPU_FEAT_NR_BITS);
|
||||
if (copy_to_user((void __user *)attr->addr, &data, sizeof(data)))
|
||||
return -EFAULT;
|
||||
VM_EVENT(kvm, 3, "GET: guest feat: 0x%16.16llx.0x%16.16llx.0x%16.16llx",
|
||||
data.feat[0],
|
||||
data.feat[1],
|
||||
data.feat[2]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1215,6 +1223,10 @@ static int kvm_s390_get_machine_feat(struct kvm *kvm,
|
||||
KVM_S390_VM_CPU_FEAT_NR_BITS);
|
||||
if (copy_to_user((void __user *)attr->addr, &data, sizeof(data)))
|
||||
return -EFAULT;
|
||||
VM_EVENT(kvm, 3, "GET: host feat: 0x%16.16llx.0x%16.16llx.0x%16.16llx",
|
||||
data.feat[0],
|
||||
data.feat[1],
|
||||
data.feat[2]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2497,9 +2509,6 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
|
||||
|
||||
vcpu->arch.sie_block->icpua = id;
|
||||
spin_lock_init(&vcpu->arch.local_int.lock);
|
||||
vcpu->arch.local_int.float_int = &kvm->arch.float_int;
|
||||
vcpu->arch.local_int.wq = &vcpu->wq;
|
||||
vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags;
|
||||
seqcount_init(&vcpu->arch.cputm_seqcount);
|
||||
|
||||
rc = kvm_vcpu_init(vcpu, kvm, id);
|
||||
|
@ -54,7 +54,7 @@ static inline int is_vcpu_stopped(struct kvm_vcpu *vcpu)
|
||||
|
||||
static inline int is_vcpu_idle(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return test_bit(vcpu->vcpu_id, vcpu->arch.local_int.float_int->idle_mask);
|
||||
return test_bit(vcpu->vcpu_id, vcpu->kvm->arch.float_int.idle_mask);
|
||||
}
|
||||
|
||||
static inline int kvm_is_ucontrol(struct kvm *kvm)
|
||||
|
@ -20,14 +20,11 @@
|
||||
static int __sigp_sense(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu,
|
||||
u64 *reg)
|
||||
{
|
||||
struct kvm_s390_local_interrupt *li;
|
||||
int cpuflags;
|
||||
int rc;
|
||||
int ext_call_pending;
|
||||
|
||||
li = &dst_vcpu->arch.local_int;
|
||||
|
||||
cpuflags = atomic_read(li->cpuflags);
|
||||
cpuflags = atomic_read(&dst_vcpu->arch.sie_block->cpuflags);
|
||||
ext_call_pending = kvm_s390_ext_call_pending(dst_vcpu);
|
||||
if (!(cpuflags & CPUSTAT_STOPPED) && !ext_call_pending)
|
||||
rc = SIGP_CC_ORDER_CODE_ACCEPTED;
|
||||
@ -211,7 +208,7 @@ static int __sigp_store_status_at_addr(struct kvm_vcpu *vcpu,
|
||||
int flags;
|
||||
int rc;
|
||||
|
||||
flags = atomic_read(dst_vcpu->arch.local_int.cpuflags);
|
||||
flags = atomic_read(&dst_vcpu->arch.sie_block->cpuflags);
|
||||
if (!(flags & CPUSTAT_STOPPED)) {
|
||||
*reg &= 0xffffffff00000000UL;
|
||||
*reg |= SIGP_STATUS_INCORRECT_STATE;
|
||||
@ -231,7 +228,6 @@ static int __sigp_store_status_at_addr(struct kvm_vcpu *vcpu,
|
||||
static int __sigp_sense_running(struct kvm_vcpu *vcpu,
|
||||
struct kvm_vcpu *dst_vcpu, u64 *reg)
|
||||
{
|
||||
struct kvm_s390_local_interrupt *li;
|
||||
int rc;
|
||||
|
||||
if (!test_kvm_facility(vcpu->kvm, 9)) {
|
||||
@ -240,8 +236,8 @@ static int __sigp_sense_running(struct kvm_vcpu *vcpu,
|
||||
return SIGP_CC_STATUS_STORED;
|
||||
}
|
||||
|
||||
li = &dst_vcpu->arch.local_int;
|
||||
if (atomic_read(li->cpuflags) & CPUSTAT_RUNNING) {
|
||||
if (atomic_read(&dst_vcpu->arch.sie_block->cpuflags) &
|
||||
CPUSTAT_RUNNING) {
|
||||
/* running */
|
||||
rc = SIGP_CC_ORDER_CODE_ACCEPTED;
|
||||
} else {
|
||||
|
@ -815,27 +815,17 @@ static inline unsigned long *gmap_table_walk(struct gmap *gmap,
|
||||
* @ptl: pointer to the spinlock pointer
|
||||
*
|
||||
* Returns a pointer to the locked pte for a guest address, or NULL
|
||||
*
|
||||
* Note: Can also be called for shadow gmaps.
|
||||
*/
|
||||
static pte_t *gmap_pte_op_walk(struct gmap *gmap, unsigned long gaddr,
|
||||
spinlock_t **ptl)
|
||||
{
|
||||
unsigned long *table;
|
||||
|
||||
if (gmap_is_shadow(gmap))
|
||||
spin_lock(&gmap->guest_table_lock);
|
||||
BUG_ON(gmap_is_shadow(gmap));
|
||||
/* Walk the gmap page table, lock and get pte pointer */
|
||||
table = gmap_table_walk(gmap, gaddr, 1); /* get segment pointer */
|
||||
if (!table || *table & _SEGMENT_ENTRY_INVALID) {
|
||||
if (gmap_is_shadow(gmap))
|
||||
spin_unlock(&gmap->guest_table_lock);
|
||||
if (!table || *table & _SEGMENT_ENTRY_INVALID)
|
||||
return NULL;
|
||||
}
|
||||
if (gmap_is_shadow(gmap)) {
|
||||
*ptl = &gmap->guest_table_lock;
|
||||
return pte_offset_map((pmd_t *) table, gaddr);
|
||||
}
|
||||
return pte_alloc_map_lock(gmap->mm, (pmd_t *) table, gaddr, ptl);
|
||||
}
|
||||
|
||||
@ -889,8 +879,6 @@ static void gmap_pte_op_end(spinlock_t *ptl)
|
||||
* -EFAULT if gaddr is invalid (or mapping for shadows is missing).
|
||||
*
|
||||
* Called with sg->mm->mmap_sem in read.
|
||||
*
|
||||
* Note: Can also be called for shadow gmaps.
|
||||
*/
|
||||
static int gmap_protect_range(struct gmap *gmap, unsigned long gaddr,
|
||||
unsigned long len, int prot, unsigned long bits)
|
||||
@ -900,6 +888,7 @@ static int gmap_protect_range(struct gmap *gmap, unsigned long gaddr,
|
||||
pte_t *ptep;
|
||||
int rc;
|
||||
|
||||
BUG_ON(gmap_is_shadow(gmap));
|
||||
while (len) {
|
||||
rc = -EAGAIN;
|
||||
ptep = gmap_pte_op_walk(gmap, gaddr, &ptl);
|
||||
@ -960,7 +949,8 @@ EXPORT_SYMBOL_GPL(gmap_mprotect_notify);
|
||||
* @val: pointer to the unsigned long value to return
|
||||
*
|
||||
* Returns 0 if the value was read, -ENOMEM if out of memory and -EFAULT
|
||||
* if reading using the virtual address failed.
|
||||
* if reading using the virtual address failed. -EINVAL if called on a gmap
|
||||
* shadow.
|
||||
*
|
||||
* Called with gmap->mm->mmap_sem in read.
|
||||
*/
|
||||
@ -971,6 +961,9 @@ int gmap_read_table(struct gmap *gmap, unsigned long gaddr, unsigned long *val)
|
||||
pte_t *ptep, pte;
|
||||
int rc;
|
||||
|
||||
if (gmap_is_shadow(gmap))
|
||||
return -EINVAL;
|
||||
|
||||
while (1) {
|
||||
rc = -EAGAIN;
|
||||
ptep = gmap_pte_op_walk(gmap, gaddr, &ptl);
|
||||
|
@ -18,6 +18,7 @@ CONFIG_VIRTUALIZATION=y
|
||||
CONFIG_HYPERVISOR_GUEST=y
|
||||
CONFIG_PARAVIRT=y
|
||||
CONFIG_KVM_GUEST=y
|
||||
CONFIG_S390_GUEST=y
|
||||
CONFIG_VIRTIO=y
|
||||
CONFIG_VIRTIO_PCI=y
|
||||
CONFIG_VIRTIO_BLK=y
|
||||
|
Loading…
Reference in New Issue
Block a user