On Wed, Apr 21, 2021 at 12:12:13PM +0000, Ashish Kalra wrote: > Yes, both have some common code, but it is only this page level/size > ... See below for what I mean. Diff ontop of yours. > I see that early_set_memory_enc_dec() is also using a for loop, so which > patches are you referring to ? The SNP guest set has this pattern: https://lkml.kernel.org/r/20210408114049.GI10192@xxxxxxx --- diff --git a/arch/x86/mm/mem_encrypt.c b/arch/x86/mm/mem_encrypt.c index b1d59d2b3bf6..e823645101ee 100644 --- a/arch/x86/mm/mem_encrypt.c +++ b/arch/x86/mm/mem_encrypt.c @@ -232,6 +232,37 @@ void __init sev_setup_arch(void) swiotlb_adjust_size(size); } +static unsigned long pg_level_to_pfn(int level, pte_t *kpte, pgprot_t *ret_prot) +{ + unsigned long pfn = 0; + pgprot_t prot; + + switch (level) { + case PG_LEVEL_4K: + pfn = pte_pfn(*kpte); + prot = pte_pgprot(*kpte); + break; + + case PG_LEVEL_2M: + pfn = pmd_pfn(*(pmd_t *)kpte); + prot = pmd_pgprot(*(pmd_t *)kpte); + break; + + case PG_LEVEL_1G: + pfn = pud_pfn(*(pud_t *)kpte); + prot = pud_pgprot(*(pud_t *)kpte); + break; + + default: + return 0; + } + + if (ret_prot) + *ret_prot = prot; + + return pfn; +} + static void set_memory_enc_dec_hypercall(unsigned long vaddr, int npages, bool enc) { @@ -249,19 +280,9 @@ static void set_memory_enc_dec_hypercall(unsigned long vaddr, int npages, if (!kpte || pte_none(*kpte)) return; - switch (level) { - case PG_LEVEL_4K: - pfn = pte_pfn(*kpte); - break; - case PG_LEVEL_2M: - pfn = pmd_pfn(*(pmd_t *)kpte); - break; - case PG_LEVEL_1G: - pfn = pud_pfn(*(pud_t *)kpte); - break; - default: - return; - } + pfn = pg_level_to_pfn(level, kpte, NULL); + if (!pfn) + continue; psize = page_level_size(level); pmask = page_level_mask(level); @@ -279,22 +300,9 @@ static void __init __set_clr_pte_enc(pte_t *kpte, int level, bool enc) unsigned long pfn, pa, size; pte_t new_pte; - switch (level) { - case PG_LEVEL_4K: - pfn = pte_pfn(*kpte); - old_prot = pte_pgprot(*kpte); - break; - case PG_LEVEL_2M: - pfn = pmd_pfn(*(pmd_t *)kpte); - old_prot = pmd_pgprot(*(pmd_t *)kpte); - break; - case PG_LEVEL_1G: - pfn = pud_pfn(*(pud_t *)kpte); - old_prot = pud_pgprot(*(pud_t *)kpte); - break; - default: + pfn = pg_level_to_pfn(level, kpte, &old_prot); + if (!pfn) return; - } new_prot = old_prot; if (enc) -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette