diff options
author | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2003-11-07 11:34:27 +0000 |
---|---|---|
committer | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2003-11-07 11:34:27 +0000 |
commit | 0a8297b33814d7c5497aab214e3011074ec941d5 (patch) | |
tree | a47c6273311d365b30113921b7be9371a0058ff2 | |
parent | 5bebf211b04948c98b307c92c361509c2d67a338 (diff) | |
download | xen-0a8297b33814d7c5497aab214e3011074ec941d5.tar.gz xen-0a8297b33814d7c5497aab214e3011074ec941d5.tar.bz2 xen-0a8297b33814d7c5497aab214e3011074ec941d5.zip |
bitkeeper revision 1.570 (3fab8343LyJPc2KVRZYbCwAIS3T15g)
Many files:
Various cleanups and fixes for suspend/resume. Just a couple more bugs to fix.
-rw-r--r-- | tools/internal/xi_build.c | 3 | ||||
-rw-r--r-- | tools/internal/xi_restore_linux.c | 72 | ||||
-rw-r--r-- | tools/internal/xi_save_linux.c | 22 | ||||
-rw-r--r-- | xen/arch/i386/mm.c | 3 | ||||
-rw-r--r-- | xen/arch/i386/process.c | 2 | ||||
-rw-r--r-- | xen/arch/i386/traps.c | 6 | ||||
-rw-r--r-- | xen/common/memory.c | 107 | ||||
-rw-r--r-- | xenolinux-2.4.22-sparse/arch/xeno/kernel/setup.c | 3 | ||||
-rw-r--r-- | xenolinux-2.4.22-sparse/include/asm-xeno/hypervisor.h | 8 |
9 files changed, 145 insertions, 81 deletions
diff --git a/tools/internal/xi_build.c b/tools/internal/xi_build.c index 0bc1f1299c..0685d723bf 100644 --- a/tools/internal/xi_build.c +++ b/tools/internal/xi_build.c @@ -461,7 +461,10 @@ int main(int argc, char **argv) load_addr, ksize, &launch_op.u.builddomain, argc, argv, args_start, op.u.getdomaininfo.shared_info_frame) < 0 ) + { + ERROR("Error constructing guest OS"); return 1; + } if ( initrd_fd >= 0 ) close(initrd_fd); diff --git a/tools/internal/xi_restore_linux.c b/tools/internal/xi_restore_linux.c index 0e2aebd9c4..bd42e62952 100644 --- a/tools/internal/xi_restore_linux.c +++ b/tools/internal/xi_restore_linux.c @@ -42,12 +42,13 @@ static int get_pfn_list( static mmu_update_t mmu_updates[MAX_MMU_UPDATES]; static int mmu_update_idx; -static void flush_mmu_updates(void) +static int flush_mmu_updates(void) { + int err = 0; privcmd_hypercall_t hypercall; if ( mmu_update_idx == 0 ) - return; + return 0; hypercall.op = __HYPERVISOR_mmu_update; hypercall.arg[0] = (unsigned long)mmu_updates; @@ -56,26 +57,31 @@ static void flush_mmu_updates(void) if ( mlock(mmu_updates, sizeof(mmu_updates)) != 0 ) { PERROR("Could not lock pagetable update array"); - exit(1); + err = 1; + goto out; } if ( do_xen_hypercall(&hypercall) < 0 ) { ERROR("Failure when submitting mmu updates"); - exit(1); + err = 1; } mmu_update_idx = 0; (void)munlock(mmu_updates, sizeof(mmu_updates)); + + out: + return err; } -static void add_mmu_update(unsigned long ptr, unsigned long val) +static int add_mmu_update(unsigned long ptr, unsigned long val) { mmu_updates[mmu_update_idx].ptr = ptr; mmu_updates[mmu_update_idx].val = val; if ( ++mmu_update_idx == MAX_MMU_UPDATES ) - flush_mmu_updates(); + return flush_mmu_updates(); + return 0; } static int devmem_fd; @@ -163,9 +169,9 @@ int main(int argc, char **argv) } filename = argv[1]; - if ( (fd = open(name, O_RDONLY)) == -1 ) + if ( (fd = open(filename, O_RDONLY)) == -1 ) { - PERROR("Could not open file for writing"); + PERROR("Could not open state file for reading"); return 1; } @@ -269,8 +275,9 @@ int main(int argc, char **argv) { case L1TAB: memset(ppage, 0, PAGE_SIZE); - add_mmu_update((mfn<<PAGE_SHIFT) | MMU_EXTENDED_COMMAND, - MMUEXT_PIN_L1_TABLE); + if ( add_mmu_update((mfn<<PAGE_SHIFT) | MMU_EXTENDED_COMMAND, + MMUEXT_PIN_L1_TABLE) ) + goto out; for ( j = 0; j < 1024; j++ ) { if ( page[j] & _PAGE_PRESENT ) @@ -285,17 +292,19 @@ int main(int argc, char **argv) ERROR("Write access requested for a restricted frame"); goto out; } - page[j] &= PAGE_SIZE - 1; + page[j] &= (PAGE_SIZE - 1) & ~(_PAGE_GLOBAL | _PAGE_PAT); page[j] |= pfn_to_mfn_table[pfn] << PAGE_SHIFT; } - add_mmu_update((unsigned long)&ppage[j], page[j]); + if ( add_mmu_update((unsigned long)&ppage[j], page[j]) ) + goto out; } break; case L2TAB: memset(ppage, 0, PAGE_SIZE); - add_mmu_update((mfn<<PAGE_SHIFT) | MMU_EXTENDED_COMMAND, - MMUEXT_PIN_L2_TABLE); - for ( j = 0; j < 1024; j++ ) + if ( add_mmu_update((mfn<<PAGE_SHIFT) | MMU_EXTENDED_COMMAND, + MMUEXT_PIN_L2_TABLE) ) + goto out; + for ( j = 0; j < (HYPERVISOR_VIRT_START>>L2_PAGETABLE_SHIFT); j++ ) { if ( page[j] & _PAGE_PRESENT ) { @@ -309,22 +318,35 @@ int main(int argc, char **argv) ERROR("Page table mistyping"); goto out; } - page[j] &= PAGE_SIZE - 1; + /* Haven't reached the L1 table yet. Ensure it is safe! */ + if ( pfn > i ) + { + unsigned long **l1 = map_pfn(pfn_to_mfn_table[pfn]); + memset(l1, 0, PAGE_SIZE); + unmap_pfn(l1); + } + page[j] &= (PAGE_SIZE - 1) & ~(_PAGE_GLOBAL | _PAGE_PSE); page[j] |= pfn_to_mfn_table[pfn] << PAGE_SHIFT; } - add_mmu_update((unsigned long)&ppage[j], page[j]); + if ( add_mmu_update((unsigned long)&ppage[j], page[j]) ) + goto out; } break; default: memcpy(ppage, page, PAGE_SIZE); break; } + /* NB. Must flush before unmapping page, as pass VAs to Xen. */ + if ( flush_mmu_updates() ) + goto out; unmap_pfn(ppage); - add_mmu_update((mfn<<PAGE_SHIFT) | MMU_MACHPHYS_UPDATE, i); + if ( add_mmu_update((mfn<<PAGE_SHIFT) | MMU_MACHPHYS_UPDATE, i) ) + goto out; } - flush_mmu_updates(); + if ( flush_mmu_updates() ) + goto out; /* Uncanonicalise the suspend-record frame number and poke resume rec. */ pfn = ctxt.i386_ctxt.esi; @@ -391,7 +413,7 @@ int main(int argc, char **argv) * 4. fast_trap_idx is checked by Xen. * 5. ldt base must be page-aligned, no more than 8192 ents, ... * 6. gdt already done, and further checking is done by Xen. - * 7. check that ring1_ss/esp is safe. + * 7. check that ring1_ss is safe. * 8. pt_base is already done. * 9. debugregs are checked by Xen. * 10. callback code selectors need checking. @@ -404,8 +426,6 @@ int main(int argc, char **argv) } if ( (ctxt.ring1_ss & 3) == 0 ) ctxt.ring1_ss = FLAT_RING1_DS; - if ( ctxt.ring1_esp > HYPERVISOR_VIRT_START ) - ctxt.ring1_esp = HYPERVISOR_VIRT_START; if ( (ctxt.event_callback_cs & 3) == 0 ) ctxt.event_callback_cs = FLAT_RING1_CS; if ( (ctxt.failsafe_callback_cs & 3) == 0 ) @@ -419,9 +439,11 @@ int main(int argc, char **argv) goto out; } - - /* Success! */ - rc = 0; + op.cmd = DOM0_BUILDDOMAIN; + op.u.builddomain.domain = dom; + op.u.builddomain.num_vifs = 1; + memcpy(&op.u.builddomain.ctxt, &ctxt, sizeof(ctxt)); + rc = do_dom0_op(&op); out: /* If we experience an error then kill the half-constructed domain. */ diff --git a/tools/internal/xi_save_linux.c b/tools/internal/xi_save_linux.c index 1716d04eb6..54d0a40550 100644 --- a/tools/internal/xi_save_linux.c +++ b/tools/internal/xi_save_linux.c @@ -98,7 +98,7 @@ static int checked_write(int fd, const void *buf, size_t count) int main(int argc, char **argv) { dom0_op_t op; - int rc = 1, i; + int rc = 1, i, j; unsigned long mfn, dom; /* Remember if we stopped the guest, so we can restart it on exit. */ @@ -148,7 +148,7 @@ int main(int argc, char **argv) } filename = argv[2]; - if ( (fd = open(name, O_CREAT|O_EXCL|O_RDWR)) == -1 ) + if ( (fd = open(filename, O_CREAT|O_EXCL|O_WRONLY, 0644)) == -1 ) { PERROR("Could not open file for writing"); return 1; @@ -255,15 +255,14 @@ int main(int argc, char **argv) goto out; } - pfn_to_mfn_table[i] = mfn; - /* Did we map this MFN already? That would be invalid! */ if ( MFN_IS_IN_PSEUDOPHYS_MAP(mfn) ) { ERROR("A machine frame appears twice in pseudophys space"); goto out; } - + + pfn_to_mfn_table[i] = mfn; mfn_to_pfn_table[mfn] = i; /* Query page type by MFN, but store it by PFN. */ @@ -331,17 +330,20 @@ int main(int argc, char **argv) if ( (pfn_type[i] == L1TAB) || (pfn_type[i] == L2TAB) ) { - for ( i = 0; i < 1024; i++ ) + for ( j = 0; + j < ((pfn_type[i] == L2TAB) ? + (HYPERVISOR_VIRT_START >> L2_PAGETABLE_SHIFT) : 1024); + j++ ) { - if ( !(page[i] & _PAGE_PRESENT) ) continue; - mfn = page[i] >> PAGE_SHIFT; + if ( !(page[j] & _PAGE_PRESENT) ) continue; + mfn = page[j] >> PAGE_SHIFT; if ( !MFN_IS_IN_PSEUDOPHYS_MAP(mfn) ) { ERROR("Frame number in pagetable page is invalid"); goto out; } - page[i] &= PAGE_SIZE - 1; - page[i] |= mfn_to_pfn_table[mfn] << PAGE_SHIFT; + page[j] &= PAGE_SIZE - 1; + page[j] |= mfn_to_pfn_table[mfn] << PAGE_SHIFT; } } diff --git a/xen/arch/i386/mm.c b/xen/arch/i386/mm.c index 61221c20a1..0546f53582 100644 --- a/xen/arch/i386/mm.c +++ b/xen/arch/i386/mm.c @@ -129,7 +129,8 @@ long do_stack_switch(unsigned long ss, unsigned long esp) int nr = smp_processor_id(); struct tss_struct *t = &init_tss[nr]; - if ( ((ss & 3) == 0) || (esp > HYPERVISOR_VIRT_START) ) + /* We need to do this check as we load and use SS on guest's behalf. */ + if ( (ss & 3) == 0 ) return -EPERM; current->thread.ss1 = ss; diff --git a/xen/arch/i386/process.c b/xen/arch/i386/process.c index 05bbe1ea92..4dc4b43e03 100644 --- a/xen/arch/i386/process.c +++ b/xen/arch/i386/process.c @@ -248,7 +248,7 @@ void switch_to(struct task_struct *prev_p, struct task_struct *next_p) * then we'll #GP. */ if ( (stack_ec->cs & 3) == 0 ) - stack_ec->cs = 0; + stack_ec->cs = FLAT_RING1_CS; unlazy_fpu(prev_p); diff --git a/xen/arch/i386/traps.c b/xen/arch/i386/traps.c index 1668a13b56..330defe3a8 100644 --- a/xen/arch/i386/traps.c +++ b/xen/arch/i386/traps.c @@ -292,14 +292,14 @@ asmlinkage void do_page_fault(struct pt_regs *regs, long error_code) __asm__ __volatile__ ("movl %%cr2,%0" : "=r" (addr) : ); - if ( unlikely(!(regs->xcs & 3)) ) - goto fault_in_hypervisor; - if ( unlikely(addr > PAGE_OFFSET) ) goto fault_in_xen_space; propagate_fault: + if ( unlikely(!(regs->xcs & 3)) ) + goto fault_in_hypervisor; + ti = p->thread.traps + 14; gtb->flags = GTBF_TRAP_CR2; /* page fault pushes %cr2 */ gtb->cr2 = addr; diff --git a/xen/common/memory.c b/xen/common/memory.c index 1629118929..8d33bd9f20 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -408,17 +408,17 @@ static int get_l2_table(unsigned long page_nr) { l2_entry = *p_l2_entry++; if ( !(l2_pgentry_val(l2_entry) & _PAGE_PRESENT) ) continue; - if ( (l2_pgentry_val(l2_entry) & (_PAGE_GLOBAL|_PAGE_PSE)) ) + if ( unlikely((l2_pgentry_val(l2_entry) & (_PAGE_GLOBAL|_PAGE_PSE))) ) { MEM_LOG("Bad L2 page type settings %04lx", l2_pgentry_val(l2_entry) & (_PAGE_GLOBAL|_PAGE_PSE)); ret = -1; - goto out; + goto fail; } /* Assume we're mapping an L1 table, falling back to twisted L2. */ ret = get_l1_table(l2_pgentry_to_pagenr(l2_entry)); - if ( ret ) ret = get_twisted_l2_table(page_nr, l2_entry); - if ( ret ) goto out; + if ( unlikely(ret) ) ret = get_twisted_l2_table(page_nr, l2_entry); + if ( unlikely(ret) ) goto fail; } /* Now we simply slap in our high mapping. */ @@ -435,6 +435,18 @@ static int get_l2_table(unsigned long page_nr) out: unmap_domain_mem(p_l2_entry); return ret; + + fail: + p_l2_entry--; + while ( i-- > 0 ) + { + l2_entry = *--p_l2_entry; + if ( (l2_pgentry_val(l2_entry) & _PAGE_PRESENT) ) + put_l1_table(l2_pgentry_to_pagenr(l2_entry)); + } + if ( dec_page_refcnt(page_nr, PGT_l2_page_table) != 0 ) + BUG(); + goto out; } @@ -453,24 +465,38 @@ static int get_l1_table(unsigned long page_nr) { l1_entry = *p_l1_entry++; if ( !(l1_pgentry_val(l1_entry) & _PAGE_PRESENT) ) continue; - if ( (l1_pgentry_val(l1_entry) & - (_PAGE_GLOBAL|_PAGE_PAT)) ) + if ( unlikely((l1_pgentry_val(l1_entry) & + (_PAGE_GLOBAL|_PAGE_PAT))) ) { MEM_LOG("Bad L1 page type settings %04lx", l1_pgentry_val(l1_entry) & (_PAGE_GLOBAL|_PAGE_PAT)); ret = -1; - goto out; + goto fail; } ret = get_page(l1_pgentry_to_pagenr(l1_entry), l1_pgentry_val(l1_entry) & _PAGE_RW); - if ( ret ) goto out; + if ( unlikely(ret) ) goto fail; } out: /* Make sure we unmap the right page! */ unmap_domain_mem(p_l1_entry-1); return ret; + + fail: + p_l1_entry--; + while ( i-- > 0 ) + { + l1_entry = *--p_l1_entry; + if ( (l1_pgentry_val(l1_entry) & _PAGE_PRESENT) ) + put_page(l1_pgentry_to_pagenr(l1_entry), + l1_pgentry_val(l1_entry) & _PAGE_RW); + } + if ( dec_page_refcnt(page_nr, PGT_l1_page_table) != 0 ) + BUG(); + unmap_domain_mem(p_l1_entry); + return ret; } @@ -550,10 +576,8 @@ static void put_l1_table(unsigned long page_nr) { l1_entry = *p_l1_entry++; if ( (l1_pgentry_val(l1_entry) & _PAGE_PRESENT) ) - { put_page(l1_pgentry_to_pagenr(l1_entry), l1_pgentry_val(l1_entry) & _PAGE_RW); - } } /* Make sure we unmap the right page! */ @@ -611,9 +635,6 @@ static int mod_l2_entry(l2_pgentry_t *p_l2_entry, l2_pgentry_t new_l2_entry) if ( ((l2_pgentry_val(old_l2_entry) ^ l2_pgentry_val(new_l2_entry)) & 0xfffff001) != 0 ) { - if ( (l2_pgentry_val(old_l2_entry) & _PAGE_PRESENT) ) - put_l1_table(l2_pgentry_to_pagenr(old_l2_entry)); - /* Assume we're mapping an L1 table, falling back to twisted L2. */ if ( unlikely(get_l1_table(l2_pgentry_to_pagenr(new_l2_entry))) ) { @@ -623,6 +644,9 @@ static int mod_l2_entry(l2_pgentry_t *p_l2_entry, l2_pgentry_t new_l2_entry) if ( get_twisted_l2_table(l1e >> PAGE_SHIFT, new_l2_entry) ) goto fail; } + + if ( (l2_pgentry_val(old_l2_entry) & _PAGE_PRESENT) ) + put_l1_table(l2_pgentry_to_pagenr(old_l2_entry)); } } else if ( (l2_pgentry_val(old_l2_entry) & _PAGE_PRESENT) ) @@ -659,13 +683,13 @@ static int mod_l1_entry(l1_pgentry_t *p_l1_entry, l1_pgentry_t new_l1_entry) if ( ((l1_pgentry_val(old_l1_entry) ^ l1_pgentry_val(new_l1_entry)) & 0xfffff003) != 0 ) { - if ( (l1_pgentry_val(old_l1_entry) & _PAGE_PRESENT) ) - put_page(l1_pgentry_to_pagenr(old_l1_entry), - l1_pgentry_val(old_l1_entry) & _PAGE_RW); - if ( get_page(l1_pgentry_to_pagenr(new_l1_entry), l1_pgentry_val(new_l1_entry) & _PAGE_RW) ) goto fail; + + if ( (l1_pgentry_val(old_l1_entry) & _PAGE_PRESENT) ) + put_page(l1_pgentry_to_pagenr(old_l1_entry), + l1_pgentry_val(old_l1_entry) & _PAGE_RW); } } else if ( (l1_pgentry_val(old_l1_entry) & _PAGE_PRESENT) ) @@ -696,10 +720,24 @@ static int do_extended_command(unsigned long ptr, unsigned long val) switch ( cmd ) { case MMUEXT_PIN_L1_TABLE: + if ( unlikely(page->type_count & REFCNT_PIN_BIT) ) + { + MEM_LOG("Pfn %08lx already pinned", pfn); + err = 1; + break; + } err = get_l1_table(pfn); goto mark_as_pinned; + case MMUEXT_PIN_L2_TABLE: + if ( unlikely(page->type_count & REFCNT_PIN_BIT) ) + { + MEM_LOG("Pfn %08lx already pinned", pfn); + err = 1; + break; + } err = get_l2_table(pfn); + mark_as_pinned: if ( unlikely(err) ) { @@ -708,16 +746,8 @@ static int do_extended_command(unsigned long ptr, unsigned long val) } put_page_type(page); put_page_tot(page); - if ( likely(!(page->type_count & REFCNT_PIN_BIT)) ) - { - page->type_count |= REFCNT_PIN_BIT; - page->tot_count |= REFCNT_PIN_BIT; - } - else - { - MEM_LOG("Pfn %08lx already pinned", pfn); - err = 1; - } + page->type_count |= REFCNT_PIN_BIT; + page->tot_count |= REFCNT_PIN_BIT; break; case MMUEXT_UNPIN_TABLE: @@ -805,7 +835,7 @@ int do_mmu_update(mmu_update_t *ureqs, int count) mmu_update_t req; unsigned long flags, pfn, l1e; struct pfn_info *page; - int err = 0, i, cpu = smp_processor_id(); + int rc = 0, err = 0, i, cpu = smp_processor_id(); unsigned int cmd; unsigned long cr0 = 0; @@ -814,11 +844,10 @@ int do_mmu_update(mmu_update_t *ureqs, int count) for ( i = 0; i < count; i++ ) { - if ( unlikely(copy_from_user(&req, ureqs, sizeof(req)) != 0) ) { - if ( cr0 != 0 ) write_cr0(cr0); - kill_domain_with_errmsg("Cannot read page update request"); + rc = -EFAULT; + break; } cmd = req.ptr & (sizeof(l1_pgentry_t)-1); @@ -939,8 +968,8 @@ int do_mmu_update(mmu_update_t *ureqs, int count) if ( unlikely(err) ) { - if ( cr0 != 0 ) write_cr0(cr0); - kill_domain_with_errmsg("Illegal page update request"); + rc = -EINVAL; + break; } ureqs++; @@ -961,7 +990,7 @@ int do_mmu_update(mmu_update_t *ureqs, int count) if ( cr0 != 0 ) write_cr0(cr0); - return 0; + return rc; } @@ -991,11 +1020,11 @@ int do_update_va_mapping(unsigned long page_nr, write_cr0(cr0 & ~X86_CR0_WP); } - if ( unlikely((err = mod_l1_entry(&linear_pg_table[page_nr], - mk_l1_pgentry(val))) != 0) ) + if ( unlikely(mod_l1_entry(&linear_pg_table[page_nr], + mk_l1_pgentry(val)) != 0) ) { - spin_unlock_irq(&p->page_lock); - kill_domain_with_errmsg("Illegal VA-mapping update request"); + err = -EINVAL; + goto check_cr0_unlock_and_out; } if ( unlikely(flags & UVMF_INVLPG) ) @@ -1004,9 +1033,9 @@ int do_update_va_mapping(unsigned long page_nr, if ( unlikely(flags & UVMF_FLUSH_TLB) ) __write_cr3_counted(pagetable_val(p->mm.pagetable)); + check_cr0_unlock_and_out: if ( unlikely(cr0 != 0) ) write_cr0(cr0); - unlock_and_out: spin_unlock_irq(&p->page_lock); out: diff --git a/xenolinux-2.4.22-sparse/arch/xeno/kernel/setup.c b/xenolinux-2.4.22-sparse/arch/xeno/kernel/setup.c index ae7c587eab..2236663120 100644 --- a/xenolinux-2.4.22-sparse/arch/xeno/kernel/setup.c +++ b/xenolinux-2.4.22-sparse/arch/xeno/kernel/setup.c @@ -155,8 +155,7 @@ static void __init parse_mem_cmdline (char ** cmdline_p) void __init setup_arch(char **cmdline_p) { - unsigned long start_pfn, max_pfn, max_low_pfn; - unsigned long bootmap_size; + unsigned long bootmap_size, start_pfn, max_low_pfn; unsigned long i; extern void hypervisor_callback(void); diff --git a/xenolinux-2.4.22-sparse/include/asm-xeno/hypervisor.h b/xenolinux-2.4.22-sparse/include/asm-xeno/hypervisor.h index 08bc1faf6b..0fbf40c951 100644 --- a/xenolinux-2.4.22-sparse/include/asm-xeno/hypervisor.h +++ b/xenolinux-2.4.22-sparse/include/asm-xeno/hypervisor.h @@ -10,6 +10,7 @@ #define __HYPERVISOR_H__ #include <linux/types.h> +#include <linux/kernel.h> #include <asm/hypervisor-ifs/hypervisor-if.h> #include <asm/hypervisor-ifs/dom0_ops.h> #include <asm/ptrace.h> @@ -167,6 +168,9 @@ static inline int HYPERVISOR_mmu_update(mmu_update_t *req, int count) : "=a" (ret) : "0" (__HYPERVISOR_mmu_update), "b" (req), "c" (count) ); + if ( unlikely(ret < 0) ) + panic("Failed mmu update: %p, %d", req, count); + return ret; } @@ -396,6 +400,10 @@ static inline int HYPERVISOR_update_va_mapping( : "=a" (ret) : "0" (__HYPERVISOR_update_va_mapping), "b" (page_nr), "c" ((new_val).pte_low), "d" (flags) ); + if ( unlikely(ret < 0) ) + panic("Failed update VA mapping: %08lx, %08lx, %08lx", + page_nr, (new_val).pte_low, flags); + return ret; } |