Commit 1330a017 authored by Paolo Bonzini's avatar Paolo Bonzini

Merge tag 'kvm-s390-next-20151013' of...

Merge tag 'kvm-s390-next-20151013' of git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux into HEAD

KVM: s390: Fixes for 4.4

A bunch of fixes and optimizations for interrupt and time
handling. No fix is important enough to qualify for 4.3 or
stable.
parents b7d20631 60417fcc
...@@ -51,11 +51,9 @@ static int psw_mchk_disabled(struct kvm_vcpu *vcpu) ...@@ -51,11 +51,9 @@ static int psw_mchk_disabled(struct kvm_vcpu *vcpu)
static int psw_interrupts_disabled(struct kvm_vcpu *vcpu) static int psw_interrupts_disabled(struct kvm_vcpu *vcpu)
{ {
if ((vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PER) || return psw_extint_disabled(vcpu) &&
(vcpu->arch.sie_block->gpsw.mask & PSW_MASK_IO) || psw_ioint_disabled(vcpu) &&
(vcpu->arch.sie_block->gpsw.mask & PSW_MASK_EXT)) psw_mchk_disabled(vcpu);
return 0;
return 1;
} }
static int ckc_interrupts_enabled(struct kvm_vcpu *vcpu) static int ckc_interrupts_enabled(struct kvm_vcpu *vcpu)
...@@ -71,13 +69,8 @@ static int ckc_interrupts_enabled(struct kvm_vcpu *vcpu) ...@@ -71,13 +69,8 @@ static int ckc_interrupts_enabled(struct kvm_vcpu *vcpu)
static int ckc_irq_pending(struct kvm_vcpu *vcpu) static int ckc_irq_pending(struct kvm_vcpu *vcpu)
{ {
preempt_disable(); if (vcpu->arch.sie_block->ckc >= kvm_s390_get_tod_clock_fast(vcpu->kvm))
if (!(vcpu->arch.sie_block->ckc <
get_tod_clock_fast() + vcpu->arch.sie_block->epoch)) {
preempt_enable();
return 0; return 0;
}
preempt_enable();
return ckc_interrupts_enabled(vcpu); return ckc_interrupts_enabled(vcpu);
} }
...@@ -109,14 +102,10 @@ static inline u8 int_word_to_isc(u32 int_word) ...@@ -109,14 +102,10 @@ static inline u8 int_word_to_isc(u32 int_word)
return (int_word & 0x38000000) >> 27; return (int_word & 0x38000000) >> 27;
} }
static inline unsigned long pending_floating_irqs(struct kvm_vcpu *vcpu) static inline unsigned long pending_irqs(struct kvm_vcpu *vcpu)
{
return vcpu->kvm->arch.float_int.pending_irqs;
}
static inline unsigned long pending_local_irqs(struct kvm_vcpu *vcpu)
{ {
return vcpu->arch.local_int.pending_irqs; return vcpu->kvm->arch.float_int.pending_irqs |
vcpu->arch.local_int.pending_irqs;
} }
static unsigned long disable_iscs(struct kvm_vcpu *vcpu, static unsigned long disable_iscs(struct kvm_vcpu *vcpu,
...@@ -135,8 +124,7 @@ static unsigned long deliverable_irqs(struct kvm_vcpu *vcpu) ...@@ -135,8 +124,7 @@ static unsigned long deliverable_irqs(struct kvm_vcpu *vcpu)
{ {
unsigned long active_mask; unsigned long active_mask;
active_mask = pending_local_irqs(vcpu); active_mask = pending_irqs(vcpu);
active_mask |= pending_floating_irqs(vcpu);
if (!active_mask) if (!active_mask)
return 0; return 0;
...@@ -204,7 +192,7 @@ static void __set_cpuflag(struct kvm_vcpu *vcpu, u32 flag) ...@@ -204,7 +192,7 @@ static void __set_cpuflag(struct kvm_vcpu *vcpu, u32 flag)
static void set_intercept_indicators_io(struct kvm_vcpu *vcpu) static void set_intercept_indicators_io(struct kvm_vcpu *vcpu)
{ {
if (!(pending_floating_irqs(vcpu) & IRQ_PEND_IO_MASK)) if (!(pending_irqs(vcpu) & IRQ_PEND_IO_MASK))
return; return;
else if (psw_ioint_disabled(vcpu)) else if (psw_ioint_disabled(vcpu))
__set_cpuflag(vcpu, CPUSTAT_IO_INT); __set_cpuflag(vcpu, CPUSTAT_IO_INT);
...@@ -214,7 +202,7 @@ static void set_intercept_indicators_io(struct kvm_vcpu *vcpu) ...@@ -214,7 +202,7 @@ static void set_intercept_indicators_io(struct kvm_vcpu *vcpu)
static void set_intercept_indicators_ext(struct kvm_vcpu *vcpu) static void set_intercept_indicators_ext(struct kvm_vcpu *vcpu)
{ {
if (!(pending_local_irqs(vcpu) & IRQ_PEND_EXT_MASK)) if (!(pending_irqs(vcpu) & IRQ_PEND_EXT_MASK))
return; return;
if (psw_extint_disabled(vcpu)) if (psw_extint_disabled(vcpu))
__set_cpuflag(vcpu, CPUSTAT_EXT_INT); __set_cpuflag(vcpu, CPUSTAT_EXT_INT);
...@@ -224,7 +212,7 @@ static void set_intercept_indicators_ext(struct kvm_vcpu *vcpu) ...@@ -224,7 +212,7 @@ static void set_intercept_indicators_ext(struct kvm_vcpu *vcpu)
static void set_intercept_indicators_mchk(struct kvm_vcpu *vcpu) static void set_intercept_indicators_mchk(struct kvm_vcpu *vcpu)
{ {
if (!(pending_local_irqs(vcpu) & IRQ_PEND_MCHK_MASK)) if (!(pending_irqs(vcpu) & IRQ_PEND_MCHK_MASK))
return; return;
if (psw_mchk_disabled(vcpu)) if (psw_mchk_disabled(vcpu))
vcpu->arch.sie_block->ictl |= ICTL_LPSW; vcpu->arch.sie_block->ictl |= ICTL_LPSW;
...@@ -815,23 +803,21 @@ int kvm_s390_ext_call_pending(struct kvm_vcpu *vcpu) ...@@ -815,23 +803,21 @@ int kvm_s390_ext_call_pending(struct kvm_vcpu *vcpu)
int kvm_s390_vcpu_has_irq(struct kvm_vcpu *vcpu, int exclude_stop) int kvm_s390_vcpu_has_irq(struct kvm_vcpu *vcpu, int exclude_stop)
{ {
int rc; if (deliverable_irqs(vcpu))
return 1;
rc = !!deliverable_irqs(vcpu);
if (!rc && kvm_cpu_has_pending_timer(vcpu)) if (kvm_cpu_has_pending_timer(vcpu))
rc = 1; return 1;
/* external call pending and deliverable */ /* external call pending and deliverable */
if (!rc && kvm_s390_ext_call_pending(vcpu) && if (kvm_s390_ext_call_pending(vcpu) &&
!psw_extint_disabled(vcpu) && !psw_extint_disabled(vcpu) &&
(vcpu->arch.sie_block->gcr[0] & 0x2000ul)) (vcpu->arch.sie_block->gcr[0] & 0x2000ul))
rc = 1; return 1;
if (!rc && !exclude_stop && kvm_s390_is_stop_irq_pending(vcpu))
rc = 1;
return rc; if (!exclude_stop && kvm_s390_is_stop_irq_pending(vcpu))
return 1;
return 0;
} }
int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
...@@ -846,7 +832,7 @@ int kvm_s390_handle_wait(struct kvm_vcpu *vcpu) ...@@ -846,7 +832,7 @@ int kvm_s390_handle_wait(struct kvm_vcpu *vcpu)
vcpu->stat.exit_wait_state++; vcpu->stat.exit_wait_state++;
/* fast path */ /* fast path */
if (kvm_cpu_has_pending_timer(vcpu) || kvm_arch_vcpu_runnable(vcpu)) if (kvm_arch_vcpu_runnable(vcpu))
return 0; return 0;
if (psw_interrupts_disabled(vcpu)) { if (psw_interrupts_disabled(vcpu)) {
...@@ -860,9 +846,7 @@ int kvm_s390_handle_wait(struct kvm_vcpu *vcpu) ...@@ -860,9 +846,7 @@ int kvm_s390_handle_wait(struct kvm_vcpu *vcpu)
goto no_timer; goto no_timer;
} }
preempt_disable(); now = kvm_s390_get_tod_clock_fast(vcpu->kvm);
now = get_tod_clock_fast() + vcpu->arch.sie_block->epoch;
preempt_enable();
sltime = tod_to_ns(vcpu->arch.sie_block->ckc - now); sltime = tod_to_ns(vcpu->arch.sie_block->ckc - now);
/* underflow */ /* underflow */
...@@ -901,9 +885,7 @@ enum hrtimer_restart kvm_s390_idle_wakeup(struct hrtimer *timer) ...@@ -901,9 +885,7 @@ enum hrtimer_restart kvm_s390_idle_wakeup(struct hrtimer *timer)
u64 now, sltime; u64 now, sltime;
vcpu = container_of(timer, struct kvm_vcpu, arch.ckc_timer); vcpu = container_of(timer, struct kvm_vcpu, arch.ckc_timer);
preempt_disable(); now = kvm_s390_get_tod_clock_fast(vcpu->kvm);
now = get_tod_clock_fast() + vcpu->arch.sie_block->epoch;
preempt_enable();
sltime = tod_to_ns(vcpu->arch.sie_block->ckc - now); sltime = tod_to_ns(vcpu->arch.sie_block->ckc - now);
/* /*
...@@ -981,39 +963,30 @@ static int __inject_prog(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq) ...@@ -981,39 +963,30 @@ static int __inject_prog(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_PROGRAM_INT, trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_PROGRAM_INT,
irq->u.pgm.code, 0); irq->u.pgm.code, 0);
if (irq->u.pgm.code == PGM_PER) {
li->irq.pgm.code |= PGM_PER;
/* only modify PER related information */
li->irq.pgm.per_address = irq->u.pgm.per_address;
li->irq.pgm.per_code = irq->u.pgm.per_code;
li->irq.pgm.per_atmid = irq->u.pgm.per_atmid;
li->irq.pgm.per_access_id = irq->u.pgm.per_access_id;
} else if (!(irq->u.pgm.code & PGM_PER)) {
li->irq.pgm.code = (li->irq.pgm.code & PGM_PER) |
irq->u.pgm.code;
/* only modify non-PER information */
li->irq.pgm.trans_exc_code = irq->u.pgm.trans_exc_code;
li->irq.pgm.mon_code = irq->u.pgm.mon_code;
li->irq.pgm.data_exc_code = irq->u.pgm.data_exc_code;
li->irq.pgm.mon_class_nr = irq->u.pgm.mon_class_nr;
li->irq.pgm.exc_access_id = irq->u.pgm.exc_access_id;
li->irq.pgm.op_access_id = irq->u.pgm.op_access_id;
} else {
li->irq.pgm = irq->u.pgm; li->irq.pgm = irq->u.pgm;
}
set_bit(IRQ_PEND_PROG, &li->pending_irqs); set_bit(IRQ_PEND_PROG, &li->pending_irqs);
return 0; return 0;
} }
int kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code)
{
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
struct kvm_s390_irq irq;
spin_lock(&li->lock);
irq.u.pgm.code = code;
__inject_prog(vcpu, &irq);
BUG_ON(waitqueue_active(li->wq));
spin_unlock(&li->lock);
return 0;
}
int kvm_s390_inject_prog_irq(struct kvm_vcpu *vcpu,
struct kvm_s390_pgm_info *pgm_info)
{
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
struct kvm_s390_irq irq;
int rc;
spin_lock(&li->lock);
irq.u.pgm = *pgm_info;
rc = __inject_prog(vcpu, &irq);
BUG_ON(waitqueue_active(li->wq));
spin_unlock(&li->lock);
return rc;
}
static int __inject_pfault_init(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq) static int __inject_pfault_init(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
{ {
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
...@@ -1390,12 +1363,9 @@ static void __floating_irq_kick(struct kvm *kvm, u64 type) ...@@ -1390,12 +1363,9 @@ static void __floating_irq_kick(struct kvm *kvm, u64 type)
static int __inject_vm(struct kvm *kvm, struct kvm_s390_interrupt_info *inti) static int __inject_vm(struct kvm *kvm, struct kvm_s390_interrupt_info *inti)
{ {
struct kvm_s390_float_interrupt *fi;
u64 type = READ_ONCE(inti->type); u64 type = READ_ONCE(inti->type);
int rc; int rc;
fi = &kvm->arch.float_int;
switch (type) { switch (type) {
case KVM_S390_MCHK: case KVM_S390_MCHK:
rc = __inject_float_mchk(kvm, inti); rc = __inject_float_mchk(kvm, inti);
......
...@@ -521,27 +521,12 @@ static int kvm_s390_set_tod_high(struct kvm *kvm, struct kvm_device_attr *attr) ...@@ -521,27 +521,12 @@ static int kvm_s390_set_tod_high(struct kvm *kvm, struct kvm_device_attr *attr)
static int kvm_s390_set_tod_low(struct kvm *kvm, struct kvm_device_attr *attr) static int kvm_s390_set_tod_low(struct kvm *kvm, struct kvm_device_attr *attr)
{ {
struct kvm_vcpu *cur_vcpu; u64 gtod;
unsigned int vcpu_idx;
u64 host_tod, gtod;
int r;
if (copy_from_user(&gtod, (void __user *)attr->addr, sizeof(gtod))) if (copy_from_user(&gtod, (void __user *)attr->addr, sizeof(gtod)))
return -EFAULT; return -EFAULT;
r = store_tod_clock(&host_tod); kvm_s390_set_tod_clock(kvm, gtod);
if (r)
return r;
mutex_lock(&kvm->lock);
preempt_disable();
kvm->arch.epoch = gtod - host_tod;
kvm_s390_vcpu_block_all(kvm);
kvm_for_each_vcpu(vcpu_idx, cur_vcpu, kvm)
cur_vcpu->arch.sie_block->epoch = kvm->arch.epoch;
kvm_s390_vcpu_unblock_all(kvm);
preempt_enable();
mutex_unlock(&kvm->lock);
VM_EVENT(kvm, 3, "SET: TOD base: 0x%llx\n", gtod); VM_EVENT(kvm, 3, "SET: TOD base: 0x%llx\n", gtod);
return 0; return 0;
} }
...@@ -581,16 +566,9 @@ static int kvm_s390_get_tod_high(struct kvm *kvm, struct kvm_device_attr *attr) ...@@ -581,16 +566,9 @@ static int kvm_s390_get_tod_high(struct kvm *kvm, struct kvm_device_attr *attr)
static int kvm_s390_get_tod_low(struct kvm *kvm, struct kvm_device_attr *attr) static int kvm_s390_get_tod_low(struct kvm *kvm, struct kvm_device_attr *attr)
{ {
u64 host_tod, gtod; u64 gtod;
int r;
r = store_tod_clock(&host_tod); gtod = kvm_s390_get_tod_clock_fast(kvm);
if (r)
return r;
preempt_disable();
gtod = host_tod + kvm->arch.epoch;
preempt_enable();
if (copy_to_user((void __user *)attr->addr, &gtod, sizeof(gtod))) if (copy_to_user((void __user *)attr->addr, &gtod, sizeof(gtod)))
return -EFAULT; return -EFAULT;
VM_EVENT(kvm, 3, "QUERY: TOD base: 0x%llx\n", gtod); VM_EVENT(kvm, 3, "QUERY: TOD base: 0x%llx\n", gtod);
...@@ -1916,6 +1894,22 @@ static int kvm_s390_handle_requests(struct kvm_vcpu *vcpu) ...@@ -1916,6 +1894,22 @@ static int kvm_s390_handle_requests(struct kvm_vcpu *vcpu)
return 0; return 0;
} }
void kvm_s390_set_tod_clock(struct kvm *kvm, u64 tod)
{
struct kvm_vcpu *vcpu;
int i;
mutex_lock(&kvm->lock);
preempt_disable();
kvm->arch.epoch = tod - get_tod_clock();
kvm_s390_vcpu_block_all(kvm);
kvm_for_each_vcpu(i, vcpu, kvm)
vcpu->arch.sie_block->epoch = kvm->arch.epoch;
kvm_s390_vcpu_unblock_all(kvm);
preempt_enable();
mutex_unlock(&kvm->lock);
}
/** /**
* kvm_arch_fault_in_page - fault-in guest page if necessary * kvm_arch_fault_in_page - fault-in guest page if necessary
* @vcpu: The corresponding virtual cpu * @vcpu: The corresponding virtual cpu
......
...@@ -175,6 +175,7 @@ static inline int kvm_s390_user_cpu_state_ctrl(struct kvm *kvm) ...@@ -175,6 +175,7 @@ static inline int kvm_s390_user_cpu_state_ctrl(struct kvm *kvm)
return kvm->arch.user_cpu_state_ctrl != 0; return kvm->arch.user_cpu_state_ctrl != 0;
} }
/* implemented in interrupt.c */
int kvm_s390_handle_wait(struct kvm_vcpu *vcpu); int kvm_s390_handle_wait(struct kvm_vcpu *vcpu);
void kvm_s390_vcpu_wakeup(struct kvm_vcpu *vcpu); void kvm_s390_vcpu_wakeup(struct kvm_vcpu *vcpu);
enum hrtimer_restart kvm_s390_idle_wakeup(struct hrtimer *timer); enum hrtimer_restart kvm_s390_idle_wakeup(struct hrtimer *timer);
...@@ -185,7 +186,25 @@ int __must_check kvm_s390_inject_vm(struct kvm *kvm, ...@@ -185,7 +186,25 @@ int __must_check kvm_s390_inject_vm(struct kvm *kvm,
struct kvm_s390_interrupt *s390int); struct kvm_s390_interrupt *s390int);
int __must_check kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu, int __must_check kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu,
struct kvm_s390_irq *irq); struct kvm_s390_irq *irq);
int __must_check kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code); static inline int kvm_s390_inject_prog_irq(struct kvm_vcpu *vcpu,
struct kvm_s390_pgm_info *pgm_info)
{
struct kvm_s390_irq irq = {
.type = KVM_S390_PROGRAM_INT,
.u.pgm = *pgm_info,
};
return kvm_s390_inject_vcpu(vcpu, &irq);
}
static inline int kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code)
{
struct kvm_s390_irq irq = {
.type = KVM_S390_PROGRAM_INT,
.u.pgm.code = code,
};
return kvm_s390_inject_vcpu(vcpu, &irq);
}
struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm, struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm,
u64 isc_mask, u32 schid); u64 isc_mask, u32 schid);
int kvm_s390_reinject_io_int(struct kvm *kvm, int kvm_s390_reinject_io_int(struct kvm *kvm,
...@@ -212,6 +231,7 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu); ...@@ -212,6 +231,7 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu);
int kvm_s390_handle_sigp_pei(struct kvm_vcpu *vcpu); int kvm_s390_handle_sigp_pei(struct kvm_vcpu *vcpu);
/* implemented in kvm-s390.c */ /* implemented in kvm-s390.c */
void kvm_s390_set_tod_clock(struct kvm *kvm, u64 tod);
long kvm_arch_fault_in_page(struct kvm_vcpu *vcpu, gpa_t gpa, int writable); long kvm_arch_fault_in_page(struct kvm_vcpu *vcpu, gpa_t gpa, int writable);
int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long addr); int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long addr);
int kvm_s390_store_adtl_status_unloaded(struct kvm_vcpu *vcpu, int kvm_s390_store_adtl_status_unloaded(struct kvm_vcpu *vcpu,
...@@ -231,9 +251,6 @@ extern unsigned long kvm_s390_fac_list_mask[]; ...@@ -231,9 +251,6 @@ extern unsigned long kvm_s390_fac_list_mask[];
/* implemented in diag.c */ /* implemented in diag.c */
int kvm_s390_handle_diag(struct kvm_vcpu *vcpu); int kvm_s390_handle_diag(struct kvm_vcpu *vcpu);
/* implemented in interrupt.c */
int kvm_s390_inject_prog_irq(struct kvm_vcpu *vcpu,
struct kvm_s390_pgm_info *pgm_info);
static inline void kvm_s390_vcpu_block_all(struct kvm *kvm) static inline void kvm_s390_vcpu_block_all(struct kvm *kvm)
{ {
...@@ -254,6 +271,16 @@ static inline void kvm_s390_vcpu_unblock_all(struct kvm *kvm) ...@@ -254,6 +271,16 @@ static inline void kvm_s390_vcpu_unblock_all(struct kvm *kvm)
kvm_s390_vcpu_unblock(vcpu); kvm_s390_vcpu_unblock(vcpu);
} }
static inline u64 kvm_s390_get_tod_clock_fast(struct kvm *kvm)
{
u64 rc;
preempt_disable();
rc = get_tod_clock_fast() + kvm->arch.epoch;
preempt_enable();
return rc;
}
/** /**
* kvm_s390_inject_prog_cond - conditionally inject a program check * kvm_s390_inject_prog_cond - conditionally inject a program check
* @vcpu: virtual cpu * @vcpu: virtual cpu
......
...@@ -33,11 +33,9 @@ ...@@ -33,11 +33,9 @@
/* Handle SCK (SET CLOCK) interception */ /* Handle SCK (SET CLOCK) interception */
static int handle_set_clock(struct kvm_vcpu *vcpu) static int handle_set_clock(struct kvm_vcpu *vcpu)
{ {
struct kvm_vcpu *cpup; int rc;
s64 hostclk, val;
int i, rc;
ar_t ar; ar_t ar;
u64 op2; u64 op2, val;
if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
...@@ -49,19 +47,8 @@ static int handle_set_clock(struct kvm_vcpu *vcpu) ...@@ -49,19 +47,8 @@ static int handle_set_clock(struct kvm_vcpu *vcpu)
if (rc) if (rc)
return kvm_s390_inject_prog_cond(vcpu, rc); return kvm_s390_inject_prog_cond(vcpu, rc);
if (store_tod_clock(&hostclk)) {
kvm_s390_set_psw_cc(vcpu, 3);
return 0;
}
VCPU_EVENT(vcpu, 3, "SCK: setting guest TOD to 0x%llx", val); VCPU_EVENT(vcpu, 3, "SCK: setting guest TOD to 0x%llx", val);
val = (val - hostclk) & ~0x3fUL; kvm_s390_set_tod_clock(vcpu->kvm, val);
mutex_lock(&vcpu->kvm->lock);
preempt_disable();
kvm_for_each_vcpu(i, cpup, vcpu->kvm)
cpup->arch.sie_block->epoch = val;
preempt_enable();
mutex_unlock(&vcpu->kvm->lock);
kvm_s390_set_psw_cc(vcpu, 0); kvm_s390_set_psw_cc(vcpu, 0);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment