Esempio n. 1
0
bool km_page_create(struct km *mem_dst, unsigned long address, page_prot_t prot)
{
	pte_t entry;
	unsigned long page = 0;
	struct km_walk_ctx dst_ctx;

	KM_WALK_INIT(mem_dst, &dst_ctx);
	
	if (unlikely(km_walk_to(&dst_ctx, address) == false))
		goto err;

	/* Create 模式应该看不到任何内容,否则可以理解被别人刚刚处理成功 */
	if (km_pte_read(&dst_ctx))
		goto err;
	page = km_page_alloc();
	if (!page)
		goto err;
	entry = page | km_arch_get_flags(prot);	
	km_pte_write(&dst_ctx, entry);
	
	/* 不需要flush tlb,因为新的page在tlb中是不存在的 */
	return true;

err:
	if (page)
		km_page_dealloc(page);
	return false;
}
Esempio n. 2
0
static uintptr_t
km_map_aligned(uintptr_t paddr, size_t size, unsigned int flags)
{
	uintptr_t vaddr;
	size_t align;
	uintptr_t offs;

	ASSERT(ALIGN_DOWN(paddr, FRAME_SIZE) == paddr);
	ASSERT(ALIGN_UP(size, FRAME_SIZE) == size);

	/* Enforce natural or at least PAGE_SIZE alignment. */
	align = ispwr2(size) ? size : (1U << (fnzb(size) + 1));
	vaddr = km_page_alloc(size, max(PAGE_SIZE, align));

	page_table_lock(AS_KERNEL, true);
	for (offs = 0; offs < size; offs += PAGE_SIZE) {
		page_mapping_insert(AS_KERNEL, vaddr + offs, paddr + offs,
		    flags);
	}
	page_table_unlock(AS_KERNEL, true);
	
	return vaddr;
}
Esempio n. 3
0
bool km_page_create_cow(struct km *mem_dst, unsigned long address)
{
	pte_t entry;
	unsigned long page = 0;
	struct km_walk_ctx dst_ctx;
	
	KM_WALK_INIT(mem_dst, &dst_ctx);
	
	if (unlikely(km_walk_to(&dst_ctx, address) == false))
		goto err;
	
	/* 必须有内容,否则就不应该Cow */
	if (!km_pte_read(&dst_ctx))
		goto err;
	page = km_page_alloc();
	if (!page)
		goto err;
	
	//TODO: Non identical map
	if (page >= CONFIG_HAL_KERNEL_MEM_LEN)
		goto err;
	memcpy((void*)HAL_GET_BASIC_KADDRESS(page), (void*)KM_PAGE_ROUND_ALIGN(address), PAGE_SIZE);
	
	entry = page | km_arch_get_flags(KM_PROT_READ | KM_PROT_WRITE);
	km_pte_write_force(&dst_ctx, entry);

	/* Must flush, because we are changing the entry */
	km_arch_flush_page(mem_dst, address);

	return true;
	
err:
	if (page)
		km_page_dealloc(page);
	return false;
}