void drm_clflush_virt_range(void *addr, unsigned long length) { #if defined(CONFIG_X86) if (cpu_has_clflush) { void *end = addr + length; mb(); for (; addr < end; addr += boot_cpu_data.x86_clflush_size) clflushopt(addr); clflushopt(end - 1); mb(); return; } if (wbinvd_on_all_cpus()) printk(KERN_ERR "Timed out waiting for cache flush.\n"); #else printk(KERN_ERR "Architecture has no drm_cache.c support\n"); WARN_ON_ONCE(1); #endif }
/* * clflushopt is an unordered instruction which needs fencing with mfence or * sfence to avoid ordering issues. For drm_clflush_page this fencing happens * in the caller. */ static void drm_clflush_page(struct page *page) { uint8_t *page_virtual; unsigned int i; const int size = boot_cpu_data.x86_clflush_size; if (unlikely(page == NULL)) return; page_virtual = kmap_atomic(page); for (i = 0; i < PAGE_SIZE; i += size) clflushopt(page_virtual + i); kunmap_atomic(page_virtual); }
void drm_clflush_virt_range(char *addr, unsigned long length) { #if defined(CONFIG_X86) if (cpu_has_clflush) { char *end = addr + length; mb(); for (; addr < end; addr += boot_cpu_data.x86_clflush_size) clflush(addr); clflushopt(end - 1); mb(); return; } if (on_each_cpu(drm_clflush_ipi_handler, NULL, 1) != 0) printk(KERN_ERR "Timed out waiting for cache flush.\n"); #else printk(KERN_ERR "Architecture has no drm_cache.c support\n"); WARN_ON_ONCE(1); #endif }