Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}