VirtualBox

Changeset 23749 in vbox


Ignore:
Timestamp:
Oct 14, 2009 9:18:53 AM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
53475
Message:

SSM: Extending SSMFIELD so it can be used for fixing old SSMR[Pu|Ge]tMem usage.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/err.h

    r23714 r23749  
    598598/** The VM was suspended while saving, don't resume execution. */
    599599#define VINF_SSM_LIVE_SUSPENDED                  1864
     600/** Complex SSM field fed to SSMR3PutStruct or SSMR3GetStruct.  Use the
     601 * extended API. */
     602#define VERR_SSM_COMPLEX_FIELD                  (-1864)
     603/** Invalid size of a SSM field with the specified transformation. */
     604#define VERR_SSM_INVALID_FIELD_SIZE             (-1865)
    600605/** @} */
    601606
  • trunk/include/VBox/ssm.h

    r23709 r23749  
    9696
    9797
     98/** Pointer to a structure field description. */
     99typedef struct SSMFIELD *PSSMFIELD;
     100/** Pointer to a const  structure field description. */
     101typedef const struct SSMFIELD *PCSSMFIELD;
     102
     103/**
     104 * SSMFIELD Get/Put callback function.
     105 *
     106 * This is call for getting and putting the field it is associated with.  It's
     107 * up to the callback to work the saved state correctly.
     108 *
     109 * @returns VBox status code.
     110 *
     111 * @param   pSSM            The saved state handle.
     112 * @param   pField          The field that is being processed.
     113 * @param   pvStruct        Pointer to the structure.
     114 * @param   fFlags          SSMSTRUCT_FLAGS_XXX.
     115 * @param   fGetOrPut       True if getting, false if putting.
     116 * @param   pvUser          The user argument specified to SSMR3GetStructEx or
     117 *                          SSMR3PutStructEx.
     118 */
     119typedef DECLCALLBACK(int) FNSSMFIELDGETPUT(PSSMHANDLE pSSM, const struct SSMFIELD *pField, void *pvStruct,
     120                                           uint32_t fFlags, bool fGetOrPut, void *pvUser);
     121/** Pointer to a SSMFIELD Get/Put callback. */
     122typedef FNSSMFIELDGETPUT *PFNSSMFIELDGETPUT;
     123
     124/**
     125 * SSM field transformers.
     126 *
     127 * These are stored in the SSMFIELD::pfnGetPutOrTransformer and must therefore
     128 * have values outside the valid pointer range.
     129 */
     130typedef enum SSMFIELDTRANS
     131{
     132    /** Invalid. */
     133    SSMFIELDTRANS_INVALID = 0,
     134    /** No transformation. */
     135    SSMFIELDTRANS_NO_TRANSFORMATION,
     136    /** Guest context (GC) virtual address. */
     137    SSMFIELDTRANS_GCPTR,
     138    /** Guest context (GC) physical address. */
     139    SSMFIELDTRANS_GCPHYS,
     140    /** Ignorable Host context (HC) virtual address. See SSMFIELD_ENTRY_HCPTR. */
     141    SSMFIELDTRANS_HCPTR,
     142    /** Ignorable field. See SSMFIELD_ENTRY_IGNORE. */
     143    SSMFIELDTRANS_IGNORE
     144} SSMFIELDTRANS;
     145
    98146/**
    99147 * A structure field description.
    100  *
    101  * @todo Add an type field here for recording what's a GCPtr, GCPhys or anything
    102  *       else that may change and is expected to continue to work.
    103  * @todo Later we need to add load transformations to this structure. I think a
    104  *       callback with a number of default transformations in SIG_DEF style
    105  *       would be good enough. The callback would take a user context from a new
    106  *       SSMR3GetStruct parameter or something.
    107148 */
    108149typedef struct SSMFIELD
    109150{
     151    /** Getter and putter callback or transformer index. */
     152    PFNSSMFIELDGETPUT   pfnGetPutOrTransformer;
    110153    /** Field offset into the structure. */
    111     uint32_t    off;
     154    uint32_t            off;
    112155    /** The size of the field. */
    113     uint32_t    cb;
     156    uint32_t            cb;
    114157} SSMFIELD;
    115 /** Pointer to a structure field description. */
    116 typedef SSMFIELD *PSSMFIELD;
    117 /** Pointer to a const  structure field description. */
    118 typedef const SSMFIELD *PCSSMFIELD;
    119 
     158
     159/** Emit a SSMFIELD array entry.
     160 * @internal  */
     161#define SSMFIELD_ENTRY_INT(Type, Field, enmTransformer) \
     162    { \
     163        (PFNSSMFIELDGETPUT)(uintptr_t)(enmTransformer), \
     164        RT_OFFSETOF(Type, Field), \
     165        RT_SIZEOFMEMB(Type, Field) \
     166    }
    120167/** Emit a SSMFIELD array entry. */
    121 #define SSMFIELD_ENTRY(Type, Field)         { RT_OFFSETOF(Type, Field), RT_SIZEOFMEMB(Type, Field) }
     168#define SSMFIELD_ENTRY(Type, Field)         SSMFIELD_ENTRY_INT(Type, Field, SSMFIELDTRANS_NO_TRANSFORMATION)
    122169/** Emit a SSMFIELD array entry for a RTGCPTR type. */
    123 #define SSMFIELD_ENTRY_GCPTR(Type, Field)   SSMFIELD_ENTRY(Type, Field)
     170#define SSMFIELD_ENTRY_GCPTR(Type, Field)   SSMFIELD_ENTRY_INT(Type, Field, SSMFIELDTRANS_GCPTR)
    124171/** Emit a SSMFIELD array entry for a RTGCPHYS type. */
    125 #define SSMFIELD_ENTRY_GCPHYS(Type, Field)  SSMFIELD_ENTRY(Type, Field)
     172#define SSMFIELD_ENTRY_GCPHYS(Type, Field)  SSMFIELD_ENTRY_INT(Type, Field, SSMFIELDTRANS_GCPHYS)
     173/** Emit a SSMFIELD array entry for a ring-0 or ring-3 pointer type that is
     174 * of no real interest to the saved state.  It follows the same save and restore
     175 * rules as SSMFIELD_ENTRY_IGNORE. */
     176#define SSMFIELD_ENTRY_HCPTR(Type, Field)   SSMFIELD_ENTRY_INT(Type, Field, SSMFIELDTRANS_HCPTR)
     177/** Emit a SSMFIELD array entry for a field that can be ignored.
     178 * It is stored if SSMSTRUCT_FLAGS_DONT_IGNORE is specified to SSMR3PutStructEx.
     179 * It is skipped if SSMSTRUCT_FLAGS_DONT_IGNORE is specified to
     180 * SSMR3GetStructEx, the structure member is never touched on restore. */
     181#define SSMFIELD_ENTRY_IGNORE(Type, Field)  SSMFIELD_ENTRY_INT(Type, Field, SSMFIELDTRANS_IGNORE)
     182/** Emit a SSMFIELD array entry for a field with a custom callback. */
     183#define SSMFIELD_ENTRY_CALLBACK(Type, Field, pfnGetPut) \
     184    { (pfnGetPut), RT_OFFSETOF(Type, Field), RT_SIZEOFMEMB(Type, Field) }
    126185/** Emit the terminating entry of a SSMFIELD array. */
    127 #define SSMFIELD_ENTRY_TERM()               { UINT32_MAX, UINT32_MAX }
    128 
     186#define SSMFIELD_ENTRY_TERM()               { (PFNSSMFIELDGETPUT)(uintptr_t)SSMFIELDTRANS_INVALID, UINT32_MAX, UINT32_MAX }
     187
     188
     189/** @name SSMR3GetStructEx and SSMR3PutStructEx flags.
     190 * @{ */
     191/** The field descriptors must exactly cover the entire struct, A to Z. */
     192#define SSMSTRUCT_FLAGS_FULL_STRUCT         RT_BIT_32(0)
     193/** Do not ignore any ignorable fields. */
     194#define SSMSTRUCT_FLAGS_DONT_IGNORE         RT_BIT_32(1)
     195/** Band-aid for old SSMR3PutMem/SSMR3GetMem of structurs with host pointers. */
     196#define SSMSTRUCT_FLAGS_MEM_BAND_AID        (SSMSTRUCT_FLAGS_DONT_IGNORE | SSMSTRUCT_FLAGS_FULL_STRUCT)
     197/** @} */
    129198
    130199
     
    763832 */
    764833VMMR3DECL(int) SSMR3PutStruct(PSSMHANDLE pSSM, const void *pvStruct, PCSSMFIELD paFields);
     834VMMR3DECL(int) SSMR3PutStructEx(PSSMHANDLE pSSM, const void *pvStruct, size_t cbStruct, uint32_t fFlags, PCSSMFIELD paFields, void *pvUser);
    765835VMMR3DECL(int) SSMR3PutBool(PSSMHANDLE pSSM, bool fBool);
    766836VMMR3DECL(int) SSMR3PutU8(PSSMHANDLE pSSM, uint8_t u8);
     
    796866 */
    797867VMMR3DECL(int) SSMR3GetStruct(PSSMHANDLE pSSM, void *pvStruct, PCSSMFIELD paFields);
     868VMMR3DECL(int) SSMR3GetStructEx(PSSMHANDLE pSSM, void *pvStruct, size_t cbStruct, uint32_t fFlags, PCSSMFIELD paFields, void *pvUser);
    798869VMMR3DECL(int) SSMR3GetBool(PSSMHANDLE pSSM, bool *pfBool);
    799870VMMR3DECL(int) SSMR3GetU8(PSSMHANDLE pSSM, uint8_t *pu8);
  • trunk/src/VBox/VMM/SSM.cpp

    r23729 r23749  
    31633163         pCur++)
    31643164    {
    3165         rc = ssmR3DataWrite(pSSM, (uint8_t *)pvStruct + pCur->off, pCur->cb);
    3166         if (RT_FAILURE(rc))
    3167             return rc;
     3165        uint8_t const *pbField = (uint8_t const *)pvStruct + pCur->off;
     3166        switch ((uintptr_t)pCur->pfnGetPutOrTransformer)
     3167        {
     3168            case SSMFIELDTRANS_NO_TRANSFORMATION:
     3169                rc = ssmR3DataWrite(pSSM, pbField, pCur->cb);
     3170                break;
     3171
     3172            case SSMFIELDTRANS_GCPTR:
     3173                AssertMsgReturn(pCur->cb == sizeof(RTGCPTR), ("%#x\n", pCur->cb), VERR_SSM_INVALID_FIELD_SIZE);
     3174                rc = SSMR3PutGCPtr(pSSM, *(PRTGCPTR)pbField);
     3175                break;
     3176
     3177            case SSMFIELDTRANS_GCPHYS:
     3178                AssertMsgReturn(pCur->cb == sizeof(RTGCPHYS), ("%#x\n", pCur->cb), VERR_SSM_INVALID_FIELD_SIZE);
     3179                rc = SSMR3PutGCPhys(pSSM, *(PRTGCPHYS)pbField);
     3180                break;
     3181
     3182            default:
     3183                AssertMsgFailedReturn(("%#x\n", pCur->pfnGetPutOrTransformer), VERR_SSM_COMPLEX_FIELD);
     3184        }
    31683185    }
    31693186
     
    55115528        AssertMsgFailedReturn(("u32Magic=%#RX32\n", u32Magic), VERR_SSM_STRUCTURE_MAGIC);
    55125529
    5513     /* put the fields */
     5530    /* get the fields */
    55145531    for (PCSSMFIELD pCur = paFields;
    55155532         pCur->cb != UINT32_MAX && pCur->off != UINT32_MAX;
    55165533         pCur++)
    55175534    {
    5518         rc = ssmR3DataRead(pSSM, (uint8_t *)pvStruct + pCur->off, pCur->cb);
    5519         if (RT_FAILURE(rc))
    5520             return rc;
     5535        uint8_t *pbField = (uint8_t *)pvStruct + pCur->off;
     5536        switch ((uintptr_t)pCur->pfnGetPutOrTransformer)
     5537        {
     5538            case SSMFIELDTRANS_NO_TRANSFORMATION:
     5539                rc = ssmR3DataRead(pSSM, pbField, pCur->cb);
     5540                break;
     5541
     5542            case SSMFIELDTRANS_GCPTR:
     5543                AssertMsgReturn(pCur->cb == sizeof(RTGCPTR), ("%#x\n", pCur->cb), VERR_SSM_INVALID_FIELD_SIZE);
     5544                rc = SSMR3GetGCPtr(pSSM, (PRTGCPTR)pbField);
     5545                break;
     5546
     5547            case SSMFIELDTRANS_GCPHYS:
     5548                AssertMsgReturn(pCur->cb == sizeof(RTGCPHYS), ("%#x\n", pCur->cb), VERR_SSM_INVALID_FIELD_SIZE);
     5549                rc = SSMR3GetGCPhys(pSSM, (PRTGCPHYS)pbField);
     5550                break;
     5551
     5552            default:
     5553                AssertMsgFailedReturn(("%#x\n", pCur->pfnGetPutOrTransformer), VERR_SSM_COMPLEX_FIELD);
     5554        }
    55215555    }
    55225556
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette