aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm
diff options
context:
space:
mode:
authorBorislav Petkov <bp@suse.de>2013-10-31 12:25:01 -0400
committerMatt Fleming <matt.fleming@intel.com>2013-11-02 07:09:12 -0400
commitf3f729661e8db476ac427a97de015307aebb7404 (patch)
treecaa0fd5caa67d58ff64be68698dc64295d8174a1 /arch/x86/mm
parent0fd64c23fdf556e9e68580cff03b3505797bbf53 (diff)
x86/mm/pageattr: Add a PGD pagetable populating function
This allocates, if necessary, and populates the corresponding PGD entry with a PUD page. The next population level is a dummy macro which will be removed by the next patch and it is added here to keep the patch small and easily reviewable but not break bisection, at the same time. Signed-off-by: Borislav Petkov <bp@suse.de> Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Diffstat (limited to 'arch/x86/mm')
-rw-r--r--arch/x86/mm/pageattr.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index c53de62a1170..4b47ae0602e1 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -666,6 +666,45 @@ static int split_large_page(pte_t *kpte, unsigned long address)
666 return 0; 666 return 0;
667} 667}
668 668
669#define populate_pud(cpa, addr, pgd, pgprot) (-1)
670
671/*
672 * Restrictions for kernel page table do not necessarily apply when mapping in
673 * an alternate PGD.
674 */
675static int populate_pgd(struct cpa_data *cpa, unsigned long addr)
676{
677 pgprot_t pgprot = __pgprot(_KERNPG_TABLE);
678 bool allocd_pgd = false;
679 pgd_t *pgd_entry;
680 pud_t *pud = NULL; /* shut up gcc */
681 int ret;
682
683 pgd_entry = cpa->pgd + pgd_index(addr);
684
685 /*
686 * Allocate a PUD page and hand it down for mapping.
687 */
688 if (pgd_none(*pgd_entry)) {
689 pud = (pud_t *)get_zeroed_page(GFP_KERNEL | __GFP_NOTRACK);
690 if (!pud)
691 return -1;
692
693 set_pgd(pgd_entry, __pgd(__pa(pud) | _KERNPG_TABLE));
694 allocd_pgd = true;
695 }
696
697 pgprot_val(pgprot) &= ~pgprot_val(cpa->mask_clr);
698 pgprot_val(pgprot) |= pgprot_val(cpa->mask_set);
699
700 ret = populate_pud(cpa, addr, pgd_entry, pgprot);
701 if (ret < 0)
702 return ret;
703
704 cpa->numpages = ret;
705 return 0;
706}
707
669static int __cpa_process_fault(struct cpa_data *cpa, unsigned long vaddr, 708static int __cpa_process_fault(struct cpa_data *cpa, unsigned long vaddr,
670 int primary) 709 int primary)
671{ 710{