Linux Audio

Check our new training course

Embedded Linux Audio

Check our new training course
with Creative Commons CC-BY-SA
lecture materials

 Bootlin logo

Elixir Cross Referencer

Loading...
 one
 two
 three
 four
 five
 six
 seven
 eight
 nine
 ten
 eleven
 twelve
 thirteen
 fourteen
 fifteen
 sixteen
 seventeen
 eighteen
 nineteen
 twenty
 twenty-one
 twenty-two
 twenty-three
 twenty-four
 twenty-five
 twenty-six
 twenty-seven
 twenty-eight
 twenty-nine
 thirty
 thirty-one
 thirty-two
 thirty-three
 thirty-four
 thirty-five
 thirty-six
 thirty-seven
 thirty-eight
 thirty-nine
 forty
 forty-one
 forty-two
 forty-three
 forty-four
 forty-five
 forty-six
 forty-seven
 forty-eight
 forty-nine
 fifty
 fifty-one
 fifty-two
 fifty-three
 fifty-four
 fifty-five
 fifty-six
 fifty-seven
 fifty-eight
 fifty-nine
 sixty
 sixty-one
 sixty-two
 sixty-three
 sixty-four
 sixty-five
 sixty-six
 sixty-seven
 sixty-eight
 sixty-nine
 seventy
 seventy-one
 seventy-two
 seventy-three
 seventy-four
 seventy-five
 seventy-six
 seventy-seven
 seventy-eight
 seventy-nine
 eighty
 eighty-one
 eighty-two
 eighty-three
 eighty-four
 eighty-five
 eighty-six
 eighty-seven
 eighty-eight
 eighty-nine
 ninety
 ninety-one
 ninety-two
 ninety-three
 ninety-four
 ninety-five
 ninety-six
 ninety-seven
 ninety-eight
 ninety-nine
 one hundred
 one hundred and one
 one hundred and two
 one hundred and three
 one hundred and four
 one hundred and five
 one hundred and six
 one hundred and seven
 one hundred and eight
 one hundred and nine
 one hundred and ten
 one hundred and eleven
 one hundred and twelve
 one hundred and thirteen
 one hundred and fourteen
 one hundred and fifteen
 one hundred and sixteen
 one hundred and seventeen
 one hundred and eighteen
 one hundred and nineteen
 one hundred and twenty
 one hundred and twenty-one
 one hundred and twenty-two
 one hundred and twenty-three
 one hundred and twenty-four
 one hundred and twenty-five
 one hundred and twenty-six
 one hundred and twenty-seven
 one hundred and twenty-eight
 one hundred and twenty-nine
 one hundred and thirty
 one hundred and thirty-one
 one hundred and thirty-two
 one hundred and thirty-three
 one hundred and thirty-four
 one hundred and thirty-five
 one hundred and thirty-six
 one hundred and thirty-seven
 one hundred and thirty-eight
 one hundred and thirty-nine
 one hundred and forty
 one hundred and forty-one
 one hundred and forty-two
 one hundred and forty-three
 one hundred and forty-four
 one hundred and forty-five
 one hundred and forty-six
 one hundred and forty-seven
 one hundred and forty-eight
 one hundred and forty-nine
 one hundred and fifty
 one hundred and fifty-one
 one hundred and fifty-two
 one hundred and fifty-three
 one hundred and fifty-four
 one hundred and fifty-five
 one hundred and fifty-six
 one hundred and fifty-seven
 one hundred and fifty-eight
 one hundred and fifty-nine
 one hundred and sixty
 one hundred and sixty-one
 one hundred and sixty-two
 one hundred and sixty-three
 one hundred and sixty-four
 one hundred and sixty-five
 one hundred and sixty-six
 one hundred and sixty-seven
 one hundred and sixty-eight
 one hundred and sixty-nine
 one hundred and seventy
 one hundred and seventy-one
 one hundred and seventy-two
 one hundred and seventy-three
 one hundred and seventy-four
 one hundred and seventy-five
 one hundred and seventy-six
 one hundred and seventy-seven
 one hundred and seventy-eight
 one hundred and seventy-nine
 one hundred and eighty
 one hundred and eighty-one
 one hundred and eighty-two
 one hundred and eighty-three
 one hundred and eighty-four
 one hundred and eighty-five
 one hundred and eighty-six
 one hundred and eighty-seven
 one hundred and eighty-eight
 one hundred and eighty-nine
 one hundred and ninety
 one hundred and ninety-one
 one hundred and ninety-two
 one hundred and ninety-three
 one hundred and ninety-four
 one hundred and ninety-five
 one hundred and ninety-six
 one hundred and ninety-seven
 one hundred and ninety-eight
 one hundred and ninety-nine
 two hundred
 two hundred and one
 two hundred and two
 two hundred and three
 two hundred and four
 two hundred and five
 two hundred and six
 two hundred and seven
 two hundred and eight
 two hundred and nine
 two hundred and ten
 two hundred and eleven
 two hundred and twelve
 two hundred and thirteen
 two hundred and fourteen
 two hundred and fifteen
 two hundred and sixteen
 two hundred and seventeen
 two hundred and eighteen
 two hundred and nineteen
 two hundred and twenty
 two hundred and twenty-one
 two hundred and twenty-two
 two hundred and twenty-three
 two hundred and twenty-four
 two hundred and twenty-five
 two hundred and twenty-six
 two hundred and twenty-seven
 two hundred and twenty-eight
 two hundred and twenty-nine
 two hundred and thirty
 two hundred and thirty-one
 two hundred and thirty-two
 two hundred and thirty-three
 two hundred and thirty-four
 two hundred and thirty-five
 two hundred and thirty-six
 two hundred and thirty-seven
 two hundred and thirty-eight
 two hundred and thirty-nine
 two hundred and forty
 two hundred and forty-one
 two hundred and forty-two
 two hundred and forty-three
 two hundred and forty-four
 two hundred and forty-five
 two hundred and forty-six
 two hundred and forty-seven
 two hundred and forty-eight
 two hundred and forty-nine
 two hundred and fifty
 two hundred and fifty-one
 two hundred and fifty-two
 two hundred and fifty-three
 two hundred and fifty-four
 two hundred and fifty-five
 two hundred and fifty-six
 two hundred and fifty-seven
 two hundred and fifty-eight
 two hundred and fifty-nine
 two hundred and sixty
 two hundred and sixty-one
 two hundred and sixty-two
 two hundred and sixty-three
 two hundred and sixty-four
 two hundred and sixty-five
 two hundred and sixty-six
 two hundred and sixty-seven
 two hundred and sixty-eight
 two hundred and sixty-nine
 two hundred and seventy
 two hundred and seventy-one
 two hundred and seventy-two
 two hundred and seventy-three
 two hundred and seventy-four
 two hundred and seventy-five
 two hundred and seventy-six
 two hundred and seventy-seven
 two hundred and seventy-eight
 two hundred and seventy-nine
 two hundred and eighty
 two hundred and eighty-one
 two hundred and eighty-two
 two hundred and eighty-three
 two hundred and eighty-four
 two hundred and eighty-five
 two hundred and eighty-six
 two hundred and eighty-seven
 two hundred and eighty-eight
 two hundred and eighty-nine
 two hundred and ninety
 two hundred and ninety-one
 two hundred and ninety-two
 two hundred and ninety-three
 two hundred and ninety-four
 two hundred and ninety-five
 two hundred and ninety-six
 two hundred and ninety-seven
 two hundred and ninety-eight
 two hundred and ninety-nine
 three hundred
 three hundred and one
 three hundred and two
 three hundred and three
 three hundred and four
 three hundred and five
 three hundred and six
 three hundred and seven
 three hundred and eight
 three hundred and nine
 three hundred and ten
 three hundred and eleven
 three hundred and twelve
 three hundred and thirteen
 three hundred and fourteen
 three hundred and fifteen
 three hundred and sixteen
 three hundred and seventeen
 three hundred and eighteen
 three hundred and nineteen
 three hundred and twenty
 three hundred and twenty-one
 three hundred and twenty-two
 three hundred and twenty-three
 three hundred and twenty-four
 three hundred and twenty-five
 three hundred and twenty-six
 three hundred and twenty-seven
 three hundred and twenty-eight
 three hundred and twenty-nine
 three hundred and thirty
 three hundred and thirty-one
 three hundred and thirty-two
 three hundred and thirty-three
 three hundred and thirty-four
 three hundred and thirty-five
 three hundred and thirty-six
 three hundred and thirty-seven
 three hundred and thirty-eight
 three hundred and thirty-nine
 three hundred and forty
 three hundred and forty-one
 three hundred and forty-two
 three hundred and forty-three
 three hundred and forty-four
 three hundred and forty-five
 three hundred and forty-six
 three hundred and forty-seven
 three hundred and forty-eight
 three hundred and forty-nine
 three hundred and fifty
 three hundred and fifty-one
 // SPDX-License-Identifier: GPL-2.0
 /*
 * This code is used on x86_64 to create page table identity mappings on
 * demand by building up a new set of page tables (or appending to the
 * existing ones),  and then switching over to them when ready.
 *
 * Copyright (C) 2015-2016  Yinghai Lu
 * Copyright (C)      2016  Kees Cook
 */

 /*
 * Since we're dealing with identity mappings,  physical and virtual
 * addresses are the same,  so override these defines which are ultimately
 * used by the headers in misc.h.
 */
 #define __pa (x)  ((unsigned long)(x))
 #define __va (x)  ((void *)((unsigned long)(x)))

 /* No PAGE_TABLE_ISOLATION support needed either: */
 # undef  CONFIG_PAGE_TABLE_ISOLATION

 #include  " error.h "
 #include  " misc.h "

 /* These actually do the work of building the kernel identity maps. */
 #include  < linux/pgtable.h >
 #include  <asm/cmpxchg.h>
 #include  <asm/trap_pf.h>
 #include  <asm/trapnr.h>
 #include  <asm/init.h>
 /* Use the static base for this part of the boot process */
 # undef  __PAGE_OFFSET
 #define __PAGE_OFFSET  __PAGE_OFFSET_BASE
 #include  " ../../ mm/ident_map.c "

 #define _SETUP
 #include  <asm/setup.h> /* For COMMAND_LINE_SIZE */
 # undef  _SETUP

 extern  unsigned  long  get_cmd_line_ptr ( void );

 /* Used by PAGE_KERN* macros: */
 pteval_t  __default_kernel_pte_mask  __read_mostly  =  ~ zero ;

 /* Used to track our page table allocation area. */
 struct  alloc_pgt_data  {
	 unsigned  char  * pgt_buf ;
	 unsigned  long  pgt_buf_size ;
	 unsigned  long  pgt_buf_offset ;
 };

 /*
 * Allocates space for a page table entry,  using struct alloc_pgt_data
 * above.  Besides the local callers, this is used as the allocation
 * callback in mapping_info below.
 */
 static  void  * alloc_pgt_page ( void  * context )
 {
	 struct  alloc_pgt_data  * pages  =  ( struct  alloc_pgt_data  * ) context ;
	 unsigned  char  * entry ;

	 /* Validate there is space available for a new page. */
	 if  ( pages -> pgt_buf_offset  >=  pages -> pgt_buf_size )  {
		 debug_putstr ( "out of pgt_buf in "  __FILE__  "!? \n " );
		 debug_putaddr ( pages -> pgt_buf_offset );
		 debug_putaddr ( pages -> pgt_buf_size );
		 return  NULL ;
	 }

	 entry  =  pages -> pgt_buf  +  pages -> pgt_buf_offset ;
	 pages -> pgt_buf_offset  +=  PAGE_SIZE ;

	 return  entry ;
 }

 /* Used to track our allocated page tables. */
 static  struct  alloc_pgt_data  pgt_data ;

 /* The top level page table entry pointer. */
 static  unsigned  long  top_level_pgt ;

 phys_addr_t  physical_mask  =  ( 1ULL  <<  __PHYSICAL_MASK_SHIFT )  -  one ;

 /*
 * Mapping information structure passed to kernel_ident_mapping_init().
 * Due to relocation,  pointers must be assigned at run time not build time.
 */
 static  struct  x86_mapping_info  mapping_info ;

 /*
 * Adds the specified range to the identity mappings.
 */
 static  void  add_identity_map ( unsigned  long  start ,  unsigned  long  end )
 {
	 int  ret ;

	 /* Align boundary to 2M. */
	 start  =  round_down ( start ,  PMD_SIZE );
	 end  =  round_up ( end ,  PMD_SIZE );
	 if  ( start  >=  end )
		 return ;

	 /* Build the mapping. */
	 ret  =  kernel_ident_mapping_init ( & mapping_info ,  ( pgd_t  * ) top_level_pgt ,  start ,  end );
	 if  ( ret )
		 error ( "Error: kernel_ident_mapping_init() failed \n " );
 }

 /* Locates and clears a region for a new top level page table. */
 void  initialize_identity_maps ( void  * rmode )
 {
	 unsigned  long  cmdline ;

	 /* Exclude the encryption mask from __PHYSICAL_MASK */
	 physical_mask  &=  ~ sme_me_mask ;

	 /* Init mapping_info with run-time function/buffer pointers. */
	 mapping_info . alloc_pgt_page  =  alloc_pgt_page ;
	 mapping_info . context  =  & pgt_data ;
	 mapping_info . page_flag  =  __PAGE_KERNEL_LARGE_EXEC  |  sme_me_mask ;
	 mapping_info . kernpg_flag  =  _KERNPG_TABLE ;

	 /*
 * It should be impossible for this not to already be true,
 * but since calling this a second time would rewind the other
 * counters,  let's just make sure this is reset too.
 */
	 pgt_data . pgt_buf_offset  =  zero ;

	 /*
 * If we came here via startup_32(),  cr3 will be _pgtable already
 * and we must append to the existing area instead of entirely
 * overwriting it.
 *
 * With 5-level paging,  we use '_pgtable' to allocate the p4d page table,
 * the top-level page table is allocated separately.
 *
 * p4d_offset(top_level_pgt, 0) would cover both the 4- and 5-level
 * cases.  On 4-level paging it's equal to 'top_level_pgt'.
 */
	 top_level_pgt  =  read_cr3_pa ();
	 if  ( p4d_offset (( pgd_t  * ) top_level_pgt ,  zero )  ==  ( p4d_t  * ) _pgtable )  {
		 pgt_data . pgt_buf  =  _pgtable  +  BOOT_INIT_PGT_SIZE ;
		 pgt_data . pgt_buf_size  =  BOOT_PGT_SIZE  -  BOOT_INIT_PGT_SIZE ;
		 memset ( pgt_data . pgt_buf ,  zero ,  pgt_data . pgt_buf_size );
	 }  else  {
		 pgt_data . pgt_buf  =  _pgtable ;
		 pgt_data . pgt_buf_size  =  BOOT_PGT_SIZE ;
		 memset ( pgt_data . pgt_buf ,  zero ,  pgt_data . pgt_buf_size );
		 top_level_pgt  =  ( unsigned  long ) alloc_pgt_page ( & pgt_data );
	 }

	 /*
 * New page-table is set up - map the kernel image, boot_params and the
 * command line.  The uncompressed kernel requires boot_params and the
 * command line to be mapped in the identity mapping.  Map them
 * explicitly here in case the compressed kernel does not touch them,
 * or does not touch all the pages covering them.
 */
	 add_identity_map (( unsigned  long ) _head ,  ( unsigned  long ) _end );
	 boot_params  =  rmode ;
	 add_identity_map (( unsigned  long ) boot_params ,  ( unsigned  long )( boot_params  +  one ));
	 cmdline  =  get_cmd_line_ptr ();
	 add_identity_map ( cmdline ,  cmdline  +  COMMAND_LINE_SIZE );

	 /* Load the new page-table. */
	 sev_verify_cbit ( top_level_pgt );
	 write_cr3 ( top_level_pgt );
 }

 static  pte_t  * split_large_pmd ( struct  x86_mapping_info  * info ,
			       pmd_t  * pmdp ,  unsigned  long  __address )
 {
	 unsigned  long  page_flags ;
	 unsigned  long  address ;
	 pte_t  * pte ;
	 pmd_t  pmd ;
	 int  i ;

	 pte  =  ( pte_t  * ) info -> alloc_pgt_page ( info -> context );
	 if  ( ! pte )
		 return  NULL ;

	 address      =  __address  &  PMD_MASK ;
	 /* No large page - clear PSE flag */
	 page_flags   =  info -> page_flag  &  ~ _PAGE_PSE ;

	 /* Populate the PTEs */
	 for  ( i  =  zero ;  i  <  PTRS_PER_PMD ;  i ++ )  {
		 set_pte ( & pte [ i ],  __pte ( address  |  page_flags ));
		 address  +=  PAGE_SIZE ;
	 }

	 /*
 * Ideally we need to clear the large PMD first and do a TLB
 * flush before we write the new PMD.  But the 2M range of the
 * PMD might contain the code we execute and/or the stack
 * we are on,  so we can't do that. But that should be safe here
 * because we are going from large to small mappings and we are
 * also the only user of the page-table,  so there is no chance
 * of a TLB multihit.
 */
	 pmd  =  __pmd (( unsigned  long ) pte  |  info -> kernpg_flag );
	 set_pmd ( pmdp ,  pmd );
	 /* Flush TLB to establish the new PMD */
	 write_cr3 ( top_level_pgt );

	 return  pte  +  pte_index ( __address );
 }

 static  void  clflush_page ( unsigned  long  address )
 {
	 unsigned  int  flush_size ;
	 char  * cl ,  * start ,  * end ;

	 /*
 * Hardcode cl-size to 64 - CPUID can't be used here because that might
 * cause another #VC exception and the GHCB is not ready to use yet.
 */
	 flush_size  =  sixty-four ;
	 start       =  ( char  * )( address  &  PAGE_MASK );
	 end         =  start  +  PAGE_SIZE ;

	 /*
 * First make sure there are no pending writes on the cache-lines to
 * flush.
 */
	 asm  volatile ( "mfence"  :  :  :  "memory" );

	 for  ( cl  =  start ;  cl  !=  end ;  cl  +=  flush_size )
		 clflush ( cl );
 }

 static  int  set_clr_page_flags ( struct  x86_mapping_info  * info ,
			       unsigned  long  address ,
			       pteval_t  set ,  pteval_t  clr )
 {
	 pgd_t  * pgdp  =  ( pgd_t  * ) top_level_pgt ;
	 p4d_t  * p4dp ;
	 pud_t  * pudp ;
	 pmd_t  * pmdp ;
	 pte_t  * ptep ,  pte ;

	 /*
 * First make sure there is a PMD mapping for 'address'.
 * It should already exist,  but keep things generic.
 *
 * To map the page just read from it and fault it in if there is no
 * mapping yet.  add_identity_map() can't be called here because that
 * would unconditionally map the address on PMD level, destroying any
 * PTE-level mappings that might already exist.  Use assembly here so
 * the access won't be optimized away.
 */
	 asm  volatile ( "mov %[address], %%r9"
		      ::  [ address ]  "g"  ( * ( unsigned  long  * ) address )
		      :  "r9" ,  "memory" );

	 /*
 * The page is mapped at least with PMD size - so skip checks and walk
 * directly to the PMD.
 */
	 p4dp  =  p4d_offset ( pgdp ,  address );
	 pudp  =  pud_offset ( p4dp ,  address );
	 pmdp  =  pmd_offset ( pudp ,  address );

	 if  ( pmd_large ( * pmdp ))
		 ptep  =  split_large_pmd ( info ,  pmdp ,  address );
	 else
		 ptep  =  pte_offset_kernel ( pmdp ,  address );

	 if  ( ! ptep )
		 return  - ENOMEM ;

	 /*
 * Changing encryption attributes of a page requires to flush it from
 * the caches.
 */
	 if  (( set  |  clr )  &  _PAGE_ENC )
		 clflush_page ( address );

	 /* Update PTE */
	 pte  =  * ptep ;
	 pte  =  pte_set_flags ( pte ,  set );
	 pte  =  pte_clear_flags ( pte ,  clr );
	 set_pte ( ptep ,  pte );

	 /* Flush TLB after changing encryption attribute */
	 write_cr3 ( top_level_pgt );

	 return  zero ;
 }

 int  set_page_decrypted ( unsigned  long  address )
 {
	 return  set_clr_page_flags ( & mapping_info ,  address ,  zero ,  _PAGE_ENC );
 }

 int  set_page_encrypted ( unsigned  long  address )
 {
	 return  set_clr_page_flags ( & mapping_info ,  address ,  _PAGE_ENC ,  zero );
 }

 int  set_page_non_present ( unsigned  long  address )
 {
	 return  set_clr_page_flags ( & mapping_info ,  address ,  zero ,  _PAGE_PRESENT );
 }

 static  void  do_pf_error ( const  char  * msg ,  unsigned  long  error_code ,
			 unsigned  long  address ,  unsigned  long  ip )
 {
	 error_putstr ( msg );

	 error_putstr ( " \n Error Code: " );
	 error_puthex ( error_code );
	 error_putstr ( " \n CR2: 0x" );
	 error_puthex ( address );
	 error_putstr ( " \n RIP relative to _head: 0x" );
	 error_puthex ( ip  -  ( unsigned  long ) _head );
	 error_putstr ( " \n " );

	 error ( "Stopping. \n " );
 }

 void  do_boot_page_fault ( struct  pt_regs  * regs ,  unsigned  long  error_code )
 {
	 unsigned  long  address  =  native_read_cr2 ();
	 unsigned  long  end ;
	 bool  ghcb_fault ;

	 ghcb_fault  =  sev_es_check_ghcb_fault ( address );

	 address    &=  PMD_MASK ;
	 end         =  address  +  PMD_SIZE ;

	 /*
 * Check for unexpected error codes.  Unexpected are:
 *	- Faults on present pages
 *	- User faults
 *	- Reserved bits set
 */
	 if  ( error_code  &  ( X86_PF_PROT  |  X86_PF_USER  |  X86_PF_RSVD ))
		 do_pf_error ( "Unexpected page-fault:" ,  error_code ,  address ,  regs -> ip );
	 else  if  ( ghcb_fault )
		 do_pf_error ( "Page-fault on GHCB page:" ,  error_code ,  address ,  regs -> ip );

	 /*
 * Error code is sane - now identity map the 2M region around
 * the faulting address.
 */
	 add_identity_map ( address ,  end );
 }