set_pte()

将pteval写入pteptr所指的页表项中:
#define set_pte(pteptr, pteval) (*(pteptr) = pteval)










 
static int mfill_atomic_pte_copy(pmd_t *dst_pmd, 242 struct vm_area_struct *dst_vma, 243 unsigned long dst_addr, 244 unsigned long src_addr, 245 uffd_flags_t flags, 246 struct folio **foliop) 247 { 248 void *kaddr; 249 int ret; 250 struct folio *folio; 251 252 if (!*foliop) { 253 ret = -ENOMEM; 254 folio = vma_alloc_folio(GFP_HIGHUSER_MOVABLE, 0, dst_vma, 255 dst_addr, false); 256 if (!folio) 257 goto out; 258 259 kaddr = kmap_local_folio(folio, 0); 260 /* 261 * The read mmap_lock is held here. Despite the 262 * mmap_lock being read recursive a deadlock is still 263 * possible if a writer has taken a lock. For example: 264 * 265 * process A thread 1 takes read lock on own mmap_lock 266 * process A thread 2 calls mmap, blocks taking write lock 267 * process B thread 1 takes page fault, read lock on own mmap lock 268 * process B thread 2 calls mmap, blocks taking write lock 269 * process A thread 1 blocks taking read lock on process B 270 * process B thread 1 blocks taking read lock on process A 271 * 272 * Disable page faults to prevent potential deadlock 273 * and retry the copy outside the mmap_lock. 274 */ 275 pagefault_disable(); 276 ret = copy_from_user(kaddr, (const void __user *) src_addr, 277 PAGE_SIZE); 278 pagefault_enable(); 279 kunmap_local(kaddr); 280 281 /* fallback to copy_from_user outside mmap_lock */ 282 if (unlikely(ret)) { 283 ret = -ENOENT; 284 *foliop = folio; 285 /* don't free the page */ 286 goto out; 287 } 288 289 flush_dcache_folio(folio); 290 } else { 291 folio = *foliop; 292 *foliop = NULL; 293 } 294 295 /* 296 * The memory barrier inside __folio_mark_uptodate makes sure that 297 * preceding stores to the page contents become visible before 298 * the set_pte_at() write. 299 */ 300 __folio_mark_uptodate(folio); 301 302 ret = -ENOMEM; 303 if (mem_cgroup_charge(folio, dst_vma->vm_mm, GFP_KERNEL)) 304 goto out_release; 305 306 ret = mfill_atomic_install_pte(dst_pmd, dst_vma, dst_addr, 307 &folio->page, true, flags); 308 if (ret) 309 goto out_release; 310 out: 311 return ret; 312 out_release: 313 folio_put(folio); 314 goto out; 315 }
最新发布
03-21
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值