* [RFC PATCH 0/10] Support POWER8 in HV KVM
@ 2013-09-06 3:48 Paul Mackerras
2013-09-06 3:50 ` [RFC PATCH 01/10] KVM: PPC: Book3S HV: Align physical CPU thread numbers with virtual Paul Mackerras
` (9 more replies)
0 siblings, 10 replies; 16+ messages in thread
From: Paul Mackerras @ 2013-09-06 3:48 UTC (permalink / raw)
To: Alexander Graf, kvm-ppc, kvm
This series adds support for the POWER8 CPU in HV KVM. POWER8 adds
several new guest-accessible instructions, special-purpose registers,
and other features such as doorbell interrupts and hardware
transactional memory. It also adds new hypervisor-controlled features
such as relocation-on interrupts, and replaces the DABR/DABRX
registers with the new DAWR/DAWRX registers with expanded
capabilities. The POWER8 CPU has compatibility modes for architecture
2.06 (POWER7/POWER7+) and 2.05 (POWER6).
This series does not yet handle the checkpointed register state of
the guest.
arch/powerpc/include/asm/kvm_asm.h | 2 +
arch/powerpc/include/asm/kvm_book3s_asm.h | 1 +
arch/powerpc/include/asm/kvm_host.h | 29 +-
arch/powerpc/include/asm/reg.h | 25 +-
arch/powerpc/include/uapi/asm/kvm.h | 1 +
arch/powerpc/kernel/asm-offsets.c | 28 +-
arch/powerpc/kvm/book3s_hv.c | 234 +++++++++++--
arch/powerpc/kvm/book3s_hv_interrupts.S | 8 +-
arch/powerpc/kvm/book3s_hv_rmhandlers.S | 538 ++++++++++++++++++++++--------
9 files changed, 694 insertions(+), 172 deletions(-)
Paul.
^ permalink raw reply [flat|nested] 16+ messages in thread
* [RFC PATCH 01/10] KVM: PPC: Book3S HV: Align physical CPU thread numbers with virtual
2013-09-06 3:48 [RFC PATCH 0/10] Support POWER8 in HV KVM Paul Mackerras
@ 2013-09-06 3:50 ` Paul Mackerras
2013-09-06 3:51 ` [RFC PATCH 02/10] KVM: PPC: Book3S HV: Don't set DABR on POWER8 Paul Mackerras
` (8 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Paul Mackerras @ 2013-09-06 3:50 UTC (permalink / raw)
To: Alexander Graf, kvm-ppc, kvm
On a threaded processor such as POWER7, we group VCPUs into virtual
cores and arrange that the VCPUs in a virtual core run on the same
physical core. Currently we don't enforce any correspondence between
virtual thread numbers within a virtual core and physical thread
numbers. Physical threads are allocated starting at 0 on a first-come
first-served basis to runnable virtual threads (VCPUs).
POWER8 implements a new "msgsndp" instruction which guest kernels can
use to interrupt other threads in the same core or sub-core. Since
the instruction takes the destination physical thread ID as a parameter,
it becomes necessary to align the physical thread IDs with the virtual
thread IDs, that is, to make sure virtual thread N within a virtual
core always runs on physical thread N.
This means that it's possible that thread 0, which is where we call
__kvmppc_vcore_entry, may end up running some other vcpu than the
one whose task called kvmppc_run_core(), or it may end up running
no vcpu at all, if for example thread 0 of the virtual core is
currently executing in userspace. Thus we can't rely on thread 0
to be the master responsible for switching the MMU. Instead we now
have an explicit 'is_master' flag which is set for the vcpu whose
task called kvmppc_run_core(). The master then has to wait for
thread 0 to enter real mode before switching the MMU. Also, we
no longer pass the vcpu pointer to __kvmppc_vcore_entry, but
instead let the assembly code load it from the PACA.
Since the assembly code will need to know the kvm pointer and the
thread ID for threads which don't have a vcpu, we move the thread
ID into the PACA and we add a kvm pointer to the virtual core
structure.
In the case where thread 0 has no vcpu to run, we arrange for it to
go to nap mode, using a new flag value in the PACA 'napping' field
so we can differentiate it when it wakes from the other nap cases.
We set the bit for the thread in the vcore 'napping_threads' field
so that when other threads come out of the guest they will send an
IPI to thread 0 to wake it up. When it does wake up, we clear that
bit, see what caused the wakeup, and either exit back to the kernel,
or start running virtual thread 0 in the case where it now wants to
enter the guest and the other threads are still in the guest.
Signed-off-by: Paul Mackerras <paulus@samba.org>
---
arch/powerpc/include/asm/kvm_book3s_asm.h | 1 +
arch/powerpc/include/asm/kvm_host.h | 4 +
arch/powerpc/kernel/asm-offsets.c | 5 +-
arch/powerpc/kvm/book3s_hv.c | 49 ++++----
arch/powerpc/kvm/book3s_hv_interrupts.S | 6 +-
arch/powerpc/kvm/book3s_hv_rmhandlers.S | 188 +++++++++++++++++++++++++-----
6 files changed, 192 insertions(+), 61 deletions(-)
diff --git a/arch/powerpc/include/asm/kvm_book3s_asm.h b/arch/powerpc/include/asm/kvm_book3s_asm.h
index 22f4606..8669ac0 100644
--- a/arch/powerpc/include/asm/kvm_book3s_asm.h
+++ b/arch/powerpc/include/asm/kvm_book3s_asm.h
@@ -87,6 +87,7 @@ struct kvmppc_host_state {
u8 hwthread_req;
u8 hwthread_state;
u8 host_ipi;
+ u8 ptid;
struct kvm_vcpu *kvm_vcpu;
struct kvmppc_vcore *kvm_vcore;
unsigned long xics_phys;
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 5a40270..6a43455 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -284,6 +284,8 @@ struct kvmppc_vcore {
int n_woken;
int nap_count;
int napping_threads;
+ int real_mode_threads;
+ int first_vcpuid;
u16 pcpu;
u16 last_cpu;
u8 vcore_state;
@@ -294,6 +296,7 @@ struct kvmppc_vcore {
u64 stolen_tb;
u64 preempt_tb;
struct kvm_vcpu *runner;
+ struct kvm *kvm;
u64 tb_offset; /* guest timebase - host timebase */
u32 arch_compat;
ulong pcr;
@@ -575,6 +578,7 @@ struct kvm_vcpu_arch {
int state;
int ptid;
bool timer_running;
+ u8 is_master;
wait_queue_head_t cpu_run;
struct kvm_vcpu_arch_shared *shared;
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 115dd64..51d7eed 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -514,13 +514,15 @@ int main(void)
DEFINE(VCPU_FAULT_DAR, offsetof(struct kvm_vcpu, arch.fault_dar));
DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
DEFINE(VCPU_TRAP, offsetof(struct kvm_vcpu, arch.trap));
- DEFINE(VCPU_PTID, offsetof(struct kvm_vcpu, arch.ptid));
+ DEFINE(VCPU_IS_MASTER, offsetof(struct kvm_vcpu, arch.is_master));
DEFINE(VCPU_CFAR, offsetof(struct kvm_vcpu, arch.cfar));
DEFINE(VCPU_PPR, offsetof(struct kvm_vcpu, arch.ppr));
DEFINE(VCORE_ENTRY_EXIT, offsetof(struct kvmppc_vcore, entry_exit_count));
DEFINE(VCORE_NAP_COUNT, offsetof(struct kvmppc_vcore, nap_count));
DEFINE(VCORE_IN_GUEST, offsetof(struct kvmppc_vcore, in_guest));
DEFINE(VCORE_NAPPING_THREADS, offsetof(struct kvmppc_vcore, napping_threads));
+ DEFINE(VCORE_RM_THREADS, offsetof(struct kvmppc_vcore, real_mode_threads));
+ DEFINE(VCORE_KVM, offsetof(struct kvmppc_vcore, kvm));
DEFINE(VCORE_TB_OFFSET, offsetof(struct kvmppc_vcore, tb_offset));
DEFINE(VCORE_PCR, offsetof(struct kvmppc_vcore, pcr));
DEFINE(VCPU_SVCPU, offsetof(struct kvmppc_vcpu_book3s, shadow_vcpu) -
@@ -590,6 +592,7 @@ int main(void)
HSTATE_FIELD(HSTATE_XICS_PHYS, xics_phys);
HSTATE_FIELD(HSTATE_SAVED_XIRR, saved_xirr);
HSTATE_FIELD(HSTATE_HOST_IPI, host_ipi);
+ HSTATE_FIELD(HSTATE_PTID, ptid);
HSTATE_FIELD(HSTATE_MMCR, host_mmcr);
HSTATE_FIELD(HSTATE_PMC, host_pmc);
HSTATE_FIELD(HSTATE_PURR, host_purr);
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 731e46e..e0791ed58 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -1030,6 +1030,8 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
spin_lock_init(&vcore->lock);
init_waitqueue_head(&vcore->wq);
vcore->preempt_tb = TB_NIL;
+ vcore->first_vcpuid = core * threads_per_core;
+ vcore->kvm = kvm;
}
kvm->arch.vcores[core] = vcore;
kvm->arch.online_vcores++;
@@ -1043,6 +1045,7 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
++vcore->num_threads;
spin_unlock(&vcore->lock);
vcpu->arch.vcore = vcore;
+ vcpu->arch.ptid = vcpu->vcpu_id - vcore->first_vcpuid;
vcpu->arch.cpu_type = KVM_CPU_3S_64;
kvmppc_sanity_check(vcpu);
@@ -1100,7 +1103,7 @@ static void kvmppc_end_cede(struct kvm_vcpu *vcpu)
}
}
-extern int __kvmppc_vcore_entry(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu);
+extern void __kvmppc_vcore_entry(void);
static void kvmppc_remove_runnable(struct kvmppc_vcore *vc,
struct kvm_vcpu *vcpu)
@@ -1174,13 +1177,14 @@ static void kvmppc_start_thread(struct kvm_vcpu *vcpu)
tpaca = &paca[cpu];
tpaca->kvm_hstate.kvm_vcpu = vcpu;
tpaca->kvm_hstate.kvm_vcore = vc;
- tpaca->kvm_hstate.napping = 0;
+ tpaca->kvm_hstate.ptid = vcpu->arch.ptid;
vcpu->cpu = vc->pcpu;
smp_wmb();
#if defined(CONFIG_PPC_ICP_NATIVE) && defined(CONFIG_SMP)
- if (vcpu->arch.ptid) {
+ if (cpu != smp_processor_id()) {
xics_wake_cpu(cpu);
- ++vc->n_woken;
+ if (vcpu->arch.ptid)
+ ++vc->n_woken;
}
#endif
}
@@ -1237,10 +1241,10 @@ static int on_primary_thread(void)
*/
static void kvmppc_run_core(struct kvmppc_vcore *vc)
{
- struct kvm_vcpu *vcpu, *vcpu0, *vnext;
+ struct kvm_vcpu *vcpu, *vnext;
long ret;
u64 now;
- int ptid, i, need_vpa_update;
+ int i, need_vpa_update;
int srcu_idx;
struct kvm_vcpu *vcpus_to_update[threads_per_core];
@@ -1265,6 +1269,7 @@ static void kvmppc_run_core(struct kvmppc_vcore *vc)
vc->vcore_state = VCORE_STARTING;
vc->in_guest = 0;
vc->napping_threads = 0;
+ vc->real_mode_threads = 0;
/*
* Updating any of the vpas requires calling kvmppc_pin_guest_page,
@@ -1278,25 +1283,6 @@ static void kvmppc_run_core(struct kvmppc_vcore *vc)
}
/*
- * Assign physical thread IDs, first to non-ceded vcpus
- * and then to ceded ones.
- */
- ptid = 0;
- vcpu0 = NULL;
- list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) {
- if (!vcpu->arch.ceded) {
- if (!ptid)
- vcpu0 = vcpu;
- vcpu->arch.ptid = ptid++;
- }
- }
- if (!vcpu0)
- goto out; /* nothing to run; should never happen */
- list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list)
- if (vcpu->arch.ceded)
- vcpu->arch.ptid = ptid++;
-
- /*
* Make sure we are running on thread 0, and that
* secondary threads are offline.
*/
@@ -1312,15 +1298,19 @@ static void kvmppc_run_core(struct kvmppc_vcore *vc)
kvmppc_create_dtl_entry(vcpu, vc);
}
+ /* Set this explicitly in case thread 0 doesn't have a vcpu */
+ get_paca()->kvm_hstate.kvm_vcore = vc;
+ get_paca()->kvm_hstate.ptid = 0;
+
vc->vcore_state = VCORE_RUNNING;
preempt_disable();
spin_unlock(&vc->lock);
kvm_guest_enter();
- srcu_idx = srcu_read_lock(&vcpu0->kvm->srcu);
+ srcu_idx = srcu_read_lock(&vc->kvm->srcu);
- __kvmppc_vcore_entry(NULL, vcpu0);
+ __kvmppc_vcore_entry();
spin_lock(&vc->lock);
/* disable sending of IPIs on virtual external irqs */
@@ -1335,7 +1325,7 @@ static void kvmppc_run_core(struct kvmppc_vcore *vc)
vc->vcore_state = VCORE_EXITING;
spin_unlock(&vc->lock);
- srcu_read_unlock(&vcpu0->kvm->srcu, srcu_idx);
+ srcu_read_unlock(&vc->kvm->srcu, srcu_idx);
/* make sure updates to secondary vcpu structs are visible now */
smp_mb();
@@ -1443,7 +1433,6 @@ static int kvmppc_run_vcpu(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
if (!signal_pending(current)) {
if (vc->vcore_state == VCORE_RUNNING &&
VCORE_EXIT_COUNT(vc) == 0) {
- vcpu->arch.ptid = vc->n_runnable - 1;
kvmppc_create_dtl_entry(vcpu, vc);
kvmppc_start_thread(vcpu);
} else if (vc->vcore_state == VCORE_SLEEPING) {
@@ -1474,6 +1463,7 @@ static int kvmppc_run_vcpu(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
if (!vc->n_runnable || vcpu->arch.state != KVMPPC_VCPU_RUNNABLE)
break;
vc->runner = vcpu;
+ vcpu->arch.is_master = 1;
n_ceded = 0;
list_for_each_entry(v, &vc->runnable_threads, arch.run_list) {
if (!v->arch.pending_exceptions)
@@ -1486,6 +1476,7 @@ static int kvmppc_run_vcpu(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
else
kvmppc_run_core(vc);
vc->runner = NULL;
+ vcpu->arch.is_master = 0;
}
while (vcpu->arch.state == KVMPPC_VCPU_RUNNABLE &&
diff --git a/arch/powerpc/kvm/book3s_hv_interrupts.S b/arch/powerpc/kvm/book3s_hv_interrupts.S
index 37f1cc4..2a85bf6 100644
--- a/arch/powerpc/kvm/book3s_hv_interrupts.S
+++ b/arch/powerpc/kvm/book3s_hv_interrupts.S
@@ -35,7 +35,7 @@
****************************************************************************/
/* Registers:
- * r4: vcpu pointer
+ * none
*/
_GLOBAL(__kvmppc_vcore_entry)
@@ -69,7 +69,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
mtmsrd r10,1
/* Save host PMU registers */
- /* R4 is live here (vcpu pointer) but not r3 or r5 */
li r3, 1
sldi r3, r3, 31 /* MMCR0_FC (freeze counters) bit */
mfspr r7, SPRN_MMCR0 /* save MMCR0 */
@@ -134,16 +133,15 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
* enters the guest with interrupts enabled.
*/
BEGIN_FTR_SECTION
+ ld r4, HSTATE_KVM_VCPU(r13)
ld r0, VCPU_PENDING_EXC(r4)
li r7, (1 << BOOK3S_IRQPRIO_EXTERNAL)
oris r7, r7, (1 << BOOK3S_IRQPRIO_EXTERNAL_LEVEL)@h
and. r0, r0, r7
beq 32f
- mr r31, r4
lhz r3, PACAPACAINDEX(r13)
bl smp_send_reschedule
nop
- mr r4, r31
32:
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
#endif /* CONFIG_SMP */
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 31030f3..0721d2a 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -53,6 +53,10 @@ kvmppc_skip_Hinterrupt:
hrfid
b .
+/* Values in HSTATE_NAPPING(r13) */
+#define NAPPING_CEDE 1
+#define NAPPING_NOVCPU 2
+
/*
* Call kvmppc_hv_entry in real mode.
* Must be called with interrupts hard-disabled.
@@ -77,6 +81,16 @@ _GLOBAL(kvmppc_hv_entry_trampoline)
RFI
kvmppc_call_hv_entry:
+ /* Indicate that we are now in real mode */
+ ld r5, HSTATE_KVM_VCORE(r13)
+ li r0, 1
+ stw r0, VCORE_RM_THREADS(r5)
+
+ /* any guest vcpu to run? */
+ ld r4, HSTATE_KVM_VCPU(r13)
+ cmpdi r4, 0
+ beq kvmppc_call_no_guest
+kvmppc_got_guest:
bl kvmppc_hv_entry
/* Back from guest - restore host state and return to caller */
@@ -91,15 +105,6 @@ kvmppc_call_hv_entry:
ld r3,PACA_SPRG3(r13)
mtspr SPRN_SPRG3,r3
- /*
- * Reload DEC. HDEC interrupts were disabled when
- * we reloaded the host's LPCR value.
- */
- ld r3, HSTATE_DECEXP(r13)
- mftb r4
- subf r4, r4, r3
- mtspr SPRN_DEC, r4
-
/* Reload the host's PMU registers */
ld r3, PACALPPACAPTR(r13) /* is the host using the PMU? */
lbz r4, LPPACA_PMCINUSE(r3)
@@ -134,6 +139,16 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
isync
23:
+kvmppc_vcore_exit:
+ /*
+ * Reload DEC. HDEC interrupts were disabled when
+ * we reloaded the host's LPCR value.
+ */
+ ld r3, HSTATE_DECEXP(r13)
+ mftb r4
+ subf r4, r4, r3
+ mtspr SPRN_DEC, r4
+
/*
* For external and machine check interrupts, we need
* to call the Linux handler to process the interrupt.
@@ -173,16 +188,114 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
13: b machine_check_fwnmi
+kvmppc_call_no_guest:
+ /* We handle this much like a ceded vcpu */
+ /* First wait for the partition switch to happen */
+ HMT_LOW
+3: lbz r3,VCORE_IN_GUEST(r5)
+ cmpwi r3,0
+ beq 3b
+ HMT_MEDIUM
+ /* now load up LPCR */
+ ld r9, VCORE_KVM(r5)
+ ld r8, KVM_LPCR(r9)
+ mtspr SPRN_LPCR, r8
+ isync
+
+ /* set our bit in napping_threads */
+ lbz r7, HSTATE_PTID(r13)
+ li r0, 1
+ sld r0, r0, r7
+ addi r6, r5, VCORE_NAPPING_THREADS
+1: lwarx r3, 0, r6
+ or r3, r3, r0
+ stwcx. r3, 0, r6
+ bne 1b
+ /* order napping_threads update vs testing entry_exit_count */
+ lwsync
+ li r12, 0
+ lwz r7, VCORE_ENTRY_EXIT(r5)
+ cmpwi r7, 0x100
+ bge kvm_novcpu_exit /* another thread already exiting */
+ li r3, NAPPING_NOVCPU
+ stb r3, HSTATE_NAPPING(r13)
+ li r3, 1
+ stb r3, HSTATE_HWTHREAD_REQ(r13)
+ std r1, HSTATE_HOST_R1(r13)
+
+ b kvm_do_nap
+
+kvm_novcpu_wakeup:
+ ld r1, HSTATE_HOST_R1(r13)
+ ld r5, HSTATE_KVM_VCORE(r13)
+ li r0, 0
+ stb r0, HSTATE_NAPPING(r13)
+ stb r0, HSTATE_HWTHREAD_REQ(r13)
+
+ /* see if any other thread is already exiting */
+ li r12, 0
+ lwz r0, VCORE_ENTRY_EXIT(r5)
+ cmpwi r0, 0x100
+ bge kvm_novcpu_exit
+
+ /* clear our bit in napping_threads */
+ lbz r7, HSTATE_PTID(r13)
+ li r0, 1
+ sld r0, r0, r7
+ addi r6, r5, VCORE_NAPPING_THREADS
+4: lwarx r3, 0, r6
+ andc r3, r3, r0
+ stwcx. r3, 0, r6
+ bne 4b
+
+ /* Check the wake reason in SRR1 to see why we got here */
+ mfspr r3, SPRN_SRR1
+ rlwinm r3, r3, 44-31, 0x7 /* extract wake reason field */
+ cmpwi r3, 4 /* was it an external interrupt? */
+ bne kvm_novcpu_exit /* if not, exit the guest */
+
+ /* extern interrupt - read and handle it */
+ li r12, BOOK3S_INTERRUPT_EXTERNAL
+ bl kvmppc_read_intr
+ cmpdi r3, 0
+ bge kvm_novcpu_exit
+ li r12, 0
+
+ /* Got an IPI but other vcpus aren't yet exiting, must be a latecomer */
+ ld r4, HSTATE_KVM_VCPU(r13)
+ cmpdi r4, 0
+ bne kvmppc_got_guest
+
+kvm_novcpu_exit:
+ ld r5, HSTATE_KVM_VCORE(r13)
+
+ /* if other threads aren't yet exiting, poke them to do so */
+ lwz r3, VCORE_ENTRY_EXIT(r5)
+ cmpwi r3, 0x100
+ bge 2f
+ li r3, 0 /* set HDEC to 0 */
+ mtspr SPRN_HDEC, r3
+2:
+ /* wait for the MMU switch */
+ HMT_LOW
+3: lbz r3, VCORE_IN_GUEST(r5)
+ cmpwi r3, 0
+ bne 3b
+ HMT_MEDIUM
+ /* reload host LPCR */
+ ld r9, VCORE_KVM(r5)
+ ld r8, KVM_HOST_LPCR(r9)
+ mtspr SPRN_LPCR, r8
+ isync
+ b kvmppc_vcore_exit
/*
- * We come in here when wakened from nap mode on a secondary hw thread.
+ * We come in here when wakened from nap mode.
* Relocation is off and most register values are lost.
* r13 points to the PACA.
*/
.globl kvm_start_guest
kvm_start_guest:
- ld r1,PACAEMERGSP(r13)
- subi r1,r1,STACK_FRAME_OVERHEAD
ld r2,PACATOC(r13)
li r0,KVM_HWTHREAD_IN_KVM
@@ -194,8 +307,13 @@ kvm_start_guest:
/* were we napping due to cede? */
lbz r0,HSTATE_NAPPING(r13)
- cmpwi r0,0
- bne kvm_end_cede
+ cmpwi r0,NAPPING_CEDE
+ beq kvm_end_cede
+ cmpwi r0,NAPPING_NOVCPU
+ beq kvm_novcpu_wakeup
+
+ ld r1,PACAEMERGSP(r13)
+ subi r1,r1,STACK_FRAME_OVERHEAD
/*
* We weren't napping due to cede, so this must be a secondary
@@ -270,6 +388,7 @@ kvm_start_guest:
kvm_no_guest:
li r0, KVM_HWTHREAD_IN_NAP
stb r0, HSTATE_HWTHREAD_STATE(r13)
+kvm_do_nap:
li r3, LPCR_PECE0
mfspr r4, SPRN_LPCR
rlwimi r4, r3, 0, LPCR_PECE0 | LPCR_PECE1
@@ -443,9 +562,15 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
/* Primary thread switches to guest partition. */
ld r9,VCPU_KVM(r4) /* pointer to struct kvm */
- lwz r6,VCPU_PTID(r4)
+ lbz r6,VCPU_IS_MASTER(r4)
+ cmpwi r6,0
+ beq 20f
+ /* wait for thread 0 to get into real mode */
+ HMT_LOW
+50: lwz r6,VCORE_RM_THREADS(r5)
cmpwi r6,0
- bne 20f
+ beq 50b
+ HMT_MEDIUM
ld r6,KVM_SDR1(r9)
lwz r7,KVM_LPID(r9)
li r0,LPID_RSVD /* switch to reserved LPID */
@@ -1014,8 +1139,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
*/
cmpwi r3,0x100 /* Are we the first here? */
bge 43f
- cmpwi r3,1 /* Are any other threads in the guest? */
- ble 43f
cmpwi r12,BOOK3S_INTERRUPT_HV_DECREMENTER
beq 40f
li r0,0
@@ -1026,7 +1149,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
* doesn't wake CPUs up from nap.
*/
lwz r3,VCORE_NAPPING_THREADS(r5)
- lwz r4,VCPU_PTID(r9)
+ lbz r4,HSTATE_PTID(r13)
li r0,1
sld r0,r0,r4
andc. r3,r3,r0 /* no sense IPI'ing ourselves */
@@ -1046,9 +1169,9 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
/* Secondary threads wait for primary to do partition switch */
43: ld r4,VCPU_KVM(r9) /* pointer to struct kvm */
ld r5,HSTATE_KVM_VCORE(r13)
- lwz r3,VCPU_PTID(r9)
+ lwz r3,VCPU_IS_MASTER(r9)
cmpwi r3,0
- beq 15f
+ bne 15f
HMT_LOW
13: lbz r3,VCORE_IN_GUEST(r5)
cmpwi r3,0
@@ -1315,10 +1438,13 @@ secondary_too_late:
cmpwi r3,0
bne 13b
HMT_MEDIUM
- li r0, KVM_GUEST_MODE_NONE
- stb r0, HSTATE_IN_GUEST(r13)
- ld r11,PACA_SLBSHADOWPTR(r13)
+ ld r6, VCORE_KVM(r5)
+ ld r8, KVM_HOST_LPCR(r6)
+ mtspr SPRN_LPCR, r8
+ isync
+
+ ld r11,PACA_SLBSHADOWPTR(r13)
.rept SLB_NUM_BOLTED
ld r5,SLBSHADOW_SAVEAREA(r11)
ld r6,SLBSHADOW_SAVEAREA+8(r11)
@@ -1327,6 +1453,14 @@ secondary_too_late:
slbmte r6,r5
1: addi r11,r11,16
.endr
+
+ li r6, 0
+ mtspr SPRN_AMR, r6
+ li r0, KVM_GUEST_MODE_NONE
+ stb r0, HSTATE_IN_GUEST(r13)
+ ld r7, HSTATE_DSCR(r13)
+ mtspr SPRN_DSCR, r7
+
b 22b
/*
@@ -1615,7 +1749,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206)
* up to the host.
*/
ld r5,HSTATE_KVM_VCORE(r13)
- lwz r6,VCPU_PTID(r3)
+ lbz r6,HSTATE_PTID(r13)
lwz r8,VCORE_ENTRY_EXIT(r5)
clrldi r8,r8,56
li r0,1
@@ -1628,7 +1762,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206)
bge kvm_cede_exit
stwcx. r4,0,r6
bne 31b
- li r0,1
+ li r0,NAPPING_CEDE
stb r0,HSTATE_NAPPING(r13)
/* order napping_threads update vs testing entry_exit_count */
lwsync
@@ -1717,7 +1851,7 @@ kvm_end_cede:
/* clear our bit in vcore->napping_threads */
33: ld r5,HSTATE_KVM_VCORE(r13)
- lwz r3,VCPU_PTID(r4)
+ lbz r3,HSTATE_PTID(r13)
li r0,1
sld r0,r0,r3
addi r6,r5,VCORE_NAPPING_THREADS
--
1.8.4.rc3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFC PATCH 02/10] KVM: PPC: Book3S HV: Don't set DABR on POWER8
2013-09-06 3:48 [RFC PATCH 0/10] Support POWER8 in HV KVM Paul Mackerras
2013-09-06 3:50 ` [RFC PATCH 01/10] KVM: PPC: Book3S HV: Align physical CPU thread numbers with virtual Paul Mackerras
@ 2013-09-06 3:51 ` Paul Mackerras
2013-09-06 3:51 ` [RFC PATCH 03/10] KVM: PPC: Book3S HV: Context-switch new POWER8 SPRs Paul Mackerras
` (7 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Paul Mackerras @ 2013-09-06 3:51 UTC (permalink / raw)
To: Alexander Graf, kvm-ppc, kvm
From: Michael Neuling <mikey@neuling.org>
POWER8 doesn't have the DABR and DABRX registers; instead it has
new DAWR/DAWRX registers, which will be handled in a later patch.
Signed-off-by: Michael Neuling <mikey@neuling.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
---
arch/powerpc/kvm/book3s_hv_interrupts.S | 2 ++
arch/powerpc/kvm/book3s_hv_rmhandlers.S | 13 ++++++++++---
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/kvm/book3s_hv_interrupts.S b/arch/powerpc/kvm/book3s_hv_interrupts.S
index 2a85bf6..0be3404 100644
--- a/arch/powerpc/kvm/book3s_hv_interrupts.S
+++ b/arch/powerpc/kvm/book3s_hv_interrupts.S
@@ -57,9 +57,11 @@ BEGIN_FTR_SECTION
std r3, HSTATE_DSCR(r13)
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
+BEGIN_FTR_SECTION
/* Save host DABR */
mfspr r3, SPRN_DABR
std r3, HSTATE_DABR(r13)
+END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
/* Hard-disable interrupts */
mfmsr r10
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 0721d2a..d4f6f5f 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -95,11 +95,13 @@ kvmppc_got_guest:
/* Back from guest - restore host state and return to caller */
+BEGIN_FTR_SECTION
/* Restore host DABR and DABRX */
ld r5,HSTATE_DABR(r13)
li r6,7
mtspr SPRN_DABR,r5
mtspr SPRN_DABRX,r6
+END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
/* Restore SPRG3 */
ld r3,PACA_SPRG3(r13)
@@ -423,15 +425,17 @@ kvmppc_hv_entry:
std r0, PPC_LR_STKOFF(r1)
stdu r1, -112(r1)
+BEGIN_FTR_SECTION
/* Set partition DABR */
/* Do this before re-enabling PMU to avoid P7 DABR corruption bug */
li r5,3
ld r6,VCPU_DABR(r4)
mtspr SPRN_DABRX,r5
mtspr SPRN_DABR,r6
-BEGIN_FTR_SECTION
+ BEGIN_FTR_SECTION_NESTED(89)
isync
-END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
+ END_FTR_SECTION_NESTED(CPU_FTR_ARCH_206, CPU_FTR_ARCH_206, 89)
+END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
/* Load guest PMU registers */
/* R4 is live here (vcpu pointer) */
@@ -1716,6 +1720,9 @@ ignore_hdec:
b fast_guest_return
_GLOBAL(kvmppc_h_set_dabr)
+BEGIN_FTR_SECTION
+ b 2f
+END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
std r4,VCPU_DABR(r3)
/* Work around P7 bug where DABR can get corrupted on mtspr */
1: mtspr SPRN_DABR,r4
@@ -1723,7 +1730,7 @@ _GLOBAL(kvmppc_h_set_dabr)
cmpd r4, r5
bne 1b
isync
- li r3,0
+2: li r3,0
blr
_GLOBAL(kvmppc_h_cede)
--
1.8.4.rc3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFC PATCH 03/10] KVM: PPC: Book3S HV: Context-switch new POWER8 SPRs
2013-09-06 3:48 [RFC PATCH 0/10] Support POWER8 in HV KVM Paul Mackerras
2013-09-06 3:50 ` [RFC PATCH 01/10] KVM: PPC: Book3S HV: Align physical CPU thread numbers with virtual Paul Mackerras
2013-09-06 3:51 ` [RFC PATCH 02/10] KVM: PPC: Book3S HV: Don't set DABR on POWER8 Paul Mackerras
@ 2013-09-06 3:51 ` Paul Mackerras
2013-09-06 3:53 ` [RFC PATCH 04/10] KVM: PPC: Book3S HV: Flush the correct number of TLB sets on POWER8 Paul Mackerras
` (6 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Paul Mackerras @ 2013-09-06 3:51 UTC (permalink / raw)
To: Alexander Graf, kvm-ppc, kvm
From: Michael Neuling <mikey@neuling.org>
This adds fields to the struct kvm_vcpu_arch to store the new
guest-accessible SPRs on POWER8, adds code to the get/set_one_reg
functions to allow userspace to access this state, and adds code to
the guest entry and exit to context-switch these SPRs between host
and guest.
Note that DPDES (Directed Privileged Doorbell Exception State) is
shared between threads on a core; hence we store it in struct
kvmppc_vcore and have the master thread save and restore it.
Signed-off-by: Michael Neuling <mikey@neuling.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
---
arch/powerpc/include/asm/kvm_host.h | 25 +++++-
arch/powerpc/include/asm/reg.h | 17 ++++
arch/powerpc/include/uapi/asm/kvm.h | 1 +
arch/powerpc/kernel/asm-offsets.c | 23 +++++
arch/powerpc/kvm/book3s_hv.c | 153 +++++++++++++++++++++++++++++++-
arch/powerpc/kvm/book3s_hv_rmhandlers.S | 144 ++++++++++++++++++++++++++++++
6 files changed, 360 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 6a43455..4786bb0 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -300,6 +300,7 @@ struct kvmppc_vcore {
u64 tb_offset; /* guest timebase - host timebase */
u32 arch_compat;
ulong pcr;
+ ulong dpdes; /* doorbell state (POWER8) */
};
#define VCORE_ENTRY_COUNT(vc) ((vc)->entry_exit_count & 0xff)
@@ -454,6 +455,7 @@ struct kvm_vcpu_arch {
ulong pc;
ulong ctr;
ulong lr;
+ ulong tar;
ulong xer;
u32 cr;
@@ -463,13 +465,32 @@ struct kvm_vcpu_arch {
ulong guest_owned_ext;
ulong purr;
ulong spurr;
+ ulong ic;
+ ulong vtb;
ulong dscr;
ulong amr;
ulong uamor;
+ ulong iamr;
u32 ctrl;
ulong dabr;
+ ulong dawr;
+ ulong dawrx;
+ ulong ciabr;
ulong cfar;
ulong ppr;
+ ulong pspb;
+ ulong fscr;
+ ulong tfhar;
+ ulong tfiar;
+ ulong texasr;
+ ulong ebbhr;
+ ulong ebbrr;
+ ulong bescr;
+ ulong csigr;
+ ulong tacr;
+ ulong tcscr;
+ ulong acop;
+ ulong wort;
#endif
u32 vrsave; /* also USPRG0 */
u32 mmucr;
@@ -503,10 +524,12 @@ struct kvm_vcpu_arch {
u32 ccr1;
u32 dbsr;
- u64 mmcr[3];
+ u64 mmcr[5];
u32 pmc[8];
+ u32 spmc[2];
u64 siar;
u64 sdar;
+ u64 sier;
#ifdef CONFIG_KVM_EXIT_TIMING
struct mutex exit_timing_lock;
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 52ff962..4ca8b85 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -218,6 +218,11 @@
#define CTRL_TE 0x00c00000 /* thread enable */
#define CTRL_RUNLATCH 0x1
#define SPRN_DAWR 0xB4
+#define SPRN_CIABR 0xBB
+#define CIABR_PRIV 0x3
+#define CIABR_PRIV_USER 1
+#define CIABR_PRIV_SUPER 2
+#define CIABR_PRIV_HYPER 3
#define SPRN_DAWRX 0xBC
#define DAWRX_USER (1UL << 0)
#define DAWRX_KERNEL (1UL << 1)
@@ -255,6 +260,8 @@
#define SPRN_HRMOR 0x139 /* Real mode offset register */
#define SPRN_HSRR0 0x13A /* Hypervisor Save/Restore 0 */
#define SPRN_HSRR1 0x13B /* Hypervisor Save/Restore 1 */
+#define SPRN_IC 0x350 /* Virtual Instruction Count */
+#define SPRN_VTB 0x351 /* Virtual Time Base */
#define SPRN_FSCR 0x099 /* Facility Status & Control Register */
#define FSCR_TAR (1 << (63-55)) /* Enable Target Address Register */
#define FSCR_EBB (1 << (63-56)) /* Enable Event Based Branching */
@@ -354,6 +361,8 @@
#define DER_EBRKE 0x00000002 /* External Breakpoint Interrupt */
#define DER_DPIE 0x00000001 /* Dev. Port Nonmaskable Request */
#define SPRN_DMISS 0x3D0 /* Data TLB Miss Register */
+#define SPRN_DHDES 0x0B1 /* Directed Hyp. Doorbell Exc. State */
+#define SPRN_DPDES 0x0B0 /* Directed Priv. Doorbell Exc. State */
#define SPRN_EAR 0x11A /* External Address Register */
#define SPRN_HASH1 0x3D2 /* Primary Hash Address Register */
#define SPRN_HASH2 0x3D3 /* Secondary Hash Address Resgister */
@@ -413,6 +422,7 @@
#define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */
#define SPRN_IABR2 0x3FA /* 83xx */
#define SPRN_IBCR 0x135 /* 83xx Insn Breakpoint Control Reg */
+#define SPRN_IAMR 0x03D /* Instr. Authority Mask Reg */
#define SPRN_HID4 0x3F4 /* 970 HID4 */
#define HID4_LPES0 (1ul << (63-0)) /* LPAR env. sel. bit 0 */
#define HID4_RMLS2_SH (63 - 2) /* Real mode limit bottom 2 bits */
@@ -526,6 +536,7 @@
#define SPRN_PIR 0x3FF /* Processor Identification Register */
#endif
#define SPRN_TIR 0x1BE /* Thread Identification Register */
+#define SPRN_PSPB 0x09F /* Problem State Priority Boost reg */
#define SPRN_PTEHI 0x3D5 /* 981 7450 PTE HI word (S/W TLB load) */
#define SPRN_PTELO 0x3D6 /* 982 7450 PTE LO word (S/W TLB load) */
#define SPRN_PURR 0x135 /* Processor Utilization of Resources Reg */
@@ -667,6 +678,7 @@
#define SPRN_EBBHR 804 /* Event based branch handler register */
#define SPRN_EBBRR 805 /* Event based branch return register */
#define SPRN_BESCR 806 /* Branch event status and control register */
+#define SPRN_WORT 895 /* Workload optimization register - thread */
#define SPRN_PMC1 787
#define SPRN_PMC2 788
@@ -683,6 +695,11 @@
#define SIER_SIHV 0x1000000 /* Sampled MSR_HV */
#define SIER_SIAR_VALID 0x0400000 /* SIAR contents valid */
#define SIER_SDAR_VALID 0x0200000 /* SDAR contents valid */
+#define SPRN_TACR 888
+#define SPRN_TCSCR 889
+#define SPRN_CSIGR 890
+#define SPRN_SPMC1 892
+#define SPRN_SPMC2 893
/* When EBB is enabled, some of MMCR0/MMCR2/SIER are user accessible */
#define MMCR0_USER_MASK (MMCR0_FC | MMCR0_PMXE | MMCR0_PMAO)
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index e420d46..26d3fd6 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -531,6 +531,7 @@ struct kvm_get_htab_header {
#define KVM_REG_PPC_TCSCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb1)
#define KVM_REG_PPC_PID (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb2)
#define KVM_REG_PPC_ACOP (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb3)
+#define KVM_REG_PPC_WORT (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb4)
#define KVM_REG_PPC_VRSAVE (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xb4)
#define KVM_REG_PPC_LPCR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xb5)
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 51d7eed..e05f42a 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -440,6 +440,7 @@ int main(void)
DEFINE(VCPU_XER, offsetof(struct kvm_vcpu, arch.xer));
DEFINE(VCPU_CTR, offsetof(struct kvm_vcpu, arch.ctr));
DEFINE(VCPU_LR, offsetof(struct kvm_vcpu, arch.lr));
+ DEFINE(VCPU_TAR, offsetof(struct kvm_vcpu, arch.tar));
DEFINE(VCPU_CR, offsetof(struct kvm_vcpu, arch.cr));
DEFINE(VCPU_PC, offsetof(struct kvm_vcpu, arch.pc));
#ifdef CONFIG_KVM_BOOK3S_64_HV
@@ -492,11 +493,17 @@ int main(void)
DEFINE(VCPU_VCPUID, offsetof(struct kvm_vcpu, vcpu_id));
DEFINE(VCPU_PURR, offsetof(struct kvm_vcpu, arch.purr));
DEFINE(VCPU_SPURR, offsetof(struct kvm_vcpu, arch.spurr));
+ DEFINE(VCPU_IC, offsetof(struct kvm_vcpu, arch.ic));
+ DEFINE(VCPU_VTB, offsetof(struct kvm_vcpu, arch.vtb));
DEFINE(VCPU_DSCR, offsetof(struct kvm_vcpu, arch.dscr));
DEFINE(VCPU_AMR, offsetof(struct kvm_vcpu, arch.amr));
DEFINE(VCPU_UAMOR, offsetof(struct kvm_vcpu, arch.uamor));
+ DEFINE(VCPU_IAMR, offsetof(struct kvm_vcpu, arch.iamr));
DEFINE(VCPU_CTRL, offsetof(struct kvm_vcpu, arch.ctrl));
DEFINE(VCPU_DABR, offsetof(struct kvm_vcpu, arch.dabr));
+ DEFINE(VCPU_DAWR, offsetof(struct kvm_vcpu, arch.dawr));
+ DEFINE(VCPU_DAWRX, offsetof(struct kvm_vcpu, arch.dawrx));
+ DEFINE(VCPU_CIABR, offsetof(struct kvm_vcpu, arch.ciabr));
DEFINE(VCPU_HFLAGS, offsetof(struct kvm_vcpu, arch.hflags));
DEFINE(VCPU_DEC, offsetof(struct kvm_vcpu, arch.dec));
DEFINE(VCPU_DEC_EXPIRES, offsetof(struct kvm_vcpu, arch.dec_expires));
@@ -505,8 +512,10 @@ int main(void)
DEFINE(VCPU_PRODDED, offsetof(struct kvm_vcpu, arch.prodded));
DEFINE(VCPU_MMCR, offsetof(struct kvm_vcpu, arch.mmcr));
DEFINE(VCPU_PMC, offsetof(struct kvm_vcpu, arch.pmc));
+ DEFINE(VCPU_SPMC, offsetof(struct kvm_vcpu, arch.spmc));
DEFINE(VCPU_SIAR, offsetof(struct kvm_vcpu, arch.siar));
DEFINE(VCPU_SDAR, offsetof(struct kvm_vcpu, arch.sdar));
+ DEFINE(VCPU_SIER, offsetof(struct kvm_vcpu, arch.sier));
DEFINE(VCPU_SLB, offsetof(struct kvm_vcpu, arch.slb));
DEFINE(VCPU_SLB_MAX, offsetof(struct kvm_vcpu, arch.slb_max));
DEFINE(VCPU_SLB_NR, offsetof(struct kvm_vcpu, arch.slb_nr));
@@ -517,6 +526,19 @@ int main(void)
DEFINE(VCPU_IS_MASTER, offsetof(struct kvm_vcpu, arch.is_master));
DEFINE(VCPU_CFAR, offsetof(struct kvm_vcpu, arch.cfar));
DEFINE(VCPU_PPR, offsetof(struct kvm_vcpu, arch.ppr));
+ DEFINE(VCPU_FSCR, offsetof(struct kvm_vcpu, arch.fscr));
+ DEFINE(VCPU_PSPB, offsetof(struct kvm_vcpu, arch.pspb));
+ DEFINE(VCPU_TFHAR, offsetof(struct kvm_vcpu, arch.tfhar));
+ DEFINE(VCPU_TFIAR, offsetof(struct kvm_vcpu, arch.tfiar));
+ DEFINE(VCPU_TEXASR, offsetof(struct kvm_vcpu, arch.texasr));
+ DEFINE(VCPU_EBBHR, offsetof(struct kvm_vcpu, arch.ebbhr));
+ DEFINE(VCPU_EBBRR, offsetof(struct kvm_vcpu, arch.ebbrr));
+ DEFINE(VCPU_BESCR, offsetof(struct kvm_vcpu, arch.bescr));
+ DEFINE(VCPU_CSIGR, offsetof(struct kvm_vcpu, arch.csigr));
+ DEFINE(VCPU_TACR, offsetof(struct kvm_vcpu, arch.tacr));
+ DEFINE(VCPU_TCSCR, offsetof(struct kvm_vcpu, arch.tcscr));
+ DEFINE(VCPU_ACOP, offsetof(struct kvm_vcpu, arch.acop));
+ DEFINE(VCPU_WORT, offsetof(struct kvm_vcpu, arch.wort));
DEFINE(VCORE_ENTRY_EXIT, offsetof(struct kvmppc_vcore, entry_exit_count));
DEFINE(VCORE_NAP_COUNT, offsetof(struct kvmppc_vcore, nap_count));
DEFINE(VCORE_IN_GUEST, offsetof(struct kvmppc_vcore, in_guest));
@@ -525,6 +547,7 @@ int main(void)
DEFINE(VCORE_KVM, offsetof(struct kvmppc_vcore, kvm));
DEFINE(VCORE_TB_OFFSET, offsetof(struct kvmppc_vcore, tb_offset));
DEFINE(VCORE_PCR, offsetof(struct kvmppc_vcore, pcr));
+ DEFINE(VCORE_DPDES, offsetof(struct kvmppc_vcore, dpdes));
DEFINE(VCPU_SVCPU, offsetof(struct kvmppc_vcpu_book3s, shadow_vcpu) -
offsetof(struct kvmppc_vcpu_book3s, vcpu));
DEFINE(VCPU_SLB_E, offsetof(struct kvmppc_slb, orige));
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index e0791ed58..724daa5 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -793,7 +793,7 @@ int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *val)
case KVM_REG_PPC_UAMOR:
*val = get_reg_val(id, vcpu->arch.uamor);
break;
- case KVM_REG_PPC_MMCR0 ... KVM_REG_PPC_MMCRA:
+ case KVM_REG_PPC_MMCR0 ... KVM_REG_PPC_MMCRS:
i = id - KVM_REG_PPC_MMCR0;
*val = get_reg_val(id, vcpu->arch.mmcr[i]);
break;
@@ -801,12 +801,85 @@ int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *val)
i = id - KVM_REG_PPC_PMC1;
*val = get_reg_val(id, vcpu->arch.pmc[i]);
break;
+ case KVM_REG_PPC_SPMC1 ... KVM_REG_PPC_SPMC2:
+ i = id - KVM_REG_PPC_SPMC1;
+ *val = get_reg_val(id, vcpu->arch.spmc[i]);
+ break;
case KVM_REG_PPC_SIAR:
*val = get_reg_val(id, vcpu->arch.siar);
break;
case KVM_REG_PPC_SDAR:
*val = get_reg_val(id, vcpu->arch.sdar);
break;
+ case KVM_REG_PPC_SIER:
+ *val = get_reg_val(id, vcpu->arch.sier);
+ break;
+ case KVM_REG_PPC_IAMR:
+ *val = get_reg_val(id, vcpu->arch.iamr);
+ break;
+ case KVM_REG_PPC_TFHAR:
+ *val = get_reg_val(id, vcpu->arch.tfhar);
+ break;
+ case KVM_REG_PPC_TFIAR:
+ *val = get_reg_val(id, vcpu->arch.tfiar);
+ break;
+ case KVM_REG_PPC_TEXASR:
+ *val = get_reg_val(id, vcpu->arch.texasr);
+ break;
+ case KVM_REG_PPC_FSCR:
+ *val = get_reg_val(id, vcpu->arch.fscr);
+ break;
+ case KVM_REG_PPC_PSPB:
+ *val = get_reg_val(id, vcpu->arch.pspb);
+ break;
+ case KVM_REG_PPC_EBBHR:
+ *val = get_reg_val(id, vcpu->arch.ebbhr);
+ break;
+ case KVM_REG_PPC_EBBRR:
+ *val = get_reg_val(id, vcpu->arch.ebbrr);
+ break;
+ case KVM_REG_PPC_BESCR:
+ *val = get_reg_val(id, vcpu->arch.bescr);
+ break;
+ case KVM_REG_PPC_TAR:
+ *val = get_reg_val(id, vcpu->arch.tar);
+ break;
+ case KVM_REG_PPC_DPDES:
+ *val = get_reg_val(id, vcpu->arch.vcore->dpdes);
+ break;
+ case KVM_REG_PPC_DAWR:
+ *val = get_reg_val(id, vcpu->arch.dawr);
+ break;
+ case KVM_REG_PPC_DAWRX:
+ *val = get_reg_val(id, vcpu->arch.dawrx);
+ break;
+ case KVM_REG_PPC_CIABR:
+ *val = get_reg_val(id, vcpu->arch.ciabr);
+ break;
+ case KVM_REG_PPC_IC:
+ *val = get_reg_val(id, vcpu->arch.ic);
+ break;
+ case KVM_REG_PPC_VTB:
+ *val = get_reg_val(id, vcpu->arch.vtb);
+ break;
+ case KVM_REG_PPC_CSIGR:
+ *val = get_reg_val(id, vcpu->arch.csigr);
+ break;
+ case KVM_REG_PPC_TACR:
+ *val = get_reg_val(id, vcpu->arch.tacr);
+ break;
+ case KVM_REG_PPC_TCSCR:
+ *val = get_reg_val(id, vcpu->arch.tcscr);
+ break;
+ case KVM_REG_PPC_PID:
+ *val = get_reg_val(id, vcpu->arch.pid);
+ break;
+ case KVM_REG_PPC_ACOP:
+ *val = get_reg_val(id, vcpu->arch.acop);
+ break;
+ case KVM_REG_PPC_WORT:
+ *val = get_reg_val(id, vcpu->arch.wort);
+ break;
#ifdef CONFIG_VSX
case KVM_REG_PPC_FPR0 ... KVM_REG_PPC_FPR31:
if (cpu_has_feature(CPU_FTR_VSX)) {
@@ -895,7 +968,7 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *val)
case KVM_REG_PPC_UAMOR:
vcpu->arch.uamor = set_reg_val(id, *val);
break;
- case KVM_REG_PPC_MMCR0 ... KVM_REG_PPC_MMCRA:
+ case KVM_REG_PPC_MMCR0 ... KVM_REG_PPC_MMCRS:
i = id - KVM_REG_PPC_MMCR0;
vcpu->arch.mmcr[i] = set_reg_val(id, *val);
break;
@@ -903,12 +976,88 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *val)
i = id - KVM_REG_PPC_PMC1;
vcpu->arch.pmc[i] = set_reg_val(id, *val);
break;
+ case KVM_REG_PPC_SPMC1 ... KVM_REG_PPC_SPMC2:
+ i = id - KVM_REG_PPC_SPMC1;
+ vcpu->arch.spmc[i] = set_reg_val(id, *val);
+ break;
case KVM_REG_PPC_SIAR:
vcpu->arch.siar = set_reg_val(id, *val);
break;
case KVM_REG_PPC_SDAR:
vcpu->arch.sdar = set_reg_val(id, *val);
break;
+ case KVM_REG_PPC_SIER:
+ vcpu->arch.sier = set_reg_val(id, *val);
+ break;
+ case KVM_REG_PPC_IAMR:
+ vcpu->arch.iamr = set_reg_val(id, *val);
+ break;
+ case KVM_REG_PPC_TFHAR:
+ vcpu->arch.tfhar = set_reg_val(id, *val);
+ break;
+ case KVM_REG_PPC_TFIAR:
+ vcpu->arch.tfiar = set_reg_val(id, *val);
+ break;
+ case KVM_REG_PPC_TEXASR:
+ vcpu->arch.texasr = set_reg_val(id, *val);
+ break;
+ case KVM_REG_PPC_FSCR:
+ vcpu->arch.fscr = set_reg_val(id, *val);
+ break;
+ case KVM_REG_PPC_PSPB:
+ vcpu->arch.pspb = set_reg_val(id, *val);
+ break;
+ case KVM_REG_PPC_EBBHR:
+ vcpu->arch.ebbhr = set_reg_val(id, *val);
+ break;
+ case KVM_REG_PPC_EBBRR:
+ vcpu->arch.ebbrr = set_reg_val(id, *val);
+ break;
+ case KVM_REG_PPC_BESCR:
+ vcpu->arch.bescr = set_reg_val(id, *val);
+ break;
+ case KVM_REG_PPC_TAR:
+ vcpu->arch.tar = set_reg_val(id, *val);
+ break;
+ case KVM_REG_PPC_DPDES:
+ vcpu->arch.vcore->dpdes = set_reg_val(id, *val);
+ break;
+ case KVM_REG_PPC_DAWR:
+ vcpu->arch.dawr = set_reg_val(id, *val);
+ break;
+ case KVM_REG_PPC_DAWRX:
+ vcpu->arch.dawrx = set_reg_val(id, *val) & ~DAWRX_HYP;
+ break;
+ case KVM_REG_PPC_CIABR:
+ vcpu->arch.ciabr = set_reg_val(id, *val);
+ /* Don't allow setting breakpoints in hypervisor code */
+ if ((vcpu->arch.ciabr & CIABR_PRIV) == CIABR_PRIV_HYPER)
+ vcpu->arch.ciabr &= ~CIABR_PRIV; /* disable */
+ break;
+ case KVM_REG_PPC_IC:
+ vcpu->arch.ic = set_reg_val(id, *val);
+ break;
+ case KVM_REG_PPC_VTB:
+ vcpu->arch.vtb = set_reg_val(id, *val);
+ break;
+ case KVM_REG_PPC_CSIGR:
+ vcpu->arch.csigr = set_reg_val(id, *val);
+ break;
+ case KVM_REG_PPC_TACR:
+ vcpu->arch.tacr = set_reg_val(id, *val);
+ break;
+ case KVM_REG_PPC_TCSCR:
+ vcpu->arch.tcscr = set_reg_val(id, *val);
+ break;
+ case KVM_REG_PPC_PID:
+ vcpu->arch.pid = set_reg_val(id, *val);
+ break;
+ case KVM_REG_PPC_ACOP:
+ vcpu->arch.acop = set_reg_val(id, *val);
+ break;
+ case KVM_REG_PPC_WORT:
+ vcpu->arch.wort = set_reg_val(id, *val);
+ break;
#ifdef CONFIG_VSX
case KVM_REG_PPC_FPR0 ... KVM_REG_PPC_FPR31:
if (cpu_has_feature(CPU_FTR_VSX)) {
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index d4f6f5f..1de0b65 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -472,6 +472,18 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
mtspr SPRN_MMCRA, r6
mtspr SPRN_SIAR, r7
mtspr SPRN_SDAR, r8
+BEGIN_FTR_SECTION
+ ld r5, VCPU_MMCR + 24(r4)
+ ld r6, VCPU_SIER(r4)
+ lwz r7, VCPU_PMC + 24(r4)
+ lwz r8, VCPU_PMC + 28(r4)
+ ld r9, VCPU_MMCR + 32(r4)
+ mtspr SPRN_MMCR2, r5
+ mtspr SPRN_SIER, r6
+ mtspr SPRN_SPMC1, r7
+ mtspr SPRN_SPMC2, r8
+ mtspr SPRN_MMCRS, r9
+END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
mtspr SPRN_MMCR0, r3
isync
@@ -503,6 +515,61 @@ BEGIN_FTR_SECTION
mtspr SPRN_DSCR, r5
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
+BEGIN_FTR_SECTION
+ /* Skip next section on POWER7 or PPC970 */
+ b 8f
+END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
+ /* Turn on TM so we can access TFHAR/TFIAR/TEXASR */
+ mfmsr r8
+ li r0, 1
+ rldimi r8, r0, MSR_TM_LG, 63-MSR_TM_LG
+ mtmsrd r8
+
+ /* Load up POWER8-specific registers */
+ ld r5, VCPU_IAMR(r4)
+ lwz r6, VCPU_PSPB(r4)
+ ld r7, VCPU_FSCR(r4)
+ mtspr SPRN_IAMR, r5
+ mtspr SPRN_PSPB, r6
+ mtspr SPRN_FSCR, r7
+ ld r5, VCPU_DAWR(r4)
+ ld r6, VCPU_DAWRX(r4)
+ ld r7, VCPU_CIABR(r4)
+ ld r8, VCPU_TAR(r4)
+ mtspr SPRN_DAWR, r5
+ mtspr SPRN_DAWRX, r6
+ mtspr SPRN_CIABR, r7
+ mtspr SPRN_TAR, r8
+ ld r5, VCPU_IC(r4)
+ ld r6, VCPU_VTB(r4)
+ mtspr SPRN_IC, r5
+ mtspr SPRN_VTB, r6
+ ld r5, VCPU_TFHAR(r4)
+ ld r6, VCPU_TFIAR(r4)
+ ld r7, VCPU_TEXASR(r4)
+ ld r8, VCPU_EBBHR(r4)
+ mtspr SPRN_TFHAR, r5
+ mtspr SPRN_TFIAR, r6
+ mtspr SPRN_TEXASR, r7
+ mtspr SPRN_EBBHR, r8
+ ld r5, VCPU_EBBRR(r4)
+ ld r6, VCPU_BESCR(r4)
+ ld r7, VCPU_CSIGR(r4)
+ ld r8, VCPU_TACR(r4)
+ mtspr SPRN_EBBRR, r5
+ mtspr SPRN_BESCR, r6
+ mtspr SPRN_CSIGR, r7
+ mtspr SPRN_TACR, r8
+ ld r5, VCPU_TCSCR(r4)
+ ld r6, VCPU_ACOP(r4)
+ lwz r7, VCPU_GUEST_PID(r4)
+ ld r8, VCPU_WORT(r4)
+ mtspr SPRN_TCSCR, r5
+ mtspr SPRN_ACOP, r6
+ mtspr SPRN_PID, r7
+ mtspr SPRN_WORT, r8
+8:
+
/*
* Set the decrementer to the guest decrementer.
*/
@@ -628,6 +695,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
37: ld r7, VCORE_PCR(r5)
mtspr SPRN_PCR, r7
+BEGIN_FTR_SECTION
+ /* DPDES is shared between threads */
+ ld r8, VCORE_DPDES(r5)
+ mtspr SPRN_DPDES, r8
+END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
+
li r0,1
stb r0,VCORE_IN_GUEST(r5) /* signal secondaries to continue */
b 10f
@@ -1201,6 +1274,15 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
mtspr SPRN_LPID,r7
isync
+BEGIN_FTR_SECTION
+ /* DPDES is shared between threads */
+ mfspr r7, SPRN_DPDES
+ std r7, VCORE_DPDES(r5)
+ /* clear DPDES so we don't get guest doorbells in the host */
+ li r8, 0
+ mtspr SPRN_DPDES, r8
+END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
+
/* Subtract timebase offset from timebase */
ld r8,VCORE_TB_OFFSET(r5)
cmpdi r8,0
@@ -1321,6 +1403,54 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
add r5,r5,r6
std r5,VCPU_DEC_EXPIRES(r9)
+BEGIN_FTR_SECTION
+ b 8f
+END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
+ /* Turn on TM so we can access TFHAR/TFIAR/TEXASR */
+ mfmsr r8
+ li r0, 1
+ rldimi r8, r0, MSR_TM_LG, 63-MSR_TM_LG
+ mtmsrd r8
+
+ /* Save POWER8-specific registers */
+ mfspr r5, SPRN_IAMR
+ mfspr r6, SPRN_PSPB
+ mfspr r7, SPRN_FSCR
+ std r5, VCPU_IAMR(r9)
+ stw r6, VCPU_PSPB(r9)
+ std r7, VCPU_FSCR(r9)
+ mfspr r5, SPRN_IC
+ mfspr r6, SPRN_VTB
+ mfspr r7, SPRN_TAR
+ std r5, VCPU_IC(r9)
+ std r6, VCPU_VTB(r9)
+ std r7, VCPU_TAR(r9)
+ mfspr r5, SPRN_TFHAR
+ mfspr r6, SPRN_TFIAR
+ mfspr r7, SPRN_TEXASR
+ mfspr r8, SPRN_EBBHR
+ std r5, VCPU_TFHAR(r9)
+ std r6, VCPU_TFIAR(r9)
+ std r7, VCPU_TEXASR(r9)
+ std r8, VCPU_EBBHR(r9)
+ mfspr r5, SPRN_EBBRR
+ mfspr r6, SPRN_BESCR
+ mfspr r7, SPRN_CSIGR
+ mfspr r8, SPRN_TACR
+ std r5, VCPU_EBBRR(r9)
+ std r6, VCPU_BESCR(r9)
+ std r7, VCPU_CSIGR(r9)
+ std r8, VCPU_TACR(r9)
+ mfspr r5, SPRN_TCSCR
+ mfspr r6, SPRN_ACOP
+ mfspr r7, SPRN_PID
+ mfspr r8, SPRN_WORT
+ std r5, VCPU_TCSCR(r9)
+ std r6, VCPU_ACOP(r9)
+ stw r7, VCPU_GUEST_PID(r9)
+ std r8, VCPU_WORT(r9)
+8:
+
/* Save and reset AMR and UAMOR before turning on the MMU */
BEGIN_FTR_SECTION
mfspr r5,SPRN_AMR
@@ -1430,6 +1560,20 @@ BEGIN_FTR_SECTION
stw r10, VCPU_PMC + 24(r9)
stw r11, VCPU_PMC + 28(r9)
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
+BEGIN_FTR_SECTION
+ mfspr r4, SPRN_MMCR2
+ mfspr r5, SPRN_SIER
+ mfspr r6, SPRN_SPMC1
+ mfspr r7, SPRN_SPMC2
+ mfspr r8, SPRN_MMCRS
+ std r4, VCPU_MMCR + 24(r9)
+ std r5, VCPU_SIER(r9)
+ stw r6, VCPU_PMC + 24(r9)
+ stw r7, VCPU_PMC + 28(r9)
+ std r8, VCPU_MMCR + 32(r9)
+ lis r4, 0x8000
+ mtspr SPRN_MMCRS, r4
+END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
22:
ld r0, 112+PPC_LR_STKOFF(r1)
addi r1, r1, 112
--
1.8.4.rc3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFC PATCH 04/10] KVM: PPC: Book3S HV: Flush the correct number of TLB sets on POWER8
2013-09-06 3:48 [RFC PATCH 0/10] Support POWER8 in HV KVM Paul Mackerras
` (2 preceding siblings ...)
2013-09-06 3:51 ` [RFC PATCH 03/10] KVM: PPC: Book3S HV: Context-switch new POWER8 SPRs Paul Mackerras
@ 2013-09-06 3:53 ` Paul Mackerras
2013-09-06 3:54 ` [RFC PATCH 05/10] KVM: PPC: Book3S HV: Add handler for HV facility unavailable Paul Mackerras
` (5 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Paul Mackerras @ 2013-09-06 3:53 UTC (permalink / raw)
To: Alexander Graf, kvm-ppc, kvm
POWER8 has 512 sets in the TLB, compared to 128 for POWER7, so we need
to do more tlbiel instructions when flushing the TLB on POWER8.
Signed-off-by: Paul Mackerras <paulus@samba.org>
---
arch/powerpc/kvm/book3s_hv_rmhandlers.S | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 1de0b65..612c9c8 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -667,7 +667,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
andc r7,r7,r0
stdcx. r7,0,r6
bne 23b
- li r6,128 /* and flush the TLB */
+ /* Flush the TLB of any entries for this LPID */
+ /* use arch 2.07S as a proxy for POWER8 */
+BEGIN_FTR_SECTION
+ li r6,512 /* POWER8 has 512 sets */
+FTR_SECTION_ELSE
+ li r6,128 /* POWER7 has 128 sets */
+ALT_FTR_SECTION_END_IFSET(CPU_FTR_ARCH_207S)
mtctr r6
li r7,0x800 /* IS field = 0b10 */
ptesync
--
1.8.4.rc3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFC PATCH 05/10] KVM: PPC: Book3S HV: Add handler for HV facility unavailable
2013-09-06 3:48 [RFC PATCH 0/10] Support POWER8 in HV KVM Paul Mackerras
` (3 preceding siblings ...)
2013-09-06 3:53 ` [RFC PATCH 04/10] KVM: PPC: Book3S HV: Flush the correct number of TLB sets on POWER8 Paul Mackerras
@ 2013-09-06 3:54 ` Paul Mackerras
2013-11-04 12:48 ` Alexander Graf
2013-09-06 3:55 ` [RFC PATCH 06/10] KVM: PPC: Book3S HV: Implement architecture compatibility modes for POWER8 Paul Mackerras
` (4 subsequent siblings)
9 siblings, 1 reply; 16+ messages in thread
From: Paul Mackerras @ 2013-09-06 3:54 UTC (permalink / raw)
To: Alexander Graf, kvm-ppc, kvm
From: Michael Ellerman <michael@ellerman.id.au>
At present this should never happen, since the host kernel sets
HFSCR to allow access to all facilities. It's better to be prepared
to handle it cleanly if it does ever happen, though.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Paul Mackerras <paulus@samba.org>
---
arch/powerpc/include/asm/kvm_asm.h | 1 +
arch/powerpc/kvm/book3s_hv.c | 9 +++++++++
2 files changed, 10 insertions(+)
diff --git a/arch/powerpc/include/asm/kvm_asm.h b/arch/powerpc/include/asm/kvm_asm.h
index 851bac7..f6401eb 100644
--- a/arch/powerpc/include/asm/kvm_asm.h
+++ b/arch/powerpc/include/asm/kvm_asm.h
@@ -99,6 +99,7 @@
#define BOOK3S_INTERRUPT_PERFMON 0xf00
#define BOOK3S_INTERRUPT_ALTIVEC 0xf20
#define BOOK3S_INTERRUPT_VSX 0xf40
+#define BOOK3S_INTERRUPT_H_FAC_UNAVAIL 0xf80
#define BOOK3S_IRQPRIO_SYSTEM_RESET 0
#define BOOK3S_IRQPRIO_DATA_SEGMENT 1
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 724daa5..da8619e 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -704,6 +704,15 @@ static int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
kvmppc_core_queue_program(vcpu, 0x80000);
r = RESUME_GUEST;
break;
+ /*
+ * This occurs if the guest (kernel or userspace), does something that
+ * is prohibited by HFSCR. We just generate a program interrupt to
+ * the guest.
+ */
+ case BOOK3S_INTERRUPT_H_FAC_UNAVAIL:
+ kvmppc_core_queue_program(vcpu, 0x80000);
+ r = RESUME_GUEST;
+ break;
default:
kvmppc_dump_regs(vcpu);
printk(KERN_EMERG "trap=0x%x | pc=0x%lx | msr=0x%llx\n",
--
1.8.4.rc3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFC PATCH 06/10] KVM: PPC: Book3S HV: Implement architecture compatibility modes for POWER8
2013-09-06 3:48 [RFC PATCH 0/10] Support POWER8 in HV KVM Paul Mackerras
` (4 preceding siblings ...)
2013-09-06 3:54 ` [RFC PATCH 05/10] KVM: PPC: Book3S HV: Add handler for HV facility unavailable Paul Mackerras
@ 2013-09-06 3:55 ` Paul Mackerras
2013-11-04 12:53 ` Alexander Graf
2013-09-06 3:58 ` [RFC PATCH 07/10] KVM: PPC: Book3S HV: Consolidate code that checks reason for wake from nap Paul Mackerras
` (3 subsequent siblings)
9 siblings, 1 reply; 16+ messages in thread
From: Paul Mackerras @ 2013-09-06 3:55 UTC (permalink / raw)
To: Alexander Graf, kvm-ppc, kvm
This allows us to select architecture 2.05 (POWER6) or 2.06 (POWER7)
compatibility modes on a POWER8 processor.
Signed-off-by: Paul Mackerras <paulus@samba.org>
---
arch/powerpc/include/asm/reg.h | 2 ++
arch/powerpc/kvm/book3s_hv.c | 16 +++++++++++++++-
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 4ca8b85..483e0a2 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -315,6 +315,8 @@
#define SPRN_PCR 0x152 /* Processor compatibility register */
#define PCR_VEC_DIS (1ul << (63-0)) /* Vec. disable (pre POWER8) */
#define PCR_VSX_DIS (1ul << (63-1)) /* VSX disable (pre POWER8) */
+#define PCR_TM_DIS (1ul << (63-2)) /* Trans. memory disable (POWER8) */
+#define PCR_ARCH_206 0x4 /* Architecture 2.06 */
#define PCR_ARCH_205 0x2 /* Architecture 2.05 */
#define SPRN_HEIR 0x153 /* Hypervisor Emulated Instruction Register */
#define SPRN_TLBINDEXR 0x154 /* P7 TLB control register */
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index da8619e..217041f 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -177,14 +177,28 @@ int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat)
switch (arch_compat) {
case PVR_ARCH_205:
- pcr = PCR_ARCH_205;
+ /*
+ * If an arch bit is set in PCR, all the defined
+ * higher-order arch bits also have to be set.
+ */
+ pcr = PCR_ARCH_206 | PCR_ARCH_205;
break;
case PVR_ARCH_206:
case PVR_ARCH_206p:
+ pcr = PCR_ARCH_206;
+ break;
+ case PVR_ARCH_207:
break;
default:
return -EINVAL;
}
+
+ if (!cpu_has_feature(CPU_FTR_ARCH_207S)) {
+ /* POWER7 can't emulate POWER8 */
+ if (!(pcr & PCR_ARCH_206))
+ return -EINVAL;
+ pcr &= ~PCR_ARCH_206;
+ }
}
spin_lock(&vc->lock);
--
1.8.4.rc3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFC PATCH 07/10] KVM: PPC: Book3S HV: Consolidate code that checks reason for wake from nap
2013-09-06 3:48 [RFC PATCH 0/10] Support POWER8 in HV KVM Paul Mackerras
` (5 preceding siblings ...)
2013-09-06 3:55 ` [RFC PATCH 06/10] KVM: PPC: Book3S HV: Implement architecture compatibility modes for POWER8 Paul Mackerras
@ 2013-09-06 3:58 ` Paul Mackerras
2013-09-06 3:58 ` [RFC PATCH 08/10] KVM: PPC: Book3S HV: Handle guest using doorbells for IPIs Paul Mackerras
` (2 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Paul Mackerras @ 2013-09-06 3:58 UTC (permalink / raw)
To: Alexander Graf, kvm-ppc, kvm
Currently in book3s_hv_rmhandlers.S we have three places where we
have woken up from nap mode and we check the reason field in SRR1
to see what event woke us up. This consolidates them into a new
function, kvmppc_check_wake_reason. It looks at the wake reason
field in SRR1, and if it indicates that an external interrupt caused
the wakeup, calls kvmppc_read_intr to check what sort of interrupt
it was.
This also consolidates the two places where we synthesize an external
interrupt (0x500 vector) for the guest. Now, if the guest exit code
finds that there was an external interrupt which has been handled
(i.e. it was an IPI indicating that there is now an interrupt pending
for the guest), it jumps to deliver_guest_interrupt, which is in the
last part of the guest entry code, where we synthesize guest external
and decrementer interrupts. That code has been streamlined a little
and now clears LPCR[MER] when appropriate as well as setting it.
The extra clearing of any pending IPI on a secondary, offline CPU
thread before going back to nap mode has been removed. It is no longer
necessary now that we have code to read and acknowledge IPIs in the
guest exit path.
This fixes a minor bug in the H_CEDE real-mode handling - previously,
if we found that other threads were already exiting the guest when we
were about to go to nap mode, we would branch to the cede wakeup path
and end up looking in SRR1 for a wakeup reason. Now we branch to a
point after we have checked the wakeup reason.
This also fixes a minor bug in kvmppc_read_intr - previously it could
return 0xff rather than 1, in the case where we find that a host IPI
is pending after we have cleared the IPI. Now it returns 1.
Signed-off-by: Paul Mackerras <paulus@samba.org>
---
arch/powerpc/kvm/book3s_hv_rmhandlers.S | 193 +++++++++++++-------------------
1 file changed, 78 insertions(+), 115 deletions(-)
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 612c9c8..6351ce2 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -234,8 +234,10 @@ kvm_novcpu_wakeup:
stb r0, HSTATE_NAPPING(r13)
stb r0, HSTATE_HWTHREAD_REQ(r13)
+ /* check the wake reason */
+ bl kvmppc_check_wake_reason
+
/* see if any other thread is already exiting */
- li r12, 0
lwz r0, VCORE_ENTRY_EXIT(r5)
cmpwi r0, 0x100
bge kvm_novcpu_exit
@@ -245,23 +247,14 @@ kvm_novcpu_wakeup:
li r0, 1
sld r0, r0, r7
addi r6, r5, VCORE_NAPPING_THREADS
-4: lwarx r3, 0, r6
- andc r3, r3, r0
- stwcx. r3, 0, r6
+4: lwarx r7, 0, r6
+ andc r7, r7, r0
+ stwcx. r7, 0, r6
bne 4b
- /* Check the wake reason in SRR1 to see why we got here */
- mfspr r3, SPRN_SRR1
- rlwinm r3, r3, 44-31, 0x7 /* extract wake reason field */
- cmpwi r3, 4 /* was it an external interrupt? */
- bne kvm_novcpu_exit /* if not, exit the guest */
-
- /* extern interrupt - read and handle it */
- li r12, BOOK3S_INTERRUPT_EXTERNAL
- bl kvmppc_read_intr
+ /* See if the wake reason means we need to exit */
cmpdi r3, 0
bge kvm_novcpu_exit
- li r12, 0
/* Got an IPI but other vcpus aren't yet exiting, must be a latecomer */
ld r4, HSTATE_KVM_VCPU(r13)
@@ -325,58 +318,23 @@ kvm_start_guest:
*/
/* Check the wake reason in SRR1 to see why we got here */
- mfspr r3,SPRN_SRR1
- rlwinm r3,r3,44-31,0x7 /* extract wake reason field */
- cmpwi r3,4 /* was it an external interrupt? */
- bne 27f /* if not */
- ld r5,HSTATE_XICS_PHYS(r13)
- li r7,XICS_XIRR /* if it was an external interrupt, */
- lwzcix r8,r5,r7 /* get and ack the interrupt */
- sync
- clrldi. r9,r8,40 /* get interrupt source ID. */
- beq 28f /* none there? */
- cmpwi r9,XICS_IPI /* was it an IPI? */
- bne 29f
- li r0,0xff
- li r6,XICS_MFRR
- stbcix r0,r5,r6 /* clear IPI */
- stwcix r8,r5,r7 /* EOI the interrupt */
- sync /* order loading of vcpu after that */
+ bl kvmppc_check_wake_reason
+ cmpdi r3, 0
+ bge kvm_no_guest
/* get vcpu pointer, NULL if we have no vcpu to run */
ld r4,HSTATE_KVM_VCPU(r13)
cmpdi r4,0
/* if we have no vcpu to run, go back to sleep */
beq kvm_no_guest
- b 30f
-27: /* XXX should handle hypervisor maintenance interrupts etc. here */
- b kvm_no_guest
-28: /* SRR1 said external but ICP said nope?? */
- b kvm_no_guest
-29: /* External non-IPI interrupt to offline secondary thread? help?? */
- stw r8,HSTATE_SAVED_XIRR(r13)
- b kvm_no_guest
-
-30: bl kvmppc_hv_entry
+ bl kvmppc_hv_entry
/* Back from the guest, go back to nap */
/* Clear our vcpu pointer so we don't come back in early */
li r0, 0
std r0, HSTATE_KVM_VCPU(r13)
lwsync
- /* Clear any pending IPI - we're an offline thread */
- ld r5, HSTATE_XICS_PHYS(r13)
- li r7, XICS_XIRR
- lwzcix r3, r5, r7 /* ack any pending interrupt */
- rlwinm. r0, r3, 0, 0xffffff /* any pending? */
- beq 37f
- sync
- li r0, 0xff
- li r6, XICS_MFRR
- stbcix r0, r5, r6 /* clear the IPI */
- stwcix r3, r5, r7 /* EOI it */
-37: sync
/* increment the nap count and then go to nap mode */
ld r4, HSTATE_KVM_VCORE(r13)
@@ -862,47 +820,46 @@ toc_tlbie_lock:
mtctr r6
mtxer r7
+kvmppc_cede_reentry: /* r4 = vcpu, r13 = paca */
ld r10, VCPU_PC(r4)
ld r11, VCPU_MSR(r4)
-kvmppc_cede_reentry: /* r4 = vcpu, r13 = paca */
ld r6, VCPU_SRR0(r4)
ld r7, VCPU_SRR1(r4)
+ mtspr SPRN_SRR0, r6
+ mtspr SPRN_SRR1, r7
+deliver_guest_interrupt:
/* r11 = vcpu->arch.msr & ~MSR_HV */
rldicl r11, r11, 63 - MSR_HV_LG, 1
rotldi r11, r11, 1 + MSR_HV_LG
ori r11, r11, MSR_ME
/* Check if we can deliver an external or decrementer interrupt now */
- ld r0,VCPU_PENDING_EXC(r4)
- lis r8,(1 << BOOK3S_IRQPRIO_EXTERNAL_LEVEL)@h
- and r0,r0,r8
- cmpdi cr1,r0,0
- andi. r0,r11,MSR_EE
- beq cr1,11f
+ ld r0, VCPU_PENDING_EXC(r4)
+ rldicl r0, r0, 64 - BOOK3S_IRQPRIO_EXTERNAL_LEVEL, 63
+ cmpdi cr1, r0, 0
+ andi. r8, r11, MSR_EE
BEGIN_FTR_SECTION
- mfspr r8,SPRN_LPCR
- ori r8,r8,LPCR_MER
- mtspr SPRN_LPCR,r8
+ mfspr r8, SPRN_LPCR
+ /* Insert EXTERNAL_LEVEL bit into LPCR at the MER bit position */
+ rldimi r8, r0, LPCR_MER_SH, 63 - LPCR_MER_SH
+ mtspr SPRN_LPCR, r8
isync
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
beq 5f
- li r0,BOOK3S_INTERRUPT_EXTERNAL
-12: mr r6,r10
+ li r0, BOOK3S_INTERRUPT_EXTERNAL
+ bne cr1, 12f
+ mfspr r0, SPRN_DEC
+ cmpwi r0, 0
+ li r0, BOOK3S_INTERRUPT_DECREMENTER
+ bge 5f
+
+12: mtspr SPRN_SRR0, r10
mr r10,r0
- mr r7,r11
+ mtspr SPRN_SRR1, r11
li r11,(MSR_ME << 1) | 1 /* synthesize MSR_SF | MSR_ME */
rotldi r11,r11,63
- b 5f
-11: beq 5f
- mfspr r0,SPRN_DEC
- cmpwi r0,0
- li r0,BOOK3S_INTERRUPT_DECREMENTER
- blt 12b
-
- /* Move SRR0 and SRR1 into the respective regs */
-5: mtspr SPRN_SRR0, r6
- mtspr SPRN_SRR1, r7
+5:
fast_guest_return:
li r0,0
@@ -1075,39 +1032,19 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206)
/* External interrupt, first check for host_ipi. If this is
* set, we know the host wants us out so let's do it now
*/
-do_ext_interrupt:
bl kvmppc_read_intr
cmpdi r3, 0
bgt ext_interrupt_to_host
- /* Allright, looks like an IPI for the guest, we need to set MER */
/* Check if any CPU is heading out to the host, if so head out too */
ld r5, HSTATE_KVM_VCORE(r13)
lwz r0, VCORE_ENTRY_EXIT(r5)
cmpwi r0, 0x100
bge ext_interrupt_to_host
- /* See if there is a pending interrupt for the guest */
- mfspr r8, SPRN_LPCR
- ld r0, VCPU_PENDING_EXC(r9)
- /* Insert EXTERNAL_LEVEL bit into LPCR at the MER bit position */
- rldicl. r0, r0, 64 - BOOK3S_IRQPRIO_EXTERNAL_LEVEL, 63
- rldimi r8, r0, LPCR_MER_SH, 63 - LPCR_MER_SH
- beq 2f
-
- /* And if the guest EE is set, we can deliver immediately, else
- * we return to the guest with MER set
- */
- andi. r0, r11, MSR_EE
- beq 2f
- mtspr SPRN_SRR0, r10
- mtspr SPRN_SRR1, r11
- li r10, BOOK3S_INTERRUPT_EXTERNAL
- li r11, (MSR_ME << 1) | 1 /* synthesize MSR_SF | MSR_ME */
- rotldi r11, r11, 63
-2: mr r4, r9
- mtspr SPRN_LPCR, r8
- b fast_guest_return
+ /* Return to guest after delivering any pending interrupt */
+ mr r4, r9
+ b deliver_guest_interrupt
ext_interrupt_to_host:
@@ -1923,7 +1860,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206)
stb r0,HSTATE_NAPPING(r13)
/* order napping_threads update vs testing entry_exit_count */
lwsync
- mr r4,r3
lwz r7,VCORE_ENTRY_EXIT(r5)
cmpwi r7,0x100
bge 33f /* another thread already exiting */
@@ -1976,6 +1912,11 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206)
nap
b .
+33: mr r4, r3
+ li r3, 0
+ li r12, 0
+ b 34f
+
kvm_end_cede:
/* get vcpu pointer */
ld r4, HSTATE_KVM_VCPU(r13)
@@ -2005,12 +1946,15 @@ kvm_end_cede:
ld r29, VCPU_GPR(R29)(r4)
ld r30, VCPU_GPR(R30)(r4)
ld r31, VCPU_GPR(R31)(r4)
+
+ /* Check the wake reason in SRR1 to see why we got here */
+ bl kvmppc_check_wake_reason
/* clear our bit in vcore->napping_threads */
-33: ld r5,HSTATE_KVM_VCORE(r13)
- lbz r3,HSTATE_PTID(r13)
+34: ld r5,HSTATE_KVM_VCORE(r13)
+ lbz r7,HSTATE_PTID(r13)
li r0,1
- sld r0,r0,r3
+ sld r0,r0,r7
addi r6,r5,VCORE_NAPPING_THREADS
32: lwarx r7,0,r6
andc r7,r7,r0
@@ -2019,23 +1963,18 @@ kvm_end_cede:
li r0,0
stb r0,HSTATE_NAPPING(r13)
- /* Check the wake reason in SRR1 to see why we got here */
- mfspr r3, SPRN_SRR1
- rlwinm r3, r3, 44-31, 0x7 /* extract wake reason field */
- cmpwi r3, 4 /* was it an external interrupt? */
- li r12, BOOK3S_INTERRUPT_EXTERNAL
+ /* See if the wake reason means we need to exit */
+ stw r12, VCPU_TRAP(r4)
mr r9, r4
- ld r10, VCPU_PC(r9)
- ld r11, VCPU_MSR(r9)
- beq do_ext_interrupt /* if so */
+ cmpdi r3, 0
+ bgt guest_exit_cont
/* see if any other thread is already exiting */
lwz r0,VCORE_ENTRY_EXIT(r5)
cmpwi r0,0x100
- blt kvmppc_cede_reentry /* if not go back to guest */
+ bge guest_exit_cont
- /* some threads are exiting, so go to the guest exit path */
- b hcall_real_fallback
+ b kvmppc_cede_reentry /* if not go back to guest */
/* cede when already previously prodded case */
kvm_cede_prodded:
@@ -2066,6 +2005,29 @@ machine_check_realmode:
b fast_interrupt_c_return
/*
+ * Check the reason we woke from nap, and take appropriate action.
+ * Returns:
+ * 0 if nothing needs to be done
+ * 1 if something happened that needs to be handled by the host
+ * -1 if there was a guest wakeup (IPI)
+ *
+ * Also sets r12 to the interrupt vector for any interrupt that needs
+ * to be handled now by the host (0x500 for external interrupt), or zero.
+ */
+kvmppc_check_wake_reason:
+ mfspr r6, SPRN_SRR1
+ rlwinm r6, r6, 44-31, 0x7 /* extract wake reason field */
+ cmpwi r6, 4 /* was it an external interrupt? */
+ li r12, BOOK3S_INTERRUPT_EXTERNAL
+ beq kvmppc_read_intr /* if so, see what it was */
+ li r3, 0
+ li r12, 0
+ cmpwi r6, 6 /* was it the decrementer? */
+ beq 0f
+ li r3, 1 /* anything else, return 1 */
+0: blr
+
+/*
* Determine what sort of external interrupt is pending (if any).
* Returns:
* 0 if no interrupt is pending
@@ -2096,7 +2058,6 @@ kvmppc_read_intr:
* interrupts directly to the guest
*/
cmpwi r3, XICS_IPI /* if there is, is it an IPI? */
- li r3, 1
bne 42f
/* It's an IPI, clear the MFRR and EOI it */
@@ -2122,12 +2083,14 @@ kvmppc_read_intr:
* before exit, it will be picked up by the host ICP driver
*/
stw r0, HSTATE_SAVED_XIRR(r13)
+ li r3, 1
b 1b
43: /* We raced with the host, we need to resend that IPI, bummer */
li r0, IPI_PRIORITY
stbcix r0, r6, r8 /* set the IPI */
sync
+ li r3, 1
b 1b
/*
--
1.8.4.rc3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFC PATCH 08/10] KVM: PPC: Book3S HV: Handle guest using doorbells for IPIs
2013-09-06 3:48 [RFC PATCH 0/10] Support POWER8 in HV KVM Paul Mackerras
` (6 preceding siblings ...)
2013-09-06 3:58 ` [RFC PATCH 07/10] KVM: PPC: Book3S HV: Consolidate code that checks reason for wake from nap Paul Mackerras
@ 2013-09-06 3:58 ` Paul Mackerras
2013-09-06 3:59 ` [RFC PATCH 09/10] KVM: PPC: Book3S HV: Handle new LPCR bits on POWER8 Paul Mackerras
2013-09-06 4:00 ` [RFC PATCH 10/10] KVM: PPC: Book3S HV: Prepare for host using hypervisor doorbells Paul Mackerras
9 siblings, 0 replies; 16+ messages in thread
From: Paul Mackerras @ 2013-09-06 3:58 UTC (permalink / raw)
To: Alexander Graf, kvm-ppc, kvm
* SRR1 wake reason field for system reset interrupt on wakeup from nap
is now a 4-bit field on P8, compared to 3 bits on P7.
* Set PECEDP in LPCR when napping because of H_CEDE so guest doorbells
will wake us up.
* Waking up from nap because of a guest doorbell interrupt is not a
reason to exit the guest.
Signed-off-by: Paul Mackerras <paulus@samba.org>
---
arch/powerpc/include/asm/reg.h | 4 +++-
arch/powerpc/kvm/book3s_hv_rmhandlers.S | 19 +++++++++++++++----
2 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 483e0a2..73fdd62 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -293,7 +293,9 @@
#define LPCR_ILE 0x02000000 /* !HV irqs set MSR:LE */
#define LPCR_AIL_0 0x00000000 /* MMU off exception offset 0x0 */
#define LPCR_AIL_3 0x01800000 /* MMU on exception offset 0xc00...4xxx */
-#define LPCR_PECE 0x00007000 /* powersave exit cause enable */
+#define LPCR_PECE 0x0001f000 /* powersave exit cause enable */
+#define LPCR_PECEDP 0x00010000 /* directed priv dbells cause exit */
+#define LPCR_PECEDH 0x00008000 /* directed hyp dbells cause exit */
#define LPCR_PECE0 0x00004000 /* ext. exceptions can cause exit */
#define LPCR_PECE1 0x00002000 /* decrementer can cause exit */
#define LPCR_PECE2 0x00001000 /* machine check etc can cause exit */
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 6351ce2..4b3a10e 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -1894,13 +1894,16 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206)
bl .kvmppc_save_fp
/*
- * Take a nap until a decrementer or external interrupt occurs,
- * with PECE1 (wake on decr) and PECE0 (wake on external) set in LPCR
+ * Take a nap until a decrementer or external or doobell interrupt
+ * occurs, with PECE1, PECE0 and PECEDP set in LPCR
*/
li r0,1
stb r0,HSTATE_HWTHREAD_REQ(r13)
mfspr r5,SPRN_LPCR
ori r5,r5,LPCR_PECE0 | LPCR_PECE1
+BEGIN_FTR_SECTION
+ oris r5,r5,LPCR_PECEDP@h
+END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
mtspr SPRN_LPCR,r5
isync
li r0, 0
@@ -2016,14 +2019,22 @@ machine_check_realmode:
*/
kvmppc_check_wake_reason:
mfspr r6, SPRN_SRR1
- rlwinm r6, r6, 44-31, 0x7 /* extract wake reason field */
- cmpwi r6, 4 /* was it an external interrupt? */
+BEGIN_FTR_SECTION
+ rlwinm r6, r6, 45-31, 0xf /* extract wake reason field (P8) */
+FTR_SECTION_ELSE
+ rlwinm r6, r6, 45-31, 0xe /* P7 wake reason field is 3 bits */
+ALT_FTR_SECTION_END_IFSET(CPU_FTR_ARCH_207S)
+ cmpwi r6, 8 /* was it an external interrupt? */
li r12, BOOK3S_INTERRUPT_EXTERNAL
beq kvmppc_read_intr /* if so, see what it was */
li r3, 0
li r12, 0
cmpwi r6, 6 /* was it the decrementer? */
beq 0f
+BEGIN_FTR_SECTION
+ cmpwi r6, 5 /* privileged doorbell? */
+ beq 0f
+END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
li r3, 1 /* anything else, return 1 */
0: blr
--
1.8.4.rc3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFC PATCH 09/10] KVM: PPC: Book3S HV: Handle new LPCR bits on POWER8
2013-09-06 3:48 [RFC PATCH 0/10] Support POWER8 in HV KVM Paul Mackerras
` (7 preceding siblings ...)
2013-09-06 3:58 ` [RFC PATCH 08/10] KVM: PPC: Book3S HV: Handle guest using doorbells for IPIs Paul Mackerras
@ 2013-09-06 3:59 ` Paul Mackerras
2013-09-06 4:00 ` [RFC PATCH 10/10] KVM: PPC: Book3S HV: Prepare for host using hypervisor doorbells Paul Mackerras
9 siblings, 0 replies; 16+ messages in thread
From: Paul Mackerras @ 2013-09-06 3:59 UTC (permalink / raw)
To: Alexander Graf, kvm-ppc, kvm
POWER8 has a bit in the LPCR to enable or disable the PURR and SPURR
registers to count when in the guest. Set this bit.
POWER8 has a field in the LPCR called AIL (Alternate Interrupt Location)
which is used to enable relocation-on interrupts. Allow userspace to
set this field.
Signed-off-by: Paul Mackerras <paulus@samba.org>
---
arch/powerpc/include/asm/reg.h | 2 ++
arch/powerpc/kvm/book3s_hv.c | 6 ++++++
2 files changed, 8 insertions(+)
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 73fdd62..60c2dd8 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -291,8 +291,10 @@
#define LPCR_RMLS 0x1C000000 /* impl dependent rmo limit sel */
#define LPCR_RMLS_SH (63-37)
#define LPCR_ILE 0x02000000 /* !HV irqs set MSR:LE */
+#define LPCR_AIL 0x01800000 /* Alternate interrupt location */
#define LPCR_AIL_0 0x00000000 /* MMU off exception offset 0x0 */
#define LPCR_AIL_3 0x01800000 /* MMU on exception offset 0xc00...4xxx */
+#define LPCR_ONL 0x00040000 /* online - PURR/SPURR count */
#define LPCR_PECE 0x0001f000 /* powersave exit cause enable */
#define LPCR_PECEDP 0x00010000 /* directed priv dbells cause exit */
#define LPCR_PECEDH 0x00008000 /* directed hyp dbells cause exit */
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 217041f..95a635d 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -783,8 +783,11 @@ static void kvmppc_set_lpcr(struct kvm_vcpu *vcpu, u64 new_lpcr)
/*
* Userspace can only modify DPFD (default prefetch depth),
* ILE (interrupt little-endian) and TC (translation control).
+ * On POWER8 userspace can also modify AIL (alt. interrupt loc.)
*/
mask = LPCR_DPFD | LPCR_ILE | LPCR_TC;
+ if (cpu_has_feature(CPU_FTR_ARCH_207S))
+ mask |= LPCR_AIL;
kvm->arch.lpcr = (kvm->arch.lpcr & ~mask) | (new_lpcr & mask);
mutex_unlock(&kvm->lock);
}
@@ -2169,6 +2172,9 @@ int kvmppc_core_init_vm(struct kvm *kvm)
LPCR_VPM0 | LPCR_VPM1;
kvm->arch.vrma_slb_v = SLB_VSID_B_1T |
(VRMA_VSID << SLB_VSID_SHIFT_1T);
+ /* On POWER8 turn on online bit to enable PURR/SPURR */
+ if (cpu_has_feature(CPU_FTR_ARCH_207S))
+ lpcr |= LPCR_ONL;
}
kvm->arch.lpcr = lpcr;
--
1.8.4.rc3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFC PATCH 10/10] KVM: PPC: Book3S HV: Prepare for host using hypervisor doorbells
2013-09-06 3:48 [RFC PATCH 0/10] Support POWER8 in HV KVM Paul Mackerras
` (8 preceding siblings ...)
2013-09-06 3:59 ` [RFC PATCH 09/10] KVM: PPC: Book3S HV: Handle new LPCR bits on POWER8 Paul Mackerras
@ 2013-09-06 4:00 ` Paul Mackerras
9 siblings, 0 replies; 16+ messages in thread
From: Paul Mackerras @ 2013-09-06 4:00 UTC (permalink / raw)
To: Alexander Graf, kvm-ppc, kvm
POWER8 has support for hypervisor doorbell interrupts. Though the
kernel doesn't use them for IPIs on the powernv platform yet, it
probably will in future, so this makes KVM cope gracefully if a
hypervisor doorbell interrupt arrives while in a guest.
Signed-off-by: Paul Mackerras <paulus@samba.org>
---
arch/powerpc/include/asm/kvm_asm.h | 1 +
arch/powerpc/kvm/book3s_hv.c | 1 +
arch/powerpc/kvm/book3s_hv_rmhandlers.S | 7 +++++++
3 files changed, 9 insertions(+)
diff --git a/arch/powerpc/include/asm/kvm_asm.h b/arch/powerpc/include/asm/kvm_asm.h
index f6401eb..4c2040a 100644
--- a/arch/powerpc/include/asm/kvm_asm.h
+++ b/arch/powerpc/include/asm/kvm_asm.h
@@ -96,6 +96,7 @@
#define BOOK3S_INTERRUPT_H_DATA_STORAGE 0xe00
#define BOOK3S_INTERRUPT_H_INST_STORAGE 0xe20
#define BOOK3S_INTERRUPT_H_EMUL_ASSIST 0xe40
+#define BOOK3S_INTERRUPT_H_DOORBELL 0xe80
#define BOOK3S_INTERRUPT_PERFMON 0xf00
#define BOOK3S_INTERRUPT_ALTIVEC 0xf20
#define BOOK3S_INTERRUPT_VSX 0xf40
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 95a635d..dc5ce77 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -644,6 +644,7 @@ static int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
r = RESUME_GUEST;
break;
case BOOK3S_INTERRUPT_EXTERNAL:
+ case BOOK3S_INTERRUPT_H_DOORBELL:
vcpu->stat.ext_intr_exits++;
r = RESUME_GUEST;
break;
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 4b3a10e..018513a 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -2034,10 +2034,17 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_ARCH_207S)
BEGIN_FTR_SECTION
cmpwi r6, 5 /* privileged doorbell? */
beq 0f
+ cmpwi r6, 3 /* hypervisor doorbell? */
+ beq 3f
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
li r3, 1 /* anything else, return 1 */
0: blr
+ /* hypervisor doorbell */
+3: li r12, BOOK3S_INTERRUPT_H_DOORBELL
+ li r3, 1
+ blr
+
/*
* Determine what sort of external interrupt is pending (if any).
* Returns:
--
1.8.4.rc3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [RFC PATCH 05/10] KVM: PPC: Book3S HV: Add handler for HV facility unavailable
2013-09-06 3:54 ` [RFC PATCH 05/10] KVM: PPC: Book3S HV: Add handler for HV facility unavailable Paul Mackerras
@ 2013-11-04 12:48 ` Alexander Graf
0 siblings, 0 replies; 16+ messages in thread
From: Alexander Graf @ 2013-11-04 12:48 UTC (permalink / raw)
To: Paul Mackerras; +Cc: kvm-ppc, kvm@vger.kernel.org mailing list
On 06.09.2013, at 05:54, Paul Mackerras <paulus@samba.org> wrote:
> From: Michael Ellerman <michael@ellerman.id.au>
>
> At present this should never happen, since the host kernel sets
> HFSCR to allow access to all facilities. It's better to be prepared
> to handle it cleanly if it does ever happen, though.
>
> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
> Signed-off-by: Paul Mackerras <paulus@samba.org>
> ---
> arch/powerpc/include/asm/kvm_asm.h | 1 +
> arch/powerpc/kvm/book3s_hv.c | 9 +++++++++
> 2 files changed, 10 insertions(+)
>
> diff --git a/arch/powerpc/include/asm/kvm_asm.h b/arch/powerpc/include/asm/kvm_asm.h
> index 851bac7..f6401eb 100644
> --- a/arch/powerpc/include/asm/kvm_asm.h
> +++ b/arch/powerpc/include/asm/kvm_asm.h
> @@ -99,6 +99,7 @@
> #define BOOK3S_INTERRUPT_PERFMON 0xf00
> #define BOOK3S_INTERRUPT_ALTIVEC 0xf20
> #define BOOK3S_INTERRUPT_VSX 0xf40
> +#define BOOK3S_INTERRUPT_H_FAC_UNAVAIL 0xf80
>
> #define BOOK3S_IRQPRIO_SYSTEM_RESET 0
> #define BOOK3S_IRQPRIO_DATA_SEGMENT 1
> diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
> index 724daa5..da8619e 100644
> --- a/arch/powerpc/kvm/book3s_hv.c
> +++ b/arch/powerpc/kvm/book3s_hv.c
> @@ -704,6 +704,15 @@ static int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
> kvmppc_core_queue_program(vcpu, 0x80000);
> r = RESUME_GUEST;
> break;
> + /*
> + * This occurs if the guest (kernel or userspace), does something that
> + * is prohibited by HFSCR. We just generate a program interrupt to
> + * the guest.
> + */
> + case BOOK3S_INTERRUPT_H_FAC_UNAVAIL:
> + kvmppc_core_queue_program(vcpu, 0x80000);
Would be nice to have a name for that bit.
Alex
> + r = RESUME_GUEST;
> + break;
> default:
> kvmppc_dump_regs(vcpu);
> printk(KERN_EMERG "trap=0x%x | pc=0x%lx | msr=0x%llx\n",
> --
> 1.8.4.rc3
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [RFC PATCH 06/10] KVM: PPC: Book3S HV: Implement architecture compatibility modes for POWER8
2013-09-06 3:55 ` [RFC PATCH 06/10] KVM: PPC: Book3S HV: Implement architecture compatibility modes for POWER8 Paul Mackerras
@ 2013-11-04 12:53 ` Alexander Graf
2013-11-05 3:53 ` Paul Mackerras
0 siblings, 1 reply; 16+ messages in thread
From: Alexander Graf @ 2013-11-04 12:53 UTC (permalink / raw)
To: Paul Mackerras; +Cc: kvm-ppc, kvm@vger.kernel.org mailing list
On 06.09.2013, at 05:55, Paul Mackerras <paulus@samba.org> wrote:
> This allows us to select architecture 2.05 (POWER6) or 2.06 (POWER7)
> compatibility modes on a POWER8 processor.
>
> Signed-off-by: Paul Mackerras <paulus@samba.org>
> ---
> arch/powerpc/include/asm/reg.h | 2 ++
> arch/powerpc/kvm/book3s_hv.c | 16 +++++++++++++++-
> 2 files changed, 17 insertions(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
> index 4ca8b85..483e0a2 100644
> --- a/arch/powerpc/include/asm/reg.h
> +++ b/arch/powerpc/include/asm/reg.h
> @@ -315,6 +315,8 @@
> #define SPRN_PCR 0x152 /* Processor compatibility register */
> #define PCR_VEC_DIS (1ul << (63-0)) /* Vec. disable (pre POWER8) */
> #define PCR_VSX_DIS (1ul << (63-1)) /* VSX disable (pre POWER8) */
> +#define PCR_TM_DIS (1ul << (63-2)) /* Trans. memory disable (POWER8) */
Is this going to get used?
Alex
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [RFC PATCH 06/10] KVM: PPC: Book3S HV: Implement architecture compatibility modes for POWER8
2013-11-04 12:53 ` Alexander Graf
@ 2013-11-05 3:53 ` Paul Mackerras
2013-11-05 6:06 ` Alexander Graf
0 siblings, 1 reply; 16+ messages in thread
From: Paul Mackerras @ 2013-11-05 3:53 UTC (permalink / raw)
To: Alexander Graf; +Cc: kvm-ppc, kvm@vger.kernel.org mailing list
On Mon, Nov 04, 2013 at 01:53:36PM +0100, Alexander Graf wrote:
>
> On 06.09.2013, at 05:55, Paul Mackerras <paulus@samba.org> wrote:
>
> > This allows us to select architecture 2.05 (POWER6) or 2.06 (POWER7)
> > compatibility modes on a POWER8 processor.
> >
> > Signed-off-by: Paul Mackerras <paulus@samba.org>
> > ---
> > arch/powerpc/include/asm/reg.h | 2 ++
> > arch/powerpc/kvm/book3s_hv.c | 16 +++++++++++++++-
> > 2 files changed, 17 insertions(+), 1 deletion(-)
> >
> > diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
> > index 4ca8b85..483e0a2 100644
> > --- a/arch/powerpc/include/asm/reg.h
> > +++ b/arch/powerpc/include/asm/reg.h
> > @@ -315,6 +315,8 @@
> > #define SPRN_PCR 0x152 /* Processor compatibility register */
> > #define PCR_VEC_DIS (1ul << (63-0)) /* Vec. disable (pre POWER8) */
> > #define PCR_VSX_DIS (1ul << (63-1)) /* VSX disable (pre POWER8) */
> > +#define PCR_TM_DIS (1ul << (63-2)) /* Trans. memory disable (POWER8) */
>
> Is this going to get used?
Perhaps not, but I thought it worthwhile to document that the bit
exists.
Paul.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [RFC PATCH 06/10] KVM: PPC: Book3S HV: Implement architecture compatibility modes for POWER8
2013-11-05 3:53 ` Paul Mackerras
@ 2013-11-05 6:06 ` Alexander Graf
2013-11-06 5:15 ` Paul Mackerras
0 siblings, 1 reply; 16+ messages in thread
From: Alexander Graf @ 2013-11-05 6:06 UTC (permalink / raw)
To: Paul Mackerras; +Cc: kvm-ppc@vger.kernel.org, kvm@vger.kernel.org mailing list
Am 05.11.2013 um 04:53 schrieb Paul Mackerras <paulus@samba.org>:
> On Mon, Nov 04, 2013 at 01:53:36PM +0100, Alexander Graf wrote:
>>
>> On 06.09.2013, at 05:55, Paul Mackerras <paulus@samba.org> wrote:
>>
>>> This allows us to select architecture 2.05 (POWER6) or 2.06 (POWER7)
>>> compatibility modes on a POWER8 processor.
>>>
>>> Signed-off-by: Paul Mackerras <paulus@samba.org>
>>> ---
>>> arch/powerpc/include/asm/reg.h | 2 ++
>>> arch/powerpc/kvm/book3s_hv.c | 16 +++++++++++++++-
>>> 2 files changed, 17 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
>>> index 4ca8b85..483e0a2 100644
>>> --- a/arch/powerpc/include/asm/reg.h
>>> +++ b/arch/powerpc/include/asm/reg.h
>>> @@ -315,6 +315,8 @@
>>> #define SPRN_PCR 0x152 /* Processor compatibility register */
>>> #define PCR_VEC_DIS (1ul << (63-0)) /* Vec. disable (pre POWER8) */
>>> #define PCR_VSX_DIS (1ul << (63-1)) /* VSX disable (pre POWER8) */
>>> +#define PCR_TM_DIS (1ul << (63-2)) /* Trans. memory disable (POWER8) */
>>
>> Is this going to get used?
>
> Perhaps not, but I thought it worthwhile to document that the bit
> exists.
But why not? Does that mean we allow TM to be used in p7 compat mode?
Alex
>
> Paul.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [RFC PATCH 06/10] KVM: PPC: Book3S HV: Implement architecture compatibility modes for POWER8
2013-11-05 6:06 ` Alexander Graf
@ 2013-11-06 5:15 ` Paul Mackerras
0 siblings, 0 replies; 16+ messages in thread
From: Paul Mackerras @ 2013-11-06 5:15 UTC (permalink / raw)
To: Alexander Graf; +Cc: kvm-ppc@vger.kernel.org, kvm@vger.kernel.org mailing list
On Tue, Nov 05, 2013 at 07:06:17AM +0100, Alexander Graf wrote:
>
>
> Am 05.11.2013 um 04:53 schrieb Paul Mackerras <paulus@samba.org>:
>
> > On Mon, Nov 04, 2013 at 01:53:36PM +0100, Alexander Graf wrote:
> >>
> >> On 06.09.2013, at 05:55, Paul Mackerras <paulus@samba.org> wrote:
> >>
> >>> This allows us to select architecture 2.05 (POWER6) or 2.06 (POWER7)
> >>> compatibility modes on a POWER8 processor.
> >>>
> >>> Signed-off-by: Paul Mackerras <paulus@samba.org>
> >>> ---
> >>> arch/powerpc/include/asm/reg.h | 2 ++
> >>> arch/powerpc/kvm/book3s_hv.c | 16 +++++++++++++++-
> >>> 2 files changed, 17 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
> >>> index 4ca8b85..483e0a2 100644
> >>> --- a/arch/powerpc/include/asm/reg.h
> >>> +++ b/arch/powerpc/include/asm/reg.h
> >>> @@ -315,6 +315,8 @@
> >>> #define SPRN_PCR 0x152 /* Processor compatibility register */
> >>> #define PCR_VEC_DIS (1ul << (63-0)) /* Vec. disable (pre POWER8) */
> >>> #define PCR_VSX_DIS (1ul << (63-1)) /* VSX disable (pre POWER8) */
> >>> +#define PCR_TM_DIS (1ul << (63-2)) /* Trans. memory disable (POWER8) */
> >>
> >> Is this going to get used?
> >
> > Perhaps not, but I thought it worthwhile to document that the bit
> > exists.
>
> But why not? Does that mean we allow TM to be used in p7 compat mode?
No; TM is disabled if either or both of the PCR_TM_DIS and PCR_ARCH_206
bits are set.
Paul.
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2013-11-06 5:15 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-09-06 3:48 [RFC PATCH 0/10] Support POWER8 in HV KVM Paul Mackerras
2013-09-06 3:50 ` [RFC PATCH 01/10] KVM: PPC: Book3S HV: Align physical CPU thread numbers with virtual Paul Mackerras
2013-09-06 3:51 ` [RFC PATCH 02/10] KVM: PPC: Book3S HV: Don't set DABR on POWER8 Paul Mackerras
2013-09-06 3:51 ` [RFC PATCH 03/10] KVM: PPC: Book3S HV: Context-switch new POWER8 SPRs Paul Mackerras
2013-09-06 3:53 ` [RFC PATCH 04/10] KVM: PPC: Book3S HV: Flush the correct number of TLB sets on POWER8 Paul Mackerras
2013-09-06 3:54 ` [RFC PATCH 05/10] KVM: PPC: Book3S HV: Add handler for HV facility unavailable Paul Mackerras
2013-11-04 12:48 ` Alexander Graf
2013-09-06 3:55 ` [RFC PATCH 06/10] KVM: PPC: Book3S HV: Implement architecture compatibility modes for POWER8 Paul Mackerras
2013-11-04 12:53 ` Alexander Graf
2013-11-05 3:53 ` Paul Mackerras
2013-11-05 6:06 ` Alexander Graf
2013-11-06 5:15 ` Paul Mackerras
2013-09-06 3:58 ` [RFC PATCH 07/10] KVM: PPC: Book3S HV: Consolidate code that checks reason for wake from nap Paul Mackerras
2013-09-06 3:58 ` [RFC PATCH 08/10] KVM: PPC: Book3S HV: Handle guest using doorbells for IPIs Paul Mackerras
2013-09-06 3:59 ` [RFC PATCH 09/10] KVM: PPC: Book3S HV: Handle new LPCR bits on POWER8 Paul Mackerras
2013-09-06 4:00 ` [RFC PATCH 10/10] KVM: PPC: Book3S HV: Prepare for host using hypervisor doorbells Paul Mackerras
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox