On Mon, Dec 12, 2011 at 10:05 AM, Avi Kivity <a...@redhat.com> wrote:
> On 12/11/2011 12:25 PM, Christoffer Dall wrote:
>> From: Christoffer Dall <cd...@cs.columbia.edu>
>>
>> Handles the guest faults in KVM by mapping in corresponding user pages
>> in the 2nd stage page tables.
>>
>> Introduces new ARM-specific kernel memory types, PAGE_KVM_GUEST and
>> pgprot_guest variables used to map 2nd stage memory for KVM guests.
>>
>>
>> +static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
>> +                       gfn_t gfn, struct kvm_memory_slot *memslot)
>> +{
>> +     pfn_t pfn;
>> +     pgd_t *pgd;
>> +     pud_t *pud;
>> +     pmd_t *pmd;
>> +     pte_t *pte, new_pte;
>> +
>> +     pfn = gfn_to_pfn(vcpu->kvm, gfn);
>> +
>> +     if (is_error_pfn(pfn)) {
>
> put_page()
>

ack

>> +             kvm_err(-EFAULT, "Guest gfn %u (0x%08lx) does not have "
>> +                             "corresponding host mapping",
>> +                             gfn, gfn << PAGE_SHIFT);
>> +             return -EFAULT;
>> +     }
>> +
>> +     /* Create 2nd stage page table mapping - Level 1 */
>> +     pgd = vcpu->kvm->arch.pgd + pgd_index(fault_ipa);
>> +     pud = pud_offset(pgd, fault_ipa);
>> +     if (pud_none(*pud)) {
>> +             pmd = pmd_alloc_one(NULL, fault_ipa);
>> +             if (!pmd) {
>> +                     kvm_err(-ENOMEM, "Cannot allocate 2nd stage pmd");
>
> put_page()
>

ack

>> +                     return -ENOMEM;
>> +             }
>> +             pud_populate(NULL, pud, pmd);
>> +             pmd += pmd_index(fault_ipa);
>> +     } else
>> +             pmd = pmd_offset(pud, fault_ipa);
>> +
>> +     /* Create 2nd stage page table mapping - Level 2 */
>> +     if (pmd_none(*pmd)) {
>> +             pte = pte_alloc_one_kernel(NULL, fault_ipa);
>> +             if (!pte) {
>> +                     kvm_err(-ENOMEM, "Cannot allocate 2nd stage pte");
>> +                     return -ENOMEM;
>> +             }
>> +             pmd_populate_kernel(NULL, pmd, pte);
>> +             pte += pte_index(fault_ipa);
>> +     } else
>> +             pte = pte_offset_kernel(pmd, fault_ipa);
>> +
>> +     /* Create 2nd stage page table mapping - Level 3 */
>> +     new_pte = pfn_pte(pfn, PAGE_KVM_GUEST);
>> +     set_pte_ext(pte, new_pte, 0);
>
>
> With LPAE and 40-bit addresses, a guest can cause 2GBs worth of page
> tables to be pinned in host memory; this can be used as a denial of
> service attack.  x86 handles this by having a shrinker that can
> dynamically free page tables, see mmu_shrinker.
>
> An alternative way may be to impose RLIMIT_AS on the sum of a guest's
> memory slots; though I prefer having a shrinker.
>
> A bigger problem is that you pin all memory; what are the plans wrt mmu
> notifiers?
>
hmm, I have no plans (yet).

I haven't looked into neither MMU shrinker nor MMU notifier.

As I see it, the problems of consuming too much memory just for the
page tables should be solved by somehow reclaiming pages used for the
second stage mappings, the question is just which mappings are the
most efficient to reclaim.

The other problem, the actual guest memory consuming too much memory,
I assumed this limit would be set by the user when creating his/her
VM, or can we do something smarter? (again, forgive my ignorance).
What is the alternative to pinning actual guest pages - as far as I
know it's not common to have swap space on ARM architectures, but I
could be wrong.
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to