Skip to content

Commit f98a8bf

Browse files
dgibsonpaulusmack
authored andcommitted
KVM: PPC: Book3S HV: Allow KVM_PPC_ALLOCATE_HTAB ioctl() to change HPT size
The KVM_PPC_ALLOCATE_HTAB ioctl() is used to set the size of hashed page table (HPT) that userspace expects a guest VM to have, and is also used to clear that HPT when necessary (e.g. guest reboot). At present, once the ioctl() is called for the first time, the HPT size can never be changed thereafter - it will be cleared but always sized as from the first call. With upcoming HPT resize implementation, we're going to need to allow userspace to resize the HPT at reset (to change it back to the default size if the guest changed it). So, we need to allow this ioctl() to change the HPT size. This patch also updates Documentation/virtual/kvm/api.txt to reflect the new behaviour. In fact the documentation was already slightly incorrect since 572abd5 "KVM: PPC: Book3S HV: Don't fall back to smaller HPT size in allocation ioctl" Signed-off-by: David Gibson <[email protected]> Signed-off-by: Paul Mackerras <[email protected]>
1 parent aae0777 commit f98a8bf

File tree

4 files changed

+26
-24
lines changed

4 files changed

+26
-24
lines changed

Documentation/virtual/kvm/api.txt

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2443,18 +2443,20 @@ are, it will do nothing and return an EBUSY error.
24432443
The parameter is a pointer to a 32-bit unsigned integer variable
24442444
containing the order (log base 2) of the desired size of the hash
24452445
table, which must be between 18 and 46. On successful return from the
2446-
ioctl, it will have been updated with the order of the hash table that
2447-
was allocated.
2446+
ioctl, the value will not be changed by the kernel.
24482447

24492448
If no hash table has been allocated when any vcpu is asked to run
24502449
(with the KVM_RUN ioctl), the host kernel will allocate a
24512450
default-sized hash table (16 MB).
24522451

24532452
If this ioctl is called when a hash table has already been allocated,
2454-
the kernel will clear out the existing hash table (zero all HPTEs) and
2455-
return the hash table order in the parameter. (If the guest is using
2456-
the virtualized real-mode area (VRMA) facility, the kernel will
2457-
re-create the VMRA HPTEs on the next KVM_RUN of any vcpu.)
2453+
with a different order from the existing hash table, the existing hash
2454+
table will be freed and a new one allocated. If this is ioctl is
2455+
called when a hash table has already been allocated of the same order
2456+
as specified, the kernel will clear out the existing hash table (zero
2457+
all HPTEs). In either case, if the guest is using the virtualized
2458+
real-mode area (VRMA) facility, the kernel will re-create the VMRA
2459+
HPTEs on the next KVM_RUN of any vcpu.
24582460

24592461
4.77 KVM_S390_INTERRUPT
24602462

arch/powerpc/include/asm/kvm_ppc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ extern void kvmppc_map_magic(struct kvm_vcpu *vcpu);
157157

158158
extern int kvmppc_allocate_hpt(struct kvm_hpt_info *info, u32 order);
159159
extern void kvmppc_set_hpt(struct kvm *kvm, struct kvm_hpt_info *info);
160-
extern long kvmppc_alloc_reset_hpt(struct kvm *kvm, u32 *htab_orderp);
160+
extern long kvmppc_alloc_reset_hpt(struct kvm *kvm, int order);
161161
extern void kvmppc_free_hpt(struct kvm_hpt_info *info);
162162
extern long kvmppc_prepare_vrma(struct kvm *kvm,
163163
struct kvm_userspace_memory_region *mem);

arch/powerpc/kvm/book3s_64_mmu_hv.c

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,10 @@ void kvmppc_set_hpt(struct kvm *kvm, struct kvm_hpt_info *info)
102102
info->virt, (long)info->order, kvm->arch.lpid);
103103
}
104104

105-
long kvmppc_alloc_reset_hpt(struct kvm *kvm, u32 *htab_orderp)
105+
long kvmppc_alloc_reset_hpt(struct kvm *kvm, int order)
106106
{
107107
long err = -EBUSY;
108-
long order;
108+
struct kvm_hpt_info info;
109109

110110
if (kvm_is_radix(kvm))
111111
return -EINVAL;
@@ -120,8 +120,9 @@ long kvmppc_alloc_reset_hpt(struct kvm *kvm, u32 *htab_orderp)
120120
goto out;
121121
}
122122
}
123-
if (kvm->arch.hpt.virt) {
124-
order = kvm->arch.hpt.order;
123+
if (kvm->arch.hpt.order == order) {
124+
/* We already have a suitable HPT */
125+
125126
/* Set the entire HPT to 0, i.e. invalid HPTEs */
126127
memset((void *)kvm->arch.hpt.virt, 0, 1ul << order);
127128
/*
@@ -130,17 +131,19 @@ long kvmppc_alloc_reset_hpt(struct kvm *kvm, u32 *htab_orderp)
130131
kvmppc_rmap_reset(kvm);
131132
/* Ensure that each vcpu will flush its TLB on next entry. */
132133
cpumask_setall(&kvm->arch.need_tlb_flush);
133-
*htab_orderp = order;
134134
err = 0;
135-
} else {
136-
struct kvm_hpt_info info;
137-
138-
err = kvmppc_allocate_hpt(&info, *htab_orderp);
139-
if (err < 0)
140-
goto out;
141-
kvmppc_set_hpt(kvm, &info);
135+
goto out;
142136
}
143-
out:
137+
138+
if (kvm->arch.hpt.virt)
139+
kvmppc_free_hpt(&kvm->arch.hpt);
140+
141+
err = kvmppc_allocate_hpt(&info, order);
142+
if (err < 0)
143+
goto out;
144+
kvmppc_set_hpt(kvm, &info);
145+
146+
out:
144147
mutex_unlock(&kvm->lock);
145148
return err;
146149
}

arch/powerpc/kvm/book3s_hv.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3704,12 +3704,9 @@ static long kvm_arch_vm_ioctl_hv(struct file *filp,
37043704
r = -EFAULT;
37053705
if (get_user(htab_order, (u32 __user *)argp))
37063706
break;
3707-
r = kvmppc_alloc_reset_hpt(kvm, &htab_order);
3707+
r = kvmppc_alloc_reset_hpt(kvm, htab_order);
37083708
if (r)
37093709
break;
3710-
r = -EFAULT;
3711-
if (put_user(htab_order, (u32 __user *)argp))
3712-
break;
37133710
r = 0;
37143711
break;
37153712
}

0 commit comments

Comments
 (0)