Exemple #1
0
int avtab_alloc(struct avtab *h, u32 nrules)
{
	u32 mask = 0;
	u32 shift = 0;
	u32 work = nrules;
	u32 nslot = 0;

	if (nrules == 0)
		goto avtab_alloc_out;

	while (work) {
		work  = work >> 1;
		shift++;
	}
	if (shift > 2)
		shift = shift - 2;
	nslot = 1 << shift;
	if (nslot > MAX_AVTAB_HASH_BUCKETS)
		nslot = MAX_AVTAB_HASH_BUCKETS;
	mask = nslot - 1;

	h->htable = flex_array_alloc(sizeof(struct avtab_node *), nslot,
				     GFP_KERNEL | __GFP_ZERO);
	if (!h->htable)
		return -ENOMEM;

 avtab_alloc_out:
	h->nel = 0;
	h->nslot = nslot;
	h->mask = mask;
	printk(KERN_DEBUG "SELinux: %d avtab hash slots, %d rules.\n",
	       h->nslot, nrules);
	return 0;
}
Exemple #2
0
static struct flex_array *fa_alloc(size_t elem_size, size_t elem_count,
				   gfp_t gfp)
{
	struct flex_array *result;
	int err;

	result = flex_array_alloc(elem_size, elem_count, gfp);
	if (result) {
		err = flex_array_prealloc(result, 0, elem_count, gfp);
		if (err) {
			flex_array_free(result);
			result = NULL;
		}
	}

	return result;
}
Exemple #3
0
static struct flex_array *alloc_buckets(unsigned int n_buckets)
{
	struct flex_array *buckets;
	int i, err;

	buckets = flex_array_alloc(sizeof(struct hlist_head *),
				   n_buckets, GFP_KERNEL);
	if (!buckets)
		return NULL;

	err = flex_array_prealloc(buckets, 0, n_buckets, GFP_KERNEL);
	if (err) {
		flex_array_free(buckets);
		return NULL;
	}

	for (i = 0; i < n_buckets; i++)
		INIT_HLIST_HEAD((struct hlist_head *)
					flex_array_get(buckets, i));

	return buckets;
}
Exemple #4
0
/**
 * Reads and parses the register descriptor.
 *
 * @fn - the function device we're working with
 * @desc - will be filled in with the parsed data
 * @address - the starting address for the register descriptor
 */
static int rmi_read_reg_descriptor(struct rmi_function *fn,
				   struct rmi_reg_descriptor *desc,
				   u16 address)
{
	struct rmi_device *rmi_dev = fn->rmi_dev;
	int retval;
	u8 *buf;
	int i, j;
	int offset;
	int reg_offset = 0;
	int nr_regs;
	int reg;
	int bitpos;
	int lastbit;
	struct rmi_register_desc reg_desc;

	retval = rmi_read(rmi_dev, address, &desc->presence_size);
	if (retval < 0)
		return retval;
	address++;

	buf = devm_kzalloc(&fn->dev, desc->presence_size, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	retval = rmi_read_block(rmi_dev, address, buf, desc->presence_size);
	if (retval < 0)
		goto exit;
	address++;

	desc->structure_size = buf[0];
	offset = 1;

        if (desc->structure_size == 0) {
		desc->structure_size = buf[1] | (buf[2] << 8);
		offset += 2;
	}
	nr_regs = desc->presence_size - offset;
	desc->presence_bits = nr_regs * 8;
	desc->presence = devm_kzalloc(&fn->dev,
			BITS_TO_LONGS(desc->presence_bits)*sizeof(unsigned long), GFP_KERNEL);
	if (!desc->presence) {
		retval = -ENOMEM;
		goto exit;
	}

	bitpos = 0;
	for (j = 0; j < nr_regs; j++) {
		for (i = 0; i < 8; i++) {
			if (buf[offset] & (1 << i)) {
				set_bit(bitpos, desc->presence);
				lastbit = bitpos;
			}
			bitpos++;
		}
		offset++;
	}

	devm_kfree(&fn->dev, buf);
	buf = devm_kzalloc(&fn->dev, desc->structure_size, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	desc->structure = flex_array_alloc(sizeof(struct rmi_register_desc),
					   desc->presence_bits, GFP_KERNEL);
	if (!desc->structure) {
		retval = -ENOMEM;
		goto exit;
	}

	retval = rmi_read_block(rmi_dev, address, buf, desc->structure_size);
	if (retval < 0)
		goto exit;

	reg = find_first_bit(desc->presence, desc->presence_bits);
	offset = 0;
	while (reg < desc->presence_bits) {
		bool done = false;
		int base;

		reg_desc.nr_subpackets = 0;
		reg_desc.size = buf[offset];
		reg_desc.offset = reg_offset;
		reg_offset += reg_desc.size;
		offset++;
		if (reg_desc.size == 0) {
			reg_desc.size = buf[offset] | (buf[offset+1] << 8);
			offset += 2;
		}
		if (reg_desc.size == 0) {
			reg_desc.size = buf[offset] | (buf[offset+1] << 8) |
				(buf[offset+2] << 16) | (buf[offset+3] << 24);
			offset += 4;
		}
		base = offset;
		while (!done) {
			reg_desc.nr_subpackets += 7;
			done = (buf[offset] & 0x80) == 0;
			offset++;
		}
		reg_desc.subpackets = devm_kzalloc(&fn->dev,
			BITS_TO_LONGS(reg_desc.nr_subpackets)*sizeof(unsigned long), GFP_KERNEL);
		if (!reg_desc.subpackets) {
			retval = -ENOMEM;
			goto exit;
		}
		offset = base;
		bitpos = 0;
		done = false;
		while (!done) {
			for (i = 0; i < 7; i++) {
				if (buf[offset] & (0x01 << i)) {
					set_bit(bitpos, reg_desc.subpackets);
				}
				bitpos++;
			}
			done = (buf[offset] & 0x80) == 0;
			offset++;
		}
		retval = flex_array_put(desc->structure, reg, &reg_desc, GFP_KERNEL);
		if (retval)
			dev_warn(&fn->dev, "Failed to put reg %d structure info. Code: %d.\n", reg, retval);
		reg = find_next_bit(desc->presence, desc->presence_bits, reg+1);
	}

	retval = 0;

exit:
	devm_kfree(&fn->dev, buf);
	return retval;
}