コード例 #1
0
ファイル: parser.c プロジェクト: 383530895/linux
static PARSER_CONTEXT *
parser_init_guts(u64 addr, u32 bytes, BOOL isLocal,
		 BOOL hasStandardPayloadHeader, BOOL *tryAgain)
{
	int allocbytes = sizeof(PARSER_CONTEXT) + bytes;
	PARSER_CONTEXT *rc = NULL;
	PARSER_CONTEXT *ctx = NULL;
	struct memregion *rgn = NULL;
	struct spar_controlvm_parameters_header *phdr = NULL;

	if (tryAgain)
		*tryAgain = FALSE;
	if (!hasStandardPayloadHeader)
		/* alloc and 0 extra byte to ensure payload is
		 * '\0'-terminated
		 */
		allocbytes++;
	if ((Controlvm_Payload_Bytes_Buffered + bytes)
	    > MAX_CONTROLVM_PAYLOAD_BYTES) {
		ERRDRV("%s (%s:%d) - prevented allocation of %d bytes to prevent exceeding throttling max (%d)",
		       __func__, __FILE__, __LINE__, allocbytes,
		       MAX_CONTROLVM_PAYLOAD_BYTES);
		if (tryAgain)
			*tryAgain = TRUE;
		rc = NULL;
		goto Away;
	}
	ctx = kzalloc(allocbytes, GFP_KERNEL|__GFP_NORETRY);
	if (ctx == NULL) {
		ERRDRV("%s (%s:%d) - failed to allocate %d bytes",
		       __func__, __FILE__, __LINE__, allocbytes);
		if (tryAgain)
			*tryAgain = TRUE;
		rc = NULL;
		goto Away;
	}

	ctx->allocbytes = allocbytes;
	ctx->param_bytes = bytes;
	ctx->curr = NULL;
	ctx->bytes_remaining = 0;
	ctx->byte_stream = FALSE;
	if (isLocal) {
		void *p;

		if (addr > virt_to_phys(high_memory - 1)) {
			ERRDRV("%s - bad local address (0x%-16.16Lx for %lu)",
			       __func__,
			       (unsigned long long) addr, (ulong) bytes);
			rc = NULL;
			goto Away;
		}
		p = __va((ulong) (addr));
		memcpy(ctx->data, p, bytes);
	} else {
		rgn = visor_memregion_create(addr, bytes);
		if (!rgn) {
			rc = NULL;
			goto Away;
		}
		if (visor_memregion_read(rgn, 0, ctx->data, bytes) < 0) {
			rc = NULL;
			goto Away;
		}
	}
	if (!hasStandardPayloadHeader) {
		ctx->byte_stream = TRUE;
		rc = ctx;
		goto Away;
	}
	phdr = (struct spar_controlvm_parameters_header *)(ctx->data);
	if (phdr->total_length != bytes) {
		ERRDRV("%s - bad total length %lu (should be %lu)",
		       __func__,
		       (ulong) (phdr->total_length), (ulong) (bytes));
		rc = NULL;
		goto Away;
	}
	if (phdr->total_length < phdr->header_length) {
		ERRDRV("%s - total length < header length (%lu < %lu)",
		       __func__,
		       (ulong) (phdr->total_length),
		       (ulong) (phdr->header_length));
		rc = NULL;
		goto Away;
	}
	if (phdr->header_length <
	    sizeof(struct spar_controlvm_parameters_header)) {
		ERRDRV("%s - header is too small (%lu < %lu)",
		       __func__,
		       (ulong) (phdr->header_length),
		       (ulong)(sizeof(
				struct spar_controlvm_parameters_header)));
		rc = NULL;
		goto Away;
	}

	rc = ctx;
Away:
	if (rgn) {
		visor_memregion_destroy(rgn);
		rgn = NULL;
	}
	if (rc)
		Controlvm_Payload_Bytes_Buffered += ctx->param_bytes;
	else {
		if (ctx) {
			parser_done(ctx);
			ctx = NULL;
		}
	}
	return rc;
}
コード例 #2
0
ファイル: visorchannel_funcs.c プロジェクト: MaxChina/linux
/* Creates the VISORCHANNEL abstraction for a data area in memory, but does
 * NOT modify this data area.
 */
static VISORCHANNEL *
visorchannel_create_guts(HOSTADDRESS physaddr, ulong channelBytes,
			 VISORCHANNEL *parent, ulong off, uuid_le guid,
			 BOOL needs_lock)
{
	VISORCHANNEL *p = NULL;
	void *rc = NULL;

	p = kmalloc(sizeof(VISORCHANNEL), GFP_KERNEL|__GFP_NORETRY);
	if (p == NULL) {
		ERRDRV("allocation failed: (status=0)\n");
		rc = NULL;
		goto Away;
	}
	p->memregion = NULL;
	p->needs_lock = needs_lock;
	spin_lock_init(&p->insert_lock);
	spin_lock_init(&p->remove_lock);

	/* prepare chan_hdr (abstraction to read/write channel memory) */
	if (parent == NULL)
		p->memregion =
		    visor_memregion_create(physaddr, sizeof(CHANNEL_HEADER));
	else
		p->memregion =
		    visor_memregion_create_overlapped(parent->memregion,
						      off,
						      sizeof(CHANNEL_HEADER));
	if (p->memregion == NULL) {
		ERRDRV("visor_memregion_create failed failed: (status=0)\n");
		rc = NULL;
		goto Away;
	}
	if (visor_memregion_read(p->memregion, 0, &p->chan_hdr,
				 sizeof(CHANNEL_HEADER)) < 0) {
		ERRDRV("visor_memregion_read failed: (status=0)\n");
		rc = NULL;
		goto Away;
	}
	if (channelBytes == 0)
		/* we had better be a CLIENT of this channel */
		channelBytes = (ulong) p->chan_hdr.Size;
	if (uuid_le_cmp(guid, NULL_UUID_LE) == 0)
		/* we had better be a CLIENT of this channel */
		guid = p->chan_hdr.Type;
	if (visor_memregion_resize(p->memregion, channelBytes) < 0) {
		ERRDRV("visor_memregion_resize failed: (status=0)\n");
		rc = NULL;
		goto Away;
	}
	p->size = channelBytes;
	p->guid = guid;

	rc = p;
Away:

	if (rc == NULL) {
		if (p != NULL) {
			visorchannel_destroy(p);
			p = NULL;
		}
	}
	return rc;
}
コード例 #3
0
ファイル: parser.c プロジェクト: 19Dan01/linux
static struct parser_context *
parser_init_guts(u64 addr, u32 bytes, BOOL local,
		 BOOL standard_payload_header, BOOL *retry)
{
	int allocbytes = sizeof(struct parser_context) + bytes;
	struct parser_context *rc = NULL;
	struct parser_context *ctx = NULL;
	struct memregion *rgn = NULL;
	struct spar_controlvm_parameters_header *phdr = NULL;

	if (retry)
		*retry = FALSE;
	if (!standard_payload_header)
		/* alloc and 0 extra byte to ensure payload is
		 * '\0'-terminated
		 */
		allocbytes++;
	if ((controlvm_payload_bytes_buffered + bytes)
	    > MAX_CONTROLVM_PAYLOAD_BYTES) {
		if (retry)
			*retry = TRUE;
		rc = NULL;
		goto cleanup;
	}
	ctx = kzalloc(allocbytes, GFP_KERNEL|__GFP_NORETRY);
	if (!ctx) {
		if (retry)
			*retry = TRUE;
		rc = NULL;
		goto cleanup;
	}

	ctx->allocbytes = allocbytes;
	ctx->param_bytes = bytes;
	ctx->curr = NULL;
	ctx->bytes_remaining = 0;
	ctx->byte_stream = FALSE;
	if (local) {
		void *p;

		if (addr > virt_to_phys(high_memory - 1)) {
			rc = NULL;
			goto cleanup;
		}
		p = __va((ulong) (addr));
		memcpy(ctx->data, p, bytes);
	} else {
		rgn = visor_memregion_create(addr, bytes);
		if (!rgn) {
			rc = NULL;
			goto cleanup;
		}
		if (visor_memregion_read(rgn, 0, ctx->data, bytes) < 0) {
			rc = NULL;
			goto cleanup;
		}
	}
	if (!standard_payload_header) {
		ctx->byte_stream = TRUE;
		rc = ctx;
		goto cleanup;
	}
	phdr = (struct spar_controlvm_parameters_header *)(ctx->data);
	if (phdr->total_length != bytes) {
		rc = NULL;
		goto cleanup;
	}
	if (phdr->total_length < phdr->header_length) {
		rc = NULL;
		goto cleanup;
	}
	if (phdr->header_length <
	    sizeof(struct spar_controlvm_parameters_header)) {
		rc = NULL;
		goto cleanup;
	}

	rc = ctx;
cleanup:
	if (rgn) {
		visor_memregion_destroy(rgn);
		rgn = NULL;
	}
	if (rc) {
		controlvm_payload_bytes_buffered += ctx->param_bytes;
	} else {
		if (ctx) {
			parser_done(ctx);
			ctx = NULL;
		}
	}
	return rc;
}