- ページテーブルエントリ(PTE)が、それはPTEが他のすべてのPAGE-に同一の物理ブロックを強要するためのポインティング/まったく同じであることを持っていることを意味し、一つのプロセスのページ・テーブルにグローバルとしてマークされている場合テーブル?
PTEは(メモリに)いくつかのページ・テーブルに(グローバルとして設定)NG = 0を持っている場合、それは何を意味します。しかし、このPTEがTLBキャッシュにロードされると、このビットはこの仮想アドレスとこのキャッシュされたPTEがどのように一致するかを変更します(ASIDがサポートされているモードでは ")。この問題を解決するために、ARMv8では、それによって、フラグ "-" ARM上のカーネルの命令レベルのデータ分離 "をクリアすることにより、特定のページでASIDが無視されます。すべての要求は、現在のASIDからnG = 1(プロセス)のPTE ASIDまで一致します。 nG = 0(グローバル)マッピングの仮想アドレスのみに基づいて一致します。したがって、すべてのページテーブルでグローバルマッピングを同じに保つことは非常に便利です。頻繁に変更することなく、カーネルのアドレス空間のようなグローバルなものに対してのみ使用してください。
- 不一致の場合はどうなりますか?つまり、あるプロセスが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_NG
arch/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に書き込まれませんでした。
スレッドが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
1つのコアが同じプロセスのページテーブルを更新すると、別のコアに対するTLBの無効化について理解します。私は、異なるプロセスのために同じ(または少なくとも私が思うもの)である必要があるグローバルページについて混乱しています。 1つのプロセスがグローバルPTEを更新する場合、更新を他のプロセスのページテーブルに伝播する必要がありますか?これはどうですか? – thorondor1990
それはLinuxのバージョンですか?いくつかのARMドキュメントをnGビット記述とリンクできますか? x86/x86_64では、ページテーブルの世界的な "グローバル"部分( "負のアドレス"はポインタを符号付きと解釈します)はカーネルメモリに使用され、ブート時にはより大きなページ(2M、1G)変化する。他の(理論的な)方法は、単一ページテーブルのサブツリーをカーネルスペースに使用し、すべてのプロセスページテーブルからリンクするだけです(いくつかのカーネルマッピングが変更された場合でもtlb flushが必要です)。以前のttbr1は、カーネルhttp:// elinuxに使用されていました。org/Tims_Notes_on_ARM_memory_allocation – osgx