Re: [PATCH v5 bpf-next 06/12] bpf: Add uptr support in the map_value of the task local storage.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Oct 14, 2024 at 05:49:56PM GMT, Martin KaFai Lau wrote:
> From: Martin KaFai Lau <martin.lau@xxxxxxxxxx>
> 
[...]
> +static void unpin_uptr_kaddr(void *kaddr)
> +{
> +	if (kaddr)
> +		unpin_user_page(virt_to_page(kaddr));
> +}
> +
> +static void __bpf_obj_unpin_uptrs(struct btf_record *rec, u32 cnt, void *obj)
> +{
> +	const struct btf_field *field;
> +	void **uptr_addr;
> +	int i;
> +
> +	for (i = 0, field = rec->fields; i < cnt; i++, field++) {
> +		if (field->type != BPF_UPTR)
> +			continue;
> +
> +		uptr_addr = obj + field->offset;
> +		unpin_uptr_kaddr(*uptr_addr);
> +	}
> +}
> +
> +static void bpf_obj_unpin_uptrs(struct btf_record *rec, void *obj)
> +{
> +	if (!btf_record_has_field(rec, BPF_UPTR))
> +		return;
> +
> +	__bpf_obj_unpin_uptrs(rec, rec->cnt, obj);
> +}
> +
> +static int bpf_obj_pin_uptrs(struct btf_record *rec, void *obj)
> +{
> +	const struct btf_field *field;
> +	const struct btf_type *t;
> +	unsigned long start, end;
> +	struct page *page;
> +	void **uptr_addr;
> +	int i, err;
> +
> +	if (!btf_record_has_field(rec, BPF_UPTR))
> +		return 0;
> +
> +	for (i = 0, field = rec->fields; i < rec->cnt; i++, field++) {
> +		if (field->type != BPF_UPTR)
> +			continue;
> +
> +		uptr_addr = obj + field->offset;
> +		start = *(unsigned long *)uptr_addr;
> +		if (!start)
> +			continue;
> +
> +		t = btf_type_by_id(field->kptr.btf, field->kptr.btf_id);
> +		if (check_add_overflow(start, t->size, &end)) {
> +			err = -EFAULT;
> +			goto unpin_all;
> +		}
> +
> +		/* The uptr's struct cannot span across two pages */
> +		if ((start & PAGE_MASK) != (end & PAGE_MASK)) {
> +			err = -EOPNOTSUPP;
> +			goto unpin_all;
> +		}
> +
> +		err = pin_user_pages_fast(start, 1, FOLL_LONGTERM | FOLL_WRITE, &page);
> +		if (err != 1)
> +			goto unpin_all;
> +
> +		*uptr_addr = page_address(page) + offset_in_page(start);

Please use kmap(page) instead of page_address(page) and then you will
need to kunmap(kptr) on the unpin side.





[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux