Skip to content

Commit 44a1aad

Browse files
committed
Merge branch 'topic/ppc-kvm' into next
Merge our topic branch containing KVM related patches.
2 parents 482b718 + 180c6b0 commit 44a1aad

8 files changed

Lines changed: 107 additions & 39 deletions

File tree

arch/powerpc/include/asm/kvm_book3s.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ void kvmhv_nested_exit(void);
302302
void kvmhv_vm_nested_init(struct kvm *kvm);
303303
long kvmhv_set_partition_table(struct kvm_vcpu *vcpu);
304304
long kvmhv_copy_tofrom_guest_nested(struct kvm_vcpu *vcpu);
305+
void kvmhv_flush_lpid(u64 lpid);
305306
void kvmhv_set_ptbl_entry(u64 lpid, u64 dw0, u64 dw1);
306307
void kvmhv_release_all_nested(struct kvm *kvm);
307308
long kvmhv_enter_nested_guest(struct kvm_vcpu *vcpu);
@@ -593,21 +594,24 @@ static inline u##size kvmppc_get_##reg(struct kvm_vcpu *vcpu) \
593594

594595

595596
KVMPPC_BOOK3S_VCORE_ACCESSOR(vtb, 64, KVMPPC_GSID_VTB)
596-
KVMPPC_BOOK3S_VCORE_ACCESSOR(tb_offset, 64, KVMPPC_GSID_TB_OFFSET)
597597
KVMPPC_BOOK3S_VCORE_ACCESSOR_GET(arch_compat, 32, KVMPPC_GSID_LOGICAL_PVR)
598598
KVMPPC_BOOK3S_VCORE_ACCESSOR_GET(lpcr, 64, KVMPPC_GSID_LPCR)
599+
KVMPPC_BOOK3S_VCORE_ACCESSOR_SET(tb_offset, 64, KVMPPC_GSID_TB_OFFSET)
600+
601+
static inline u64 kvmppc_get_tb_offset(struct kvm_vcpu *vcpu)
602+
{
603+
return vcpu->arch.vcore->tb_offset;
604+
}
599605

600606
static inline u64 kvmppc_get_dec_expires(struct kvm_vcpu *vcpu)
601607
{
602-
WARN_ON(kvmhv_nestedv2_cached_reload(vcpu, KVMPPC_GSID_TB_OFFSET) < 0);
603608
WARN_ON(kvmhv_nestedv2_cached_reload(vcpu, KVMPPC_GSID_DEC_EXPIRY_TB) < 0);
604609
return vcpu->arch.dec_expires;
605610
}
606611

607612
static inline void kvmppc_set_dec_expires(struct kvm_vcpu *vcpu, u64 val)
608613
{
609614
vcpu->arch.dec_expires = val;
610-
WARN_ON(kvmhv_nestedv2_cached_reload(vcpu, KVMPPC_GSID_TB_OFFSET) < 0);
611615
kvmhv_nestedv2_mark_dirty(vcpu, KVMPPC_GSID_DEC_EXPIRY_TB);
612616
}
613617

arch/powerpc/include/asm/kvm_book3s_64.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,7 @@ void kvmhv_nestedv2_vcpu_free(struct kvm_vcpu *vcpu, struct kvmhv_nestedv2_io *i
682682
int kvmhv_nestedv2_flush_vcpu(struct kvm_vcpu *vcpu, u64 time_limit);
683683
int kvmhv_nestedv2_set_ptbl_entry(unsigned long lpid, u64 dw0, u64 dw1);
684684
int kvmhv_nestedv2_parse_output(struct kvm_vcpu *vcpu);
685+
int kvmhv_nestedv2_set_vpa(struct kvm_vcpu *vcpu, unsigned long vpa);
685686

686687
#endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */
687688

arch/powerpc/kvm/book3s.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,11 +302,11 @@ static int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu,
302302

303303
switch (priority) {
304304
case BOOK3S_IRQPRIO_DECREMENTER:
305-
deliver = (kvmppc_get_msr(vcpu) & MSR_EE) && !crit;
305+
deliver = !kvmhv_is_nestedv2() && (kvmppc_get_msr(vcpu) & MSR_EE) && !crit;
306306
vec = BOOK3S_INTERRUPT_DECREMENTER;
307307
break;
308308
case BOOK3S_IRQPRIO_EXTERNAL:
309-
deliver = (kvmppc_get_msr(vcpu) & MSR_EE) && !crit;
309+
deliver = !kvmhv_is_nestedv2() && (kvmppc_get_msr(vcpu) & MSR_EE) && !crit;
310310
vec = BOOK3S_INTERRUPT_EXTERNAL;
311311
break;
312312
case BOOK3S_IRQPRIO_SYSTEM_RESET:

arch/powerpc/kvm/book3s_64_mmu_radix.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ unsigned long __kvmhv_copy_tofrom_guest_radix(int lpid, int pid,
4040
unsigned long quadrant, ret = n;
4141
bool is_load = !!to;
4242

43+
if (kvmhv_is_nestedv2())
44+
return H_UNSUPPORTED;
45+
4346
/* Can't access quadrants 1 or 2 in non-HV mode, call the HV to do it */
4447
if (kvmhv_on_pseries())
4548
return plpar_hcall_norets(H_COPY_TOFROM_GUEST, lpid, pid, eaddr,
@@ -97,7 +100,7 @@ static long kvmhv_copy_tofrom_guest_radix(struct kvm_vcpu *vcpu, gva_t eaddr,
97100
void *to, void *from, unsigned long n)
98101
{
99102
int lpid = vcpu->kvm->arch.lpid;
100-
int pid = kvmppc_get_pid(vcpu);
103+
int pid;
101104

102105
/* This would cause a data segment intr so don't allow the access */
103106
if (eaddr & (0x3FFUL << 52))
@@ -110,6 +113,8 @@ static long kvmhv_copy_tofrom_guest_radix(struct kvm_vcpu *vcpu, gva_t eaddr,
110113
/* If accessing quadrant 3 then pid is expected to be 0 */
111114
if (((eaddr >> 62) & 0x3) == 0x3)
112115
pid = 0;
116+
else
117+
pid = kvmppc_get_pid(vcpu);
113118

114119
eaddr &= ~(0xFFFUL << 52);
115120

arch/powerpc/kvm/book3s_hv.c

Lines changed: 51 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,8 @@ static unsigned long do_h_register_vpa(struct kvm_vcpu *vcpu,
650650
return err;
651651
}
652652

653-
static void kvmppc_update_vpa(struct kvm_vcpu *vcpu, struct kvmppc_vpa *vpap)
653+
static void kvmppc_update_vpa(struct kvm_vcpu *vcpu, struct kvmppc_vpa *vpap,
654+
struct kvmppc_vpa *old_vpap)
654655
{
655656
struct kvm *kvm = vcpu->kvm;
656657
void *va;
@@ -690,9 +691,8 @@ static void kvmppc_update_vpa(struct kvm_vcpu *vcpu, struct kvmppc_vpa *vpap)
690691
kvmppc_unpin_guest_page(kvm, va, gpa, false);
691692
va = NULL;
692693
}
693-
if (vpap->pinned_addr)
694-
kvmppc_unpin_guest_page(kvm, vpap->pinned_addr, vpap->gpa,
695-
vpap->dirty);
694+
*old_vpap = *vpap;
695+
696696
vpap->gpa = gpa;
697697
vpap->pinned_addr = va;
698698
vpap->dirty = false;
@@ -702,24 +702,44 @@ static void kvmppc_update_vpa(struct kvm_vcpu *vcpu, struct kvmppc_vpa *vpap)
702702

703703
static void kvmppc_update_vpas(struct kvm_vcpu *vcpu)
704704
{
705+
struct kvm *kvm = vcpu->kvm;
706+
struct kvmppc_vpa old_vpa = { 0 };
707+
705708
if (!(vcpu->arch.vpa.update_pending ||
706709
vcpu->arch.slb_shadow.update_pending ||
707710
vcpu->arch.dtl.update_pending))
708711
return;
709712

710713
spin_lock(&vcpu->arch.vpa_update_lock);
711714
if (vcpu->arch.vpa.update_pending) {
712-
kvmppc_update_vpa(vcpu, &vcpu->arch.vpa);
713-
if (vcpu->arch.vpa.pinned_addr)
715+
kvmppc_update_vpa(vcpu, &vcpu->arch.vpa, &old_vpa);
716+
if (old_vpa.pinned_addr) {
717+
if (kvmhv_is_nestedv2())
718+
kvmhv_nestedv2_set_vpa(vcpu, ~0ull);
719+
kvmppc_unpin_guest_page(kvm, old_vpa.pinned_addr, old_vpa.gpa,
720+
old_vpa.dirty);
721+
}
722+
if (vcpu->arch.vpa.pinned_addr) {
714723
init_vpa(vcpu, vcpu->arch.vpa.pinned_addr);
724+
if (kvmhv_is_nestedv2())
725+
kvmhv_nestedv2_set_vpa(vcpu, __pa(vcpu->arch.vpa.pinned_addr));
726+
}
715727
}
716728
if (vcpu->arch.dtl.update_pending) {
717-
kvmppc_update_vpa(vcpu, &vcpu->arch.dtl);
729+
kvmppc_update_vpa(vcpu, &vcpu->arch.dtl, &old_vpa);
730+
if (old_vpa.pinned_addr)
731+
kvmppc_unpin_guest_page(kvm, old_vpa.pinned_addr, old_vpa.gpa,
732+
old_vpa.dirty);
718733
vcpu->arch.dtl_ptr = vcpu->arch.dtl.pinned_addr;
719734
vcpu->arch.dtl_index = 0;
720735
}
721-
if (vcpu->arch.slb_shadow.update_pending)
722-
kvmppc_update_vpa(vcpu, &vcpu->arch.slb_shadow);
736+
if (vcpu->arch.slb_shadow.update_pending) {
737+
kvmppc_update_vpa(vcpu, &vcpu->arch.slb_shadow, &old_vpa);
738+
if (old_vpa.pinned_addr)
739+
kvmppc_unpin_guest_page(kvm, old_vpa.pinned_addr, old_vpa.gpa,
740+
old_vpa.dirty);
741+
}
742+
723743
spin_unlock(&vcpu->arch.vpa_update_lock);
724744
}
725745

@@ -1597,7 +1617,7 @@ static int kvmppc_handle_exit_hv(struct kvm_vcpu *vcpu,
15971617
* That can happen due to a bug, or due to a machine check
15981618
* occurring at just the wrong time.
15991619
*/
1600-
if (__kvmppc_get_msr_hv(vcpu) & MSR_HV) {
1620+
if (!kvmhv_is_nestedv2() && (__kvmppc_get_msr_hv(vcpu) & MSR_HV)) {
16011621
printk(KERN_EMERG "KVM trap in HV mode!\n");
16021622
printk(KERN_EMERG "trap=0x%x | pc=0x%lx | msr=0x%llx\n",
16031623
vcpu->arch.trap, kvmppc_get_pc(vcpu),
@@ -1688,7 +1708,7 @@ static int kvmppc_handle_exit_hv(struct kvm_vcpu *vcpu,
16881708
{
16891709
int i;
16901710

1691-
if (unlikely(__kvmppc_get_msr_hv(vcpu) & MSR_PR)) {
1711+
if (!kvmhv_is_nestedv2() && unlikely(__kvmppc_get_msr_hv(vcpu) & MSR_PR)) {
16921712
/*
16931713
* Guest userspace executed sc 1. This can only be
16941714
* reached by the P9 path because the old path
@@ -4084,6 +4104,8 @@ static int kvmhv_vcpu_entry_nestedv2(struct kvm_vcpu *vcpu, u64 time_limit,
40844104
if (rc < 0)
40854105
return -EINVAL;
40864106

4107+
kvmppc_gse_put_u64(io->vcpu_run_input, KVMPPC_GSID_LPCR, lpcr);
4108+
40874109
accumulate_time(vcpu, &vcpu->arch.in_guest);
40884110
rc = plpar_guest_run_vcpu(0, vcpu->kvm->arch.lpid, vcpu->vcpu_id,
40894111
&trap, &i);
@@ -4736,13 +4758,19 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit,
47364758

47374759
if (!nested) {
47384760
kvmppc_core_prepare_to_enter(vcpu);
4739-
if (__kvmppc_get_msr_hv(vcpu) & MSR_EE) {
4740-
if (xive_interrupt_pending(vcpu))
4761+
if (test_bit(BOOK3S_IRQPRIO_EXTERNAL,
4762+
&vcpu->arch.pending_exceptions) ||
4763+
xive_interrupt_pending(vcpu)) {
4764+
/*
4765+
* For nested HV, don't synthesize but always pass MER,
4766+
* the L0 will be able to optimise that more
4767+
* effectively than manipulating registers directly.
4768+
*/
4769+
if (!kvmhv_on_pseries() && (__kvmppc_get_msr_hv(vcpu) & MSR_EE))
47414770
kvmppc_inject_interrupt_hv(vcpu,
4742-
BOOK3S_INTERRUPT_EXTERNAL, 0);
4743-
} else if (test_bit(BOOK3S_IRQPRIO_EXTERNAL,
4744-
&vcpu->arch.pending_exceptions)) {
4745-
lpcr |= LPCR_MER;
4771+
BOOK3S_INTERRUPT_EXTERNAL, 0);
4772+
else
4773+
lpcr |= LPCR_MER;
47464774
}
47474775
} else if (vcpu->arch.pending_exceptions ||
47484776
vcpu->arch.doorbell_request ||
@@ -4806,7 +4834,7 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit,
48064834
* entering a nested guest in which case the decrementer is now owned
48074835
* by L2 and the L1 decrementer is provided in hdec_expires
48084836
*/
4809-
if (kvmppc_core_pending_dec(vcpu) &&
4837+
if (!kvmhv_is_nestedv2() && kvmppc_core_pending_dec(vcpu) &&
48104838
((tb < kvmppc_dec_expires_host_tb(vcpu)) ||
48114839
(trap == BOOK3S_INTERRUPT_SYSCALL &&
48124840
kvmppc_get_gpr(vcpu, 3) == H_ENTER_NESTED)))
@@ -4949,7 +4977,7 @@ static int kvmppc_vcpu_run_hv(struct kvm_vcpu *vcpu)
49494977
if (run->exit_reason == KVM_EXIT_PAPR_HCALL) {
49504978
accumulate_time(vcpu, &vcpu->arch.hcall);
49514979

4952-
if (WARN_ON_ONCE(__kvmppc_get_msr_hv(vcpu) & MSR_PR)) {
4980+
if (!kvmhv_is_nestedv2() && WARN_ON_ONCE(__kvmppc_get_msr_hv(vcpu) & MSR_PR)) {
49534981
/*
49544982
* These should have been caught reflected
49554983
* into the guest by now. Final sanity check:
@@ -5691,10 +5719,12 @@ static void kvmppc_core_destroy_vm_hv(struct kvm *kvm)
56915719
kvmhv_set_ptbl_entry(kvm->arch.lpid, 0, 0);
56925720
}
56935721

5694-
if (kvmhv_is_nestedv2())
5722+
if (kvmhv_is_nestedv2()) {
5723+
kvmhv_flush_lpid(kvm->arch.lpid);
56955724
plpar_guest_delete(0, kvm->arch.lpid);
5696-
else
5725+
} else {
56975726
kvmppc_free_lpid(kvm->arch.lpid);
5727+
}
56985728

56995729
kvmppc_free_pimap(kvm);
57005730
}

arch/powerpc/kvm/book3s_hv_nested.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ void kvmhv_nested_exit(void)
503503
}
504504
}
505505

506-
static void kvmhv_flush_lpid(u64 lpid)
506+
void kvmhv_flush_lpid(u64 lpid)
507507
{
508508
long rc;
509509

arch/powerpc/kvm/book3s_hv_nestedv2.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,35 @@ int kvmhv_nestedv2_set_ptbl_entry(unsigned long lpid, u64 dw0, u64 dw1)
855855
}
856856
EXPORT_SYMBOL_GPL(kvmhv_nestedv2_set_ptbl_entry);
857857

858+
/**
859+
* kvmhv_nestedv2_set_vpa() - register L2 VPA with L0
860+
* @vcpu: vcpu
861+
* @vpa: L1 logical real address
862+
*/
863+
int kvmhv_nestedv2_set_vpa(struct kvm_vcpu *vcpu, unsigned long vpa)
864+
{
865+
struct kvmhv_nestedv2_io *io;
866+
struct kvmppc_gs_buff *gsb;
867+
int rc = 0;
868+
869+
io = &vcpu->arch.nestedv2_io;
870+
gsb = io->vcpu_run_input;
871+
872+
kvmppc_gsb_reset(gsb);
873+
rc = kvmppc_gse_put_u64(gsb, KVMPPC_GSID_VPA, vpa);
874+
if (rc < 0)
875+
goto out;
876+
877+
rc = kvmppc_gsb_send(gsb, 0);
878+
if (rc < 0)
879+
pr_err("KVM-NESTEDv2: couldn't register the L2 VPA (rc=%d)\n", rc);
880+
881+
out:
882+
kvmppc_gsb_reset(gsb);
883+
return rc;
884+
}
885+
EXPORT_SYMBOL_GPL(kvmhv_nestedv2_set_vpa);
886+
858887
/**
859888
* kvmhv_nestedv2_parse_output() - receive values from H_GUEST_RUN_VCPU output
860889
* @vcpu: vcpu

arch/powerpc/kvm/emulate_loadstore.c

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
9393

9494
emulated = EMULATE_FAIL;
9595
vcpu->arch.regs.msr = kvmppc_get_msr(vcpu);
96-
kvmhv_nestedv2_reload_ptregs(vcpu, &vcpu->arch.regs);
9796
if (analyse_instr(&op, &vcpu->arch.regs, inst) == 0) {
9897
int type = op.type & INSTR_TYPE_MASK;
9998
int size = GETSIZE(op.type);
@@ -112,7 +111,7 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
112111
op.reg, size, !instr_byte_swap);
113112

114113
if ((op.type & UPDATE) && (emulated != EMULATE_FAIL))
115-
kvmppc_set_gpr(vcpu, op.update_reg, op.ea);
114+
kvmppc_set_gpr(vcpu, op.update_reg, vcpu->arch.vaddr_accessed);
116115

117116
break;
118117
}
@@ -132,7 +131,7 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
132131
KVM_MMIO_REG_FPR|op.reg, size, 1);
133132

134133
if ((op.type & UPDATE) && (emulated != EMULATE_FAIL))
135-
kvmppc_set_gpr(vcpu, op.update_reg, op.ea);
134+
kvmppc_set_gpr(vcpu, op.update_reg, vcpu->arch.vaddr_accessed);
136135

137136
break;
138137
#endif
@@ -224,16 +223,17 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
224223
break;
225224
}
226225
#endif
227-
case STORE:
228-
/* if need byte reverse, op.val has been reversed by
229-
* analyse_instr().
230-
*/
231-
emulated = kvmppc_handle_store(vcpu, op.val, size, 1);
226+
case STORE: {
227+
int instr_byte_swap = op.type & BYTEREV;
228+
229+
emulated = kvmppc_handle_store(vcpu, kvmppc_get_gpr(vcpu, op.reg),
230+
size, !instr_byte_swap);
232231

233232
if ((op.type & UPDATE) && (emulated != EMULATE_FAIL))
234-
kvmppc_set_gpr(vcpu, op.update_reg, op.ea);
233+
kvmppc_set_gpr(vcpu, op.update_reg, vcpu->arch.vaddr_accessed);
235234

236235
break;
236+
}
237237
#ifdef CONFIG_PPC_FPU
238238
case STORE_FP:
239239
if (kvmppc_check_fp_disabled(vcpu))
@@ -254,7 +254,7 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
254254
kvmppc_get_fpr(vcpu, op.reg), size, 1);
255255

256256
if ((op.type & UPDATE) && (emulated != EMULATE_FAIL))
257-
kvmppc_set_gpr(vcpu, op.update_reg, op.ea);
257+
kvmppc_set_gpr(vcpu, op.update_reg, vcpu->arch.vaddr_accessed);
258258

259259
break;
260260
#endif
@@ -358,7 +358,6 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
358358
}
359359

360360
trace_kvm_ppc_instr(ppc_inst_val(inst), kvmppc_get_pc(vcpu), emulated);
361-
kvmhv_nestedv2_mark_dirty_ptregs(vcpu, &vcpu->arch.regs);
362361

363362
/* Advance past emulated instruction. */
364363
if (emulated != EMULATE_FAIL)

0 commit comments

Comments
 (0)