x86 の新しいメモリ保護機能 Supervisor Mode Access Prevention(SMAP)

Intel64 and IA-32 アーキテクチャ仕様書に取り込まれる前の新機能を定義する Intel Architecture Instruction Set Extensions Programming Reference が Aug. 2012 に改定され 014 になったようだ。前回は日記を書いたのは id:nminoru:20120901:intelcpu だった。

今回は Supervisor Mode Access Prevention (SMAP) というメモリ保護機能の追加がメインらしい。SMAP を有効にするには CR4 の bit 21 を立てる。

もともと x86 のページテーブルエントリには U/S (User/supervisor) ビットがあり、U/S が 0 なら supervisor-mode でのみアクセスが可能で user-mode がアクセスすると #PF 例外となっていた。一方、U/S が 1 なら supervisor-mode でも user-mode でもアクセスが可能である。あるいは supervisor-mode では U/S ビットにかかわらず全てのページがアクセス可能であるといえる。

しかし superviosr-mode であれば自由に user-mode のデータにアクセス可能というのもよろしくないと Intel は思ったらしい。SMAP 機能が有効な場合は、U/S が 1 のページにページにアクセス不能になり #PF 例外がでるようになる。User-mode では user page(U/S = 1)だけをアクセスして、super-visor では supervisor page(U/S = 0)だけをアクセスしなさいとのことらしい。

ただし仮想記憶が有効だと IA-32 だと 2段、Intel64 だと 4 段のページテーブルがあり U/S ビットは各段階に存在している。User-mode がアクセスするためにはその全ての段の U/S が 1 になっている必要があった。一方、SMAP で supervisor-mode はページテーブルのどこか一段でも U/S が 0 になっていればアクセスが可能である。

また super-visor から U/S = 1 のページが全部アクセスできなくなると不便なので、EFLAGS の AC フラグを 1 にすると SMAP 保護を一時的に無効化できるという例外がついている。EFLAGS の AC ビットは Aligment Check フラグだったはずだが、なぜこんなことに流用されるのかトンと分からぬ。本来の AC ビットの役割はどこにいったのだろう。

命令は CLAC(Clear AC Flag in EFLAGS Register) と STAC (Set AC Flag in EFLAGS Regsiter) の 2 命令が追加されている。