Commit da51b55e authored by Zhou Guanghui's avatar Zhou Guanghui Committed by Yongqiang Liu
Browse files

mm/share_pool: Support read-only memory allocation

ascend inclusion
category: Bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I578LV


CVE: NA

--------------------------------

When the driver uses the shared pool memory to share the memory
with the user space, the user space is not allowed to operate
this area. This prevents users from damaging sensitive data.

When the sp_alloc and k2u processes apply for private memory,
read-only memory can be applied for.

Signed-off-by: default avatarZhou Guanghui <zhouguanghui1@huawei.com>
Reviewed-by: default avatarWeilong Chen <chenweilong@huawei.com>
Signed-off-by: default avatarYongqiang Liu <liuyongqiang13@huawei.com>
parent 009c22bb
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
#define SP_HUGEPAGE_ONLY	(1 << 1)
#define SP_DVPP			(1 << 2)
#define SP_SPEC_NODE_ID		(1 << 3)
#define SP_PROT_RO		(1 << 16)

#define DEVICE_ID_BITS		4UL
#define DEVICE_ID_MASK		((1UL << DEVICE_ID_BITS) - 1UL)
@@ -22,7 +23,7 @@
#define NODE_ID_SHIFT		(DEVICE_ID_SHIFT + DEVICE_ID_BITS)

#define SP_FLAG_MASK		(SP_HUGEPAGE | SP_HUGEPAGE_ONLY | SP_DVPP | \
				 SP_SPEC_NODE_ID | \
				 SP_SPEC_NODE_ID | SP_PROT_RO | \
				(DEVICE_ID_MASK << DEVICE_ID_SHIFT) | \
				(NODE_ID_MASK << NODE_ID_SHIFT))

+16 −2
Original line number Diff line number Diff line
@@ -2349,6 +2349,9 @@ static int sp_alloc_mmap(struct mm_struct *mm, struct sp_area *spa,
	if (spg_node)
		prot = spg_node->prot;

	if (ac->sp_flags & SP_PROT_RO)
		prot = PROT_READ;

	/* when success, mmap_addr == spa->va_start */
	mmap_addr = sp_mmap(mm, spa_file(spa), spa, &populate, prot);
	if (IS_ERR_VALUE(mmap_addr)) {
@@ -2373,6 +2376,10 @@ static int sp_alloc_mmap(struct mm_struct *mm, struct sp_area *spa,
		ret = -EINVAL;
		goto unmap;
	}

	if (ac->sp_flags & SP_PROT_RO)
		vma->vm_flags &= ~VM_MAYWRITE;

	/* clean PTE_RDONLY flags or trigger SMMU event */
	if (prot & PROT_WRITE)
		vma->vm_page_prot = __pgprot(((~PTE_RDONLY) & vma->vm_page_prot.pgprot) | PTE_DIRTY);
@@ -2666,6 +2673,9 @@ static unsigned long sp_remap_kva_to_vma(unsigned long kva, struct sp_area *spa,
		goto put_mm;
	}

	if (kc && kc->sp_flags & SP_PROT_RO)
		prot = PROT_READ;

	ret_addr = sp_mmap(mm, spa_file(spa), spa, &populate, prot);
	if (IS_ERR_VALUE(ret_addr)) {
		pr_debug("k2u mmap failed %lx\n", ret_addr);
@@ -2678,6 +2688,9 @@ static unsigned long sp_remap_kva_to_vma(unsigned long kva, struct sp_area *spa,
	if (prot & PROT_WRITE)
		vma->vm_page_prot = __pgprot(((~PTE_RDONLY) & vma->vm_page_prot.pgprot) | PTE_DIRTY);

	if (kc && kc->sp_flags & SP_PROT_RO)
		vma->vm_flags &= ~VM_MAYWRITE;

	if (is_vm_hugetlb_page(vma)) {
		ret = remap_vmalloc_hugepage_range(vma, (void *)kva, 0);
		if (ret) {
@@ -2729,6 +2742,7 @@ static void *sp_make_share_kva_to_task(unsigned long kva, unsigned long size, un
	struct sp_area *spa;
	struct spg_proc_stat *stat;
	unsigned long prot = PROT_READ | PROT_WRITE;
	struct sp_k2u_context kc;

	down_write(&sp_group_sem);
	stat = sp_init_process_stat(current, current->mm, spg_none);
@@ -2747,8 +2761,8 @@ static void *sp_make_share_kva_to_task(unsigned long kva, unsigned long size, un
	}

	spa->kva = kva;

	uva = (void *)sp_remap_kva_to_vma(kva, spa, current->mm, prot, NULL);
	kc.sp_flags = sp_flags;
	uva = (void *)sp_remap_kva_to_vma(kva, spa, current->mm, prot, &kc);
	__sp_area_drop(spa);
	if (IS_ERR(uva))
		pr_err("remap k2u to task failed %ld\n", PTR_ERR(uva));