ia64/xen-unstable
changeset 18872:3acca92b9597
IA64: fix efi_emulate_set_virtual_address_map()
get_page() before touching guest pages.
Otherwise pages may be freed during those operations.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
get_page() before touching guest pages.
Otherwise pages may be freed during those operations.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author | Isaku Yamahata <yamahata@valinux.co.jp> |
---|---|
date | Wed Dec 10 15:39:47 2008 +0900 (2008-12-10) |
parents | e239a47180fb |
children | a86a4ddd8b2b |
files | xen/arch/ia64/xen/fw_emul.c |
line diff
1.1 --- a/xen/arch/ia64/xen/fw_emul.c Wed Dec 10 15:39:46 2008 +0900 1.2 +++ b/xen/arch/ia64/xen/fw_emul.c Wed Dec 10 15:39:47 2008 +0900 1.3 @@ -1334,6 +1334,10 @@ efi_emulate_set_virtual_address_map( 1.4 efi_desc_size = sizeof(efi_memory_desc_t); 1.5 1.6 for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { 1.7 + struct page_info *efi_runtime_page = NULL; 1.8 + struct page_info *fpswa_inf_page = NULL; 1.9 + struct page_info *fw_table_page = NULL; 1.10 + 1.11 if (copy_from_user(&entry, p, sizeof(efi_memory_desc_t))) { 1.12 printk ("efi_emulate_set_virtual_address_map: copy_from_user() fault. addr=0x%p\n", p); 1.13 return EFI_UNSUPPORTED; 1.14 @@ -1343,6 +1347,27 @@ efi_emulate_set_virtual_address_map( 1.15 if (md->type != EFI_PAL_CODE) 1.16 continue; 1.17 1.18 + /* get pages to prevend them from being freed 1.19 + * during touching them. 1.20 + * those entres are in [FW_TABLES_BASE_PADDR, ...] 1.21 + * see dom_fw.h for its layout. 1.22 + */ 1.23 + efi_runtime_page = virt_to_page(efi_runtime); 1.24 + fpswa_inf_page = virt_to_page(fpswa_inf); 1.25 + fw_table_page = virt_to_page( 1.26 + domain_mpa_to_imva(d, FW_TABLES_BASE_PADDR)); 1.27 + if (get_page(efi_runtime_page, d) == 0) 1.28 + return EFI_INVALID_PARAMETER; 1.29 + if (get_page(fpswa_inf_page, d) == 0) { 1.30 + put_page(efi_runtime_page); 1.31 + return EFI_INVALID_PARAMETER; 1.32 + } 1.33 + if (get_page(fw_table_page, d) == 0) { 1.34 + put_page(fpswa_inf_page); 1.35 + put_page(efi_runtime_page); 1.36 + return EFI_INVALID_PARAMETER; 1.37 + } 1.38 + 1.39 #define EFI_HYPERCALL_PATCH_TO_VIRT(tgt,call) \ 1.40 do { \ 1.41 vfn = (unsigned long *) domain_mpa_to_imva(d, tgt); \ 1.42 @@ -1365,6 +1390,10 @@ efi_emulate_set_virtual_address_map( 1.43 *vfn++ = FW_HYPERCALL_FPSWA_PATCH_INDEX * 16UL + md->virt_addr; 1.44 *vfn = 0; 1.45 fpswa_inf->fpswa = (void *) (FW_HYPERCALL_FPSWA_ENTRY_INDEX * 16UL + md->virt_addr); 1.46 + 1.47 + put_page(fw_table_page); 1.48 + put_page(fpswa_inf_page); 1.49 + put_page(efi_runtime_page); 1.50 break; 1.51 } 1.52