@ -76,6 +76,8 @@ typedef struct {
unsigned char * buffer ;
uint32_t numbytes ; /* number of bytes to deliver on resume */
TPMBackendCmd cmd ;
TPMBackend * be_driver ;
@ -240,6 +242,14 @@ static void tpm_spapr_request_completed(TPMIf *ti, int ret)
/* a max. of be_buffer_size bytes can be transported */
len = MIN ( tpm_cmd_get_size ( s - > buffer ) , s - > be_buffer_size ) ;
if ( runstate_check ( RUN_STATE_FINISH_MIGRATE ) ) {
trace_tpm_spapr_caught_response ( len ) ;
/* defer delivery of response until .post_load */
s - > numbytes = len ;
return ;
}
rc = spapr_vio_dma_write ( & s - > vdev , be32_to_cpu ( crq - > data ) ,
s - > buffer , len ) ;
@ -288,6 +298,7 @@ static void tpm_spapr_reset(SpaprVioDevice *dev)
SpaprTpmState * s = VIO_SPAPR_VTPM ( dev ) ;
s - > state = SPAPR_VTPM_STATE_NONE ;
s - > numbytes = 0 ;
s - > be_tpm_version = tpm_backend_get_tpm_version ( s - > be_driver ) ;
@ -309,9 +320,48 @@ static enum TPMVersion tpm_spapr_get_version(TPMIf *ti)
return tpm_backend_get_tpm_version ( s - > be_driver ) ;
}
/* persistent state handling */
static int tpm_spapr_pre_save ( void * opaque )
{
SpaprTpmState * s = opaque ;
tpm_backend_finish_sync ( s - > be_driver ) ;
/*
* we cannot deliver the results to the VM since DMA would touch VM memory
*/
return 0 ;
}
static int tpm_spapr_post_load ( void * opaque , int version_id )
{
SpaprTpmState * s = opaque ;
if ( s - > numbytes ) {
trace_tpm_spapr_post_load ( ) ;
/* deliver the results to the VM via DMA */
tpm_spapr_request_completed ( TPM_IF ( s ) , 0 ) ;
s - > numbytes = 0 ;
}
return 0 ;
}
static const VMStateDescription vmstate_spapr_vtpm = {
. name = " tpm-spapr " ,
. unmigratable = 1 ,
. pre_save = tpm_spapr_pre_save ,
. post_load = tpm_spapr_post_load ,
. fields = ( VMStateField [ ] ) {
VMSTATE_SPAPR_VIO ( vdev , SpaprTpmState ) ,
VMSTATE_UINT8 ( state , SpaprTpmState ) ,
VMSTATE_UINT32 ( numbytes , SpaprTpmState ) ,
VMSTATE_VBUFFER_UINT32 ( buffer , SpaprTpmState , 0 , NULL , numbytes ) ,
/* remember DMA address */
VMSTATE_UINT32 ( crq . data , SpaprTpmState ) ,
VMSTATE_END_OF_LIST ( ) ,
}
} ;
static Property tpm_spapr_properties [ ] = {