uboot/lib/efi_loader/efi_variable_tee.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 *  EFI variable service via OP-TEE
   4 *
   5 *  Copyright (C) 2019 Linaro Ltd. <sughosh.ganu@linaro.org>
   6 *  Copyright (C) 2019 Linaro Ltd. <ilias.apalodimas@linaro.org>
   7 */
   8
   9#include <common.h>
  10#include <efi.h>
  11#include <efi_api.h>
  12#include <efi_loader.h>
  13#include <tee.h>
  14#include <malloc.h>
  15#include <mm_communication.h>
  16
  17static efi_uintn_t max_buffer_size;     /* comm + var + func + data */
  18static efi_uintn_t max_payload_size;    /* func + data */
  19
  20struct mm_connection {
  21        struct udevice *tee;
  22        u32 session;
  23};
  24
  25/**
  26 * get_connection() - Retrieve OP-TEE session for a specific UUID.
  27 *
  28 * @conn:   session buffer to fill
  29 * Return:  status code
  30 */
  31static int get_connection(struct mm_connection *conn)
  32{
  33        static const struct tee_optee_ta_uuid uuid = PTA_STMM_UUID;
  34        struct udevice *tee = NULL;
  35        struct tee_open_session_arg arg;
  36        int rc;
  37
  38        tee = tee_find_device(tee, NULL, NULL, NULL);
  39        if (!tee)
  40                return -ENODEV;
  41
  42        memset(&arg, 0, sizeof(arg));
  43        tee_optee_ta_uuid_to_octets(arg.uuid, &uuid);
  44        rc = tee_open_session(tee, &arg, 0, NULL);
  45        if (!rc) {
  46                conn->tee = tee;
  47                conn->session = arg.session;
  48        }
  49
  50        return rc;
  51}
  52
  53/**
  54 * optee_mm_communicate() - Pass a buffer to StandaloneMM running in OP-TEE
  55 *
  56 * @comm_buf:           locally allocted communcation buffer
  57 * @dsize:              buffer size
  58 * Return:              status code
  59 */
  60static efi_status_t optee_mm_communicate(void *comm_buf, ulong dsize)
  61{
  62        ulong buf_size;
  63        efi_status_t ret;
  64        struct efi_mm_communicate_header *mm_hdr;
  65        struct mm_connection conn = { NULL, 0 };
  66        struct tee_invoke_arg arg;
  67        struct tee_param param[2];
  68        struct tee_shm *shm = NULL;
  69        int rc;
  70
  71        if (!comm_buf)
  72                return EFI_INVALID_PARAMETER;
  73
  74        mm_hdr = (struct efi_mm_communicate_header *)comm_buf;
  75        buf_size = mm_hdr->message_len + sizeof(efi_guid_t) + sizeof(size_t);
  76
  77        if (dsize != buf_size)
  78                return EFI_INVALID_PARAMETER;
  79
  80        rc = get_connection(&conn);
  81        if (rc) {
  82                log_err("Unable to open OP-TEE session (err=%d)\n", rc);
  83                return EFI_UNSUPPORTED;
  84        }
  85
  86        if (tee_shm_register(conn.tee, comm_buf, buf_size, 0, &shm)) {
  87                log_err("Unable to register shared memory\n");
  88                return EFI_UNSUPPORTED;
  89        }
  90
  91        memset(&arg, 0, sizeof(arg));
  92        arg.func = PTA_STMM_CMDID_COMMUNICATE;
  93        arg.session = conn.session;
  94
  95        memset(param, 0, sizeof(param));
  96        param[0].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INOUT;
  97        param[0].u.memref.size = buf_size;
  98        param[0].u.memref.shm = shm;
  99        param[1].attr = TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT;
 100
 101        rc = tee_invoke_func(conn.tee, &arg, 2, param);
 102        if (rc)
 103                return EFI_INVALID_PARAMETER;
 104        tee_shm_free(shm);
 105        tee_close_session(conn.tee, conn.session);
 106
 107        switch (param[1].u.value.a) {
 108        case ARM_SMC_MM_RET_SUCCESS:
 109                ret = EFI_SUCCESS;
 110                break;
 111
 112        case ARM_SMC_MM_RET_INVALID_PARAMS:
 113                ret = EFI_INVALID_PARAMETER;
 114                break;
 115
 116        case ARM_SMC_MM_RET_DENIED:
 117                ret = EFI_ACCESS_DENIED;
 118                break;
 119
 120        case ARM_SMC_MM_RET_NO_MEMORY:
 121                ret = EFI_OUT_OF_RESOURCES;
 122                break;
 123
 124        default:
 125                ret = EFI_ACCESS_DENIED;
 126        }
 127
 128        return ret;
 129}
 130
 131/**
 132 * mm_communicate() - Adjust the cmonnucation buffer to StandAlonneMM and send
 133 * it to OP-TEE
 134 *
 135 * @comm_buf:           locally allocted communcation buffer
 136 * @dsize:              buffer size
 137 * Return:              status code
 138 */
 139static efi_status_t mm_communicate(u8 *comm_buf, efi_uintn_t dsize)
 140{
 141        efi_status_t ret;
 142        struct efi_mm_communicate_header *mm_hdr;
 143        struct smm_variable_communicate_header *var_hdr;
 144
 145        dsize += MM_COMMUNICATE_HEADER_SIZE + MM_VARIABLE_COMMUNICATE_SIZE;
 146        mm_hdr = (struct efi_mm_communicate_header *)comm_buf;
 147        var_hdr = (struct smm_variable_communicate_header *)mm_hdr->data;
 148
 149        ret = optee_mm_communicate(comm_buf, dsize);
 150        if (ret != EFI_SUCCESS) {
 151                log_err("%s failed!\n", __func__);
 152                return ret;
 153        }
 154
 155        return var_hdr->ret_status;
 156}
 157
 158/**
 159 * setup_mm_hdr() -     Allocate a buffer for StandAloneMM and initialize the
 160 *                      header data.
 161 *
 162 * @dptr:               pointer address of the corresponding StandAloneMM
 163 *                      function
 164 * @payload_size:       buffer size
 165 * @func:               standAloneMM function number
 166 * @ret:                EFI return code
 167 * Return:              buffer or NULL
 168 */
 169static u8 *setup_mm_hdr(void **dptr, efi_uintn_t payload_size,
 170                        efi_uintn_t func, efi_status_t *ret)
 171{
 172        const efi_guid_t mm_var_guid = EFI_MM_VARIABLE_GUID;
 173        struct efi_mm_communicate_header *mm_hdr;
 174        struct smm_variable_communicate_header *var_hdr;
 175        u8 *comm_buf;
 176
 177        /* In the init function we initialize max_buffer_size with
 178         * get_max_payload(). So skip the test if max_buffer_size is initialized
 179         * StandAloneMM will perform similar checks and drop the buffer if it's
 180         * too long
 181         */
 182        if (max_buffer_size && max_buffer_size <
 183                        (MM_COMMUNICATE_HEADER_SIZE +
 184                         MM_VARIABLE_COMMUNICATE_SIZE +
 185                         payload_size)) {
 186                *ret = EFI_INVALID_PARAMETER;
 187                return NULL;
 188        }
 189
 190        comm_buf = calloc(1, MM_COMMUNICATE_HEADER_SIZE +
 191                          MM_VARIABLE_COMMUNICATE_SIZE +
 192                          payload_size);
 193        if (!comm_buf) {
 194                *ret = EFI_OUT_OF_RESOURCES;
 195                return NULL;
 196        }
 197
 198        mm_hdr = (struct efi_mm_communicate_header *)comm_buf;
 199        guidcpy(&mm_hdr->header_guid, &mm_var_guid);
 200        mm_hdr->message_len = MM_VARIABLE_COMMUNICATE_SIZE + payload_size;
 201
 202        var_hdr = (struct smm_variable_communicate_header *)mm_hdr->data;
 203        var_hdr->function = func;
 204        if (dptr)
 205                *dptr = var_hdr->data;
 206        *ret = EFI_SUCCESS;
 207
 208        return comm_buf;
 209}
 210
 211/**
 212 * get_max_payload() - Get variable payload size from StandAloneMM.
 213 *
 214 * @size:    size of the variable in storage
 215 * Return:   status code
 216 */
 217efi_status_t EFIAPI get_max_payload(efi_uintn_t *size)
 218{
 219        struct smm_variable_payload_size *var_payload = NULL;
 220        efi_uintn_t payload_size;
 221        u8 *comm_buf = NULL;
 222        efi_status_t ret;
 223
 224        if (!size) {
 225                ret = EFI_INVALID_PARAMETER;
 226                goto out;
 227        }
 228
 229        payload_size = sizeof(*var_payload);
 230        comm_buf = setup_mm_hdr((void **)&var_payload, payload_size,
 231                                SMM_VARIABLE_FUNCTION_GET_PAYLOAD_SIZE, &ret);
 232        if (!comm_buf)
 233                goto out;
 234
 235        ret = mm_communicate(comm_buf, payload_size);
 236        if (ret != EFI_SUCCESS)
 237                goto out;
 238
 239        *size = var_payload->size;
 240
 241out:
 242        free(comm_buf);
 243        return ret;
 244}
 245
 246/**
 247 * efi_get_variable() - retrieve value of a UEFI variable
 248 *
 249 * This function implements the GetVariable runtime service.
 250 *
 251 * See the Unified Extensible Firmware Interface (UEFI) specification for
 252 * details.
 253 *
 254 * @name:               name of the variable
 255 * @guid:               vendor GUID
 256 * @attr:               attributes of the variable
 257 * @data_size:          size of the buffer to which the variable value is copied
 258 * @data:               buffer to which the variable value is copied
 259 * Return:              status code
 260 */
 261efi_status_t EFIAPI efi_get_variable(u16 *name, const efi_guid_t *guid,
 262                                     u32 *attr, efi_uintn_t *data_size,
 263                                     void *data)
 264{
 265        struct smm_variable_access *var_acc;
 266        efi_uintn_t payload_size;
 267        efi_uintn_t name_size;
 268        efi_uintn_t tmp_dsize;
 269        u8 *comm_buf = NULL;
 270        efi_status_t ret;
 271
 272        EFI_ENTRY("\"%ls\" %pUl %p %p %p", name, guid, attr, data_size, data);
 273
 274        if (!name || !guid || !data_size) {
 275                ret = EFI_INVALID_PARAMETER;
 276                goto out;
 277        }
 278
 279        /* Check payload size */
 280        name_size = u16_strsize(name);
 281        if (name_size > max_payload_size - MM_VARIABLE_ACCESS_HEADER_SIZE) {
 282                ret = EFI_INVALID_PARAMETER;
 283                goto out;
 284        }
 285
 286        /* Trim output buffer size */
 287        tmp_dsize = *data_size;
 288        if (name_size + tmp_dsize >
 289                        max_payload_size - MM_VARIABLE_ACCESS_HEADER_SIZE) {
 290                tmp_dsize = max_payload_size -
 291                                MM_VARIABLE_ACCESS_HEADER_SIZE -
 292                                name_size;
 293        }
 294
 295        /* Get communication buffer and initialize header */
 296        payload_size = MM_VARIABLE_ACCESS_HEADER_SIZE + name_size + tmp_dsize;
 297        comm_buf = setup_mm_hdr((void **)&var_acc, payload_size,
 298                                SMM_VARIABLE_FUNCTION_GET_VARIABLE, &ret);
 299        if (!comm_buf)
 300                goto out;
 301
 302        /* Fill in contents */
 303        guidcpy(&var_acc->guid, guid);
 304        var_acc->data_size = tmp_dsize;
 305        var_acc->name_size = name_size;
 306        var_acc->attr = attr ? *attr : 0;
 307        memcpy(var_acc->name, name, name_size);
 308
 309        /* Communicate */
 310        ret = mm_communicate(comm_buf, payload_size);
 311        if (ret == EFI_SUCCESS || ret == EFI_BUFFER_TOO_SMALL) {
 312                /* Update with reported data size for trimmed case */
 313                *data_size = var_acc->data_size;
 314        }
 315        if (ret != EFI_SUCCESS)
 316                goto out;
 317
 318        if (attr)
 319                *attr = var_acc->attr;
 320        if (data)
 321                memcpy(data, (u8 *)var_acc->name + var_acc->name_size,
 322                       var_acc->data_size);
 323        else
 324                ret = EFI_INVALID_PARAMETER;
 325
 326out:
 327        free(comm_buf);
 328        return EFI_EXIT(ret);
 329}
 330
 331/**
 332 * efi_get_next_variable_name() - enumerate the current variable names
 333 *
 334 * @variable_name_size: size of variable_name buffer in bytes
 335 * @variable_name:      name of uefi variable's name in u16
 336 * @guid:               vendor's guid
 337 *
 338 * This function implements the GetNextVariableName service.
 339 *
 340 * See the Unified Extensible Firmware Interface (UEFI) specification for
 341 * details.
 342 *
 343 * Return: status code
 344 */
 345efi_status_t EFIAPI efi_get_next_variable_name(efi_uintn_t *variable_name_size,
 346                                               u16 *variable_name,
 347                                               efi_guid_t *guid)
 348{
 349        struct smm_variable_getnext *var_getnext;
 350        efi_uintn_t payload_size;
 351        efi_uintn_t out_name_size;
 352        efi_uintn_t in_name_size;
 353        efi_uintn_t tmp_dsize;
 354        efi_uintn_t name_size;
 355        u8 *comm_buf = NULL;
 356        efi_status_t ret;
 357
 358        EFI_ENTRY("%p \"%ls\" %pUl", variable_name_size, variable_name, guid);
 359
 360        if (!variable_name_size || !variable_name || !guid) {
 361                ret = EFI_INVALID_PARAMETER;
 362                goto out;
 363        }
 364
 365        out_name_size = *variable_name_size;
 366        in_name_size = u16_strsize(variable_name);
 367
 368        if (out_name_size < in_name_size) {
 369                ret = EFI_INVALID_PARAMETER;
 370                goto out;
 371        }
 372
 373        name_size = u16_strsize(variable_name);
 374        if (name_size > max_payload_size - MM_VARIABLE_GET_NEXT_HEADER_SIZE) {
 375                ret = EFI_INVALID_PARAMETER;
 376                goto out;
 377        }
 378
 379        /* Trim output buffer size */
 380        tmp_dsize = *variable_name_size;
 381        if (name_size + tmp_dsize >
 382                        max_payload_size - MM_VARIABLE_GET_NEXT_HEADER_SIZE) {
 383                tmp_dsize = max_payload_size -
 384                                MM_VARIABLE_GET_NEXT_HEADER_SIZE -
 385                                name_size;
 386        }
 387
 388        payload_size = MM_VARIABLE_GET_NEXT_HEADER_SIZE + out_name_size;
 389        comm_buf = setup_mm_hdr((void **)&var_getnext, payload_size,
 390                                SMM_VARIABLE_FUNCTION_GET_NEXT_VARIABLE_NAME,
 391                                &ret);
 392        if (!comm_buf)
 393                goto out;
 394
 395        /* Fill in contents */
 396        guidcpy(&var_getnext->guid, guid);
 397        var_getnext->name_size = out_name_size;
 398        memcpy(var_getnext->name, variable_name, in_name_size);
 399        memset((u8 *)var_getnext->name + in_name_size, 0x0,
 400               out_name_size - in_name_size);
 401
 402        /* Communicate */
 403        ret = mm_communicate(comm_buf, payload_size);
 404        if (ret == EFI_SUCCESS || ret == EFI_BUFFER_TOO_SMALL) {
 405                /* Update with reported data size for trimmed case */
 406                *variable_name_size = var_getnext->name_size;
 407        }
 408        if (ret != EFI_SUCCESS)
 409                goto out;
 410
 411        guidcpy(guid, &var_getnext->guid);
 412        memcpy(variable_name, (u8 *)var_getnext->name,
 413               var_getnext->name_size);
 414
 415out:
 416        free(comm_buf);
 417        return EFI_EXIT(ret);
 418}
 419
 420/**
 421 * efi_set_variable() - set value of a UEFI variable
 422 *
 423 * This function implements the SetVariable runtime service.
 424 *
 425 * See the Unified Extensible Firmware Interface (UEFI) specification for
 426 * details.
 427 *
 428 * @name:               name of the variable
 429 * @guid:               vendor GUID
 430 * @attr:               attributes of the variable
 431 * @data_size:          size of the buffer with the variable value
 432 * @data:               buffer with the variable value
 433 * Return:              status code
 434 */
 435efi_status_t EFIAPI efi_set_variable(u16 *name, const efi_guid_t *guid,
 436                                     u32 attr, efi_uintn_t data_size,
 437                                     const void *data)
 438{
 439        struct smm_variable_access *var_acc;
 440        efi_uintn_t payload_size;
 441        efi_uintn_t name_size;
 442        u8 *comm_buf = NULL;
 443        efi_status_t ret;
 444
 445        EFI_ENTRY("\"%ls\" %pUl %x %zu %p", name, guid, attr, data_size, data);
 446
 447        if (!name || name[0] == 0 || !guid) {
 448                ret = EFI_INVALID_PARAMETER;
 449                goto out;
 450        }
 451        if (data_size > 0 && !data) {
 452                ret = EFI_INVALID_PARAMETER;
 453                goto out;
 454        }
 455
 456        /* Check payload size */
 457        name_size = u16_strsize(name);
 458        payload_size = MM_VARIABLE_ACCESS_HEADER_SIZE + name_size + data_size;
 459        if (payload_size > max_payload_size) {
 460                ret = EFI_INVALID_PARAMETER;
 461                goto out;
 462        }
 463
 464        /* Get communication buffer and initialize header */
 465        comm_buf = setup_mm_hdr((void **)&var_acc, payload_size,
 466                                SMM_VARIABLE_FUNCTION_SET_VARIABLE, &ret);
 467        if (!comm_buf)
 468                goto out;
 469
 470        /* Fill in contents */
 471        guidcpy(&var_acc->guid, guid);
 472        var_acc->data_size = data_size;
 473        var_acc->name_size = name_size;
 474        var_acc->attr = attr;
 475        memcpy(var_acc->name, name, name_size);
 476        memcpy((u8 *)var_acc->name + name_size, data, data_size);
 477
 478        /* Communicate */
 479        ret = mm_communicate(comm_buf, payload_size);
 480
 481out:
 482        free(comm_buf);
 483        return EFI_EXIT(ret);
 484}
 485
 486/**
 487 * efi_query_variable_info() - get information about EFI variables
 488 *
 489 * This function implements the QueryVariableInfo() runtime service.
 490 *
 491 * See the Unified Extensible Firmware Interface (UEFI) specification for
 492 * details.
 493 *
 494 * @attributes:                         bitmask to select variables to be
 495 *                                      queried
 496 * @maximum_variable_storage_size:      maximum size of storage area for the
 497 *                                      selected variable types
 498 * @remaining_variable_storage_size:    remaining size of storage are for the
 499 *                                      selected variable types
 500 * @maximum_variable_size:              maximum size of a variable of the
 501 *                                      selected type
 502 * Returns:                             status code
 503 */
 504efi_status_t EFIAPI __efi_runtime
 505efi_query_variable_info(u32 attributes, u64 *max_variable_storage_size,
 506                        u64 *remain_variable_storage_size,
 507                        u64 *max_variable_size)
 508{
 509        struct smm_variable_query_info *mm_query_info;
 510        efi_uintn_t payload_size;
 511        efi_status_t ret;
 512        u8 *comm_buf;
 513
 514        EFI_ENTRY("%x %p %p %p", attributes, max_variable_storage_size,
 515                  remain_variable_storage_size, max_variable_size);
 516
 517        payload_size = sizeof(*mm_query_info);
 518        comm_buf = setup_mm_hdr((void **)&mm_query_info, payload_size,
 519                                SMM_VARIABLE_FUNCTION_QUERY_VARIABLE_INFO,
 520                                &ret);
 521        if (!comm_buf)
 522                goto out;
 523
 524        mm_query_info->attr = attributes;
 525        ret = mm_communicate(comm_buf, payload_size);
 526        if (ret != EFI_SUCCESS)
 527                goto out;
 528        *max_variable_storage_size = mm_query_info->max_variable_storage;
 529        *remain_variable_storage_size =
 530                        mm_query_info->remaining_variable_storage;
 531        *max_variable_size = mm_query_info->max_variable_size;
 532
 533out:
 534        free(comm_buf);
 535        return EFI_EXIT(ret);
 536}
 537
 538/**
 539 * efi_get_variable_runtime() - runtime implementation of GetVariable()
 540 *
 541 * @variable_name:      name of the variable
 542 * @guid:               vendor GUID
 543 * @attributes:         attributes of the variable
 544 * @data_size:          size of the buffer to which the variable value is copied
 545 * @data:               buffer to which the variable value is copied
 546 * Return:              status code
 547 */
 548static efi_status_t __efi_runtime EFIAPI
 549efi_get_variable_runtime(u16 *variable_name, const efi_guid_t *guid,
 550                         u32 *attributes, efi_uintn_t *data_size, void *data)
 551{
 552        return EFI_UNSUPPORTED;
 553}
 554
 555/**
 556 * efi_get_next_variable_name_runtime() - runtime implementation of
 557 *                                        GetNextVariable()
 558 *
 559 * @variable_name_size: size of variable_name buffer in byte
 560 * @variable_name:      name of uefi variable's name in u16
 561 * @guid:               vendor's guid
 562 * Return:              status code
 563 */
 564static efi_status_t __efi_runtime EFIAPI
 565efi_get_next_variable_name_runtime(efi_uintn_t *variable_name_size,
 566                                   u16 *variable_name, efi_guid_t *guid)
 567{
 568        return EFI_UNSUPPORTED;
 569}
 570
 571/**
 572 * efi_query_variable_info() - get information about EFI variables
 573 *
 574 * This function implements the QueryVariableInfo() runtime service.
 575 *
 576 * See the Unified Extensible Firmware Interface (UEFI) specification for
 577 * details.
 578 *
 579 * @attributes:                         bitmask to select variables to be
 580 *                                      queried
 581 * @maximum_variable_storage_size:      maximum size of storage area for the
 582 *                                      selected variable types
 583 * @remaining_variable_storage_size:    remaining size of storage are for the
 584 *                                      selected variable types
 585 * @maximum_variable_size:              maximum size of a variable of the
 586 *                                      selected type
 587 * Return:                              status code
 588 */
 589efi_status_t EFIAPI __efi_runtime
 590efi_query_variable_info_runtime(u32 attributes, u64 *max_variable_storage_size,
 591                                u64 *remain_variable_storage_size,
 592                                u64 *max_variable_size)
 593{
 594        return EFI_UNSUPPORTED;
 595}
 596
 597/**
 598 * efi_set_variable_runtime() - runtime implementation of SetVariable()
 599 *
 600 * @variable_name:      name of the variable
 601 * @guid:               vendor GUID
 602 * @attributes:         attributes of the variable
 603 * @data_size:          size of the buffer with the variable value
 604 * @data:               buffer with the variable value
 605 * Return:              status code
 606 */
 607static efi_status_t __efi_runtime EFIAPI
 608efi_set_variable_runtime(u16 *variable_name, const efi_guid_t *guid,
 609                         u32 attributes, efi_uintn_t data_size,
 610                         const void *data)
 611{
 612        return EFI_UNSUPPORTED;
 613}
 614
 615/**
 616 * efi_variables_boot_exit_notify() - notify ExitBootServices() is called
 617 */
 618void efi_variables_boot_exit_notify(void)
 619{
 620        u8 *comm_buf;
 621        efi_status_t ret;
 622
 623        comm_buf = setup_mm_hdr(NULL, 0,
 624                                SMM_VARIABLE_FUNCTION_EXIT_BOOT_SERVICE, &ret);
 625        if (comm_buf)
 626                ret = mm_communicate(comm_buf, 0);
 627        else
 628                ret = EFI_NOT_FOUND;
 629
 630        if (ret != EFI_SUCCESS)
 631                log_err("Unable to notify StMM for ExitBootServices\n");
 632        free(comm_buf);
 633
 634        /* Update runtime service table */
 635        efi_runtime_services.query_variable_info =
 636                        efi_query_variable_info_runtime;
 637        efi_runtime_services.get_variable = efi_get_variable_runtime;
 638        efi_runtime_services.get_next_variable_name =
 639                        efi_get_next_variable_name_runtime;
 640        efi_runtime_services.set_variable = efi_set_variable_runtime;
 641        efi_update_table_header_crc32(&efi_runtime_services.hdr);
 642}
 643
 644/**
 645 * efi_init_variables() - initialize variable services
 646 *
 647 * Return:      status code
 648 */
 649efi_status_t efi_init_variables(void)
 650{
 651        efi_status_t ret;
 652
 653        ret = get_max_payload(&max_payload_size);
 654        if (ret != EFI_SUCCESS)
 655                return ret;
 656
 657        max_buffer_size = MM_COMMUNICATE_HEADER_SIZE +
 658                          MM_VARIABLE_COMMUNICATE_SIZE +
 659                          max_payload_size;
 660
 661        return EFI_SUCCESS;
 662}
 663