1

私は、各プロセスが別々のページテーブルを持つことができ、TTBR0/1_EL1を更新することによってコンテキスト切り替え中にポイントできることを理解します。各プロセスのページテーブルの内側には、プロセス固有のエントリ(nG = 1)と、他のエントリが共通リソース(nG = 0)を指すエントリがあります。ARMv8では、グローバルページテーブルエントリが異なるプロセス間で競合するとどうなりますか?

  1. ページテーブルエントリ(PTE)が1つのプロセスのページテーブルでグローバルとしてマークされている場合、PTEは他のすべてのページテーブルとまったく同じ物理ブロックに同じである必要がありますか?
  2. 「はい」の場合、不一致の場合はどうなりますか?つまり、あるプロセスがnG = 0で、別のプロセスが同じ仮想 - >物理マッピングでnG = 1の場合、OSからのページテーブルの作成に問題がありますか?
  3. 私の2番目の質問が関連している場合、どのようにグローバルPTEがすべてのプロセスのページテーブルに表示されるように、すべてのグローバルPTEが異なるプロセス間でコヒーレントであることをOSが確認しますか?

スタックオーバーフローやその他のサイトで検索しましたが、グローバルページのメンテナンスに関して十分な説明がありませんでした。

ありがとうございます!

+0

スレッドが1つ以上あるプロセスがあります。 OSは、このプロセス(ページテーブル)に対して単一の仮想 - 物理変換を作成します。このプロセスのスレッドがCPU上にある場合、CPUのPTレジスタはプロセスページテーブルを指すように設定されます。したがって、すべてのCPUから単一のページテーブルを使用することによって、OSがPTEをプロセスコヒーレントにする方法があります。実際の問題は、PTEをTLBにキャッシュすることです - メモリ内のPTEの1つが変更された場合、このプロセスのスレッドを実行している(またはPTEをTLBにキャッシュしている)他のCPUのTLBは 'flush_tlb_ *':https:// www .kernel.org/doc/Documentation/cachetlb.txt – osgx

+0

1つのコアが同じプロセスのページテーブルを更新すると、別のコアに対するTLBの無効化について理解します。私は、異なるプロセスのために同じ(または少なくとも私が思うもの)である必要があるグローバルページについて混乱しています。 1つのプロセスがグローバルPTEを更新する場合、更新を他のプロセスのページテーブルに伝播する必要がありますか?これはどうですか? – thorondor1990

+0

それはLinuxのバージョンですか?いくつかのARMドキュメントをnGビット記述とリンクできますか? x86/x86_64では、ページテーブルの世界的な "グローバル"部分( "負のアドレス"はポインタを符号付きと解釈します)はカーネルメモリに使用され、ブート時にはより大きなページ(2M、1G)変化する。他の(理論的な)方法は、単一ページテーブルのサブツリーをカーネルスペースに使用し、すべてのプロセスページテーブルからリンクするだけです(いくつかのカーネルマッピングが変更された場合でもtlb flushが必要です)。以前のttbr1は、カーネルhttp:// elinuxに使用されていました。org/Tims_Notes_on_ARM_memory_allocation – osgx

答えて

1
  1. ページテーブルエントリ(PTE)が、それはPTEが他のすべてのPAGE-に同一の物理ブロックを強要するためのポインティング/まったく同じであることを持っていることを意味し、一つのプロセスのページ・テーブルにグローバルとしてマークされている場合テーブル?

PTEは(メモリに)いくつかのページ・テーブルに(グローバルとして設定)NG = 0を持っている場合、それは何を意味します。しかし、このPTEがTLBキャッシュにロードされると、このビットはこの仮想アドレスとこのキャッシュされたPTEがどのように一致するかを変更します(ASIDがサポートされているモードでは ")。この問題を解決するために、ARMv8では、それによって、フラグ "-" ARM上のカーネルの命令レベルのデータ分離 "をクリアすることにより、特定のページでASIDが無視されます。すべての要求は、現在のASIDからnG = 1(プロセス)のPTE ASIDまで一致します。 nG = 0(グローバル)マッピングの仮想アドレスのみに基づいて一致します。したがって、すべてのページテーブルでグローバルマッピングを同じに保つことは非常に便利です。頻繁に変更することなく、カーネルのアドレス空間のようなグローバルなものに対してのみ使用してください。

  1. 不一致の場合はどうなりますか?つまり、あるプロセスがnG = 0で、別のプロセスが同じ仮想 - >物理マッピングでnG = 1の場合、OSからのページテーブルの作成に問題がありますか?

PTEが正しくメモリに格納されていないときは何も起こりません。 TLBにキャッシュされ、プロセスが切り替わると、この仮想アドレス(マッピング)へのアクセスに間違った物理アドレスが生成されます。

どのようにグローバルPTEがすべてのプロセスのページテーブルに表示されるように、すべてのグローバルPTEが異なるプロセス間でコヒーレントであることをOSが確認しますか?

OSがマッピングを作成すると、関連するページテーブルが編集されます。グローバルマッピングが追加されると、正しい場所に書き込まれます。私は、プロセス間でカーネル空間のページテーブルのいくつかのサブツリーを部分的に共有することが可能だと考えています(アーキテクチャはページテーブルをx86のような階層ツリーとして実装しています)。多くの場合、カーネル空間 - ユーザー空間分割(歴史的には2GB/2GBの仮想アドレス空間https://lkml.org/lkml/2006/1/10/189)があり、仮想メモリの半分がカーネル用に(グローバルに)マップされています。 ARMでは、この分割は通常、EL1のTTBR0をユーザスペースのページテーブルルートに使用し、TTBR1をカーネルスペースのページテーブルルートに使用します(http://infocenter.arm.com/help/topic/com.arm.doc.den0024a/BABBEFAE.html翻訳制御レジスタTCR_EL1を使用して分割ポイントを検索します)。 L2/L3ページテーブルでは、ARMはページテーブルにもサブツリーを持つので、異なるプロセスのいくつかのL2レコードは、カーネル/グローバルマッピングの一部に対して同じL3ページテーブルを指すことがあります(図12.8 64KBページin http://infocenter.arm.com/help/topic/com.arm.doc.den0024a/ch12s03.html ARM Cortex-AシリーズプログラマーズガイドARMv8-A - 12.3。仮想アドレスを物理アドレスに変換する)。異なるプロセスでグローバルマッピングを管理する別の解決策は、OSメモリ記述子(LinuxのVMA)から登録されたすべてのページテーブルへのリンクを持ち、それを使用できるすべてのCPU /コア/プロセスを何らかの停止で更新することですマッピングを変更し、すべてのCPUコアで範囲をフラッシュし、すべてのCPU /コア/プロセスを停止します。 = NGに設定することで

#define PTE_NG   (_AT(pteval_t, 1) << 11) /* nG */ 

が、just uses itをどこでもユーザースペースとNGのための1(プロセス)=:私は理解したよう

、ARM64のためのLinuxカーネル4.11 PTE_NGarch/arm64/include/asm/pgtable-hwdef.hとしてNGのビットを知っています(PROT_DEVICE_*PROT_NORMAL_*PROT_KERNEL_*)カーネル空間のための0(グローバル): http://elixir.free-electrons.com/linux/v4.11/source/arch/arm64/include/asm/pgtable-prot.h#L67

#define PAGE_KERNEL  __pgprot(_PAGE_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE) 
#define PAGE_KERNEL_RO  __pgprot(_PAGE_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_RDONLY) 
#define PAGE_KERNEL_ROX  __pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_RDONLY) 
#define PAGE_KERNEL_EXEC __pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_WRITE) 
#define PAGE_KERNEL_EXEC_CONT __pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_CONT) 
... 
#define PAGE_NONE  __pgprot(((_PAGE_DEFAULT) & ~PTE_VALID) | PTE_PROT_NONE | PTE_PXN | PTE_UXN) 
#define PAGE_SHARED  __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE) 
#define PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_WRITE) 
#define PAGE_COPY  __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) 
#define PAGE_COPY_EXEC  __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN) 
#define PAGE_READONLY  __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) 
#define PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN) 
#define PAGE_EXECONLY  __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_PXN) 

およびLinux/Aarch64のドキュメントはTTBR0/TTBR1についてこう述べています。https://www.kernel.org/doc/Documentation/arm64/memory.txt「AArch64 Linux上のメモリレイアウト」カーネルアドレスが1に設定さ 同じビットを持っていながら、

ユーザーアドレスは0ビット63:48セットを持っていますTTBRxの選択は、 仮想アドレスのビット63によって与えられる。 swapper_pg_dirにはカーネル(グローバル) マッピングのみが含まれ、ユーザーpgdにはユーザー(非グローバル)マッピングのみが含まれます。 swapper_pg_dirアドレスがTTBR1に書き込まれ、 TTBR0に書き込まれませんでした。

+0

説明をありがとう!したがって、実際には、異なるプロセスページテーブルごとにすべてのグローバルページテーブルエントリを同じに保つ必要があります – thorondor1990

+0

ARMアーキテクチャには厳しい要件はありません。 2つのプロセスセットがあり、それらを同じCPUコアセットにマップしない場合、いくつかのグローバルマッピングが存在する場合があります。どうやらLinuxはTTBR1のためだけにグローバルを使い、常にすべてのコアのTTBR1で同じテーブルツリーの半分のツリーを使います。 – osgx

関連する問題