HWPOISON: Add basic support for poisoned pages in fault handler v3
- Add a new VM_FAULT_HWPOISON error code to handle_mm_fault. Right now architectures have to explicitely enable poison page support, so this is forward compatible to all architectures. They only need to add it when they enable poison page support. - Add poison page handling in swap in fault code v2: Add missing delayacct_clear_flag (Hidehiro Kawai) v3: Really use delayacct_clear_flag (Hidehiro Kawai) Signed-off-by: Andi Kleen <ak@linux.intel.com>
This commit is contained in:
		
					parent
					
						
							
								ad5fa91399
							
						
					
				
			
			
				commit
				
					
						d1737fdbec
					
				
			
		
					 2 changed files with 17 additions and 4 deletions
				
			
		| 
						 | 
				
			
			@ -685,11 +685,12 @@ static inline int page_mapped(struct page *page)
 | 
			
		|||
#define VM_FAULT_SIGBUS	0x0002
 | 
			
		||||
#define VM_FAULT_MAJOR	0x0004
 | 
			
		||||
#define VM_FAULT_WRITE	0x0008	/* Special case for get_user_pages */
 | 
			
		||||
#define VM_FAULT_HWPOISON 0x0010	/* Hit poisoned page */
 | 
			
		||||
 | 
			
		||||
#define VM_FAULT_NOPAGE	0x0100	/* ->fault installed the pte, not return page */
 | 
			
		||||
#define VM_FAULT_LOCKED	0x0200	/* ->fault locked the returned page */
 | 
			
		||||
 | 
			
		||||
#define VM_FAULT_ERROR	(VM_FAULT_OOM | VM_FAULT_SIGBUS)
 | 
			
		||||
#define VM_FAULT_ERROR	(VM_FAULT_OOM | VM_FAULT_SIGBUS | VM_FAULT_HWPOISON)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Can be called by the pagefault handler when it gets a VM_FAULT_OOM.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										14
									
								
								mm/memory.c
									
										
									
									
									
								
							
							
						
						
									
										14
									
								
								mm/memory.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1319,7 +1319,8 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
 | 
			
		|||
				if (ret & VM_FAULT_ERROR) {
 | 
			
		||||
					if (ret & VM_FAULT_OOM)
 | 
			
		||||
						return i ? i : -ENOMEM;
 | 
			
		||||
					else if (ret & VM_FAULT_SIGBUS)
 | 
			
		||||
					if (ret &
 | 
			
		||||
					    (VM_FAULT_HWPOISON|VM_FAULT_SIGBUS))
 | 
			
		||||
						return i ? i : -EFAULT;
 | 
			
		||||
					BUG();
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			@ -2511,8 +2512,15 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
 | 
			
		|||
		goto out;
 | 
			
		||||
 | 
			
		||||
	entry = pte_to_swp_entry(orig_pte);
 | 
			
		||||
	if (unlikely(non_swap_entry(entry))) {
 | 
			
		||||
		if (is_migration_entry(entry)) {
 | 
			
		||||
			migration_entry_wait(mm, pmd, address);
 | 
			
		||||
		} else if (is_hwpoison_entry(entry)) {
 | 
			
		||||
			ret = VM_FAULT_HWPOISON;
 | 
			
		||||
		} else {
 | 
			
		||||
			print_bad_pte(vma, address, orig_pte, NULL);
 | 
			
		||||
			ret = VM_FAULT_OOM;
 | 
			
		||||
		}
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
	delayacct_set_flag(DELAYACCT_PF_SWAPIN);
 | 
			
		||||
| 
						 | 
				
			
			@ -2536,6 +2544,10 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
 | 
			
		|||
		/* Had to read the page from swap area: Major fault */
 | 
			
		||||
		ret = VM_FAULT_MAJOR;
 | 
			
		||||
		count_vm_event(PGMAJFAULT);
 | 
			
		||||
	} else if (PageHWPoison(page)) {
 | 
			
		||||
		ret = VM_FAULT_HWPOISON;
 | 
			
		||||
		delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	lock_page(page);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue