OSDN Git Service

Merge branch 'kvm-ppc-next' of git://github.com/agraf/linux-2.6 into queue
authorGleb Natapov <gleb@redhat.com>
Fri, 30 Aug 2013 12:33:11 +0000 (15:33 +0300)
committerGleb Natapov <gleb@redhat.com>
Fri, 30 Aug 2013 12:33:11 +0000 (15:33 +0300)
* 'kvm-ppc-next' of git://github.com/agraf/linux-2.6:
  KVM: PPC: Book3S PR: Rework kvmppc_mmu_book3s_64_xlate()
  KVM: PPC: Book3S PR: Make instruction fetch fallback work for system calls
  KVM: PPC: Book3S PR: Don't corrupt guest state when kernel uses VMX
  KVM: PPC: Book3S: Fix compile error in XICS emulation
  KVM: PPC: Book3S PR: return appropriate error when allocation fails
  arch: powerpc: kvm: add signed type cast for comparation
  powerpc/kvm: Copy the pvr value after memset
  KVM: PPC: Book3S PR: Load up SPRG3 register with guest value on guest entry
  kvm/ppc/booke: Don't call kvm_guest_enter twice
  kvm/ppc: Call trace_hardirqs_on before entry
  KVM: PPC: Book3S HV: Allow negative offsets to real-mode hcall handlers
  KVM: PPC: Book3S HV: Correct tlbie usage
  powerpc/kvm: Use 256K chunk to track both RMA and hash page table allocation.
  powerpc/kvm: Contiguous memory allocator based RMA allocation
  powerpc/kvm: Contiguous memory allocator based hash page table allocation
  KVM: PPC: Book3S: Ignore DABR register
  mm/cma: Move dma contiguous changes into a seperate config

1  2 
arch/powerpc/kvm/book3s_64_mmu_hv.c
arch/powerpc/kvm/book3s_hv.c

@@@ -37,6 -37,8 +37,8 @@@
  #include <asm/ppc-opcode.h>
  #include <asm/cputable.h>
  
+ #include "book3s_hv_cma.h"
  /* POWER7 has 10-bit LPIDs, PPC970 has 6-bit LPIDs */
  #define MAX_LPID_970  63
  
@@@ -52,8 -54,8 +54,8 @@@ long kvmppc_alloc_hpt(struct kvm *kvm, 
  {
        unsigned long hpt;
        struct revmap_entry *rev;
-       struct kvmppc_linear_info *li;
-       long order = kvm_hpt_order;
+       struct page *page = NULL;
+       long order = KVM_DEFAULT_HPT_ORDER;
  
        if (htab_orderp) {
                order = *htab_orderp;
                        order = PPC_MIN_HPT_ORDER;
        }
  
+       kvm->arch.hpt_cma_alloc = 0;
        /*
-        * If the user wants a different size from default,
         * try first to allocate it from the kernel page allocator.
+        * We keep the CMA reserved for failed allocation.
         */
-       hpt = 0;
-       if (order != kvm_hpt_order) {
-               hpt = __get_free_pages(GFP_KERNEL|__GFP_ZERO|__GFP_REPEAT|
-                                      __GFP_NOWARN, order - PAGE_SHIFT);
-               if (!hpt)
-                       --order;
-       }
+       hpt = __get_free_pages(GFP_KERNEL | __GFP_ZERO | __GFP_REPEAT |
+                              __GFP_NOWARN, order - PAGE_SHIFT);
  
        /* Next try to allocate from the preallocated pool */
        if (!hpt) {
-               li = kvm_alloc_hpt();
-               if (li) {
-                       hpt = (ulong)li->base_virt;
-                       kvm->arch.hpt_li = li;
-                       order = kvm_hpt_order;
-               }
+               VM_BUG_ON(order < KVM_CMA_CHUNK_ORDER);
+               page = kvm_alloc_hpt(1 << (order - PAGE_SHIFT));
+               if (page) {
+                       hpt = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
+                       kvm->arch.hpt_cma_alloc = 1;
+               } else
+                       --order;
        }
  
        /* Lastly try successively smaller sizes from the page allocator */
        return 0;
  
   out_freehpt:
-       if (kvm->arch.hpt_li)
-               kvm_release_hpt(kvm->arch.hpt_li);
+       if (kvm->arch.hpt_cma_alloc)
+               kvm_release_hpt(page, 1 << (order - PAGE_SHIFT));
        else
                free_pages(hpt, order - PAGE_SHIFT);
        return -ENOMEM;
@@@ -165,8 -164,9 +164,9 @@@ void kvmppc_free_hpt(struct kvm *kvm
  {
        kvmppc_free_lpid(kvm->arch.lpid);
        vfree(kvm->arch.revmap);
-       if (kvm->arch.hpt_li)
-               kvm_release_hpt(kvm->arch.hpt_li);
+       if (kvm->arch.hpt_cma_alloc)
+               kvm_release_hpt(virt_to_page(kvm->arch.hpt_virt),
+                               1 << (kvm->arch.hpt_order - PAGE_SHIFT));
        else
                free_pages(kvm->arch.hpt_virt,
                           kvm->arch.hpt_order - PAGE_SHIFT);
@@@ -1579,7 -1579,7 +1579,7 @@@ int kvm_vm_ioctl_get_htab_fd(struct kv
        ctx->first_pass = 1;
  
        rwflag = (ghf->flags & KVM_GET_HTAB_WRITE) ? O_WRONLY : O_RDONLY;
 -      ret = anon_inode_getfd("kvm-htab", &kvm_htab_fops, ctx, rwflag);
 +      ret = anon_inode_getfd("kvm-htab", &kvm_htab_fops, ctx, rwflag | O_CLOEXEC);
        if (ret < 0) {
                kvm_put_kvm(kvm);
                return ret;
@@@ -680,13 -680,12 +680,12 @@@ static int kvmppc_handle_exit(struct kv
  }
  
  int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
-                                   struct kvm_sregs *sregs)
+                                 struct kvm_sregs *sregs)
  {
        int i;
  
-       sregs->pvr = vcpu->arch.pvr;
        memset(sregs, 0, sizeof(struct kvm_sregs));
+       sregs->pvr = vcpu->arch.pvr;
        for (i = 0; i < vcpu->arch.slb_max; i++) {
                sregs->u.s.ppc64.slb[i].slbe = vcpu->arch.slb[i].orige;
                sregs->u.s.ppc64.slb[i].slbv = vcpu->arch.slb[i].origv;
  }
  
  int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
-                                   struct kvm_sregs *sregs)
+                                 struct kvm_sregs *sregs)
  {
        int i, j;
  
@@@ -1511,10 -1510,10 +1510,10 @@@ static inline int lpcr_rmls(unsigned lo
  
  static int kvm_rma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
  {
-       struct kvmppc_linear_info *ri = vma->vm_file->private_data;
        struct page *page;
+       struct kvm_rma_info *ri = vma->vm_file->private_data;
  
-       if (vmf->pgoff >= ri->npages)
+       if (vmf->pgoff >= kvm_rma_pages)
                return VM_FAULT_SIGBUS;
  
        page = pfn_to_page(ri->base_pfn + vmf->pgoff);
@@@ -1536,7 -1535,7 +1535,7 @@@ static int kvm_rma_mmap(struct file *fi
  
  static int kvm_rma_release(struct inode *inode, struct file *filp)
  {
-       struct kvmppc_linear_info *ri = filp->private_data;
+       struct kvm_rma_info *ri = filp->private_data;
  
        kvm_release_rma(ri);
        return 0;
@@@ -1549,18 -1548,27 +1548,27 @@@ static const struct file_operations kvm
  
  long kvm_vm_ioctl_allocate_rma(struct kvm *kvm, struct kvm_allocate_rma *ret)
  {
-       struct kvmppc_linear_info *ri;
        long fd;
+       struct kvm_rma_info *ri;
+       /*
+        * Only do this on PPC970 in HV mode
+        */
+       if (!cpu_has_feature(CPU_FTR_HVMODE) ||
+           !cpu_has_feature(CPU_FTR_ARCH_201))
+               return -EINVAL;
+       if (!kvm_rma_pages)
+               return -EINVAL;
  
        ri = kvm_alloc_rma();
        if (!ri)
                return -ENOMEM;
  
 -      fd = anon_inode_getfd("kvm-rma", &kvm_rma_fops, ri, O_RDWR);
 +      fd = anon_inode_getfd("kvm-rma", &kvm_rma_fops, ri, O_RDWR | O_CLOEXEC);
        if (fd < 0)
                kvm_release_rma(ri);
  
-       ret->rma_size = ri->npages << PAGE_SHIFT;
+       ret->rma_size = kvm_rma_pages << PAGE_SHIFT;
        return fd;
  }
  
@@@ -1725,7 -1733,7 +1733,7 @@@ static int kvmppc_hv_setup_htab_rma(str
  {
        int err = 0;
        struct kvm *kvm = vcpu->kvm;
-       struct kvmppc_linear_info *ri = NULL;
+       struct kvm_rma_info *ri = NULL;
        unsigned long hva;
        struct kvm_memory_slot *memslot;
        struct vm_area_struct *vma;
  
        } else {
                /* Set up to use an RMO region */
-               rma_size = ri->npages;
+               rma_size = kvm_rma_pages;
                if (rma_size > memslot->npages)
                        rma_size = memslot->npages;
                rma_size <<= PAGE_SHIFT;
                rmls = lpcr_rmls(rma_size);
                err = -EINVAL;
-               if (rmls < 0) {
+               if ((long)rmls < 0) {
                        pr_err("KVM: Can't use RMA of 0x%lx bytes\n", rma_size);
                        goto out_srcu;
                }
                        /* POWER7 */
                        lpcr &= ~(LPCR_VPM0 | LPCR_VRMA_L);
                        lpcr |= rmls << LPCR_RMLS_SH;
-                       kvm->arch.rmor = kvm->arch.rma->base_pfn << PAGE_SHIFT;
+                       kvm->arch.rmor = ri->base_pfn << PAGE_SHIFT;
                }
                kvm->arch.lpcr = lpcr;
                pr_info("KVM: Using RMO at %lx size %lx (LPCR = %lx)\n",
                        ri->base_pfn << PAGE_SHIFT, rma_size, lpcr);
  
                /* Initialize phys addrs of pages in RMO */
-               npages = ri->npages;
+               npages = kvm_rma_pages;
                porder = __ilog2(npages);
                physp = memslot->arch.slot_phys;
                if (physp) {
@@@ -1874,7 -1882,7 +1882,7 @@@ int kvmppc_core_init_vm(struct kvm *kvm
        /* Allocate the guest's logical partition ID */
  
        lpid = kvmppc_alloc_lpid();
-       if (lpid < 0)
+       if ((long)lpid < 0)
                return -ENOMEM;
        kvm->arch.lpid = lpid;