2626#include "sp-dev.h"
2727#include "psp-dev.h"
2828
29+ #define DEVICE_NAME "sev"
30+
31+ static DEFINE_MUTEX (sev_cmd_mutex );
32+ static struct sev_misc_dev * misc_dev ;
33+ static struct psp_device * psp_master ;
34+
2935static struct psp_device * psp_alloc_struct (struct sp_device * sp )
3036{
3137 struct device * dev = sp -> dev ;
@@ -45,9 +51,285 @@ static struct psp_device *psp_alloc_struct(struct sp_device *sp)
4551
4652static irqreturn_t psp_irq_handler (int irq , void * data )
4753{
54+ struct psp_device * psp = data ;
55+ unsigned int status ;
56+ int reg ;
57+
58+ /* Read the interrupt status: */
59+ status = ioread32 (psp -> io_regs + PSP_P2CMSG_INTSTS );
60+
61+ /* Check if it is command completion: */
62+ if (!(status & BIT (PSP_CMD_COMPLETE_REG )))
63+ goto done ;
64+
65+ /* Check if it is SEV command completion: */
66+ reg = ioread32 (psp -> io_regs + PSP_CMDRESP );
67+ if (reg & PSP_CMDRESP_RESP ) {
68+ psp -> sev_int_rcvd = 1 ;
69+ wake_up (& psp -> sev_int_queue );
70+ }
71+
72+ done :
73+ /* Clear the interrupt status by writing the same value we read. */
74+ iowrite32 (status , psp -> io_regs + PSP_P2CMSG_INTSTS );
75+
4876 return IRQ_HANDLED ;
4977}
5078
79+ static void sev_wait_cmd_ioc (struct psp_device * psp , unsigned int * reg )
80+ {
81+ psp -> sev_int_rcvd = 0 ;
82+
83+ wait_event (psp -> sev_int_queue , psp -> sev_int_rcvd );
84+ * reg = ioread32 (psp -> io_regs + PSP_CMDRESP );
85+ }
86+
87+ static int sev_cmd_buffer_len (int cmd )
88+ {
89+ switch (cmd ) {
90+ case SEV_CMD_INIT : return sizeof (struct sev_data_init );
91+ case SEV_CMD_PLATFORM_STATUS : return sizeof (struct sev_user_data_status );
92+ case SEV_CMD_PEK_CSR : return sizeof (struct sev_data_pek_csr );
93+ case SEV_CMD_PEK_CERT_IMPORT : return sizeof (struct sev_data_pek_cert_import );
94+ case SEV_CMD_PDH_CERT_EXPORT : return sizeof (struct sev_data_pdh_cert_export );
95+ case SEV_CMD_LAUNCH_START : return sizeof (struct sev_data_launch_start );
96+ case SEV_CMD_LAUNCH_UPDATE_DATA : return sizeof (struct sev_data_launch_update_data );
97+ case SEV_CMD_LAUNCH_UPDATE_VMSA : return sizeof (struct sev_data_launch_update_vmsa );
98+ case SEV_CMD_LAUNCH_FINISH : return sizeof (struct sev_data_launch_finish );
99+ case SEV_CMD_LAUNCH_MEASURE : return sizeof (struct sev_data_launch_measure );
100+ case SEV_CMD_ACTIVATE : return sizeof (struct sev_data_activate );
101+ case SEV_CMD_DEACTIVATE : return sizeof (struct sev_data_deactivate );
102+ case SEV_CMD_DECOMMISSION : return sizeof (struct sev_data_decommission );
103+ case SEV_CMD_GUEST_STATUS : return sizeof (struct sev_data_guest_status );
104+ case SEV_CMD_DBG_DECRYPT : return sizeof (struct sev_data_dbg );
105+ case SEV_CMD_DBG_ENCRYPT : return sizeof (struct sev_data_dbg );
106+ case SEV_CMD_SEND_START : return sizeof (struct sev_data_send_start );
107+ case SEV_CMD_SEND_UPDATE_DATA : return sizeof (struct sev_data_send_update_data );
108+ case SEV_CMD_SEND_UPDATE_VMSA : return sizeof (struct sev_data_send_update_vmsa );
109+ case SEV_CMD_SEND_FINISH : return sizeof (struct sev_data_send_finish );
110+ case SEV_CMD_RECEIVE_START : return sizeof (struct sev_data_receive_start );
111+ case SEV_CMD_RECEIVE_FINISH : return sizeof (struct sev_data_receive_finish );
112+ case SEV_CMD_RECEIVE_UPDATE_DATA : return sizeof (struct sev_data_receive_update_data );
113+ case SEV_CMD_RECEIVE_UPDATE_VMSA : return sizeof (struct sev_data_receive_update_vmsa );
114+ case SEV_CMD_LAUNCH_UPDATE_SECRET : return sizeof (struct sev_data_launch_secret );
115+ default : return 0 ;
116+ }
117+
118+ return 0 ;
119+ }
120+
121+ static int __sev_do_cmd_locked (int cmd , void * data , int * psp_ret )
122+ {
123+ struct psp_device * psp = psp_master ;
124+ unsigned int phys_lsb , phys_msb ;
125+ unsigned int reg , ret = 0 ;
126+
127+ if (!psp )
128+ return - ENODEV ;
129+
130+ /* Get the physical address of the command buffer */
131+ phys_lsb = data ? lower_32_bits (__psp_pa (data )) : 0 ;
132+ phys_msb = data ? upper_32_bits (__psp_pa (data )) : 0 ;
133+
134+ dev_dbg (psp -> dev , "sev command id %#x buffer 0x%08x%08x\n" ,
135+ cmd , phys_msb , phys_lsb );
136+
137+ print_hex_dump_debug ("(in): " , DUMP_PREFIX_OFFSET , 16 , 2 , data ,
138+ sev_cmd_buffer_len (cmd ), false);
139+
140+ iowrite32 (phys_lsb , psp -> io_regs + PSP_CMDBUFF_ADDR_LO );
141+ iowrite32 (phys_msb , psp -> io_regs + PSP_CMDBUFF_ADDR_HI );
142+
143+ reg = cmd ;
144+ reg <<= PSP_CMDRESP_CMD_SHIFT ;
145+ reg |= PSP_CMDRESP_IOC ;
146+ iowrite32 (reg , psp -> io_regs + PSP_CMDRESP );
147+
148+ /* wait for command completion */
149+ sev_wait_cmd_ioc (psp , & reg );
150+
151+ if (psp_ret )
152+ * psp_ret = reg & PSP_CMDRESP_ERR_MASK ;
153+
154+ if (reg & PSP_CMDRESP_ERR_MASK ) {
155+ dev_dbg (psp -> dev , "sev command %#x failed (%#010x)\n" ,
156+ cmd , reg & PSP_CMDRESP_ERR_MASK );
157+ ret = - EIO ;
158+ }
159+
160+ print_hex_dump_debug ("(out): " , DUMP_PREFIX_OFFSET , 16 , 2 , data ,
161+ sev_cmd_buffer_len (cmd ), false);
162+
163+ return ret ;
164+ }
165+
166+ static int sev_do_cmd (int cmd , void * data , int * psp_ret )
167+ {
168+ int rc ;
169+
170+ mutex_lock (& sev_cmd_mutex );
171+ rc = __sev_do_cmd_locked (cmd , data , psp_ret );
172+ mutex_unlock (& sev_cmd_mutex );
173+
174+ return rc ;
175+ }
176+
177+ static int __sev_platform_init_locked (int * error )
178+ {
179+ struct psp_device * psp = psp_master ;
180+ int rc = 0 ;
181+
182+ if (!psp )
183+ return - ENODEV ;
184+
185+ if (psp -> sev_state == SEV_STATE_INIT )
186+ return 0 ;
187+
188+ rc = __sev_do_cmd_locked (SEV_CMD_INIT , & psp -> init_cmd_buf , error );
189+ if (rc )
190+ return rc ;
191+
192+ psp -> sev_state = SEV_STATE_INIT ;
193+ dev_dbg (psp -> dev , "SEV firmware initialized\n" );
194+
195+ return rc ;
196+ }
197+
198+ int sev_platform_init (int * error )
199+ {
200+ int rc ;
201+
202+ mutex_lock (& sev_cmd_mutex );
203+ rc = __sev_platform_init_locked (error );
204+ mutex_unlock (& sev_cmd_mutex );
205+
206+ return rc ;
207+ }
208+ EXPORT_SYMBOL_GPL (sev_platform_init );
209+
210+ static int __sev_platform_shutdown_locked (int * error )
211+ {
212+ int ret ;
213+
214+ ret = __sev_do_cmd_locked (SEV_CMD_SHUTDOWN , 0 , error );
215+ if (ret )
216+ return ret ;
217+
218+ psp_master -> sev_state = SEV_STATE_UNINIT ;
219+ dev_dbg (psp_master -> dev , "SEV firmware shutdown\n" );
220+
221+ return ret ;
222+ }
223+
224+ static int sev_platform_shutdown (int * error )
225+ {
226+ int rc ;
227+
228+ mutex_lock (& sev_cmd_mutex );
229+ rc = __sev_platform_shutdown_locked (NULL );
230+ mutex_unlock (& sev_cmd_mutex );
231+
232+ return rc ;
233+ }
234+
235+ static long sev_ioctl (struct file * file , unsigned int ioctl , unsigned long arg )
236+ {
237+ return - ENOTTY ;
238+ }
239+
240+ static const struct file_operations sev_fops = {
241+ .owner = THIS_MODULE ,
242+ .unlocked_ioctl = sev_ioctl ,
243+ };
244+
245+ int sev_platform_status (struct sev_user_data_status * data , int * error )
246+ {
247+ return sev_do_cmd (SEV_CMD_PLATFORM_STATUS , data , error );
248+ }
249+ EXPORT_SYMBOL_GPL (sev_platform_status );
250+
251+ int sev_guest_deactivate (struct sev_data_deactivate * data , int * error )
252+ {
253+ return sev_do_cmd (SEV_CMD_DEACTIVATE , data , error );
254+ }
255+ EXPORT_SYMBOL_GPL (sev_guest_deactivate );
256+
257+ int sev_guest_activate (struct sev_data_activate * data , int * error )
258+ {
259+ return sev_do_cmd (SEV_CMD_ACTIVATE , data , error );
260+ }
261+ EXPORT_SYMBOL_GPL (sev_guest_activate );
262+
263+ int sev_guest_decommission (struct sev_data_decommission * data , int * error )
264+ {
265+ return sev_do_cmd (SEV_CMD_DECOMMISSION , data , error );
266+ }
267+ EXPORT_SYMBOL_GPL (sev_guest_decommission );
268+
269+ int sev_guest_df_flush (int * error )
270+ {
271+ return sev_do_cmd (SEV_CMD_DF_FLUSH , 0 , error );
272+ }
273+ EXPORT_SYMBOL_GPL (sev_guest_df_flush );
274+
275+ static void sev_exit (struct kref * ref )
276+ {
277+ struct sev_misc_dev * misc_dev = container_of (ref , struct sev_misc_dev , refcount );
278+
279+ misc_deregister (& misc_dev -> misc );
280+ }
281+
282+ static int sev_misc_init (struct psp_device * psp )
283+ {
284+ struct device * dev = psp -> dev ;
285+ int ret ;
286+
287+ /*
288+ * SEV feature support can be detected on multiple devices but the SEV
289+ * FW commands must be issued on the master. During probe, we do not
290+ * know the master hence we create /dev/sev on the first device probe.
291+ * sev_do_cmd() finds the right master device to which to issue the
292+ * command to the firmware.
293+ */
294+ if (!misc_dev ) {
295+ struct miscdevice * misc ;
296+
297+ misc_dev = devm_kzalloc (dev , sizeof (* misc_dev ), GFP_KERNEL );
298+ if (!misc_dev )
299+ return - ENOMEM ;
300+
301+ misc = & misc_dev -> misc ;
302+ misc -> minor = MISC_DYNAMIC_MINOR ;
303+ misc -> name = DEVICE_NAME ;
304+ misc -> fops = & sev_fops ;
305+
306+ ret = misc_register (misc );
307+ if (ret )
308+ return ret ;
309+
310+ kref_init (& misc_dev -> refcount );
311+ } else {
312+ kref_get (& misc_dev -> refcount );
313+ }
314+
315+ init_waitqueue_head (& psp -> sev_int_queue );
316+ psp -> sev_misc = misc_dev ;
317+ dev_dbg (dev , "registered SEV device\n" );
318+
319+ return 0 ;
320+ }
321+
322+ static int sev_init (struct psp_device * psp )
323+ {
324+ /* Check if device supports SEV feature */
325+ if (!(ioread32 (psp -> io_regs + PSP_FEATURE_REG ) & 1 )) {
326+ dev_dbg (psp -> dev , "device does not support SEV\n" );
327+ return 1 ;
328+ }
329+
330+ return sev_misc_init (psp );
331+ }
332+
51333int psp_dev_init (struct sp_device * sp )
52334{
53335 struct device * dev = sp -> dev ;
@@ -81,6 +363,10 @@ int psp_dev_init(struct sp_device *sp)
81363 goto e_err ;
82364 }
83365
366+ ret = sev_init (psp );
367+ if (ret )
368+ goto e_irq ;
369+
84370 if (sp -> set_psp_master_device )
85371 sp -> set_psp_master_device (sp );
86372
@@ -89,6 +375,8 @@ int psp_dev_init(struct sp_device *sp)
89375
90376 return 0 ;
91377
378+ e_irq :
379+ sp_free_psp_irq (psp -> sp , psp );
92380e_err :
93381 sp -> psp_data = NULL ;
94382
@@ -101,5 +389,61 @@ void psp_dev_destroy(struct sp_device *sp)
101389{
102390 struct psp_device * psp = sp -> psp_data ;
103391
392+ if (psp -> sev_misc )
393+ kref_put (& misc_dev -> refcount , sev_exit );
394+
104395 sp_free_psp_irq (sp , psp );
105396}
397+
398+ int sev_issue_cmd_external_user (struct file * filep , unsigned int cmd ,
399+ void * data , int * error )
400+ {
401+ if (!filep || filep -> f_op != & sev_fops )
402+ return - EBADF ;
403+
404+ return sev_do_cmd (cmd , data , error );
405+ }
406+ EXPORT_SYMBOL_GPL (sev_issue_cmd_external_user );
407+
408+ void psp_pci_init (void )
409+ {
410+ struct sev_user_data_status * status ;
411+ struct sp_device * sp ;
412+ int error , rc ;
413+
414+ sp = sp_get_psp_master_device ();
415+ if (!sp )
416+ return ;
417+
418+ psp_master = sp -> psp_data ;
419+
420+ /* Initialize the platform */
421+ rc = sev_platform_init (& error );
422+ if (rc ) {
423+ dev_err (sp -> dev , "SEV: failed to INIT error %#x\n" , error );
424+ goto err ;
425+ }
426+
427+ /* Display SEV firmware version */
428+ status = & psp_master -> status_cmd_buf ;
429+ rc = sev_platform_status (status , & error );
430+ if (rc ) {
431+ dev_err (sp -> dev , "SEV: failed to get status error %#x\n" , error );
432+ goto err ;
433+ }
434+
435+ dev_info (sp -> dev , "SEV API:%d.%d build:%d\n" , status -> api_major ,
436+ status -> api_minor , status -> build );
437+ return ;
438+
439+ err :
440+ psp_master = NULL ;
441+ }
442+
443+ void psp_pci_exit (void )
444+ {
445+ if (!psp_master )
446+ return ;
447+
448+ sev_platform_shutdown (NULL );
449+ }
0 commit comments