On 01.07.2011, at 20:37, Dave Hansen wrote:

> On Wed, 2011-06-29 at 20:21 +1000, Paul Mackerras wrote: 
>> +struct kvmppc_pginfo {
>> +    unsigned long pfn;
>> +    atomic_t refcnt;
>> +};
> 
> I only see this refcnt inc'd in one spot and never decremented or read.
> Is the refcnt just the number of hptes we have for this particular page
> at the moment?  
> 
>> +long kvmppc_alloc_hpt(struct kvm *kvm)
>> +{
>> +    unsigned long hpt;
>> +    unsigned long lpid;
>> +
>> +    hpt = __get_free_pages(GFP_KERNEL|__GFP_ZERO|__GFP_REPEAT|__GFP_NOWARN,
>> +                           HPT_ORDER - PAGE_SHIFT);
>> +    if (!hpt) {
>> +            pr_err("kvm_alloc_hpt: Couldn't alloc HPT\n");
>> +            return -ENOMEM;
>> +    }
>> +    kvm->arch.hpt_virt = hpt;
>> +
>> +    do {
>> +            lpid = find_first_zero_bit(lpid_inuse, NR_LPIDS);
>> +            if (lpid >= NR_LPIDS) {
>> +                    pr_err("kvm_alloc_hpt: No LPIDs free\n");
>> +                    free_pages(hpt, HPT_ORDER - PAGE_SHIFT);
>> +                    return -ENOMEM;
>> +            }
>> +    } while (test_and_set_bit(lpid, lpid_inuse));
>> +
>> +    kvm->arch.sdr1 = __pa(hpt) | (HPT_ORDER - 18);
>> +    kvm->arch.lpid = lpid;
>> +    kvm->arch.host_sdr1 = mfspr(SPRN_SDR1);
>> +    kvm->arch.host_lpid = mfspr(SPRN_LPID);
>> +    kvm->arch.host_lpcr = mfspr(SPRN_LPCR);
>> +
>> +    pr_info("KVM guest htab at %lx, LPID %lx\n", hpt, lpid);
>> +    return 0;
>> +}
> 
>> +static unsigned long user_page_size(unsigned long addr)
>> +{
>> +    struct vm_area_struct *vma;
>> +    unsigned long size = PAGE_SIZE;
>> +
>> +    down_read(&current->mm->mmap_sem);
>> +    vma = find_vma(current->mm, addr);
>> +    if (vma)
>> +            size = vma_kernel_pagesize(vma);
>> +    up_read(&current->mm->mmap_sem);
>> +    return size;
>> +}
> 
> That one looks pretty arch-independent and like it could use some
> consolidation with: virt/kvm/kvm_main.c::kvm_host_page_size()

Yep, I'd deem that a cleanup for later though. Good point however! We have 
similar code in e500 kvm today.

> 
>> +void kvmppc_map_vrma(struct kvm *kvm, struct kvm_userspace_memory_region 
>> *mem)
>> +{
>> +    unsigned long i;
>> +    unsigned long npages = kvm->arch.ram_npages;
>> +    unsigned long pfn;
>> +    unsigned long *hpte;
>> +    unsigned long hash;
>> +    struct kvmppc_pginfo *pginfo = kvm->arch.ram_pginfo;
>> +
>> +    if (!pginfo)
>> +            return;
>> +
>> +    /* VRMA can't be > 1TB */
>> +    if (npages > 1ul << (40 - kvm->arch.ram_porder))
>> +            npages = 1ul << (40 - kvm->arch.ram_porder);
> 
> Is that because it can only be a single segment?  Does that mean that we
> can't ever have guests larger than 1TB?  Or just that they have to live
> with 1TB until they get their own page tables up?

The VRMA is only important in real mode, so this part looks good. The RMA is 
usually a lot smaller than 1TB ;).


Alex

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Reply via email to