.. | .. |
---|
39 | 39 | asm("mov %%db6, %0" :"=r" (val)); |
---|
40 | 40 | break; |
---|
41 | 41 | case 7: |
---|
42 | | - asm("mov %%db7, %0" :"=r" (val)); |
---|
| 42 | + /* |
---|
| 43 | + * Apply __FORCE_ORDER to DR7 reads to forbid re-ordering them |
---|
| 44 | + * with other code. |
---|
| 45 | + * |
---|
| 46 | + * This is needed because a DR7 access can cause a #VC exception |
---|
| 47 | + * when running under SEV-ES. Taking a #VC exception is not a |
---|
| 48 | + * safe thing to do just anywhere in the entry code and |
---|
| 49 | + * re-ordering might place the access into an unsafe location. |
---|
| 50 | + * |
---|
| 51 | + * This happened in the NMI handler, where the DR7 read was |
---|
| 52 | + * re-ordered to happen before the call to sev_es_ist_enter(), |
---|
| 53 | + * causing stack recursion. |
---|
| 54 | + */ |
---|
| 55 | + asm volatile("mov %%db7, %0" : "=r" (val) : __FORCE_ORDER); |
---|
43 | 56 | break; |
---|
44 | 57 | default: |
---|
45 | 58 | BUG(); |
---|
.. | .. |
---|
66 | 79 | asm("mov %0, %%db6" ::"r" (value)); |
---|
67 | 80 | break; |
---|
68 | 81 | case 7: |
---|
69 | | - asm("mov %0, %%db7" ::"r" (value)); |
---|
| 82 | + /* |
---|
| 83 | + * Apply __FORCE_ORDER to DR7 writes to forbid re-ordering them |
---|
| 84 | + * with other code. |
---|
| 85 | + * |
---|
| 86 | + * While is didn't happen with a DR7 write (see the DR7 read |
---|
| 87 | + * comment above which explains where it happened), add the |
---|
| 88 | + * __FORCE_ORDER here too to avoid similar problems in the |
---|
| 89 | + * future. |
---|
| 90 | + */ |
---|
| 91 | + asm volatile("mov %0, %%db7" ::"r" (value), __FORCE_ORDER); |
---|
70 | 92 | break; |
---|
71 | 93 | default: |
---|
72 | 94 | BUG(); |
---|