diff options
-rw-r--r-- | arch/arm/include/asm/kvm_mmu.h | 31 | ||||
-rw-r--r-- | arch/arm/include/asm/pgtable.h | 2 | ||||
-rw-r--r-- | arch/arm/kvm/arm.c | 5 | ||||
-rw-r--r-- | arch/arm/kvm/interrupts_head.S | 7 | ||||
-rw-r--r-- | arch/arm/kvm/mmu.c | 235 | ||||
-rw-r--r-- | arch/arm64/include/asm/kvm_mmu.h | 127 | ||||
-rw-r--r-- | arch/arm64/include/asm/pgtable.h | 2 | ||||
-rw-r--r-- | arch/arm64/kvm/vgic-v2-switch.S | 12 | ||||
-rw-r--r-- | include/kvm/arm_vgic.h | 12 | ||||
-rw-r--r-- | virt/kvm/arm/vgic-v2.c | 24 | ||||
-rw-r--r-- | virt/kvm/arm/vgic.c | 21 |
11 files changed, 392 insertions, 86 deletions
diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h index 3f688b458143..acb0d5712716 100644 --- a/arch/arm/include/asm/kvm_mmu.h +++ b/arch/arm/include/asm/kvm_mmu.h | |||
@@ -37,6 +37,11 @@ | |||
37 | */ | 37 | */ |
38 | #define TRAMPOLINE_VA UL(CONFIG_VECTORS_BASE) | 38 | #define TRAMPOLINE_VA UL(CONFIG_VECTORS_BASE) |
39 | 39 | ||
40 | /* | ||
41 | * KVM_MMU_CACHE_MIN_PAGES is the number of stage2 page table translation levels. | ||
42 | */ | ||
43 | #define KVM_MMU_CACHE_MIN_PAGES 2 | ||
44 | |||
40 | #ifndef __ASSEMBLY__ | 45 | #ifndef __ASSEMBLY__ |
41 | 46 | ||
42 | #include <asm/cacheflush.h> | 47 | #include <asm/cacheflush.h> |
@@ -50,7 +55,7 @@ void free_hyp_pgds(void); | |||
50 | int kvm_alloc_stage2_pgd(struct kvm *kvm); | 55 | int kvm_alloc_stage2_pgd(struct kvm *kvm); |
51 | void kvm_free_stage2_pgd(struct kvm *kvm); | 56 | void kvm_free_stage2_pgd(struct kvm *kvm); |
52 | int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa, | 57 | int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa, |
53 | phys_addr_t pa, unsigned long size); | 58 | phys_addr_t pa, unsigned long size, bool writable); |
54 | 59 | ||
55 | int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run); | 60 | int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run); |
56 | 61 | ||
@@ -83,6 +88,11 @@ static inline void kvm_clean_pgd(pgd_t *pgd) | |||
83 | clean_dcache_area(pgd, PTRS_PER_S2_PGD * sizeof(pgd_t)); | 88 | clean_dcache_area(pgd, PTRS_PER_S2_PGD * sizeof(pgd_t)); |
84 | } | 89 | } |
85 | 90 | ||
91 | static inline void kvm_clean_pmd(pmd_t *pmd) | ||
92 | { | ||
93 | clean_dcache_area(pmd, PTRS_PER_PMD * sizeof(pmd_t)); | ||
94 | } | ||
95 | |||
86 | static inline void kvm_clean_pmd_entry(pmd_t *pmd) | 96 | static inline void kvm_clean_pmd_entry(pmd_t *pmd) |
87 | { | 97 | { |
88 | clean_pmd_entry(pmd); | 98 | clean_pmd_entry(pmd); |
@@ -123,10 +133,23 @@ static inline bool kvm_page_empty(void *ptr) | |||
123 | } | 133 | } |
124 | 134 | ||
125 | 135 | ||
126 | #define kvm_pte_table_empty(ptep) kvm_page_empty(ptep) | 136 | #define kvm_pte_table_empty(kvm, ptep) kvm_page_empty(ptep) |
127 | #define kvm_pmd_table_empty(pmdp) kvm_page_empty(pmdp) | 137 | #define kvm_pmd_table_empty(kvm, pmdp) kvm_page_empty(pmdp) |
128 | #define kvm_pud_table_empty(pudp) (0) | 138 | #define kvm_pud_table_empty(kvm, pudp) (0) |
139 | |||
140 | #define KVM_PREALLOC_LEVEL 0 | ||
129 | 141 | ||
142 | static inline int kvm_prealloc_hwpgd(struct kvm *kvm, pgd_t *pgd) | ||
143 | { | ||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | static inline void kvm_free_hwpgd(struct kvm *kvm) { } | ||
148 | |||
149 | static inline void *kvm_get_hwpgd(struct kvm *kvm) | ||
150 | { | ||
151 | return kvm->arch.pgd; | ||
152 | } | ||
130 | 153 | ||
131 | struct kvm; | 154 | struct kvm; |
132 | 155 | ||
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index 90aa4583b308..3b30062975b2 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h | |||
@@ -100,7 +100,7 @@ extern pgprot_t pgprot_s2_device; | |||
100 | #define PAGE_HYP _MOD_PROT(pgprot_kernel, L_PTE_HYP) | 100 | #define PAGE_HYP _MOD_PROT(pgprot_kernel, L_PTE_HYP) |
101 | #define PAGE_HYP_DEVICE _MOD_PROT(pgprot_hyp_device, L_PTE_HYP) | 101 | #define PAGE_HYP_DEVICE _MOD_PROT(pgprot_hyp_device, L_PTE_HYP) |
102 | #define PAGE_S2 _MOD_PROT(pgprot_s2, L_PTE_S2_RDONLY) | 102 | #define PAGE_S2 _MOD_PROT(pgprot_s2, L_PTE_S2_RDONLY) |
103 | #define PAGE_S2_DEVICE _MOD_PROT(pgprot_s2_device, L_PTE_S2_RDWR) | 103 | #define PAGE_S2_DEVICE _MOD_PROT(pgprot_s2_device, L_PTE_S2_RDONLY) |
104 | 104 | ||
105 | #define __PAGE_NONE __pgprot(_L_PTE_DEFAULT | L_PTE_RDONLY | L_PTE_XN | L_PTE_NONE) | 105 | #define __PAGE_NONE __pgprot(_L_PTE_DEFAULT | L_PTE_RDONLY | L_PTE_XN | L_PTE_NONE) |
106 | #define __PAGE_SHARED __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_XN) | 106 | #define __PAGE_SHARED __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_XN) |
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 779605122f32..9e193c8a959e 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c | |||
@@ -409,7 +409,7 @@ static void update_vttbr(struct kvm *kvm) | |||
409 | kvm_next_vmid++; | 409 | kvm_next_vmid++; |
410 | 410 | ||
411 | /* update vttbr to be used with the new vmid */ | 411 | /* update vttbr to be used with the new vmid */ |
412 | pgd_phys = virt_to_phys(kvm->arch.pgd); | 412 | pgd_phys = virt_to_phys(kvm_get_hwpgd(kvm)); |
413 | BUG_ON(pgd_phys & ~VTTBR_BADDR_MASK); | 413 | BUG_ON(pgd_phys & ~VTTBR_BADDR_MASK); |
414 | vmid = ((u64)(kvm->arch.vmid) << VTTBR_VMID_SHIFT) & VTTBR_VMID_MASK; | 414 | vmid = ((u64)(kvm->arch.vmid) << VTTBR_VMID_SHIFT) & VTTBR_VMID_MASK; |
415 | kvm->arch.vttbr = pgd_phys | vmid; | 415 | kvm->arch.vttbr = pgd_phys | vmid; |
@@ -808,7 +808,8 @@ static int hyp_init_cpu_notify(struct notifier_block *self, | |||
808 | switch (action) { | 808 | switch (action) { |
809 | case CPU_STARTING: | 809 | case CPU_STARTING: |
810 | case CPU_STARTING_FROZEN: | 810 | case CPU_STARTING_FROZEN: |
811 | cpu_init_hyp_mode(NULL); | 811 | if (__hyp_get_vectors() == hyp_default_vectors) |
812 | cpu_init_hyp_mode(NULL); | ||
812 | break; | 813 | break; |
813 | } | 814 | } |
814 | 815 | ||
diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S index 98c8c5b9a87f..14d488388480 100644 --- a/arch/arm/kvm/interrupts_head.S +++ b/arch/arm/kvm/interrupts_head.S | |||
@@ -433,10 +433,17 @@ ARM_BE8(rev r10, r10 ) | |||
433 | str r3, [r11, #VGIC_V2_CPU_HCR] | 433 | str r3, [r11, #VGIC_V2_CPU_HCR] |
434 | str r4, [r11, #VGIC_V2_CPU_VMCR] | 434 | str r4, [r11, #VGIC_V2_CPU_VMCR] |
435 | str r5, [r11, #VGIC_V2_CPU_MISR] | 435 | str r5, [r11, #VGIC_V2_CPU_MISR] |
436 | #ifdef CONFIG_CPU_ENDIAN_BE8 | ||
437 | str r6, [r11, #(VGIC_V2_CPU_EISR + 4)] | ||
438 | str r7, [r11, #VGIC_V2_CPU_EISR] | ||
439 | str r8, [r11, #(VGIC_V2_CPU_ELRSR + 4)] | ||
440 | str r9, [r11, #VGIC_V2_CPU_ELRSR] | ||
441 | #else | ||
436 | str r6, [r11, #VGIC_V2_CPU_EISR] | 442 | str r6, [r11, #VGIC_V2_CPU_EISR] |
437 | str r7, [r11, #(VGIC_V2_CPU_EISR + 4)] | 443 | str r7, [r11, #(VGIC_V2_CPU_EISR + 4)] |
438 | str r8, [r11, #VGIC_V2_CPU_ELRSR] | 444 | str r8, [r11, #VGIC_V2_CPU_ELRSR] |
439 | str r9, [r11, #(VGIC_V2_CPU_ELRSR + 4)] | 445 | str r9, [r11, #(VGIC_V2_CPU_ELRSR + 4)] |
446 | #endif | ||
440 | str r10, [r11, #VGIC_V2_CPU_APR] | 447 | str r10, [r11, #VGIC_V2_CPU_APR] |
441 | 448 | ||
442 | /* Clear GICH_HCR */ | 449 | /* Clear GICH_HCR */ |
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index eea03069161b..57a403a5c22b 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c | |||
@@ -42,7 +42,7 @@ static unsigned long hyp_idmap_start; | |||
42 | static unsigned long hyp_idmap_end; | 42 | static unsigned long hyp_idmap_end; |
43 | static phys_addr_t hyp_idmap_vector; | 43 | static phys_addr_t hyp_idmap_vector; |
44 | 44 | ||
45 | #define pgd_order get_order(PTRS_PER_PGD * sizeof(pgd_t)) | 45 | #define hyp_pgd_order get_order(PTRS_PER_PGD * sizeof(pgd_t)) |
46 | 46 | ||
47 | #define kvm_pmd_huge(_x) (pmd_huge(_x) || pmd_trans_huge(_x)) | 47 | #define kvm_pmd_huge(_x) (pmd_huge(_x) || pmd_trans_huge(_x)) |
48 | 48 | ||
@@ -134,7 +134,7 @@ static void unmap_ptes(struct kvm *kvm, pmd_t *pmd, | |||
134 | } | 134 | } |
135 | } while (pte++, addr += PAGE_SIZE, addr != end); | 135 | } while (pte++, addr += PAGE_SIZE, addr != end); |
136 | 136 | ||
137 | if (kvm_pte_table_empty(start_pte)) | 137 | if (kvm_pte_table_empty(kvm, start_pte)) |
138 | clear_pmd_entry(kvm, pmd, start_addr); | 138 | clear_pmd_entry(kvm, pmd, start_addr); |
139 | } | 139 | } |
140 | 140 | ||
@@ -158,7 +158,7 @@ static void unmap_pmds(struct kvm *kvm, pud_t *pud, | |||
158 | } | 158 | } |
159 | } while (pmd++, addr = next, addr != end); | 159 | } while (pmd++, addr = next, addr != end); |
160 | 160 | ||
161 | if (kvm_pmd_table_empty(start_pmd)) | 161 | if (kvm_pmd_table_empty(kvm, start_pmd)) |
162 | clear_pud_entry(kvm, pud, start_addr); | 162 | clear_pud_entry(kvm, pud, start_addr); |
163 | } | 163 | } |
164 | 164 | ||
@@ -182,7 +182,7 @@ static void unmap_puds(struct kvm *kvm, pgd_t *pgd, | |||
182 | } | 182 | } |
183 | } while (pud++, addr = next, addr != end); | 183 | } while (pud++, addr = next, addr != end); |
184 | 184 | ||
185 | if (kvm_pud_table_empty(start_pud)) | 185 | if (kvm_pud_table_empty(kvm, start_pud)) |
186 | clear_pgd_entry(kvm, pgd, start_addr); | 186 | clear_pgd_entry(kvm, pgd, start_addr); |
187 | } | 187 | } |
188 | 188 | ||
@@ -306,7 +306,7 @@ void free_boot_hyp_pgd(void) | |||
306 | if (boot_hyp_pgd) { | 306 | if (boot_hyp_pgd) { |
307 | unmap_range(NULL, boot_hyp_pgd, hyp_idmap_start, PAGE_SIZE); | 307 | unmap_range(NULL, boot_hyp_pgd, hyp_idmap_start, PAGE_SIZE); |
308 | unmap_range(NULL, boot_hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE); | 308 | unmap_range(NULL, boot_hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE); |
309 | free_pages((unsigned long)boot_hyp_pgd, pgd_order); | 309 | free_pages((unsigned long)boot_hyp_pgd, hyp_pgd_order); |
310 | boot_hyp_pgd = NULL; | 310 | boot_hyp_pgd = NULL; |
311 | } | 311 | } |
312 | 312 | ||
@@ -343,7 +343,7 @@ void free_hyp_pgds(void) | |||
343 | for (addr = VMALLOC_START; is_vmalloc_addr((void*)addr); addr += PGDIR_SIZE) | 343 | for (addr = VMALLOC_START; is_vmalloc_addr((void*)addr); addr += PGDIR_SIZE) |
344 | unmap_range(NULL, hyp_pgd, KERN_TO_HYP(addr), PGDIR_SIZE); | 344 | unmap_range(NULL, hyp_pgd, KERN_TO_HYP(addr), PGDIR_SIZE); |
345 | 345 | ||
346 | free_pages((unsigned long)hyp_pgd, pgd_order); | 346 | free_pages((unsigned long)hyp_pgd, hyp_pgd_order); |
347 | hyp_pgd = NULL; | 347 | hyp_pgd = NULL; |
348 | } | 348 | } |
349 | 349 | ||
@@ -401,13 +401,46 @@ static int create_hyp_pmd_mappings(pud_t *pud, unsigned long start, | |||
401 | return 0; | 401 | return 0; |
402 | } | 402 | } |
403 | 403 | ||
404 | static int create_hyp_pud_mappings(pgd_t *pgd, unsigned long start, | ||
405 | unsigned long end, unsigned long pfn, | ||
406 | pgprot_t prot) | ||
407 | { | ||
408 | pud_t *pud; | ||
409 | pmd_t *pmd; | ||
410 | unsigned long addr, next; | ||
411 | int ret; | ||
412 | |||
413 | addr = start; | ||
414 | do { | ||
415 | pud = pud_offset(pgd, addr); | ||
416 | |||
417 | if (pud_none_or_clear_bad(pud)) { | ||
418 | pmd = pmd_alloc_one(NULL, addr); | ||
419 | if (!pmd) { | ||
420 | kvm_err("Cannot allocate Hyp pmd\n"); | ||
421 | return -ENOMEM; | ||
422 | } | ||
423 | pud_populate(NULL, pud, pmd); | ||
424 | get_page(virt_to_page(pud)); | ||
425 | kvm_flush_dcache_to_poc(pud, sizeof(*pud)); | ||
426 | } | ||
427 | |||
428 | next = pud_addr_end(addr, end); | ||
429 | ret = create_hyp_pmd_mappings(pud, addr, next, pfn, prot); | ||
430 | if (ret) | ||
431 | return ret; | ||
432 | pfn += (next - addr) >> PAGE_SHIFT; | ||
433 | } while (addr = next, addr != end); | ||
434 | |||
435 | return 0; | ||
436 | } | ||
437 | |||
404 | static int __create_hyp_mappings(pgd_t *pgdp, | 438 | static int __create_hyp_mappings(pgd_t *pgdp, |
405 | unsigned long start, unsigned long end, | 439 | unsigned long start, unsigned long end, |
406 | unsigned long pfn, pgprot_t prot) | 440 | unsigned long pfn, pgprot_t prot) |
407 | { | 441 | { |
408 | pgd_t *pgd; | 442 | pgd_t *pgd; |
409 | pud_t *pud; | 443 | pud_t *pud; |
410 | pmd_t *pmd; | ||
411 | unsigned long addr, next; | 444 | unsigned long addr, next; |
412 | int err = 0; | 445 | int err = 0; |
413 | 446 | ||
@@ -416,22 +449,21 @@ static int __create_hyp_mappings(pgd_t *pgdp, | |||
416 | end = PAGE_ALIGN(end); | 449 | end = PAGE_ALIGN(end); |
417 | do { | 450 | do { |
418 | pgd = pgdp + pgd_index(addr); | 451 | pgd = pgdp + pgd_index(addr); |
419 | pud = pud_offset(pgd, addr); | ||
420 | 452 | ||
421 | if (pud_none_or_clear_bad(pud)) { | 453 | if (pgd_none(*pgd)) { |
422 | pmd = pmd_alloc_one(NULL, addr); | 454 | pud = pud_alloc_one(NULL, addr); |
423 | if (!pmd) { | 455 | if (!pud) { |
424 | kvm_err("Cannot allocate Hyp pmd\n"); | 456 | kvm_err("Cannot allocate Hyp pud\n"); |
425 | err = -ENOMEM; | 457 | err = -ENOMEM; |
426 | goto out; | 458 | goto out; |
427 | } | 459 | } |
428 | pud_populate(NULL, pud, pmd); | 460 | pgd_populate(NULL, pgd, pud); |
429 | get_page(virt_to_page(pud)); | 461 | get_page(virt_to_page(pgd)); |
430 | kvm_flush_dcache_to_poc(pud, sizeof(*pud)); | 462 | kvm_flush_dcache_to_poc(pgd, sizeof(*pgd)); |
431 | } | 463 | } |
432 | 464 | ||
433 | next = pgd_addr_end(addr, end); | 465 | next = pgd_addr_end(addr, end); |
434 | err = create_hyp_pmd_mappings(pud, addr, next, pfn, prot); | 466 | err = create_hyp_pud_mappings(pgd, addr, next, pfn, prot); |
435 | if (err) | 467 | if (err) |
436 | goto out; | 468 | goto out; |
437 | pfn += (next - addr) >> PAGE_SHIFT; | 469 | pfn += (next - addr) >> PAGE_SHIFT; |
@@ -521,6 +553,7 @@ int create_hyp_io_mappings(void *from, void *to, phys_addr_t phys_addr) | |||
521 | */ | 553 | */ |
522 | int kvm_alloc_stage2_pgd(struct kvm *kvm) | 554 | int kvm_alloc_stage2_pgd(struct kvm *kvm) |
523 | { | 555 | { |
556 | int ret; | ||
524 | pgd_t *pgd; | 557 | pgd_t *pgd; |
525 | 558 | ||
526 | if (kvm->arch.pgd != NULL) { | 559 | if (kvm->arch.pgd != NULL) { |
@@ -528,15 +561,38 @@ int kvm_alloc_stage2_pgd(struct kvm *kvm) | |||
528 | return -EINVAL; | 561 | return -EINVAL; |
529 | } | 562 | } |
530 | 563 | ||
531 | pgd = (pgd_t *)__get_free_pages(GFP_KERNEL, S2_PGD_ORDER); | 564 | if (KVM_PREALLOC_LEVEL > 0) { |
565 | /* | ||
566 | * Allocate fake pgd for the page table manipulation macros to | ||
567 | * work. This is not used by the hardware and we have no | ||
568 | * alignment requirement for this allocation. | ||
569 | */ | ||
570 | pgd = (pgd_t *)kmalloc(PTRS_PER_S2_PGD * sizeof(pgd_t), | ||
571 | GFP_KERNEL | __GFP_ZERO); | ||
572 | } else { | ||
573 | /* | ||
574 | * Allocate actual first-level Stage-2 page table used by the | ||
575 | * hardware for Stage-2 page table walks. | ||
576 | */ | ||
577 | pgd = (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, S2_PGD_ORDER); | ||
578 | } | ||
579 | |||
532 | if (!pgd) | 580 | if (!pgd) |
533 | return -ENOMEM; | 581 | return -ENOMEM; |
534 | 582 | ||
535 | memset(pgd, 0, PTRS_PER_S2_PGD * sizeof(pgd_t)); | 583 | ret = kvm_prealloc_hwpgd(kvm, pgd); |
584 | if (ret) | ||
585 | goto out_err; | ||
586 | |||
536 | kvm_clean_pgd(pgd); | 587 | kvm_clean_pgd(pgd); |
537 | kvm->arch.pgd = pgd; | 588 | kvm->arch.pgd = pgd; |
538 | |||
539 | return 0; | 589 | return 0; |
590 | out_err: | ||
591 | if (KVM_PREALLOC_LEVEL > 0) | ||
592 | kfree(pgd); | ||
593 | else | ||
594 | free_pages((unsigned long)pgd, S2_PGD_ORDER); | ||
595 | return ret; | ||
540 | } | 596 | } |
541 | 597 | ||
542 | /** | 598 | /** |
@@ -572,19 +628,39 @@ void kvm_free_stage2_pgd(struct kvm *kvm) | |||
572 | return; | 628 | return; |
573 | 629 | ||
574 | unmap_stage2_range(kvm, 0, KVM_PHYS_SIZE); | 630 | unmap_stage2_range(kvm, 0, KVM_PHYS_SIZE); |
575 | free_pages((unsigned long)kvm->arch.pgd, S2_PGD_ORDER); | 631 | kvm_free_hwpgd(kvm); |
632 | if (KVM_PREALLOC_LEVEL > 0) | ||
633 | kfree(kvm->arch.pgd); | ||
634 | else | ||
635 | free_pages((unsigned long)kvm->arch.pgd, S2_PGD_ORDER); | ||
576 | kvm->arch.pgd = NULL; | 636 | kvm->arch.pgd = NULL; |
577 | } | 637 | } |
578 | 638 | ||
579 | static pmd_t *stage2_get_pmd(struct kvm *kvm, struct kvm_mmu_memory_cache *cache, | 639 | static pud_t *stage2_get_pud(struct kvm *kvm, struct kvm_mmu_memory_cache *cache, |
580 | phys_addr_t addr) | 640 | phys_addr_t addr) |
581 | { | 641 | { |
582 | pgd_t *pgd; | 642 | pgd_t *pgd; |
583 | pud_t *pud; | 643 | pud_t *pud; |
584 | pmd_t *pmd; | ||
585 | 644 | ||
586 | pgd = kvm->arch.pgd + pgd_index(addr); | 645 | pgd = kvm->arch.pgd + pgd_index(addr); |
587 | pud = pud_offset(pgd, addr); | 646 | if (WARN_ON(pgd_none(*pgd))) { |
647 | if (!cache) | ||
648 | return NULL; | ||
649 | pud = mmu_memory_cache_alloc(cache); | ||
650 | pgd_populate(NULL, pgd, pud); | ||
651 | get_page(virt_to_page(pgd)); | ||
652 | } | ||
653 | |||
654 | return pud_offset(pgd, addr); | ||
655 | } | ||
656 | |||
657 | static pmd_t *stage2_get_pmd(struct kvm *kvm, struct kvm_mmu_memory_cache *cache, | ||
658 | phys_addr_t addr) | ||
659 | { | ||
660 | pud_t *pud; | ||
661 | pmd_t *pmd; | ||
662 | |||
663 | pud = stage2_get_pud(kvm, cache, addr); | ||
588 | if (pud_none(*pud)) { | 664 | if (pud_none(*pud)) { |
589 | if (!cache) | 665 | if (!cache) |
590 | return NULL; | 666 | return NULL; |
@@ -630,7 +706,7 @@ static int stage2_set_pte(struct kvm *kvm, struct kvm_mmu_memory_cache *cache, | |||
630 | pmd_t *pmd; | 706 | pmd_t *pmd; |
631 | pte_t *pte, old_pte; | 707 | pte_t *pte, old_pte; |
632 | 708 | ||
633 | /* Create stage-2 page table mapping - Level 1 */ | 709 | /* Create stage-2 page table mapping - Levels 0 and 1 */ |
634 | pmd = stage2_get_pmd(kvm, cache, addr); | 710 | pmd = stage2_get_pmd(kvm, cache, addr); |
635 | if (!pmd) { | 711 | if (!pmd) { |
636 | /* | 712 | /* |
@@ -675,7 +751,7 @@ static int stage2_set_pte(struct kvm *kvm, struct kvm_mmu_memory_cache *cache, | |||
675 | * @size: The size of the mapping | 751 | * @size: The size of the mapping |
676 | */ | 752 | */ |
677 | int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa, | 753 | int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa, |
678 | phys_addr_t pa, unsigned long size) | 754 | phys_addr_t pa, unsigned long size, bool writable) |
679 | { | 755 | { |
680 | phys_addr_t addr, end; | 756 | phys_addr_t addr, end; |
681 | int ret = 0; | 757 | int ret = 0; |
@@ -688,7 +764,11 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa, | |||
688 | for (addr = guest_ipa; addr < end; addr += PAGE_SIZE) { | 764 | for (addr = guest_ipa; addr < end; addr += PAGE_SIZE) { |
689 | pte_t pte = pfn_pte(pfn, PAGE_S2_DEVICE); | 765 | pte_t pte = pfn_pte(pfn, PAGE_S2_DEVICE); |
690 | 766 | ||
691 | ret = mmu_topup_memory_cache(&cache, 2, 2); | 767 | if (writable) |
768 | kvm_set_s2pte_writable(&pte); | ||
769 | |||
770 | ret = mmu_topup_memory_cache(&cache, KVM_MMU_CACHE_MIN_PAGES, | ||
771 | KVM_NR_MEM_OBJS); | ||
692 | if (ret) | 772 | if (ret) |
693 | goto out; | 773 | goto out; |
694 | spin_lock(&kvm->mmu_lock); | 774 | spin_lock(&kvm->mmu_lock); |
@@ -777,6 +857,12 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | |||
777 | /* Let's check if we will get back a huge page backed by hugetlbfs */ | 857 | /* Let's check if we will get back a huge page backed by hugetlbfs */ |
778 | down_read(¤t->mm->mmap_sem); | 858 | down_read(¤t->mm->mmap_sem); |
779 | vma = find_vma_intersection(current->mm, hva, hva + 1); | 859 | vma = find_vma_intersection(current->mm, hva, hva + 1); |
860 | if (unlikely(!vma)) { | ||
861 | kvm_err("Failed to find VMA for hva 0x%lx\n", hva); | ||
862 | up_read(¤t->mm->mmap_sem); | ||
863 | return -EFAULT; | ||
864 | } | ||
865 | |||
780 | if (is_vm_hugetlb_page(vma)) { | 866 | if (is_vm_hugetlb_page(vma)) { |
781 | hugetlb = true; | 867 | hugetlb = true; |
782 | gfn = (fault_ipa & PMD_MASK) >> PAGE_SHIFT; | 868 | gfn = (fault_ipa & PMD_MASK) >> PAGE_SHIFT; |
@@ -797,7 +883,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | |||
797 | up_read(¤t->mm->mmap_sem); | 883 | up_read(¤t->mm->mmap_sem); |
798 | 884 | ||
799 | /* We need minimum second+third level pages */ | 885 | /* We need minimum second+third level pages */ |
800 | ret = mmu_topup_memory_cache(memcache, 2, KVM_NR_MEM_OBJS); | 886 | ret = mmu_topup_memory_cache(memcache, KVM_MMU_CACHE_MIN_PAGES, |
887 | KVM_NR_MEM_OBJS); | ||
801 | if (ret) | 888 | if (ret) |
802 | return ret; | 889 | return ret; |
803 | 890 | ||
@@ -843,7 +930,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | |||
843 | } | 930 | } |
844 | coherent_cache_guest_page(vcpu, hva, PAGE_SIZE); | 931 | coherent_cache_guest_page(vcpu, hva, PAGE_SIZE); |
845 | ret = stage2_set_pte(kvm, memcache, fault_ipa, &new_pte, | 932 | ret = stage2_set_pte(kvm, memcache, fault_ipa, &new_pte, |
846 | mem_type == PAGE_S2_DEVICE); | 933 | pgprot_val(mem_type) == pgprot_val(PAGE_S2_DEVICE)); |
847 | } | 934 | } |
848 | 935 | ||
849 | 936 | ||
@@ -916,6 +1003,9 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
916 | goto out_unlock; | 1003 | goto out_unlock; |
917 | } | 1004 | } |
918 | 1005 | ||
1006 | /* Userspace should not be able to register out-of-bounds IPAs */ | ||
1007 | VM_BUG_ON(fault_ipa >= KVM_PHYS_SIZE); | ||
1008 | |||
919 | ret = user_mem_abort(vcpu, fault_ipa, memslot, hva, fault_status); | 1009 | ret = user_mem_abort(vcpu, fault_ipa, memslot, hva, fault_status); |
920 | if (ret == 0) | 1010 | if (ret == 0) |
921 | ret = 1; | 1011 | ret = 1; |
@@ -1072,8 +1162,8 @@ int kvm_mmu_init(void) | |||
1072 | (unsigned long)phys_base); | 1162 | (unsigned long)phys_base); |
1073 | } | 1163 | } |
1074 | 1164 | ||
1075 | hyp_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, pgd_order); | 1165 | hyp_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, hyp_pgd_order); |
1076 | boot_hyp_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, pgd_order); | 1166 | boot_hyp_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, hyp_pgd_order); |
1077 | 1167 | ||
1078 | if (!hyp_pgd || !boot_hyp_pgd) { | 1168 | if (!hyp_pgd || !boot_hyp_pgd) { |
1079 | kvm_err("Hyp mode PGD not allocated\n"); | 1169 | kvm_err("Hyp mode PGD not allocated\n"); |
@@ -1126,13 +1216,6 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, | |||
1126 | const struct kvm_memory_slot *old, | 1216 | const struct kvm_memory_slot *old, |
1127 | enum kvm_mr_change change) | 1217 | enum kvm_mr_change change) |
1128 | { | 1218 | { |
1129 | gpa_t gpa = old->base_gfn << PAGE_SHIFT; | ||
1130 | phys_addr_t size = old->npages << PAGE_SHIFT; | ||
1131 | if (change == KVM_MR_DELETE || change == KVM_MR_MOVE) { | ||
1132 | spin_lock(&kvm->mmu_lock); | ||
1133 | unmap_stage2_range(kvm, gpa, size); | ||
1134 | spin_unlock(&kvm->mmu_lock); | ||
1135 | } | ||
1136 | } | 1219 | } |
1137 | 1220 | ||
1138 | int kvm_arch_prepare_memory_region(struct kvm *kvm, | 1221 | int kvm_arch_prepare_memory_region(struct kvm *kvm, |
@@ -1140,7 +1223,77 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, | |||
1140 | struct kvm_userspace_memory_region *mem, | 1223 | struct kvm_userspace_memory_region *mem, |
1141 | enum kvm_mr_change change) | 1224 | enum kvm_mr_change change) |
1142 | { | 1225 | { |
1143 | return 0; | 1226 | hva_t hva = mem->userspace_addr; |
1227 | hva_t reg_end = hva + mem->memory_size; | ||
1228 | bool writable = !(mem->flags & KVM_MEM_READONLY); | ||
1229 | int ret = 0; | ||
1230 | |||
1231 | if (change != KVM_MR_CREATE && change != KVM_MR_MOVE) | ||
1232 | return 0; | ||
1233 | |||
1234 | /* | ||
1235 | * Prevent userspace from creating a memory region outside of the IPA | ||
1236 | * space addressable by the KVM guest IPA space. | ||
1237 | */ | ||
1238 | if (memslot->base_gfn + memslot->npages >= | ||
1239 | (KVM_PHYS_SIZE >> PAGE_SHIFT)) | ||
1240 | return -EFAULT; | ||
1241 | |||
1242 | /* | ||
1243 | * A memory region could potentially cover multiple VMAs, and any holes | ||
1244 | * between them, so iterate over all of them to find out if we can map | ||
1245 | * any of them right now. | ||
1246 | * | ||
1247 | * +--------------------------------------------+ | ||
1248 | * +---------------+----------------+ +----------------+ | ||
1249 | * | : VMA 1 | VMA 2 | | VMA 3 : | | ||
1250 | * +---------------+----------------+ +----------------+ | ||
1251 | * | memory region | | ||
1252 | * +--------------------------------------------+ | ||
1253 | */ | ||
1254 | do { | ||
1255 | struct vm_area_struct *vma = find_vma(current->mm, hva); | ||
1256 | hva_t vm_start, vm_end; | ||
1257 | |||
1258 | if (!vma || vma->vm_start >= reg_end) | ||
1259 | break; | ||
1260 | |||
1261 | /* | ||
1262 | * Mapping a read-only VMA is only allowed if the | ||
1263 | * memory region is configured as read-only. | ||
1264 | */ | ||
1265 | if (writable && !(vma->vm_flags & VM_WRITE)) { | ||
1266 | ret = -EPERM; | ||
1267 | break; | ||
1268 | } | ||
1269 | |||
1270 | /* | ||
1271 | * Take the intersection of this VMA with the memory region | ||
1272 | */ | ||
1273 | vm_start = max(hva, vma->vm_start); | ||
1274 | vm_end = min(reg_end, vma->vm_end); | ||
1275 | |||
1276 | if (vma->vm_flags & VM_PFNMAP) { | ||
1277 | gpa_t gpa = mem->guest_phys_addr + | ||
1278 | (vm_start - mem->userspace_addr); | ||
1279 | phys_addr_t pa = (vma->vm_pgoff << PAGE_SHIFT) + | ||
1280 | vm_start - vma->vm_start; | ||
1281 | |||
1282 | ret = kvm_phys_addr_ioremap(kvm, gpa, pa, | ||
1283 | vm_end - vm_start, | ||
1284 | writable); | ||
1285 | if (ret) | ||
1286 | break; | ||
1287 | } | ||
1288 | hva = vm_end; | ||
1289 | } while (hva < reg_end); | ||
1290 | |||
1291 | if (ret) { | ||
1292 | spin_lock(&kvm->mmu_lock); | ||
1293 | unmap_stage2_range(kvm, mem->guest_phys_addr, mem->memory_size); | ||
1294 | spin_unlock(&kvm->mmu_lock); | ||
1295 | } | ||
1296 | return ret; | ||
1144 | } | 1297 | } |
1145 | 1298 | ||
1146 | void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free, | 1299 | void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free, |
@@ -1165,4 +1318,10 @@ void kvm_arch_flush_shadow_all(struct kvm *kvm) | |||
1165 | void kvm_arch_flush_shadow_memslot(struct kvm *kvm, | 1318 | void kvm_arch_flush_shadow_memslot(struct kvm *kvm, |
1166 | struct kvm_memory_slot *slot) | 1319 | struct kvm_memory_slot *slot) |
1167 | { | 1320 | { |
1321 | gpa_t gpa = slot->base_gfn << PAGE_SHIFT; | ||
1322 | phys_addr_t size = slot->npages << PAGE_SHIFT; | ||
1323 | |||
1324 | spin_lock(&kvm->mmu_lock); | ||
1325 | unmap_stage2_range(kvm, gpa, size); | ||
1326 | spin_unlock(&kvm->mmu_lock); | ||
1168 | } | 1327 | } |
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h index a030d163840b..0caf7a59f6a1 100644 --- a/arch/arm64/include/asm/kvm_mmu.h +++ b/arch/arm64/include/asm/kvm_mmu.h | |||
@@ -41,6 +41,18 @@ | |||
41 | */ | 41 | */ |
42 | #define TRAMPOLINE_VA (HYP_PAGE_OFFSET_MASK & PAGE_MASK) | 42 | #define TRAMPOLINE_VA (HYP_PAGE_OFFSET_MASK & PAGE_MASK) |
43 | 43 | ||
44 | /* | ||
45 | * KVM_MMU_CACHE_MIN_PAGES is the number of stage2 page table translation | ||
46 | * levels in addition to the PGD and potentially the PUD which are | ||
47 | * pre-allocated (we pre-allocate the fake PGD and the PUD when the Stage-2 | ||
48 | * tables use one level of tables less than the kernel. | ||
49 | */ | ||
50 | #ifdef CONFIG_ARM64_64K_PAGES | ||
51 | #define KVM_MMU_CACHE_MIN_PAGES 1 | ||
52 | #else | ||
53 | #define KVM_MMU_CACHE_MIN_PAGES 2 | ||
54 | #endif | ||
55 | |||
44 | #ifdef __ASSEMBLY__ | 56 | #ifdef __ASSEMBLY__ |
45 | 57 | ||
46 | /* | 58 | /* |
@@ -53,6 +65,7 @@ | |||
53 | 65 | ||
54 | #else | 66 | #else |
55 | 67 | ||
68 | #include <asm/pgalloc.h> | ||
56 | #include <asm/cachetype.h> | 69 | #include <asm/cachetype.h> |
57 | #include <asm/cacheflush.h> | 70 | #include <asm/cacheflush.h> |
58 | 71 | ||
@@ -65,10 +78,6 @@ | |||
65 | #define KVM_PHYS_SIZE (1UL << KVM_PHYS_SHIFT) | 78 | #define KVM_PHYS_SIZE (1UL << KVM_PHYS_SHIFT) |
66 | #define KVM_PHYS_MASK (KVM_PHYS_SIZE - 1UL) | 79 | #define KVM_PHYS_MASK (KVM_PHYS_SIZE - 1UL) |
67 | 80 | ||
68 | /* Make sure we get the right size, and thus the right alignment */ | ||
69 | #define PTRS_PER_S2_PGD (1 << (KVM_PHYS_SHIFT - PGDIR_SHIFT)) | ||
70 | #define S2_PGD_ORDER get_order(PTRS_PER_S2_PGD * sizeof(pgd_t)) | ||
71 | |||
72 | int create_hyp_mappings(void *from, void *to); | 81 | int create_hyp_mappings(void *from, void *to); |
73 | int create_hyp_io_mappings(void *from, void *to, phys_addr_t); | 82 | int create_hyp_io_mappings(void *from, void *to, phys_addr_t); |
74 | void free_boot_hyp_pgd(void); | 83 | void free_boot_hyp_pgd(void); |
@@ -77,7 +86,7 @@ void free_hyp_pgds(void); | |||
77 | int kvm_alloc_stage2_pgd(struct kvm *kvm); | 86 | int kvm_alloc_stage2_pgd(struct kvm *kvm); |
78 | void kvm_free_stage2_pgd(struct kvm *kvm); | 87 | void kvm_free_stage2_pgd(struct kvm *kvm); |
79 | int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa, | 88 | int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa, |
80 | phys_addr_t pa, unsigned long size); | 89 | phys_addr_t pa, unsigned long size, bool writable); |
81 | 90 | ||
82 | int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run); | 91 | int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run); |
83 | 92 | ||
@@ -93,6 +102,7 @@ void kvm_clear_hyp_idmap(void); | |||
93 | #define kvm_set_pmd(pmdp, pmd) set_pmd(pmdp, pmd) | 102 | #define kvm_set_pmd(pmdp, pmd) set_pmd(pmdp, pmd) |
94 | 103 | ||
95 | static inline void kvm_clean_pgd(pgd_t *pgd) {} | 104 | static inline void kvm_clean_pgd(pgd_t *pgd) {} |
105 | static inline void kvm_clean_pmd(pmd_t *pmd) {} | ||
96 | static inline void kvm_clean_pmd_entry(pmd_t *pmd) {} | 106 | static inline void kvm_clean_pmd_entry(pmd_t *pmd) {} |
97 | static inline void kvm_clean_pte(pte_t *pte) {} | 107 | static inline void kvm_clean_pte(pte_t *pte) {} |
98 | static inline void kvm_clean_pte_entry(pte_t *pte) {} | 108 | static inline void kvm_clean_pte_entry(pte_t *pte) {} |
@@ -111,19 +121,116 @@ static inline void kvm_set_s2pmd_writable(pmd_t *pmd) | |||
111 | #define kvm_pud_addr_end(addr, end) pud_addr_end(addr, end) | 121 | #define kvm_pud_addr_end(addr, end) pud_addr_end(addr, end) |
112 | #define kvm_pmd_addr_end(addr, end) pmd_addr_end(addr, end) | 122 | #define kvm_pmd_addr_end(addr, end) pmd_addr_end(addr, end) |
113 | 123 | ||
124 | /* | ||
125 | * In the case where PGDIR_SHIFT is larger than KVM_PHYS_SHIFT, we can address | ||
126 | * the entire IPA input range with a single pgd entry, and we would only need | ||
127 | * one pgd entry. Note that in this case, the pgd is actually not used by | ||
128 | * the MMU for Stage-2 translations, but is merely a fake pgd used as a data | ||
129 | * structure for the kernel pgtable macros to work. | ||
130 | */ | ||
131 | #if PGDIR_SHIFT > KVM_PHYS_SHIFT | ||
132 | #define PTRS_PER_S2_PGD_SHIFT 0 | ||
133 | #else | ||
134 | #define PTRS_PER_S2_PGD_SHIFT (KVM_PHYS_SHIFT - PGDIR_SHIFT) | ||
135 | #endif | ||
136 | #define PTRS_PER_S2_PGD (1 << PTRS_PER_S2_PGD_SHIFT) | ||
137 | #define S2_PGD_ORDER get_order(PTRS_PER_S2_PGD * sizeof(pgd_t)) | ||
138 | |||
139 | /* | ||
140 | * If we are concatenating first level stage-2 page tables, we would have less | ||
141 | * than or equal to 16 pointers in the fake PGD, because that's what the | ||
142 | * architecture allows. In this case, (4 - CONFIG_ARM64_PGTABLE_LEVELS) | ||
143 | * represents the first level for the host, and we add 1 to go to the next | ||
144 | * level (which uses contatenation) for the stage-2 tables. | ||
145 | */ | ||
146 | #if PTRS_PER_S2_PGD <= 16 | ||
147 | #define KVM_PREALLOC_LEVEL (4 - CONFIG_ARM64_PGTABLE_LEVELS + 1) | ||
148 | #else | ||
149 | #define KVM_PREALLOC_LEVEL (0) | ||
150 | #endif | ||
151 | |||
152 | /** | ||
153 | * kvm_prealloc_hwpgd - allocate inital table for VTTBR | ||
154 | * @kvm: The KVM struct pointer for the VM. | ||
155 | * @pgd: The kernel pseudo pgd | ||
156 | * | ||
157 | * When the kernel uses more levels of page tables than the guest, we allocate | ||
158 | * a fake PGD and pre-populate it to point to the next-level page table, which | ||
159 | * will be the real initial page table pointed to by the VTTBR. | ||
160 | * | ||
161 | * When KVM_PREALLOC_LEVEL==2, we allocate a single page for the PMD and | ||
162 | * the kernel will use folded pud. When KVM_PREALLOC_LEVEL==1, we | ||
163 | * allocate 2 consecutive PUD pages. | ||
164 | */ | ||
165 | static inline int kvm_prealloc_hwpgd(struct kvm *kvm, pgd_t *pgd) | ||
166 | { | ||
167 | unsigned int i; | ||
168 | unsigned long hwpgd; | ||
169 | |||
170 | if (KVM_PREALLOC_LEVEL == 0) | ||
171 | return 0; | ||
172 | |||
173 | hwpgd = __get_free_pages(GFP_KERNEL | __GFP_ZERO, PTRS_PER_S2_PGD_SHIFT); | ||
174 | if (!hwpgd) | ||
175 | return -ENOMEM; | ||
176 | |||
177 | for (i = 0; i < PTRS_PER_S2_PGD; i++) { | ||
178 | if (KVM_PREALLOC_LEVEL == 1) | ||
179 | pgd_populate(NULL, pgd + i, | ||
180 | (pud_t *)hwpgd + i * PTRS_PER_PUD); | ||
181 | else if (KVM_PREALLOC_LEVEL == 2) | ||
182 | pud_populate(NULL, pud_offset(pgd, 0) + i, | ||
183 | (pmd_t *)hwpgd + i * PTRS_PER_PMD); | ||
184 | } | ||
185 | |||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | static inline void *kvm_get_hwpgd(struct kvm *kvm) | ||
190 | { | ||
191 | pgd_t *pgd = kvm->arch.pgd; | ||
192 | pud_t *pud; | ||
193 | |||
194 | if (KVM_PREALLOC_LEVEL == 0) | ||
195 | return pgd; | ||
196 | |||
197 | pud = pud_offset(pgd, 0); | ||
198 | if (KVM_PREALLOC_LEVEL == 1) | ||
199 | return pud; | ||
200 | |||
201 | BUG_ON(KVM_PREALLOC_LEVEL != 2); | ||
202 | return pmd_offset(pud, 0); | ||
203 | } | ||
204 | |||
205 | static inline void kvm_free_hwpgd(struct kvm *kvm) | ||
206 | { | ||
207 | if (KVM_PREALLOC_LEVEL > 0) { | ||
208 | unsigned long hwpgd = (unsigned long)kvm_get_hwpgd(kvm); | ||
209 | free_pages(hwpgd, PTRS_PER_S2_PGD_SHIFT); | ||
210 | } | ||
211 | } | ||
212 | |||
114 | static inline bool kvm_page_empty(void *ptr) | 213 | static inline bool kvm_page_empty(void *ptr) |
115 | { | 214 | { |
116 | struct page *ptr_page = virt_to_page(ptr); | 215 | struct page *ptr_page = virt_to_page(ptr); |
117 | return page_count(ptr_page) == 1; | 216 | return page_count(ptr_page) == 1; |
118 | } | 217 | } |
119 | 218 | ||
120 | #define kvm_pte_table_empty(ptep) kvm_page_empty(ptep) | 219 | #define kvm_pte_table_empty(kvm, ptep) kvm_page_empty(ptep) |
121 | #ifndef CONFIG_ARM64_64K_PAGES | 220 | |
122 | #define kvm_pmd_table_empty(pmdp) kvm_page_empty(pmdp) | 221 | #ifdef __PAGETABLE_PMD_FOLDED |
222 | #define kvm_pmd_table_empty(kvm, pmdp) (0) | ||
223 | #else | ||
224 | #define kvm_pmd_table_empty(kvm, pmdp) \ | ||
225 | (kvm_page_empty(pmdp) && (!(kvm) || KVM_PREALLOC_LEVEL < 2)) | ||
226 | #endif | ||
227 | |||
228 | #ifdef __PAGETABLE_PUD_FOLDED | ||
229 | #define kvm_pud_table_empty(kvm, pudp) (0) | ||
123 | #else | 230 | #else |
124 | #define kvm_pmd_table_empty(pmdp) (0) | 231 | #define kvm_pud_table_empty(kvm, pudp) \ |
232 | (kvm_page_empty(pudp) && (!(kvm) || KVM_PREALLOC_LEVEL < 1)) | ||
125 | #endif | 233 | #endif |
126 | #define kvm_pud_table_empty(pudp) (0) | ||
127 | 234 | ||
128 | 235 | ||
129 | struct kvm; | 236 | struct kvm; |
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index cefd3e825612..41a43bf26492 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h | |||
@@ -79,7 +79,7 @@ extern void __pgd_error(const char *file, int line, unsigned long val); | |||
79 | #define PAGE_HYP_DEVICE __pgprot(PROT_DEVICE_nGnRE | PTE_HYP) | 79 | #define PAGE_HYP_DEVICE __pgprot(PROT_DEVICE_nGnRE | PTE_HYP) |
80 | 80 | ||
81 | #define PAGE_S2 __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_NORMAL) | PTE_S2_RDONLY) | 81 | #define PAGE_S2 __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_NORMAL) | PTE_S2_RDONLY) |
82 | #define PAGE_S2_DEVICE __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_DEVICE_nGnRE) | PTE_S2_RDWR | PTE_UXN) | 82 | #define PAGE_S2_DEVICE __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_DEVICE_nGnRE) | PTE_S2_RDONLY | PTE_UXN) |
83 | 83 | ||
84 | #define PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_TYPE_MASK) | PTE_PROT_NONE | PTE_PXN | PTE_UXN) | 84 | #define PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_TYPE_MASK) | PTE_PROT_NONE | PTE_PXN | PTE_UXN) |
85 | #define PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE) | 85 | #define PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE) |
diff --git a/arch/arm64/kvm/vgic-v2-switch.S b/arch/arm64/kvm/vgic-v2-switch.S index ae211772f991..f002fe1c3700 100644 --- a/arch/arm64/kvm/vgic-v2-switch.S +++ b/arch/arm64/kvm/vgic-v2-switch.S | |||
@@ -67,10 +67,14 @@ CPU_BE( rev w11, w11 ) | |||
67 | str w4, [x3, #VGIC_V2_CPU_HCR] | 67 | str w4, [x3, #VGIC_V2_CPU_HCR] |
68 | str w5, [x3, #VGIC_V2_CPU_VMCR] | 68 | str w5, [x3, #VGIC_V2_CPU_VMCR] |
69 | str w6, [x3, #VGIC_V2_CPU_MISR] | 69 | str w6, [x3, #VGIC_V2_CPU_MISR] |
70 | str w7, [x3, #VGIC_V2_CPU_EISR] | 70 | CPU_LE( str w7, [x3, #VGIC_V2_CPU_EISR] ) |
71 | str w8, [x3, #(VGIC_V2_CPU_EISR + 4)] | 71 | CPU_LE( str w8, [x3, #(VGIC_V2_CPU_EISR + 4)] ) |
72 | str w9, [x3, #VGIC_V2_CPU_ELRSR] | 72 | CPU_LE( str w9, [x3, #VGIC_V2_CPU_ELRSR] ) |
73 | str w10, [x3, #(VGIC_V2_CPU_ELRSR + 4)] | 73 | CPU_LE( str w10, [x3, #(VGIC_V2_CPU_ELRSR + 4)] ) |
74 | CPU_BE( str w7, [x3, #(VGIC_V2_CPU_EISR + 4)] ) | ||
75 | CPU_BE( str w8, [x3, #VGIC_V2_CPU_EISR] ) | ||
76 | CPU_BE( str w9, [x3, #(VGIC_V2_CPU_ELRSR + 4)] ) | ||
77 | CPU_BE( str w10, [x3, #VGIC_V2_CPU_ELRSR] ) | ||
74 | str w11, [x3, #VGIC_V2_CPU_APR] | 78 | str w11, [x3, #VGIC_V2_CPU_APR] |
75 | 79 | ||
76 | /* Clear GICH_HCR */ | 80 | /* Clear GICH_HCR */ |
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index 2f2aac8448a4..206dcc3b3f7a 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h | |||
@@ -219,8 +219,8 @@ struct vgic_v2_cpu_if { | |||
219 | u32 vgic_hcr; | 219 | u32 vgic_hcr; |
220 | u32 vgic_vmcr; | 220 | u32 vgic_vmcr; |
221 | u32 vgic_misr; /* Saved only */ | 221 | u32 vgic_misr; /* Saved only */ |
222 | u32 vgic_eisr[2]; /* Saved only */ | 222 | u64 vgic_eisr; /* Saved only */ |
223 | u32 vgic_elrsr[2]; /* Saved only */ | 223 | u64 vgic_elrsr; /* Saved only */ |
224 | u32 vgic_apr; | 224 | u32 vgic_apr; |
225 | u32 vgic_lr[VGIC_V2_MAX_LRS]; | 225 | u32 vgic_lr[VGIC_V2_MAX_LRS]; |
226 | }; | 226 | }; |
@@ -331,6 +331,14 @@ static inline int kvm_vgic_create(struct kvm *kvm) | |||
331 | return 0; | 331 | return 0; |
332 | } | 332 | } |
333 | 333 | ||
334 | static inline void kvm_vgic_destroy(struct kvm *kvm) | ||
335 | { | ||
336 | } | ||
337 | |||
338 | static inline void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu) | ||
339 | { | ||
340 | } | ||
341 | |||
334 | static inline int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) | 342 | static inline int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) |
335 | { | 343 | { |
336 | return 0; | 344 | return 0; |
diff --git a/virt/kvm/arm/vgic-v2.c b/virt/kvm/arm/vgic-v2.c index 416baedfc89f..2935405ad22f 100644 --- a/virt/kvm/arm/vgic-v2.c +++ b/virt/kvm/arm/vgic-v2.c | |||
@@ -71,35 +71,17 @@ static void vgic_v2_sync_lr_elrsr(struct kvm_vcpu *vcpu, int lr, | |||
71 | struct vgic_lr lr_desc) | 71 | struct vgic_lr lr_desc) |
72 | { | 72 | { |
73 | if (!(lr_desc.state & LR_STATE_MASK)) | 73 | if (!(lr_desc.state & LR_STATE_MASK)) |
74 | __set_bit(lr, (unsigned long *)vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr); | 74 | vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr |= (1ULL << lr); |
75 | } | 75 | } |
76 | 76 | ||
77 | static u64 vgic_v2_get_elrsr(const struct kvm_vcpu *vcpu) | 77 | static u64 vgic_v2_get_elrsr(const struct kvm_vcpu *vcpu) |
78 | { | 78 | { |
79 | u64 val; | 79 | return vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr; |
80 | |||
81 | #if BITS_PER_LONG == 64 | ||
82 | val = vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr[1]; | ||
83 | val <<= 32; | ||
84 | val |= vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr[0]; | ||
85 | #else | ||
86 | val = *(u64 *)vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr; | ||
87 | #endif | ||
88 | return val; | ||
89 | } | 80 | } |
90 | 81 | ||
91 | static u64 vgic_v2_get_eisr(const struct kvm_vcpu *vcpu) | 82 | static u64 vgic_v2_get_eisr(const struct kvm_vcpu *vcpu) |
92 | { | 83 | { |
93 | u64 val; | 84 | return vcpu->arch.vgic_cpu.vgic_v2.vgic_eisr; |
94 | |||
95 | #if BITS_PER_LONG == 64 | ||
96 | val = vcpu->arch.vgic_cpu.vgic_v2.vgic_eisr[1]; | ||
97 | val <<= 32; | ||
98 | val |= vcpu->arch.vgic_cpu.vgic_v2.vgic_eisr[0]; | ||
99 | #else | ||
100 | val = *(u64 *)vcpu->arch.vgic_cpu.vgic_v2.vgic_eisr; | ||
101 | #endif | ||
102 | return val; | ||
103 | } | 85 | } |
104 | 86 | ||
105 | static u32 vgic_v2_get_interrupt_status(const struct kvm_vcpu *vcpu) | 87 | static u32 vgic_v2_get_interrupt_status(const struct kvm_vcpu *vcpu) |
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c index 862967852d5a..3aaca49de325 100644 --- a/virt/kvm/arm/vgic.c +++ b/virt/kvm/arm/vgic.c | |||
@@ -145,6 +145,20 @@ static void vgic_free_bitmap(struct vgic_bitmap *b) | |||
145 | b->shared = NULL; | 145 | b->shared = NULL; |
146 | } | 146 | } |
147 | 147 | ||
148 | /* | ||
149 | * Call this function to convert a u64 value to an unsigned long * bitmask | ||
150 | * in a way that works on both 32-bit and 64-bit LE and BE platforms. | ||
151 | * | ||
152 | * Warning: Calling this function may modify *val. | ||
153 | */ | ||
154 | static unsigned long *u64_to_bitmask(u64 *val) | ||
155 | { | ||
156 | #if defined(CONFIG_CPU_BIG_ENDIAN) && BITS_PER_LONG == 32 | ||
157 | *val = (*val >> 32) | (*val << 32); | ||
158 | #endif | ||
159 | return (unsigned long *)val; | ||
160 | } | ||
161 | |||
148 | static u32 *vgic_bitmap_get_reg(struct vgic_bitmap *x, | 162 | static u32 *vgic_bitmap_get_reg(struct vgic_bitmap *x, |
149 | int cpuid, u32 offset) | 163 | int cpuid, u32 offset) |
150 | { | 164 | { |
@@ -1442,7 +1456,7 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu) | |||
1442 | * active bit. | 1456 | * active bit. |
1443 | */ | 1457 | */ |
1444 | u64 eisr = vgic_get_eisr(vcpu); | 1458 | u64 eisr = vgic_get_eisr(vcpu); |
1445 | unsigned long *eisr_ptr = (unsigned long *)&eisr; | 1459 | unsigned long *eisr_ptr = u64_to_bitmask(&eisr); |
1446 | int lr; | 1460 | int lr; |
1447 | 1461 | ||
1448 | for_each_set_bit(lr, eisr_ptr, vgic->nr_lr) { | 1462 | for_each_set_bit(lr, eisr_ptr, vgic->nr_lr) { |
@@ -1505,7 +1519,7 @@ static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu) | |||
1505 | 1519 | ||
1506 | level_pending = vgic_process_maintenance(vcpu); | 1520 | level_pending = vgic_process_maintenance(vcpu); |
1507 | elrsr = vgic_get_elrsr(vcpu); | 1521 | elrsr = vgic_get_elrsr(vcpu); |
1508 | elrsr_ptr = (unsigned long *)&elrsr; | 1522 | elrsr_ptr = u64_to_bitmask(&elrsr); |
1509 | 1523 | ||
1510 | /* Clear mappings for empty LRs */ | 1524 | /* Clear mappings for empty LRs */ |
1511 | for_each_set_bit(lr, elrsr_ptr, vgic->nr_lr) { | 1525 | for_each_set_bit(lr, elrsr_ptr, vgic->nr_lr) { |
@@ -1899,7 +1913,8 @@ int kvm_vgic_init(struct kvm *kvm) | |||
1899 | } | 1913 | } |
1900 | 1914 | ||
1901 | ret = kvm_phys_addr_ioremap(kvm, kvm->arch.vgic.vgic_cpu_base, | 1915 | ret = kvm_phys_addr_ioremap(kvm, kvm->arch.vgic.vgic_cpu_base, |
1902 | vgic->vcpu_base, KVM_VGIC_V2_CPU_SIZE); | 1916 | vgic->vcpu_base, KVM_VGIC_V2_CPU_SIZE, |
1917 | true); | ||
1903 | if (ret) { | 1918 | if (ret) { |
1904 | kvm_err("Unable to remap VGIC CPU to VCPU\n"); | 1919 | kvm_err("Unable to remap VGIC CPU to VCPU\n"); |
1905 | goto out; | 1920 | goto out; |