cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cache.c (1511B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * OpenRISC cache.c
      4 *
      5 * Linux architectural port borrowing liberally from similar works of
      6 * others.  All original copyrights apply as per the original source
      7 * declaration.
      8 *
      9 * Modifications for the OpenRISC architecture:
     10 * Copyright (C) 2015 Jan Henrik Weinstock <jan.weinstock@rwth-aachen.de>
     11 */
     12
     13#include <asm/spr.h>
     14#include <asm/spr_defs.h>
     15#include <asm/cache.h>
     16#include <asm/cacheflush.h>
     17#include <asm/tlbflush.h>
     18
     19static __always_inline void cache_loop(struct page *page, const unsigned int reg)
     20{
     21	unsigned long paddr = page_to_pfn(page) << PAGE_SHIFT;
     22	unsigned long line = paddr & ~(L1_CACHE_BYTES - 1);
     23
     24	while (line < paddr + PAGE_SIZE) {
     25		mtspr(reg, line);
     26		line += L1_CACHE_BYTES;
     27	}
     28}
     29
     30void local_dcache_page_flush(struct page *page)
     31{
     32	cache_loop(page, SPR_DCBFR);
     33}
     34EXPORT_SYMBOL(local_dcache_page_flush);
     35
     36void local_icache_page_inv(struct page *page)
     37{
     38	cache_loop(page, SPR_ICBIR);
     39}
     40EXPORT_SYMBOL(local_icache_page_inv);
     41
     42void update_cache(struct vm_area_struct *vma, unsigned long address,
     43	pte_t *pte)
     44{
     45	unsigned long pfn = pte_val(*pte) >> PAGE_SHIFT;
     46	struct page *page = pfn_to_page(pfn);
     47	int dirty = !test_and_set_bit(PG_dc_clean, &page->flags);
     48
     49	/*
     50	 * Since icaches do not snoop for updated data on OpenRISC, we
     51	 * must write back and invalidate any dirty pages manually. We
     52	 * can skip data pages, since they will not end up in icaches.
     53	 */
     54	if ((vma->vm_flags & VM_EXEC) && dirty)
     55		sync_icache_dcache(page);
     56}
     57