static int pt_image_read_cold(struct pt_image *image, int *isid, uint8_t *buffer, uint16_t size, const struct pt_asid *asid, uint64_t addr) { struct pt_mapped_section *msec; struct pt_section_list *section; int errcode; if (!image || !isid) return -pte_internal; errcode = pt_image_fetch_section(image, asid, addr); if (errcode < 0) { if (errcode != -pte_nomap) return errcode; } section = image->sections; if (!section) return pt_image_read_callback(image, isid, buffer, size, asid, addr); msec = §ion->section; errcode = pt_image_check_msec(msec, asid, addr); if (errcode < 0) { if (errcode != -pte_nomap) return errcode; return pt_image_read_callback(image, isid, buffer, size, asid, addr); } *isid = section->isid; if (section->mapped) return pt_image_read_msec(buffer, size, msec, addr); else { struct pt_section *sec; int status; sec = pt_msec_section(msec); errcode = pt_section_map(sec); if (errcode < 0) return errcode; status = pt_image_read_msec(buffer, size, msec, addr); errcode = pt_section_unmap(sec); if (errcode < 0) return errcode; return status; } }
static int pt_image_read_cold(struct pt_image *image, struct pt_section_list **list, uint8_t *buffer, uint16_t size, const struct pt_asid *asid, uint64_t addr) { struct pt_section_list **start; if (!image || !list) return -pte_internal; start = &image->sections; while (*list) { struct pt_mapped_section *msec; struct pt_section_list *elem; struct pt_section *sec; int mapped, errcode, status; elem = *list; msec = &elem->section; sec = msec->section; mapped = elem->mapped; if (!mapped) { errcode = pt_section_map(sec); if (errcode < 0) return errcode; } status = pt_msec_read_mapped(msec, buffer, size, asid, addr); if (status < 0) { if (!mapped) { errcode = pt_section_unmap(sec); if (errcode < 0) return errcode; } list = &elem->next; continue; } /* Move the section to the front if it isn't already. */ if (list != start) { *list = elem->next; elem->next = *start; *start = elem; } /* Keep the section mapped if it isn't already - provided we * do cache recently used sections. */ if (!mapped) { uint16_t cache, already; already = image->mapped; cache = image->cache; if (cache) { elem->mapped = 1; already += 1; image->mapped = already; if (cache < already) { errcode = pt_image_prune_cache(image); if (errcode < 0) return errcode; } } else { errcode = pt_section_unmap(sec); if (errcode < 0) return errcode; } } return status; } return pt_image_read_callback(image, buffer, size, asid, addr); }