/* * Given a nasid, get the physical address of the partition's reserved page * for that nasid. This function returns 0 on any error. */ static u64 xpc_get_rsvd_page_pa(int nasid) { bte_result_t bte_res; s64 status; u64 cookie = 0; u64 rp_pa = nasid; /* seed with nasid */ u64 len = 0; u64 buf = buf; u64 buf_len = 0; void *buf_base = NULL; while (1) { status = sn_partition_reserved_page_pa(buf, &cookie, &rp_pa, &len); dev_dbg(xpc_part, "SAL returned with status=%li, cookie=" "0x%016lx, address=0x%016lx, len=0x%016lx\n", status, cookie, rp_pa, len); if (status != SALRET_MORE_PASSES) { break; } if (L1_CACHE_ALIGN(len) > buf_len) { if (buf_base != NULL) { kfree(buf_base); } buf_len = L1_CACHE_ALIGN(len); buf = (u64) xpc_kmalloc_cacheline_aligned(buf_len, GFP_KERNEL, &buf_base); if (buf_base == NULL) { dev_err(xpc_part, "unable to kmalloc " "len=0x%016lx\n", buf_len); status = SALRET_ERROR; break; } } bte_res = xp_bte_copy(rp_pa, ia64_tpa(buf), buf_len, (BTE_NOTIFY | BTE_WACQUIRE), NULL); if (bte_res != BTE_SUCCESS) { dev_dbg(xpc_part, "xp_bte_copy failed %i\n", bte_res); status = SALRET_ERROR; break; } } if (buf_base != NULL) { kfree(buf_base); } if (status != SALRET_OK) { rp_pa = 0; } dev_dbg(xpc_part, "reserved page at phys address 0x%016lx\n", rp_pa); return rp_pa; }
static enum xp_retval xpc_get_partition_rsvd_page_pa_uv(void *buf, u64 *cookie, unsigned long *rp_pa, size_t *len) { s64 status; enum xp_retval ret; #if defined CONFIG_X86_64 status = uv_bios_reserved_page_pa((u64)buf, cookie, (u64 *)rp_pa, (u64 *)len); if (status == BIOS_STATUS_SUCCESS) ret = xpSuccess; else if (status == BIOS_STATUS_MORE_PASSES) ret = xpNeedMoreInfo; else ret = xpBiosError; #elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV status = sn_partition_reserved_page_pa((u64)buf, cookie, rp_pa, len); if (status == SALRET_OK) ret = xpSuccess; else if (status == SALRET_MORE_PASSES) ret = xpNeedMoreInfo; else ret = xpSalError; #else #error not a supported configuration #endif return ret; }
/* * Given a nasid, get the physical address of the partition's reserved page * for that nasid. This function returns 0 on any error. */ static u64 xpc_get_rsvd_page_pa(int nasid, u64 buf, u64 buf_size) { bte_result_t bte_res; s64 status; u64 cookie = 0; u64 rp_pa = nasid; /* seed with nasid */ u64 len = 0; while (1) { status = sn_partition_reserved_page_pa(buf, &cookie, &rp_pa, &len); dev_dbg(xpc_part, "SAL returned with status=%li, cookie=" "0x%016lx, address=0x%016lx, len=0x%016lx\n", status, cookie, rp_pa, len); if (status != SALRET_MORE_PASSES) { break; } if (len > buf_size) { dev_err(xpc_part, "len (=0x%016lx) > buf_size\n", len); status = SALRET_ERROR; break; } bte_res = xp_bte_copy(rp_pa, ia64_tpa(buf), buf_size, (BTE_NOTIFY | BTE_WACQUIRE), NULL); if (bte_res != BTE_SUCCESS) { dev_dbg(xpc_part, "xp_bte_copy failed %i\n", bte_res); status = SALRET_ERROR; break; } } if (status != SALRET_OK) { rp_pa = 0; } dev_dbg(xpc_part, "reserved page at phys address 0x%016lx\n", rp_pa); return rp_pa; }