aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/x86.c
diff options
context:
space:
mode:
authorTakuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>2012-02-07 23:02:18 -0500
committerAvi Kivity <avi@redhat.com>2012-03-08 07:10:22 -0500
commitdb3fe4eb45f3555d91a7124e18cf3a2f2a30eb90 (patch)
tree5d294feef8f6281d4cd6c67180e0514c74e87079 /arch/x86/kvm/x86.c
parent189a2f7b24677deced3d2a9803969ba69f4b75f6 (diff)
KVM: Introduce kvm_memory_slot::arch and move lpage_info into it
Some members of kvm_memory_slot are not used by every architecture. This patch is the first step to make this difference clear by introducing kvm_memory_slot::arch; lpage_info is moved into it. Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r--arch/x86/kvm/x86.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 3df0b7a140b..ca74c1dadf3 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -6239,6 +6239,65 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
6239 put_page(kvm->arch.ept_identity_pagetable); 6239 put_page(kvm->arch.ept_identity_pagetable);
6240} 6240}
6241 6241
6242void kvm_arch_free_memslot(struct kvm_memory_slot *free,
6243 struct kvm_memory_slot *dont)
6244{
6245 int i;
6246
6247 for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) {
6248 if (!dont || free->arch.lpage_info[i] != dont->arch.lpage_info[i]) {
6249 vfree(free->arch.lpage_info[i]);
6250 free->arch.lpage_info[i] = NULL;
6251 }
6252 }
6253}
6254
6255int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages)
6256{
6257 int i;
6258
6259 for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) {
6260 unsigned long ugfn;
6261 int lpages;
6262 int level = i + 2;
6263
6264 lpages = gfn_to_index(slot->base_gfn + npages - 1,
6265 slot->base_gfn, level) + 1;
6266
6267 slot->arch.lpage_info[i] =
6268 vzalloc(lpages * sizeof(*slot->arch.lpage_info[i]));
6269 if (!slot->arch.lpage_info[i])
6270 goto out_free;
6271
6272 if (slot->base_gfn & (KVM_PAGES_PER_HPAGE(level) - 1))
6273 slot->arch.lpage_info[i][0].write_count = 1;
6274 if ((slot->base_gfn + npages) & (KVM_PAGES_PER_HPAGE(level) - 1))
6275 slot->arch.lpage_info[i][lpages - 1].write_count = 1;
6276 ugfn = slot->userspace_addr >> PAGE_SHIFT;
6277 /*
6278 * If the gfn and userspace address are not aligned wrt each
6279 * other, or if explicitly asked to, disable large page
6280 * support for this slot
6281 */
6282 if ((slot->base_gfn ^ ugfn) & (KVM_PAGES_PER_HPAGE(level) - 1) ||
6283 !kvm_largepages_enabled()) {
6284 unsigned long j;
6285
6286 for (j = 0; j < lpages; ++j)
6287 slot->arch.lpage_info[i][j].write_count = 1;
6288 }
6289 }
6290
6291 return 0;
6292
6293out_free:
6294 for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) {
6295 vfree(slot->arch.lpage_info[i]);
6296 slot->arch.lpage_info[i] = NULL;
6297 }
6298 return -ENOMEM;
6299}
6300
6242int kvm_arch_prepare_memory_region(struct kvm *kvm, 6301int kvm_arch_prepare_memory_region(struct kvm *kvm,
6243 struct kvm_memory_slot *memslot, 6302 struct kvm_memory_slot *memslot,
6244 struct kvm_memory_slot old, 6303 struct kvm_memory_slot old,