5.6 例外

5.6.1 例外要因コード

ハイパーバイザー拡張では、例外要因のエンコーディングについて決められている。表5.5はハイパーバイザーが実装された場合でのMモードおよびHSモードでの例外要因コードを示している。VSレベル例外(割り込み要因コード2,6,10)、スーパーバイザーレベルゲスト外部割込み(割り込み要因コード12)、仮想命令例外(例外要因コード22)、ゲストページフォルト例外(例外要因コード20, 21, 23)が定義されている。さらに、VSモードからのEnvironment Callが要因コード10に割り付けられており、一方でHSモードもしくはSモードからの要因コードが9に割り付けられている。

HSモードとVSモードのECALLは異なる割り込み要因コードを使用しているため、独立して移譲の設定を行うことができる。

V=1の場合、仮想命令例外(不定命令例外ではない)は以下の条件で発生する。

  • hcounterenの該当するビットが0であり、mcounterenの同じ場所のビットが1であるときにカウンタCSRにアクセスしようとした場合

  • ハイパーバイザー命令(HLV, HLVX, HSV, HFENCE)命令を実行しようとした場合、もしくは実装されているハイパーバイザーCSRかVS CSRにアクセスしようとした場合

  • VUモードでは、WFI命令もしくはスーパーバイザー命令(SRETもしくはSFENCE)命令を実行しようとした場合もしくはスーパーバイザーCSRにアクセスしようとした場合

  • VSモードでは、hstatus.VTW=1かつmstatus.TW=0のときにWFI命令を実行し、実装で定義されている特定の時間が経っても命令が完了しなかった場合。

  • VSモードでは、hstatus.VTSR=1の場合にSRET命令を実行しようとした場合、もしくは

  • VSモードにおいてhstatus.VTVM=1の場合にSFENCE命令を実行しようとした場合、もしくはsatpレジスタにアクセスしようとした場合

  • 表5.5: ハイパーバイザー拡張が実装されている場合のマシンモードとスーパーバイザーモードの例外要因レジスタ (mcause, scause)

割り込み

要因コード

説明

1

0

予約

1

1

スーパーバイザーソフトウェア割込み

1

2

仮想スーパーバイザーソフトウェア割込み

1

3

マシンレベルソフトウェア割込み

1

4

予約

1

5

スーパーバイザータイマ割り込み

1

6

仮想スーパーバイザータイマ割り込み

1

7

マシンモードタイマ割り込み

1

8

予約

1

9

スーパーバイザー外部割込み

1

10

仮想スーパーバイザー外部割込み

1

11

マシンモード外部割込み

1

12

スーパーバイザーゲスト外部割込み

1

13 - 15

予約

1

>= 16

プラットフォーム独自の割り込み、カスタム向け

0

0

命令フェッチアドレスミスアライン

0

1

命令アクセスフォルト

0

2

不正命令

0

3

ブレークポイント

0

4

ロードアドレスミスアライン

0

5

ロードアクセスフォルト

0

6

ストア/AMOアクセスミスアライン

0

7

ストア/AMOアクセスフォルト

0

8

UモードもしくはVUモードでのEnvironment Call

0

9

HSモードでのEnvironment Call

0

10

VSモードでのEnvironment Call

0

11

MモードでのEnvironment Call

0

12

命令フェッチページフォルト

0

13

ロードページフォルト

0

14

予約

0

15

ストア/AMOページフォルト

0

16 - 19

予約

0

20

命令フェッチゲストページフォルト

0

21

ロードゲストページフォルト

0

22

仮想命令

0

23

ストア/AMOゲストページフォルト

0

24 - 31

カスタム向け

0

32 - 47

予約

0

48 - 63

カスタム向け

0

>= 64

予約

仮想命令例外では、mtvalstvalに不正命令例外と同じ値が書き込まれる。

V=1の場合、VSモードまたはVUモードで無効な特権命令は、通常、不正な命令トラップではなく仮想命令トラップを引き起こす。同じことが、V=1のときにハイパーバイザーやスーパーバイザーレベルのCSRにアクセスしようとしても、特権が不十分なために失敗したり、ハイパーバイザーのCSRによってアクセスが明示的に無効にされているCSRにアクセスしようとしたりする場合にも当てはまる(例:hcounteren)。ネストしたハイパーバイザーをサポートするため、あるいはその他の理由で、ハイパーバイザーがこのような命令をエミュレートしなければならないことは珍しくない。命令をエミュレートしない場合、ハイパーバイザーは仮想命令トラップをゲスト仮想マシンの不正な命令例外に変換しなければならない。

通常、マシンレベルでは仮想命令トラップを直接HSレベルに委譲することが期待されるが、不正な命令トラップは、(ソフトウェアによって)HSレベルにコンディショナルに委譲される前に、Mモードで最初に処理される可能性が高い。その結果、仮想命令トラップは通常、違法命令トラップよりも高速に処理されることが期待されている。

5.6.2 例外発生時の動作

HSモードもしくはUモードで例外が発生した場合、medelegmidelegにより権限が委譲されない限りはMモードに移行する(移譲される場合はHSモードに移行する)。VSモードかVUモードで例外が発生した場合はmedelegmidelegにより移譲されない限りはMモードに移行する(移譲される場合はhedeleghidelegによりさらに移譲されてVSモードに移譲されない限りはHSモードに移行する)。

例外によりMモードに移行した場合、仮想モードVは0に設定され、mstatus(と``mstatush``)のMPVとMPPビットは表5.6に示す条件に則り設定される。例外によりMモードに移行されると、mstatus/mstatushのGVA, MPIE, MIEフィールドに値が書き込まれ、mepc, mcause, mtval, mtval2レジスタが書き込まれる。

以前のモード

MPV

MPP

Uモード

0

0

HSモード

0

1

Mモード

0

3

VUモード

1

0

VSモード

1

1

  • 表5.6: 例外発生によりMモードに移行した後のmstatus/mstatushのMPV、MPPの値。例外から復帰する場合、MPP=3の時にMPVの値は無視される。

例外発生によりHSモードに移行した場合、仮想モードVは0に設定され、hstatus.SPVhstatus.SPP表5.7に従い設定される。例外発生前にV=1であった場合、hstatusのSPVPはsstatus.SPPと同じ値が設定される; そうでなければ、SPVPの値は変化しない。例外発生によりHSモードに移行した場hstatusのGVAフィールド、sstatusSPIESIEフィールドも書き込まれ、sepc, scause, stval, htval, htinst CSRも更新される。

以前のモード

SPV

SPP

Uモード

0

0

HSモード

0

1

VUモード

1

0

VSモード

1

1

  • 表5.7: 例外発生によりHSモードに移行した後のhstatus/sstatusのSPV、SPPの値

例外発生によりVSモードに移行した場合、vsstatus.SPP表5.8に従い設定される。hstatusとHSレベルのsstatusの値は変更されず、仮想モードVも1が維持される。例外発生によりVSモードに移行した場合には、vsstatusのSPIEとSIEビットが設定され、vsepc, vscause, vstvalの値が更新される。

以前のモード

SPP

VUモード

0

VSモード

1

  • 表5.8: 例外発生によりVSモードに移行した後のvsstatusのSPPの値

5.6.3 mtinst, htinstの命令変換と疑似命令

MモードもしくはHSモードに移行するすべての命令は、自動的にトラップ命令CSR mtinstもしくはhtinstに適切な値が書き込まれる:

  • ゼロ

  • トラップが発生した命令の変形

  • カスタム値(トラップされた命令が標準的なものでない場合のみ許される)

  • 特殊な疑似命令

後述するつ疑似命令の値が必要である場合を除いて、mtinstもしくはhtinstに書き込まれる値は常に0であり、これらの特定の例外にハードウェアは何の情報も提供しないということを示している。

例外命令CSRに書き込まれる値には2つの目的がある。1つ目の目的は例外ハンドラにより命令のエミュレーション速度を向上させるためであり、特に例外ハンドラが例外の情報をメモリからロードする必要性を省略し、デコードと命令実行のいくつかのタスクを除去するためである。2つ目の目的はVSステージのアドレス変換による暗黙的なメモリアクセスにより発生した場合のゲストページフォルト例時に、さらなる情報を疑似命令を通じて提供するためである。

例外の発生した命令の「変換」とは、ハードウェアの負担を最小限に抑えつつ、例外ハンドラに命令をエミュレートするために必要な情報を提供するために、単に元の命令をコピーするのではなく変換処理が行われるものである。変換命令の代わりにゼロを代入することで、効率が低下する。

割り込み発生時には、例外命令レジスタの値は常にゼロである。同期例外発生時にゼロ以外の値が書き込まれた場合、その値について以下のことが成り立つ。

  • 0ビット目に1が書き込まれ、1ビット目に1が設定されることにより標準的な命令のエンコーディングにおいてこの値が有効であるということが示される。この場合には、レジスタの値は例外の発生した命令に関連する情報であることが示され、以降に示すようにレジスタの値は例外の発生した命令から変換されたものである。たとえば、ビット1:0が2進数11でありレジスタの値が標準的なLW(Load Word)である場合、例外の発生した命令はLWであり、レジスタには例外の発生したLW命令の変換が書き込まれる。

  • 0ビット目に 1が書き込まれ、1ビット目に1が設定されることでカスタム命令に明示的に指定されたエンコーディングとなる(使用されていない予約済みのエンコーディングではない)。これは「カスタム値」である。標準的でない命令により例外が発生した場合である。カスタム値の解釈は標準では定められていない。

  • 後述する特殊な疑似命令が設定される場合。ビット1:0は2進数で00が設定される。

これらの2つの場合は例えばビット1:0の値が2進数で10である場合など、他にも設定可能な多くの値を省略している。将来の仕様更新や拡張により他の条件が定義される可能性があり、このため現在はこれらの値の条件は省略されている。ソフトウェアは例外命令レジスタのこれらの値について、値がゼロであるのと同様に安全にこれらの値を扱わなければならない。

この規格の将来のリビジョンとの互換性を保つために、mtinstまたはhtinstから非ゼロ値を解釈するソフトウェアは、値が上記のいずれかのケースに準拠していることを完全に検証する必要がある。例えば、RV64の場合、mtinstのビット6:0が0000011、ビット14:12が010であることを発見しても、最初のケースが適用され、トラッピング命令が標準LW命令であることを確認するには不十分である。将来の標準規格では、ビット63:32がゼロではなく、ビット31:0が標準のRV64命令と同じビットパターンを持つ64ビットのmtinstの新しい値が定義される可能性がある。

標準命令とは異なり、カスタム値の命令エンコーディングは、トラップした命令と同じ「種類」である必要はない(例外発生命令との相関関係もない)。

表5.9は各標準的な例外要因について、例外命令レジスタに自動的に書き込まれる値を示している。例外時にこれらの命令のフェッチを防ぐために、ゼロもしくは疑似命令のみ書き込まれるようになている。例外の発生した命令が標準命令でない場合にのみ自動的にカスタム値が書き込まれる。将来の仕様更新や拡張により、上記の許可される値の集合の値を選択して他の値が書き込まれることは許される。

この表に示されるように、同期例外の場合、明示的なメモリアクセス(ロード命令、ストア命令、AMO命令)により例外が発生した場合にのみ例外命令レジスタに標準的な変換後の値が書き込まれる。この表によると、標準的な変換では現在はこれらのメモリアクセス命令のみ定義されている。もしこれらの変換が定義されていない同期例外が発生した場合、例外命令レジスにはゼロが書き込まれる(もしくはこのような状況の場合には特殊な疑似命令が書き込まれる)。

例外 ゼロ値 変換された標準命令 カスタム値 疑似命令値 ============================== ====== ================== ========== ========== 命令アドレスミスアライン Yes No Yes No 命令アクセスフォルト Yes No No No 不正命令 Yes No No No ブレークポイント Yes No Yes No 仮想命令 Yes No Yes No ロードアドレスミスアライン Yes Yes Yes No ロードアクセスフォルト Yes Yes Yes No ストア/AMOアドレスミスアライン Yes Yes Yes No ストア/AMOアクセスフォルト Yes Yes Yes No Environment Call Yes No Yes No 命令ページフォルト Yes No No No ロードページフォルト Yes Yes Yes No ストア/AMOページフォルト Yes Yes Yes No 命令ゲストページフォルト Yes No No Yes ロードゲストページフォルト Yes Yes Yes Yes ストア/AMOゲストページフォルト Yes Yes Yes Yes ============================== ====== ================== ========== ==========

  • 表5.9: 例外発生時に例外命令レジスタ(mtinstもしくはhtinst)に自動的に書き込まれる値

  • 表5.9: 例外発生時に例外命令レジスタ(mtinstもしくはhtinst)に自動的に書き込まれる値

Compressed命令ではない標準的なロード命令で、LB,LBU,LH, LHU, LW, LWU, LD, FLW, FLD, FLQの内一つに例外が発生した場合の変換された命令のフォーマットを図5.42に示す。

img

img

Compressedではない標準的なストア命令で、SB, SH, SW, SD, FSW, FSD, FSQのうち一つに例が外が発生した場合の変換された命令フォーマットを図5.43に示す。

img

img

標準的なアトミック命令(Load Reserved, Store Conditional, AMO命令)の、変換後の命令フォーマットを図5.44に示す。

img

img

標準的な仮想マシンロードストア命令(HLV, HLVX, HSV)では、変換後の命令フォーマットを図5.45に示す。

img

img

すべての変換された命令では、19:15ビットのrs1フィールドがAddr. Offsetフィールドに置き換えられており、この値は例外の発生した仮想アドレス(mtvalとstvalに書き込まれた値)とオリジナルの仮想アドレスの正の差分を表現している。ミスアラインメモリアクセスの場合、この値は非ゼロとなる可能性がある。基本的なロードストア命令では、即値のフィールドはすべて変換によりゼロに置き換えられる。

標準的なCompressed命令(16bit長)では、変換された命令は以下のようなフォーマットとなる。

  1. Compressed命令は32ビットに置き換えられる。

  2. 32ビットの等価な命令に置き換えられる。

  3. ビット1が0に置き換えられる。

例外の発生した命令がCompressed命令ではなく、ビット1:0が11ではない場合、変換後の標準的な命令では、ビット1:0が2進数01に置き換えられる。

  • mtinstまたはhtinstの内容をデコードする際に、ソフトウェアがレジスタが標準の基本ロード(LB,LBU,LH,LHU,LW,LWU,LD,FLW,FLD,FLQ)または基本ストア(SB,SH,SW,SD,FSW,FSD,FSQ)のエンコーディングを含んでいると判断した場合、即値オフセットフィールド(ビット31:25,および24:20または11:7)がゼロであることも証明する必要はない。レジスタの値が基本的なロード・ストアのエンコーディングであるという知識は、例外の命令が同じ種類のものであることを証明するのに十分である。

  • この規格の将来のバージョンでは、現在ゼロであるレジスタに情報が追加される可能性がある。しかし、下位互換性のために、そのような情報は性能向上のためだけのものであり、安全に無視することができる。

ゲストページフォルトでは、例外命令レジスには特殊な疑似命令が以下の条件で書き込まれる:

  1. : VSステージアドレス変換中の暗黙的なメモリアクセスにて例外が発生した場合

  2. : mtval2, htvalに非ゼロの値(例外の発生したゲスト物理アドレス)が書き込まれた場合

2つの条件に合致した場合、mtinstもしくはhtinstは表5.10に基づく値が書き込まれ、ゼロは許可されない。

意味

0x00002000

VSステージアドレス変換の32ビットメモリ読み込み(RV32)

0x00002020

VSステージアドレス変換の32ビットメモリ書き込み(RV32)

0x00003000

VSステージアドレス変換の64ビットメモリ読み込み(RV64)

0x00003020

VSステージアドレス変換の64ビットメモリ書き込み(RV32)

  • 表5.10: ゲストページフォルト例外における特殊な疑似命令。RV32での値はVSXLEN=32、RV64での値はVSXLEN=64の場合に使用される。

これらの疑似命令は表5.11に示す基本的なロードストア命令のエンコーディングに近づけるように設計されている。

エンコーディング

命令

0x00002003

lw x0,0(x0)

0x00002023

sw x0,0(x0)

0x00003003

ld x0,0(x0)

0x00003023

sd x0,0(x0)

  • 表5.11: 表5.10の特殊な疑似命令に相当する標準的な命令

「メモリ書き込み」の疑似命令(0x00002020, 0x00003020)は、マシンがVSレベルのページテーブルのA/Dビットを自動的に更新しようとする場合に使用される。VSステージアドレス変換における他の暗黙的なメモリアクセスはすべてメモリ読み込みである。VSレベルのページテーブルのA/Dビットをマシンにより自動的に更新されない場合(ソフトウェアにより実行される)、「メモリ書き込み」のケースは決して発生しない。このようなページテーブルの更新は、単純な書き込みではなく実際にはアトミックに実行されなくてはならないという事実は、疑似命令では無視されている。

  • 擬似命令値を必要とする条件がMモードで発生することがある場合、mtinstは完全にハードウェアによりゼロ固定とすることは出来ない。しかし、その場合、例外命令レジスタは最小限の値0と0x00002000または0x00003000、場合によっては0x00002020または0x00003020のみをサポートし、1つのレジスタあたりハードウェアで1つまたは2つのフリップフロップがひつようなだけである。

  • ハイパーバイザーはこのような状況では、例外の発生した暗黙のメモリアクセスをエミュレートすることは期待されていないため、ページテーブル更新のためのアトミック性の要件を無視しても何の問題もない。むしろ、ハイパーバイザーには、障害が発生したアクセスに関する十分な情報が与えられており、障害が発生した命令を再試行して実行を再開する前に、メモリにアクセス可能な状態にすることができる(例えば、仮想メモリの欠落したページを復元する)。

5.6.4 例外からの復帰

Mモードで処理された例外から復帰するためにMRET命令が使用される。MRET命令はまず表5.6に基づいてmstatusもしくはmstatushレジスタのMPPとMPVフィールドの値を用いて新しい動作モードを決定する。次にMRETはmstatus/mstatushのMPVとMPPを0に設定し、MIEをMPIEに、MPIEを1に設定する。最後に、MRETは仮想モードと特権モードを設定し、pcをmepcに設定する。

SRET命令はHSモードもしくはVSモードで処理された例外から復帰するために使用される。この命令の動作は現在の仮想モードに依存する。

MモードもしくはHSモード(つまりV=0)で実行中の場合、SRETは最初にhstatus.SPVとsstatus.SPPに基づき表5.7に従って新しい動作モードを決定する。SRETは次にhstatus.SPVを0に設定し、sstatusのSPP=0、SIE=SPIE、SPIE=1に設定する。最後に、SRETは新しい仮想化モードと特権モードを設定し、pc=sepcとする。

VSモードで実行中の場合(つまりV=1)、SRETは表5.8に基づいて特権モードを設定し、vstatusのSPP=0、SIE=SPIE、SPIE=1として最後にpc=vsepcとする。