Merge tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull arm64 updates from Will Deacon: "Here are the core arm64 updates for 4.1. Highlights include a significant rework to head.S (allowing us to boot on machines with physical memory at a really high address), an AES performance boost on Cortex-A57 and the ability to run a 32-bit userspace with 64k pages (although this requires said userspace to be built with a recent binutils). The head.S rework spilt over into KVM, so there are some changes under arch/arm/ which have been acked by Marc Zyngier (KVM co-maintainer). In particular, the linker script changes caused us some issues in -next, so there are a few merge commits where we had to apply fixes on top of a stable branch. Other changes include: - AES performance boost for Cortex-A57 - AArch32 (compat) userspace with 64k pages - Cortex-A53 erratum workaround for #845719 - defconfig updates (new platforms, PCI, ...)" * tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: (39 commits) arm64: fix midr range for Cortex-A57 erratum 832075 arm64: errata: add workaround for cortex-a53 erratum #845719 arm64: Use bool function return values of true/false not 1/0 arm64: defconfig: updates for 4.1 arm64: Extract feature parsing code from cpu_errata.c arm64: alternative: Allow immediate branch as alternative instruction arm64: insn: Add aarch64_insn_decode_immediate ARM: kvm: round HYP section to page size instead of log2 upper bound ARM: kvm: assert on HYP section boundaries not actual code size arm64: head.S: ensure idmap_t0sz is visible arm64: pmu: add support for interrupt-affinity property dt: pmu: extend ARM PMU binding to allow for explicit interrupt affinity arm64: head.S: ensure visibility of page tables arm64: KVM: use ID map with increased VA range if required arm64: mm: increase VA range of identity map ARM: kvm: implement replacement for ld's LOG2CEIL() arm64: proc: remove unused cpu_get_pgd macro arm64: enforce x1|x2|x3 == 0 upon kernel entry as per boot protocol arm64: remove __calc_phys_offset arm64: merge __enable_mmu and __turn_mmu_on ...
This commit is contained in:
@@ -35,9 +35,9 @@ extern char __hyp_idmap_text_start[], __hyp_idmap_text_end[];
|
||||
|
||||
static pgd_t *boot_hyp_pgd;
|
||||
static pgd_t *hyp_pgd;
|
||||
static pgd_t *merged_hyp_pgd;
|
||||
static DEFINE_MUTEX(kvm_hyp_pgd_mutex);
|
||||
|
||||
static void *init_bounce_page;
|
||||
static unsigned long hyp_idmap_start;
|
||||
static unsigned long hyp_idmap_end;
|
||||
static phys_addr_t hyp_idmap_vector;
|
||||
@@ -405,9 +405,6 @@ void free_boot_hyp_pgd(void)
|
||||
if (hyp_pgd)
|
||||
unmap_range(NULL, hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE);
|
||||
|
||||
free_page((unsigned long)init_bounce_page);
|
||||
init_bounce_page = NULL;
|
||||
|
||||
mutex_unlock(&kvm_hyp_pgd_mutex);
|
||||
}
|
||||
|
||||
@@ -438,6 +435,11 @@ void free_hyp_pgds(void)
|
||||
free_pages((unsigned long)hyp_pgd, hyp_pgd_order);
|
||||
hyp_pgd = NULL;
|
||||
}
|
||||
if (merged_hyp_pgd) {
|
||||
clear_page(merged_hyp_pgd);
|
||||
free_page((unsigned long)merged_hyp_pgd);
|
||||
merged_hyp_pgd = NULL;
|
||||
}
|
||||
|
||||
mutex_unlock(&kvm_hyp_pgd_mutex);
|
||||
}
|
||||
@@ -1622,12 +1624,18 @@ void kvm_mmu_free_memory_caches(struct kvm_vcpu *vcpu)
|
||||
|
||||
phys_addr_t kvm_mmu_get_httbr(void)
|
||||
{
|
||||
return virt_to_phys(hyp_pgd);
|
||||
if (__kvm_cpu_uses_extended_idmap())
|
||||
return virt_to_phys(merged_hyp_pgd);
|
||||
else
|
||||
return virt_to_phys(hyp_pgd);
|
||||
}
|
||||
|
||||
phys_addr_t kvm_mmu_get_boot_httbr(void)
|
||||
{
|
||||
return virt_to_phys(boot_hyp_pgd);
|
||||
if (__kvm_cpu_uses_extended_idmap())
|
||||
return virt_to_phys(merged_hyp_pgd);
|
||||
else
|
||||
return virt_to_phys(boot_hyp_pgd);
|
||||
}
|
||||
|
||||
phys_addr_t kvm_get_idmap_vector(void)
|
||||
@@ -1643,39 +1651,11 @@ int kvm_mmu_init(void)
|
||||
hyp_idmap_end = kvm_virt_to_phys(__hyp_idmap_text_end);
|
||||
hyp_idmap_vector = kvm_virt_to_phys(__kvm_hyp_init);
|
||||
|
||||
if ((hyp_idmap_start ^ hyp_idmap_end) & PAGE_MASK) {
|
||||
/*
|
||||
* Our init code is crossing a page boundary. Allocate
|
||||
* a bounce page, copy the code over and use that.
|
||||
*/
|
||||
size_t len = __hyp_idmap_text_end - __hyp_idmap_text_start;
|
||||
phys_addr_t phys_base;
|
||||
|
||||
init_bounce_page = (void *)__get_free_page(GFP_KERNEL);
|
||||
if (!init_bounce_page) {
|
||||
kvm_err("Couldn't allocate HYP init bounce page\n");
|
||||
err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memcpy(init_bounce_page, __hyp_idmap_text_start, len);
|
||||
/*
|
||||
* Warning: the code we just copied to the bounce page
|
||||
* must be flushed to the point of coherency.
|
||||
* Otherwise, the data may be sitting in L2, and HYP
|
||||
* mode won't be able to observe it as it runs with
|
||||
* caches off at that point.
|
||||
*/
|
||||
kvm_flush_dcache_to_poc(init_bounce_page, len);
|
||||
|
||||
phys_base = kvm_virt_to_phys(init_bounce_page);
|
||||
hyp_idmap_vector += phys_base - hyp_idmap_start;
|
||||
hyp_idmap_start = phys_base;
|
||||
hyp_idmap_end = phys_base + len;
|
||||
|
||||
kvm_info("Using HYP init bounce page @%lx\n",
|
||||
(unsigned long)phys_base);
|
||||
}
|
||||
/*
|
||||
* We rely on the linker script to ensure at build time that the HYP
|
||||
* init code does not cross a page boundary.
|
||||
*/
|
||||
BUG_ON((hyp_idmap_start ^ (hyp_idmap_end - 1)) & PAGE_MASK);
|
||||
|
||||
hyp_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, hyp_pgd_order);
|
||||
boot_hyp_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, hyp_pgd_order);
|
||||
@@ -1698,6 +1678,17 @@ int kvm_mmu_init(void)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (__kvm_cpu_uses_extended_idmap()) {
|
||||
merged_hyp_pgd = (pgd_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
|
||||
if (!merged_hyp_pgd) {
|
||||
kvm_err("Failed to allocate extra HYP pgd\n");
|
||||
goto out;
|
||||
}
|
||||
__kvm_extend_hypmap(boot_hyp_pgd, hyp_pgd, merged_hyp_pgd,
|
||||
hyp_idmap_start);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Map the very same page at the trampoline VA */
|
||||
err = __create_hyp_mappings(boot_hyp_pgd,
|
||||
TRAMPOLINE_VA, TRAMPOLINE_VA + PAGE_SIZE,
|
||||
|
Reference in New Issue
Block a user