forked from Minki/linux
Merge branch 'kvm-ppc-next' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc into next
PPC KVM updates for 4.9. - Fix for the bug that Thomas Huth found which caused guests to falsely report soft lockups, - other minor fixes from Thomas Huth and Dan Carpenter, - and a small optimization from Balbir Singh.
This commit is contained in:
commit
40a6d22084
@ -101,6 +101,7 @@ struct kvmppc_vcore {
|
||||
u32 arch_compat;
|
||||
ulong pcr;
|
||||
ulong dpdes; /* doorbell state (POWER8) */
|
||||
ulong vtb; /* virtual timebase */
|
||||
ulong conferring_threads;
|
||||
unsigned int halt_poll_ns;
|
||||
};
|
||||
@ -119,6 +120,7 @@ struct kvmppc_vcpu_book3s {
|
||||
u64 sdr1;
|
||||
u64 hior;
|
||||
u64 msr_mask;
|
||||
u64 vtb;
|
||||
#ifdef CONFIG_PPC_BOOK3S_32
|
||||
u32 vsid_pool[VSID_POOL_SIZE];
|
||||
u32 vsid_next;
|
||||
|
@ -125,7 +125,6 @@ static inline unsigned long compute_tlbie_rb(unsigned long v, unsigned long r,
|
||||
/* This covers 14..54 bits of va*/
|
||||
rb = (v & ~0x7fUL) << 16; /* AVA field */
|
||||
|
||||
rb |= (v >> HPTE_V_SSIZE_SHIFT) << 8; /* B field */
|
||||
/*
|
||||
* AVA in v had cleared lower 23 bits. We need to derive
|
||||
* that from pteg index
|
||||
@ -177,7 +176,7 @@ static inline unsigned long compute_tlbie_rb(unsigned long v, unsigned long r,
|
||||
break;
|
||||
}
|
||||
}
|
||||
rb |= (v >> 54) & 0x300; /* B field */
|
||||
rb |= (v >> HPTE_V_SSIZE_SHIFT) << 8; /* B field */
|
||||
return rb;
|
||||
}
|
||||
|
||||
|
@ -475,7 +475,6 @@ struct kvm_vcpu_arch {
|
||||
ulong purr;
|
||||
ulong spurr;
|
||||
ulong ic;
|
||||
ulong vtb;
|
||||
ulong dscr;
|
||||
ulong amr;
|
||||
ulong uamor;
|
||||
|
@ -737,6 +737,7 @@
|
||||
#define MMCR0_FCHV 0x00000001UL /* freeze conditions in hypervisor mode */
|
||||
#define SPRN_MMCR1 798
|
||||
#define SPRN_MMCR2 785
|
||||
#define SPRN_UMMCR2 769
|
||||
#define SPRN_MMCRA 0x312
|
||||
#define MMCRA_SDSYNC 0x80000000UL /* SDAR synced with SIAR */
|
||||
#define MMCRA_SDAR_DCACHE_MISS 0x40000000UL
|
||||
|
@ -506,7 +506,6 @@ int main(void)
|
||||
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));
|
||||
@ -557,6 +556,7 @@ int main(void)
|
||||
DEFINE(VCORE_LPCR, offsetof(struct kvmppc_vcore, lpcr));
|
||||
DEFINE(VCORE_PCR, offsetof(struct kvmppc_vcore, pcr));
|
||||
DEFINE(VCORE_DPDES, offsetof(struct kvmppc_vcore, dpdes));
|
||||
DEFINE(VCORE_VTB, offsetof(struct kvmppc_vcore, vtb));
|
||||
DEFINE(VCPU_SLB_E, offsetof(struct kvmppc_slb, orige));
|
||||
DEFINE(VCPU_SLB_V, offsetof(struct kvmppc_slb, origv));
|
||||
DEFINE(VCPU_SLB_SIZE, sizeof(struct kvmppc_slb));
|
||||
|
@ -599,9 +599,6 @@ int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
|
||||
case KVM_REG_PPC_BESCR:
|
||||
*val = get_reg_val(id, vcpu->arch.bescr);
|
||||
break;
|
||||
case KVM_REG_PPC_VTB:
|
||||
*val = get_reg_val(id, vcpu->arch.vtb);
|
||||
break;
|
||||
case KVM_REG_PPC_IC:
|
||||
*val = get_reg_val(id, vcpu->arch.ic);
|
||||
break;
|
||||
@ -673,9 +670,6 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
|
||||
case KVM_REG_PPC_BESCR:
|
||||
vcpu->arch.bescr = set_reg_val(id, *val);
|
||||
break;
|
||||
case KVM_REG_PPC_VTB:
|
||||
vcpu->arch.vtb = set_reg_val(id, *val);
|
||||
break;
|
||||
case KVM_REG_PPC_IC:
|
||||
vcpu->arch.ic = set_reg_val(id, *val);
|
||||
break;
|
||||
|
@ -498,6 +498,7 @@ int kvmppc_core_emulate_mtspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)
|
||||
case SPRN_MMCR0:
|
||||
case SPRN_MMCR1:
|
||||
case SPRN_MMCR2:
|
||||
case SPRN_UMMCR2:
|
||||
#endif
|
||||
break;
|
||||
unprivileged:
|
||||
@ -579,7 +580,7 @@ int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val
|
||||
*spr_val = vcpu->arch.spurr;
|
||||
break;
|
||||
case SPRN_VTB:
|
||||
*spr_val = vcpu->arch.vtb;
|
||||
*spr_val = to_book3s(vcpu)->vtb;
|
||||
break;
|
||||
case SPRN_IC:
|
||||
*spr_val = vcpu->arch.ic;
|
||||
@ -640,6 +641,7 @@ int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val
|
||||
case SPRN_MMCR0:
|
||||
case SPRN_MMCR1:
|
||||
case SPRN_MMCR2:
|
||||
case SPRN_UMMCR2:
|
||||
case SPRN_TIR:
|
||||
#endif
|
||||
*spr_val = 0;
|
||||
|
@ -1199,6 +1199,9 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
|
||||
case KVM_REG_PPC_DPDES:
|
||||
*val = get_reg_val(id, vcpu->arch.vcore->dpdes);
|
||||
break;
|
||||
case KVM_REG_PPC_VTB:
|
||||
*val = get_reg_val(id, vcpu->arch.vcore->vtb);
|
||||
break;
|
||||
case KVM_REG_PPC_DAWR:
|
||||
*val = get_reg_val(id, vcpu->arch.dawr);
|
||||
break;
|
||||
@ -1391,6 +1394,9 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
|
||||
case KVM_REG_PPC_DPDES:
|
||||
vcpu->arch.vcore->dpdes = set_reg_val(id, *val);
|
||||
break;
|
||||
case KVM_REG_PPC_VTB:
|
||||
vcpu->arch.vcore->vtb = set_reg_val(id, *val);
|
||||
break;
|
||||
case KVM_REG_PPC_DAWR:
|
||||
vcpu->arch.dawr = set_reg_val(id, *val);
|
||||
break;
|
||||
@ -2097,66 +2103,6 @@ static void init_master_vcore(struct kvmppc_vcore *vc)
|
||||
vc->conferring_threads = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* See if the existing subcores can be split into 3 (or fewer) subcores
|
||||
* of at most two threads each, so we can fit in another vcore. This
|
||||
* assumes there are at most two subcores and at most 6 threads in total.
|
||||
*/
|
||||
static bool can_split_piggybacked_subcores(struct core_info *cip)
|
||||
{
|
||||
int sub, new_sub;
|
||||
int large_sub = -1;
|
||||
int thr;
|
||||
int n_subcores = cip->n_subcores;
|
||||
struct kvmppc_vcore *vc, *vcnext;
|
||||
struct kvmppc_vcore *master_vc = NULL;
|
||||
|
||||
for (sub = 0; sub < cip->n_subcores; ++sub) {
|
||||
if (cip->subcore_threads[sub] <= 2)
|
||||
continue;
|
||||
if (large_sub >= 0)
|
||||
return false;
|
||||
large_sub = sub;
|
||||
vc = list_first_entry(&cip->vcs[sub], struct kvmppc_vcore,
|
||||
preempt_list);
|
||||
if (vc->num_threads > 2)
|
||||
return false;
|
||||
n_subcores += (cip->subcore_threads[sub] - 1) >> 1;
|
||||
}
|
||||
if (large_sub < 0 || !subcore_config_ok(n_subcores + 1, 2))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Seems feasible, so go through and move vcores to new subcores.
|
||||
* Note that when we have two or more vcores in one subcore,
|
||||
* all those vcores must have only one thread each.
|
||||
*/
|
||||
new_sub = cip->n_subcores;
|
||||
thr = 0;
|
||||
sub = large_sub;
|
||||
list_for_each_entry_safe(vc, vcnext, &cip->vcs[sub], preempt_list) {
|
||||
if (thr >= 2) {
|
||||
list_del(&vc->preempt_list);
|
||||
list_add_tail(&vc->preempt_list, &cip->vcs[new_sub]);
|
||||
/* vc->num_threads must be 1 */
|
||||
if (++cip->subcore_threads[new_sub] == 1) {
|
||||
cip->subcore_vm[new_sub] = vc->kvm;
|
||||
init_master_vcore(vc);
|
||||
master_vc = vc;
|
||||
++cip->n_subcores;
|
||||
} else {
|
||||
vc->master_vcore = master_vc;
|
||||
++new_sub;
|
||||
}
|
||||
}
|
||||
thr += vc->num_threads;
|
||||
}
|
||||
cip->subcore_threads[large_sub] = 2;
|
||||
cip->max_subcore_threads = 2;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool can_dynamic_split(struct kvmppc_vcore *vc, struct core_info *cip)
|
||||
{
|
||||
int n_threads = vc->num_threads;
|
||||
@ -2167,23 +2113,9 @@ static bool can_dynamic_split(struct kvmppc_vcore *vc, struct core_info *cip)
|
||||
|
||||
if (n_threads < cip->max_subcore_threads)
|
||||
n_threads = cip->max_subcore_threads;
|
||||
if (subcore_config_ok(cip->n_subcores + 1, n_threads)) {
|
||||
cip->max_subcore_threads = n_threads;
|
||||
} else if (cip->n_subcores <= 2 && cip->total_threads <= 6 &&
|
||||
vc->num_threads <= 2) {
|
||||
/*
|
||||
* We may be able to fit another subcore in by
|
||||
* splitting an existing subcore with 3 or 4
|
||||
* threads into two 2-thread subcores, or one
|
||||
* with 5 or 6 threads into three subcores.
|
||||
* We can only do this if those subcores have
|
||||
* piggybacked virtual cores.
|
||||
*/
|
||||
if (!can_split_piggybacked_subcores(cip))
|
||||
return false;
|
||||
} else {
|
||||
if (!subcore_config_ok(cip->n_subcores + 1, n_threads))
|
||||
return false;
|
||||
}
|
||||
cip->max_subcore_threads = n_threads;
|
||||
|
||||
sub = cip->n_subcores;
|
||||
++cip->n_subcores;
|
||||
@ -2197,43 +2129,6 @@ static bool can_dynamic_split(struct kvmppc_vcore *vc, struct core_info *cip)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool can_piggyback_subcore(struct kvmppc_vcore *pvc,
|
||||
struct core_info *cip, int sub)
|
||||
{
|
||||
struct kvmppc_vcore *vc;
|
||||
int n_thr;
|
||||
|
||||
vc = list_first_entry(&cip->vcs[sub], struct kvmppc_vcore,
|
||||
preempt_list);
|
||||
|
||||
/* require same VM and same per-core reg values */
|
||||
if (pvc->kvm != vc->kvm ||
|
||||
pvc->tb_offset != vc->tb_offset ||
|
||||
pvc->pcr != vc->pcr ||
|
||||
pvc->lpcr != vc->lpcr)
|
||||
return false;
|
||||
|
||||
/* P8 guest with > 1 thread per core would see wrong TIR value */
|
||||
if (cpu_has_feature(CPU_FTR_ARCH_207S) &&
|
||||
(vc->num_threads > 1 || pvc->num_threads > 1))
|
||||
return false;
|
||||
|
||||
n_thr = cip->subcore_threads[sub] + pvc->num_threads;
|
||||
if (n_thr > cip->max_subcore_threads) {
|
||||
if (!subcore_config_ok(cip->n_subcores, n_thr))
|
||||
return false;
|
||||
cip->max_subcore_threads = n_thr;
|
||||
}
|
||||
|
||||
cip->total_threads += pvc->num_threads;
|
||||
cip->subcore_threads[sub] = n_thr;
|
||||
pvc->master_vcore = vc;
|
||||
list_del(&pvc->preempt_list);
|
||||
list_add_tail(&pvc->preempt_list, &cip->vcs[sub]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Work out whether it is possible to piggyback the execution of
|
||||
* vcore *pvc onto the execution of the other vcores described in *cip.
|
||||
@ -2241,19 +2136,10 @@ static bool can_piggyback_subcore(struct kvmppc_vcore *pvc,
|
||||
static bool can_piggyback(struct kvmppc_vcore *pvc, struct core_info *cip,
|
||||
int target_threads)
|
||||
{
|
||||
int sub;
|
||||
|
||||
if (cip->total_threads + pvc->num_threads > target_threads)
|
||||
return false;
|
||||
for (sub = 0; sub < cip->n_subcores; ++sub)
|
||||
if (cip->subcore_threads[sub] &&
|
||||
can_piggyback_subcore(pvc, cip, sub))
|
||||
return true;
|
||||
|
||||
if (can_dynamic_split(pvc, cip))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return can_dynamic_split(pvc, cip);
|
||||
}
|
||||
|
||||
static void prepare_threads(struct kvmppc_vcore *vc)
|
||||
|
@ -644,9 +644,11 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_ARCH_207S)
|
||||
38:
|
||||
|
||||
BEGIN_FTR_SECTION
|
||||
/* DPDES is shared between threads */
|
||||
/* DPDES and VTB are shared between threads */
|
||||
ld r8, VCORE_DPDES(r5)
|
||||
ld r7, VCORE_VTB(r5)
|
||||
mtspr SPRN_DPDES, r8
|
||||
mtspr SPRN_VTB, r7
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
|
||||
|
||||
/* Mark the subcore state as inside guest */
|
||||
@ -806,10 +808,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
|
||||
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 r8, VCPU_EBBHR(r4)
|
||||
mtspr SPRN_IC, r5
|
||||
mtspr SPRN_EBBHR, r8
|
||||
ld r5, VCPU_EBBRR(r4)
|
||||
ld r6, VCPU_BESCR(r4)
|
||||
@ -1334,10 +1334,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
|
||||
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 r8, SPRN_EBBHR
|
||||
std r8, VCPU_EBBHR(r9)
|
||||
@ -1564,9 +1562,11 @@ kvmhv_switch_to_host:
|
||||
isync
|
||||
|
||||
BEGIN_FTR_SECTION
|
||||
/* DPDES is shared between threads */
|
||||
/* DPDES and VTB are shared between threads */
|
||||
mfspr r7, SPRN_DPDES
|
||||
mfspr r8, SPRN_VTB
|
||||
std r7, VCORE_DPDES(r5)
|
||||
std r8, VCORE_VTB(r5)
|
||||
/* clear DPDES so we don't get guest doorbells in the host */
|
||||
li r8, 0
|
||||
mtspr SPRN_DPDES, r8
|
||||
|
@ -226,7 +226,7 @@ void kvmppc_copy_from_svcpu(struct kvm_vcpu *vcpu,
|
||||
*/
|
||||
vcpu->arch.purr += get_tb() - vcpu->arch.entry_tb;
|
||||
vcpu->arch.spurr += get_tb() - vcpu->arch.entry_tb;
|
||||
vcpu->arch.vtb += get_vtb() - vcpu->arch.entry_vtb;
|
||||
to_book3s(vcpu)->vtb += get_vtb() - vcpu->arch.entry_vtb;
|
||||
if (cpu_has_feature(CPU_FTR_ARCH_207S))
|
||||
vcpu->arch.ic += mfspr(SPRN_IC) - vcpu->arch.entry_ic;
|
||||
svcpu->in_use = false;
|
||||
@ -448,6 +448,8 @@ void kvmppc_set_pvr_pr(struct kvm_vcpu *vcpu, u32 pvr)
|
||||
case PVR_POWER7:
|
||||
case PVR_POWER7p:
|
||||
case PVR_POWER8:
|
||||
case PVR_POWER8E:
|
||||
case PVR_POWER8NVL:
|
||||
vcpu->arch.hflags |= BOOK3S_HFLAG_MULTI_PGSIZE |
|
||||
BOOK3S_HFLAG_NEW_TLBIE;
|
||||
break;
|
||||
@ -1361,6 +1363,9 @@ static int kvmppc_get_one_reg_pr(struct kvm_vcpu *vcpu, u64 id,
|
||||
case KVM_REG_PPC_HIOR:
|
||||
*val = get_reg_val(id, to_book3s(vcpu)->hior);
|
||||
break;
|
||||
case KVM_REG_PPC_VTB:
|
||||
*val = get_reg_val(id, to_book3s(vcpu)->vtb);
|
||||
break;
|
||||
case KVM_REG_PPC_LPCR:
|
||||
case KVM_REG_PPC_LPCR_64:
|
||||
/*
|
||||
@ -1397,6 +1402,9 @@ static int kvmppc_set_one_reg_pr(struct kvm_vcpu *vcpu, u64 id,
|
||||
to_book3s(vcpu)->hior = set_reg_val(id, *val);
|
||||
to_book3s(vcpu)->hior_explicit = true;
|
||||
break;
|
||||
case KVM_REG_PPC_VTB:
|
||||
to_book3s(vcpu)->vtb = set_reg_val(id, *val);
|
||||
break;
|
||||
case KVM_REG_PPC_LPCR:
|
||||
case KVM_REG_PPC_LPCR_64:
|
||||
kvmppc_set_lpcr_pr(vcpu, set_reg_val(id, *val));
|
||||
|
@ -2038,7 +2038,7 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
|
||||
if (type == KVMPPC_DEBUG_NONE)
|
||||
continue;
|
||||
|
||||
if (type & !(KVMPPC_DEBUG_WATCH_READ |
|
||||
if (type & ~(KVMPPC_DEBUG_WATCH_READ |
|
||||
KVMPPC_DEBUG_WATCH_WRITE |
|
||||
KVMPPC_DEBUG_BREAKPOINT))
|
||||
return -EINVAL;
|
||||
|
Loading…
Reference in New Issue
Block a user