Blame opae-libs/plugins/xfpga/bitstream.c

Packit 534379
// Copyright(c) 2017-2020, Intel Corporation
Packit 534379
//
Packit 534379
// Redistribution  and  use  in source  and  binary  forms,  with  or  without
Packit 534379
// modification, are permitted provided that the following conditions are met:
Packit 534379
//
Packit 534379
// * Redistributions of  source code  must retain the  above copyright notice,
Packit 534379
//   this list of conditions and the following disclaimer.
Packit 534379
// * Redistributions in binary form must reproduce the above copyright notice,
Packit 534379
//   this list of conditions and the following disclaimer in the documentation
Packit 534379
//   and/or other materials provided with the distribution.
Packit 534379
// * Neither the name  of Intel Corporation  nor the names of its contributors
Packit 534379
//   may be used to  endorse or promote  products derived  from this  software
Packit 534379
//   without specific prior written permission.
Packit 534379
//
Packit 534379
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Packit 534379
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,  BUT NOT LIMITED TO,  THE
Packit 534379
// IMPLIED WARRANTIES OF  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Packit 534379
// ARE DISCLAIMED.  IN NO EVENT  SHALL THE COPYRIGHT OWNER  OR CONTRIBUTORS BE
Packit 534379
// LIABLE  FOR  ANY  DIRECT,  INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR
Packit 534379
// CONSEQUENTIAL  DAMAGES  (INCLUDING,  BUT  NOT LIMITED  TO,  PROCUREMENT  OF
Packit 534379
// SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE,  DATA, OR PROFITS;  OR BUSINESS
Packit 534379
// INTERRUPTION)  HOWEVER CAUSED  AND ON ANY THEORY  OF LIABILITY,  WHETHER IN
Packit 534379
// CONTRACT,  STRICT LIABILITY,  OR TORT  (INCLUDING NEGLIGENCE  OR OTHERWISE)
Packit 534379
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  EVEN IF ADVISED OF THE
Packit 534379
// POSSIBILITY OF SUCH DAMAGE.
Packit 534379
Packit 534379
#ifdef HAVE_CONFIG_H
Packit 534379
#include <config.h>
Packit 534379
#endif // HAVE_CONFIG_H
Packit 534379
Packit 534379
#include <string.h>
Packit 534379
#include <uuid/uuid.h>
Packit 534379
#include <json-c/json.h>
Packit 534379
#include <sys/types.h>
Packit 534379
#include <sys/stat.h>
Packit 534379
Packit 534379
#include "opae/utils.h"
Packit 534379
Packit 534379
#include "common_int.h"
Packit 534379
#include "bitstream_int.h"
Packit 534379
Packit 534379
#define METADATA_GUID "58656F6E-4650-4741-B747-425376303031"
Packit 534379
#define METADATA_GUID_LEN 16
Packit 534379
#define METADATA_MAX_LEN 8192
Packit 534379
#define FPGA_GBS_6_3_0_MAGIC	0x1d1f8680 // dec: 488605312
Packit 534379
#define PR_INTERFACE_ID 	"pr/interface_id"
Packit 534379
#define INTFC_ID_LOW_LEN	16
Packit 534379
#define INTFC_ID_HIGH_LEN	16
Packit 534379
#define BUFFER_SIZE		32
Packit 534379
Packit 534379
// GBS json metadata
Packit 534379
// GBS version
Packit 534379
#define GBS_VERSION                                 "version"
Packit 534379
Packit 534379
// AFU image
Packit 534379
#define GBS_AFU_IMAGE                               "afu-image"
Packit 534379
#define GBS_MAGIC_NUM                               "magic-no"
Packit 534379
#define BBS_INTERFACE_ID                            "interface-uuid"
Packit 534379
#define GBS_CLOCK_FREQUENCY_HIGH                    "clock-frequency-high"
Packit 534379
#define GBS_CLOCK_FREQUENCY_LOW                     "clock-frequency-low"
Packit 534379
#define GBS_AFU_POWER                               "power"
Packit 534379
Packit 534379
// AFU Clusters
Packit 534379
#define GBS_ACCELERATOR_CLUSTERS                    "accelerator-clusters"
Packit 534379
#define GBS_AFU_NAME                                "name"
Packit 534379
#define GBS_ACCELERATOR_TYPE_UUID                   "accelerator-type-uuid"
Packit 534379
#define GBS_ACCELERATOR_TOTAL_CONTEXTS              "total-contexts"
Packit 534379
Packit 534379
Packit 534379
fpga_result string_to_guid(const char *guid, fpga_guid *result)
Packit 534379
{
Packit 534379
	if (uuid_parse(guid, *result) < 0) {
Packit 534379
		OPAE_MSG("Error parsing GUID %s\n", guid);
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	return FPGA_OK;
Packit 534379
}
Packit 534379
Packit 534379
STATIC json_bool get_json_object(json_object **object, json_object **parent,
Packit 534379
				char *field_name)
Packit 534379
{
Packit 534379
	return json_object_object_get_ex(*parent, field_name, &(*object));
Packit 534379
}
Packit 534379
Packit 534379
STATIC uint64_t read_int_from_bitstream(const uint8_t *bitstream, uint8_t size)
Packit 534379
{
Packit 534379
	uint64_t ret = 0;
Packit 534379
	switch (size) {
Packit 534379
Packit 534379
	case sizeof(uint8_t):
Packit 534379
		ret = *((uint8_t *) bitstream);
Packit 534379
		break;
Packit 534379
	case sizeof(uint16_t):
Packit 534379
		ret = *((uint16_t *) bitstream);
Packit 534379
		break;
Packit 534379
	case sizeof(uint32_t):
Packit 534379
		ret = *((uint32_t *) bitstream);
Packit 534379
		break;
Packit 534379
	case sizeof(uint64_t):
Packit 534379
		ret = *((uint64_t *) bitstream);
Packit 534379
		break;
Packit 534379
	default:
Packit 534379
		OPAE_ERR("Unknown integer size");
Packit 534379
	}
Packit 534379
Packit 534379
	return ret;
Packit 534379
}
Packit 534379
Packit 534379
STATIC int64_t int64_be_to_le(int64_t val)
Packit 534379
{
Packit 534379
	val = ((val << 8) & 0xFF00FF00FF00FF00ULL) |
Packit 534379
					((val >> 8) & 0x00FF00FF00FF00FFULL);
Packit 534379
	val = ((val << 16) & 0xFFFF0000FFFF0000ULL) |
Packit 534379
					((val >> 16) & 0x0000FFFF0000FFFFULL);
Packit 534379
	return (val << 32) | ((val >> 32) & 0xFFFFFFFFULL);
Packit 534379
}
Packit 534379
Packit 534379
fpga_result get_interface_id(fpga_handle handle, uint64_t *id_l, uint64_t *id_h)
Packit 534379
{
Packit 534379
Packit 534379
	struct _fpga_token  *_token;
Packit 534379
	struct _fpga_handle *_handle = (struct _fpga_handle *)handle;
Packit 534379
	fpga_result result = FPGA_OK;
Packit 534379
	fpga_guid guid;
Packit 534379
Packit 534379
	_token = (struct _fpga_token *)_handle->token;
Packit 534379
	if (!_token) {
Packit 534379
		OPAE_MSG("Token is NULL");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	if (_token->magic != FPGA_TOKEN_MAGIC) {
Packit 534379
		OPAE_MSG("Invalid token in handle");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	if (id_l == NULL || id_h == NULL) {
Packit 534379
		OPAE_MSG("id_l or id_h are NULL");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	// PR Interface id
Packit 534379
	result = sysfs_get_interface_id(_token, guid);
Packit 534379
	if (FPGA_OK != result) {
Packit 534379
		OPAE_ERR("Failed to get PR interface id");
Packit 534379
		return FPGA_EXCEPTION;
Packit 534379
	}
Packit 534379
Packit 534379
	memcpy(id_h, guid, sizeof(uint64_t));
Packit 534379
	*id_h = int64_be_to_le(*id_h);
Packit 534379
Packit 534379
	memcpy(id_l, guid + sizeof(uint64_t), sizeof(uint64_t));
Packit 534379
	*id_l = int64_be_to_le(*id_l);
Packit 534379
Packit 534379
	return FPGA_OK;
Packit 534379
}
Packit 534379
Packit 534379
fpga_result check_interface_id(fpga_handle handle,
Packit 534379
				uint32_t bitstream_magic_no,
Packit 534379
				uint64_t ifid_l, uint64_t ifid_h)
Packit 534379
{
Packit 534379
	uint64_t intfc_id_l = 0;
Packit 534379
	uint64_t intfc_id_h = 0;
Packit 534379
	fpga_result result  = FPGA_OK;
Packit 534379
Packit 534379
	if (bitstream_magic_no != FPGA_GBS_6_3_0_MAGIC) {
Packit 534379
		OPAE_MSG("Invalid bitstream magic number");
Packit 534379
		return FPGA_NOT_FOUND;
Packit 534379
	}
Packit 534379
Packit 534379
	if (get_interface_id(handle, &intfc_id_l, &intfc_id_h)) {
Packit 534379
		OPAE_MSG("Get interface ID failed");
Packit 534379
		return FPGA_NOT_FOUND;
Packit 534379
	}
Packit 534379
Packit 534379
	if ((ifid_l != intfc_id_l) ||
Packit 534379
		(ifid_h != intfc_id_h)) {
Packit 534379
		OPAE_MSG("Interface id doesn't match metadata");
Packit 534379
		return FPGA_NOT_FOUND;
Packit 534379
	}
Packit 534379
Packit 534379
	return result;
Packit 534379
}
Packit 534379
Packit 534379
fpga_result check_bitstream_guid(const uint8_t *bitstream)
Packit 534379
{
Packit 534379
	fpga_guid bitstream_guid;
Packit 534379
	fpga_guid expected_guid;
Packit 534379
Packit 534379
	memcpy(bitstream_guid, bitstream, sizeof(fpga_guid));
Packit 534379
Packit 534379
	if (string_to_guid(METADATA_GUID, &expected_guid) != FPGA_OK)
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
Packit 534379
	if (uuid_compare(bitstream_guid, expected_guid) != 0)
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
Packit 534379
	return FPGA_OK;
Packit 534379
}
Packit 534379
Packit 534379
int get_bitstream_header_len(const uint8_t *bitstream)
Packit 534379
{
Packit 534379
	uint32_t json_len = 0;
Packit 534379
Packit 534379
	if (!bitstream) {
Packit 534379
		OPAE_ERR("NULL input bitstream pointer");
Packit 534379
		return -1;
Packit 534379
	}
Packit 534379
Packit 534379
	if (check_bitstream_guid(bitstream) != FPGA_OK)
Packit 534379
		return -1;
Packit 534379
Packit 534379
	json_len = read_int_from_bitstream(bitstream + METADATA_GUID_LEN, sizeof(uint32_t));
Packit 534379
Packit 534379
	return (METADATA_GUID_LEN + sizeof(uint32_t) + json_len);
Packit 534379
}
Packit 534379
Packit 534379
int32_t get_bitstream_json_len(const uint8_t *bitstream)
Packit 534379
{
Packit 534379
	uint32_t json_len = 0;
Packit 534379
Packit 534379
	if (!bitstream) {
Packit 534379
		OPAE_ERR("NULL input bitstream pointer");
Packit 534379
		return -1;
Packit 534379
	}
Packit 534379
Packit 534379
	if (check_bitstream_guid(bitstream) != FPGA_OK)
Packit 534379
		return -1;
Packit 534379
Packit 534379
	json_len = read_int_from_bitstream(bitstream + METADATA_GUID_LEN, sizeof(uint32_t));
Packit 534379
Packit 534379
	return json_len;
Packit 534379
}
Packit 534379
Packit 534379
fpga_result validate_bitstream_metadata(fpga_handle handle,
Packit 534379
			const uint8_t *bitstream)
Packit 534379
{
Packit 534379
	fpga_result result = FPGA_EXCEPTION;
Packit 534379
	char *json_metadata = NULL;
Packit 534379
	uint32_t json_len = 0;
Packit 534379
	uint32_t bitstream_magic_no = 0;
Packit 534379
	uint64_t ifc_id_val_l, ifc_id_val_h;
Packit 534379
	const uint8_t *json_metadata_ptr = NULL;
Packit 534379
	json_object *root = NULL;
Packit 534379
	json_object *afu_image = NULL, *magic_no = NULL;
Packit 534379
	json_object *interface_id = NULL;
Packit 534379
	fpga_guid expected_guid;
Packit 534379
Packit 534379
	if (check_bitstream_guid(bitstream) != FPGA_OK)
Packit 534379
		goto out_free;
Packit 534379
Packit 534379
	json_len = read_int_from_bitstream(bitstream + METADATA_GUID_LEN, sizeof(uint32_t));
Packit 534379
	if (json_len == 0) {
Packit 534379
		OPAE_MSG("Bitstream has no metadata");
Packit 534379
		result = FPGA_OK;
Packit 534379
		goto out_free;
Packit 534379
	}
Packit 534379
Packit 534379
	if (json_len >= METADATA_MAX_LEN) {
Packit 534379
		OPAE_ERR("Bitstream metadata too large");
Packit 534379
		goto out_free;
Packit 534379
	}
Packit 534379
Packit 534379
	json_metadata_ptr = bitstream + METADATA_GUID_LEN + sizeof(uint32_t);
Packit 534379
Packit 534379
	json_metadata = (char *) malloc(json_len + 1);
Packit 534379
	if (json_metadata == NULL) {
Packit 534379
		OPAE_ERR("Could not allocate memory for metadata");
Packit 534379
		return FPGA_NO_MEMORY;
Packit 534379
	}
Packit 534379
Packit 534379
	memcpy(json_metadata, json_metadata_ptr, json_len);
Packit 534379
	json_metadata[json_len] = '\0';
Packit 534379
Packit 534379
	root = json_tokener_parse(json_metadata);
Packit 534379
Packit 534379
	if (root != NULL) {
Packit 534379
		if (get_json_object(&afu_image, &root, GBS_AFU_IMAGE)) {
Packit 534379
			get_json_object(&magic_no, &afu_image, GBS_MAGIC_NUM);
Packit 534379
			get_json_object(&interface_id, &afu_image,
Packit 534379
					BBS_INTERFACE_ID);
Packit 534379
Packit 534379
			if (magic_no == NULL || interface_id == NULL) {
Packit 534379
				OPAE_ERR("Invalid metadata");
Packit 534379
				result = FPGA_INVALID_PARAM;
Packit 534379
				goto out_free;
Packit 534379
			}
Packit 534379
Packit 534379
			result = string_to_guid(
Packit 534379
				json_object_get_string(interface_id),
Packit 534379
				&expected_guid);
Packit 534379
			if (result != FPGA_OK) {
Packit 534379
				OPAE_ERR("Invalid BBS interface ID");
Packit 534379
				goto out_free;
Packit 534379
			}
Packit 534379
Packit 534379
			memcpy(&ifc_id_val_h, expected_guid, sizeof(uint64_t));
Packit 534379
			ifc_id_val_h = int64_be_to_le(ifc_id_val_h);
Packit 534379
Packit 534379
			memcpy(&ifc_id_val_l,
Packit 534379
				expected_guid + sizeof(uint64_t),
Packit 534379
				sizeof(uint64_t));
Packit 534379
			ifc_id_val_l = int64_be_to_le(ifc_id_val_l);
Packit 534379
Packit 534379
			bitstream_magic_no = json_object_get_int(magic_no);
Packit 534379
Packit 534379
			result = check_interface_id(handle, bitstream_magic_no,
Packit 534379
						ifc_id_val_l, ifc_id_val_h);
Packit 534379
Packit 534379
			if (result != FPGA_OK) {
Packit 534379
				OPAE_ERR("Interface ID check failed");
Packit 534379
				goto out_free;
Packit 534379
			}
Packit 534379
		} else {
Packit 534379
			OPAE_ERR("Invalid metadata");
Packit 534379
			result = FPGA_INVALID_PARAM;
Packit 534379
			goto out_free;
Packit 534379
		}
Packit 534379
	}
Packit 534379
Packit 534379
out_free:
Packit 534379
	if (root)
Packit 534379
		json_object_put(root);
Packit 534379
	if (json_metadata)
Packit 534379
		free(json_metadata);
Packit 534379
Packit 534379
	return result;
Packit 534379
}
Packit 534379
Packit 534379
fpga_result read_gbs_metadata(const uint8_t *bitstream,
Packit 534379
				struct gbs_metadata *gbs_metadata)
Packit 534379
{
Packit 534379
	uint32_t json_len                   = 0;
Packit 534379
	fpga_result result                  = FPGA_OK;
Packit 534379
	const uint8_t *json_metadata_ptr    = NULL;
Packit 534379
	char *json_metadata                 = NULL;
Packit 534379
	json_object *root                   = NULL;
Packit 534379
	json_object *magic_num              = NULL;
Packit 534379
	json_object *interface_id           = NULL;
Packit 534379
	json_object *afu_image              = NULL;
Packit 534379
	json_object *version                = NULL;
Packit 534379
	json_object *accelerator_clusters   = NULL;
Packit 534379
	json_object *cluster                = NULL;
Packit 534379
	json_object *uuid                   = NULL;
Packit 534379
	json_object *name                   = NULL;
Packit 534379
	json_object *contexts               = NULL;
Packit 534379
	json_object *power                  = NULL;
Packit 534379
	json_object *userclk1               = NULL;
Packit 534379
	json_object *userclk2               = NULL;
Packit 534379
Packit 534379
	if (gbs_metadata == NULL) {
Packit 534379
		OPAE_ERR("Invalid input metadata");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	if (bitstream == NULL) {
Packit 534379
		OPAE_ERR("Invalid input bitstream");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	if (check_bitstream_guid(bitstream) != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to read GUID");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	json_len = *((uint32_t *) (bitstream + METADATA_GUID_LEN));
Packit 534379
	if (!json_len || json_len >= METADATA_MAX_LEN) {
Packit 534379
		OPAE_ERR("Invalid bitstream metadata size");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	json_metadata_ptr = bitstream + METADATA_GUID_LEN + sizeof(uint32_t);
Packit 534379
Packit 534379
	json_metadata = (char *) malloc(json_len + 1);
Packit 534379
	if (!json_metadata) {
Packit 534379
		OPAE_ERR("Could not allocate memory for metadata");
Packit 534379
		return FPGA_NO_MEMORY;
Packit 534379
	}
Packit 534379
Packit 534379
	memcpy(json_metadata, json_metadata_ptr, json_len);
Packit 534379
	json_metadata[json_len] = '\0';
Packit 534379
Packit 534379
	root = json_tokener_parse(json_metadata);
Packit 534379
Packit 534379
	if (root) {
Packit 534379
Packit 534379
		// GBS version
Packit 534379
		if (get_json_object(&version, &root, GBS_VERSION)) {
Packit 534379
			gbs_metadata->version = json_object_get_double(version);
Packit 534379
		} else {
Packit 534379
			OPAE_ERR("No GBS version");
Packit 534379
			result = FPGA_INVALID_PARAM;
Packit 534379
			goto out_free;
Packit 534379
		}
Packit 534379
Packit 534379
		// afu-image
Packit 534379
		if (get_json_object(&afu_image, &root, GBS_AFU_IMAGE)) {
Packit 534379
Packit 534379
			// magic number
Packit 534379
			if (get_json_object(&magic_num, &afu_image, GBS_MAGIC_NUM)) {
Packit 534379
				gbs_metadata->afu_image.magic_num = json_object_get_int64(magic_num);
Packit 534379
			}
Packit 534379
Packit 534379
			// Interface type GUID
Packit 534379
			if (get_json_object(&interface_id, &afu_image, BBS_INTERFACE_ID)) {
Packit 534379
				memcpy(gbs_metadata->afu_image.interface_uuid,
Packit 534379
						json_object_get_string(interface_id),
Packit 534379
						GUID_LEN);
Packit 534379
				gbs_metadata->afu_image.interface_uuid[GUID_LEN] = '\0';
Packit 534379
			} else {
Packit 534379
				OPAE_ERR("No interface ID found in JSON metadata");
Packit 534379
				result = FPGA_INVALID_PARAM;
Packit 534379
				goto out_free;
Packit 534379
			}
Packit 534379
Packit 534379
			// AFU user clock frequency High
Packit 534379
			if (get_json_object(&userclk1, &afu_image, GBS_CLOCK_FREQUENCY_HIGH)) {
Packit 534379
				gbs_metadata->afu_image.clock_frequency_high = json_object_get_int64(userclk1);
Packit 534379
			}
Packit 534379
Packit 534379
			// AFU user clock frequency Low
Packit 534379
			if (get_json_object(&userclk2, &afu_image, GBS_CLOCK_FREQUENCY_LOW)) {
Packit 534379
				gbs_metadata->afu_image.clock_frequency_low = json_object_get_int64(userclk2);
Packit 534379
			}
Packit 534379
Packit 534379
			// GBS power
Packit 534379
			if (get_json_object(&power, &afu_image, GBS_AFU_POWER)) {
Packit 534379
				gbs_metadata->afu_image.power = json_object_get_int64(power);
Packit 534379
			}
Packit 534379
Packit 534379
		} else {
Packit 534379
			OPAE_ERR("No AFU image in metadata");
Packit 534379
			result = FPGA_INVALID_PARAM;
Packit 534379
			goto out_free;
Packit 534379
		}
Packit 534379
Packit 534379
		// afu clusters
Packit 534379
		if (get_json_object(&afu_image, &root, GBS_AFU_IMAGE) &&
Packit 534379
			get_json_object(&accelerator_clusters, &afu_image, GBS_ACCELERATOR_CLUSTERS)) {
Packit 534379
Packit 534379
			cluster = json_object_array_get_idx(accelerator_clusters, 0);
Packit 534379
Packit 534379
			// AFU GUID
Packit 534379
			if (get_json_object(&uuid, &cluster, GBS_ACCELERATOR_TYPE_UUID)) {
Packit 534379
				memcpy(gbs_metadata->afu_image.afu_clusters.afu_uuid,
Packit 534379
						json_object_get_string(uuid),
Packit 534379
						GUID_LEN);
Packit 534379
				gbs_metadata->afu_image.afu_clusters.afu_uuid[GUID_LEN] = '\0';
Packit 534379
			} else {
Packit 534379
				OPAE_ERR("No accelerator-type-uuid in JSON metadata");
Packit 534379
				result = FPGA_INVALID_PARAM;
Packit 534379
				goto out_free;
Packit 534379
			}
Packit 534379
Packit 534379
			// AFU Name
Packit 534379
			if (get_json_object(&name, &cluster, GBS_AFU_NAME)) {
Packit 534379
				memcpy(gbs_metadata->afu_image.afu_clusters.name,
Packit 534379
						json_object_get_string(name),
Packit 534379
						json_object_get_string_len(name));
Packit 534379
			}
Packit 534379
Packit 534379
			// AFU Total number of contexts
Packit 534379
			if (get_json_object(&contexts, &cluster, GBS_ACCELERATOR_TOTAL_CONTEXTS)) {
Packit 534379
				gbs_metadata->afu_image.afu_clusters.total_contexts = json_object_get_int64(contexts);
Packit 534379
			}
Packit 534379
Packit 534379
		} else {
Packit 534379
			OPAE_ERR("No accelerator clusters in metadata");
Packit 534379
			result = FPGA_INVALID_PARAM;
Packit 534379
			goto out_free;
Packit 534379
		}
Packit 534379
	} else {
Packit 534379
		OPAE_ERR("Invalid JSON in metadata");
Packit 534379
		result = FPGA_INVALID_PARAM;
Packit 534379
		goto out_free;
Packit 534379
	}
Packit 534379
Packit 534379
out_free:
Packit 534379
	if (root)
Packit 534379
		json_object_put(root);
Packit 534379
	if (json_metadata)
Packit 534379
		free(json_metadata);
Packit 534379
Packit 534379
	return result;
Packit 534379
}