Skip to content

Commit 1b151ce

Browse files
committed
KVM: PPC: Book3S HV: Rename hpte_setup_done to mmu_ready
This renames the kvm->arch.hpte_setup_done field to mmu_ready because we will want to use it for radix guests too -- both for setting things up before vcpu execution, and for excluding vcpus from executing while MMU-related things get changed, such as in future switching the MMU from radix to HPT mode or vice-versa. This also moves the call to kvmppc_setup_partition_table() that was done in kvmppc_hv_setup_htab_rma() for HPT guests, and the setting of mmu_ready, into the caller in kvmppc_vcpu_run_hv(). Signed-off-by: Paul Mackerras <[email protected]>
1 parent 8dc6cca commit 1b151ce

File tree

3 files changed

+44
-33
lines changed

3 files changed

+44
-33
lines changed

arch/powerpc/include/asm/kvm_host.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ struct kvm_arch {
276276
int tlbie_lock;
277277
unsigned long lpcr;
278278
unsigned long vrma_slb_v;
279-
int hpte_setup_done;
279+
int mmu_ready;
280280
atomic_t vcpus_running;
281281
u32 online_vcores;
282282
atomic_t hpte_mod_interest;

arch/powerpc/kvm/book3s_64_mmu_hv.c

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,12 @@ long kvmppc_alloc_reset_hpt(struct kvm *kvm, int order)
140140
return -EINVAL;
141141

142142
mutex_lock(&kvm->lock);
143-
if (kvm->arch.hpte_setup_done) {
144-
kvm->arch.hpte_setup_done = 0;
145-
/* order hpte_setup_done vs. vcpus_running */
143+
if (kvm->arch.mmu_ready) {
144+
kvm->arch.mmu_ready = 0;
145+
/* order mmu_ready vs. vcpus_running */
146146
smp_mb();
147147
if (atomic_read(&kvm->arch.vcpus_running)) {
148-
kvm->arch.hpte_setup_done = 1;
148+
kvm->arch.mmu_ready = 1;
149149
goto out;
150150
}
151151
}
@@ -1533,15 +1533,15 @@ long kvm_vm_ioctl_resize_hpt_commit(struct kvm *kvm,
15331533

15341534
/* This shouldn't be possible */
15351535
ret = -EIO;
1536-
if (WARN_ON(!kvm->arch.hpte_setup_done))
1536+
if (WARN_ON(!kvm->arch.mmu_ready))
15371537
goto out_no_hpt;
15381538

15391539
/* Stop VCPUs from running while we mess with the HPT */
1540-
kvm->arch.hpte_setup_done = 0;
1540+
kvm->arch.mmu_ready = 0;
15411541
smp_mb();
15421542

15431543
/* Boot all CPUs out of the guest so they re-read
1544-
* hpte_setup_done */
1544+
* mmu_ready */
15451545
on_each_cpu(resize_hpt_boot_vcpu, NULL, 1);
15461546

15471547
ret = -ENXIO;
@@ -1564,7 +1564,7 @@ long kvm_vm_ioctl_resize_hpt_commit(struct kvm *kvm,
15641564

15651565
out:
15661566
/* Let VCPUs run again */
1567-
kvm->arch.hpte_setup_done = 1;
1567+
kvm->arch.mmu_ready = 1;
15681568
smp_mb();
15691569
out_no_hpt:
15701570
resize_hpt_release(kvm, resize);
@@ -1802,7 +1802,7 @@ static ssize_t kvm_htab_write(struct file *file, const char __user *buf,
18021802
unsigned long tmp[2];
18031803
ssize_t nb;
18041804
long int err, ret;
1805-
int hpte_setup;
1805+
int mmu_ready;
18061806

18071807
if (!access_ok(VERIFY_READ, buf, count))
18081808
return -EFAULT;
@@ -1811,13 +1811,13 @@ static ssize_t kvm_htab_write(struct file *file, const char __user *buf,
18111811

18121812
/* lock out vcpus from running while we're doing this */
18131813
mutex_lock(&kvm->lock);
1814-
hpte_setup = kvm->arch.hpte_setup_done;
1815-
if (hpte_setup) {
1816-
kvm->arch.hpte_setup_done = 0; /* temporarily */
1817-
/* order hpte_setup_done vs. vcpus_running */
1814+
mmu_ready = kvm->arch.mmu_ready;
1815+
if (mmu_ready) {
1816+
kvm->arch.mmu_ready = 0; /* temporarily */
1817+
/* order mmu_ready vs. vcpus_running */
18181818
smp_mb();
18191819
if (atomic_read(&kvm->arch.vcpus_running)) {
1820-
kvm->arch.hpte_setup_done = 1;
1820+
kvm->arch.mmu_ready = 1;
18211821
mutex_unlock(&kvm->lock);
18221822
return -EBUSY;
18231823
}
@@ -1870,7 +1870,7 @@ static ssize_t kvm_htab_write(struct file *file, const char __user *buf,
18701870
"r=%lx\n", ret, i, v, r);
18711871
goto out;
18721872
}
1873-
if (!hpte_setup && is_vrma_hpte(v)) {
1873+
if (!mmu_ready && is_vrma_hpte(v)) {
18741874
unsigned long psize = hpte_base_page_size(v, r);
18751875
unsigned long senc = slb_pgsize_encoding(psize);
18761876
unsigned long lpcr;
@@ -1879,7 +1879,7 @@ static ssize_t kvm_htab_write(struct file *file, const char __user *buf,
18791879
(VRMA_VSID << SLB_VSID_SHIFT_1T);
18801880
lpcr = senc << (LPCR_VRMASD_SH - 4);
18811881
kvmppc_update_lpcr(kvm, lpcr, LPCR_VRMASD);
1882-
hpte_setup = 1;
1882+
mmu_ready = 1;
18831883
}
18841884
++i;
18851885
hptp += 2;
@@ -1895,9 +1895,9 @@ static ssize_t kvm_htab_write(struct file *file, const char __user *buf,
18951895
}
18961896

18971897
out:
1898-
/* Order HPTE updates vs. hpte_setup_done */
1898+
/* Order HPTE updates vs. mmu_ready */
18991899
smp_wmb();
1900-
kvm->arch.hpte_setup_done = hpte_setup;
1900+
kvm->arch.mmu_ready = mmu_ready;
19011901
mutex_unlock(&kvm->lock);
19021902

19031903
if (err)

arch/powerpc/kvm/book3s_hv.c

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ MODULE_PARM_DESC(h_ipi_redirect, "Redirect H_IPI wakeup to a free host core");
115115

116116
static void kvmppc_end_cede(struct kvm_vcpu *vcpu);
117117
static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu);
118+
static void kvmppc_setup_partition_table(struct kvm *kvm);
118119

119120
static inline struct kvm_vcpu *next_runnable_thread(struct kvmppc_vcore *vc,
120121
int *ip)
@@ -3198,6 +3199,7 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu)
31983199
unsigned long ebb_regs[3] = {}; /* shut up GCC */
31993200
unsigned long user_tar = 0;
32003201
unsigned int user_vrsave;
3202+
struct kvm *kvm;
32013203

32023204
if (!vcpu->arch.sane) {
32033205
run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
@@ -3235,13 +3237,25 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu)
32353237
return -EINTR;
32363238
}
32373239

3238-
atomic_inc(&vcpu->kvm->arch.vcpus_running);
3239-
/* Order vcpus_running vs. hpte_setup_done, see kvmppc_alloc_reset_hpt */
3240+
kvm = vcpu->kvm;
3241+
atomic_inc(&kvm->arch.vcpus_running);
3242+
/* Order vcpus_running vs. mmu_ready, see kvmppc_alloc_reset_hpt */
32403243
smp_mb();
32413244

3242-
/* On the first time here, set up HTAB and VRMA */
3243-
if (!kvm_is_radix(vcpu->kvm) && !vcpu->kvm->arch.hpte_setup_done) {
3244-
r = kvmppc_hv_setup_htab_rma(vcpu);
3245+
/* On the first time here, set up MMU if necessary */
3246+
if (!vcpu->kvm->arch.mmu_ready) {
3247+
mutex_lock(&kvm->lock);
3248+
r = 0;
3249+
if (!kvm->arch.mmu_ready) {
3250+
if (!kvm_is_radix(vcpu->kvm))
3251+
r = kvmppc_hv_setup_htab_rma(vcpu);
3252+
if (!r) {
3253+
if (cpu_has_feature(CPU_FTR_ARCH_300))
3254+
kvmppc_setup_partition_table(kvm);
3255+
kvm->arch.mmu_ready = 1;
3256+
}
3257+
}
3258+
mutex_unlock(&kvm->lock);
32453259
if (r)
32463260
goto out;
32473261
}
@@ -3530,6 +3544,10 @@ static void kvmppc_setup_partition_table(struct kvm *kvm)
35303544
mmu_partition_table_set_entry(kvm->arch.lpid, dw0, dw1);
35313545
}
35323546

3547+
/*
3548+
* Set up HPT (hashed page table) and RMA (real-mode area).
3549+
* Must be called with kvm->lock held.
3550+
*/
35333551
static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu)
35343552
{
35353553
int err = 0;
@@ -3541,10 +3559,6 @@ static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu)
35413559
unsigned long psize, porder;
35423560
int srcu_idx;
35433561

3544-
mutex_lock(&kvm->lock);
3545-
if (kvm->arch.hpte_setup_done)
3546-
goto out; /* another vcpu beat us to it */
3547-
35483562
/* Allocate hashed page table (if not done already) and reset it */
35493563
if (!kvm->arch.hpt.virt) {
35503564
int order = KVM_DEFAULT_HPT_ORDER;
@@ -3603,18 +3617,14 @@ static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu)
36033617
/* the -4 is to account for senc values starting at 0x10 */
36043618
lpcr = senc << (LPCR_VRMASD_SH - 4);
36053619
kvmppc_update_lpcr(kvm, lpcr, LPCR_VRMASD);
3606-
} else {
3607-
kvmppc_setup_partition_table(kvm);
36083620
}
36093621

3610-
/* Order updates to kvm->arch.lpcr etc. vs. hpte_setup_done */
3622+
/* Order updates to kvm->arch.lpcr etc. vs. mmu_ready */
36113623
smp_wmb();
3612-
kvm->arch.hpte_setup_done = 1;
36133624
err = 0;
36143625
out_srcu:
36153626
srcu_read_unlock(&kvm->srcu, srcu_idx);
36163627
out:
3617-
mutex_unlock(&kvm->lock);
36183628
return err;
36193629

36203630
up_out:
@@ -3769,6 +3779,7 @@ static int kvmppc_core_init_vm_hv(struct kvm *kvm)
37693779
*/
37703780
if (radix_enabled()) {
37713781
kvm->arch.radix = 1;
3782+
kvm->arch.mmu_ready = 1;
37723783
lpcr &= ~LPCR_VPM1;
37733784
lpcr |= LPCR_UPRT | LPCR_GTSE | LPCR_HR;
37743785
ret = kvmppc_init_vm_radix(kvm);

0 commit comments

Comments
 (0)