1313#include "misc.h"
1414
1515#include <asm/sev-es.h>
16+ #include <asm/trapnr.h>
17+ #include <asm/trap_pf.h>
1618#include <asm/msr-index.h>
1719#include <asm/ptrace.h>
1820#include <asm/svm.h>
1921
22+ #include "error.h"
23+
24+ struct ghcb boot_ghcb_page __aligned (PAGE_SIZE );
25+ struct ghcb * boot_ghcb ;
26+
2027static inline u64 sev_es_rd_ghcb_msr (void )
2128{
2229 unsigned long low , high ;
@@ -38,8 +45,112 @@ static inline void sev_es_wr_ghcb_msr(u64 val)
3845 "a" (low ), "d" (high ) : "memory" );
3946}
4047
48+ static enum es_result vc_decode_insn (struct es_em_ctxt * ctxt )
49+ {
50+ char buffer [MAX_INSN_SIZE ];
51+ enum es_result ret ;
52+
53+ memcpy (buffer , (unsigned char * )ctxt -> regs -> ip , MAX_INSN_SIZE );
54+
55+ insn_init (& ctxt -> insn , buffer , MAX_INSN_SIZE , 1 );
56+ insn_get_length (& ctxt -> insn );
57+
58+ ret = ctxt -> insn .immediate .got ? ES_OK : ES_DECODE_FAILED ;
59+
60+ return ret ;
61+ }
62+
63+ static enum es_result vc_write_mem (struct es_em_ctxt * ctxt ,
64+ void * dst , char * buf , size_t size )
65+ {
66+ memcpy (dst , buf , size );
67+
68+ return ES_OK ;
69+ }
70+
71+ static enum es_result vc_read_mem (struct es_em_ctxt * ctxt ,
72+ void * src , char * buf , size_t size )
73+ {
74+ memcpy (buf , src , size );
75+
76+ return ES_OK ;
77+ }
78+
4179#undef __init
80+ #undef __pa
4281#define __init
82+ #define __pa (x ) ((unsigned long)(x))
83+
84+ #define __BOOT_COMPRESSED
85+
86+ /* Basic instruction decoding support needed */
87+ #include "../../lib/inat.c"
88+ #include "../../lib/insn.c"
4389
4490/* Include code for early handlers */
4591#include "../../kernel/sev-es-shared.c"
92+
93+ static bool early_setup_sev_es (void )
94+ {
95+ if (!sev_es_negotiate_protocol ())
96+ sev_es_terminate (GHCB_SEV_ES_REASON_PROTOCOL_UNSUPPORTED );
97+
98+ if (set_page_decrypted ((unsigned long )& boot_ghcb_page ))
99+ return false;
100+
101+ /* Page is now mapped decrypted, clear it */
102+ memset (& boot_ghcb_page , 0 , sizeof (boot_ghcb_page ));
103+
104+ boot_ghcb = & boot_ghcb_page ;
105+
106+ /* Initialize lookup tables for the instruction decoder */
107+ inat_init_tables ();
108+
109+ return true;
110+ }
111+
112+ void sev_es_shutdown_ghcb (void )
113+ {
114+ if (!boot_ghcb )
115+ return ;
116+
117+ /*
118+ * GHCB Page must be flushed from the cache and mapped encrypted again.
119+ * Otherwise the running kernel will see strange cache effects when
120+ * trying to use that page.
121+ */
122+ if (set_page_encrypted ((unsigned long )& boot_ghcb_page ))
123+ error ("Can't map GHCB page encrypted" );
124+ }
125+
126+ void do_boot_stage2_vc (struct pt_regs * regs , unsigned long exit_code )
127+ {
128+ struct es_em_ctxt ctxt ;
129+ enum es_result result ;
130+
131+ if (!boot_ghcb && !early_setup_sev_es ())
132+ sev_es_terminate (GHCB_SEV_ES_REASON_GENERAL_REQUEST );
133+
134+ vc_ghcb_invalidate (boot_ghcb );
135+ result = vc_init_em_ctxt (& ctxt , regs , exit_code );
136+ if (result != ES_OK )
137+ goto finish ;
138+
139+ switch (exit_code ) {
140+ default :
141+ result = ES_UNSUPPORTED ;
142+ break ;
143+ }
144+
145+ finish :
146+ if (result == ES_OK ) {
147+ vc_finish_insn (& ctxt );
148+ } else if (result != ES_RETRY ) {
149+ /*
150+ * For now, just halt the machine. That makes debugging easier,
151+ * later we just call sev_es_terminate() here.
152+ */
153+ while (true)
154+ asm volatile ("hlt\n" );
155+ }
156+ }
0 commit comments