Changeset 454f1da in mainline for kernel/arch/sparc64/src/mm/cache.c


Ignore:
Timestamp:
2007-03-26T19:35:28Z (18 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
5d7daff
Parents:
4638401
Message:

Reworked handling of illegal virtual aliases caused by frame reuse.
We moved the incomplete handling from backend's frame method to
backend's page_fault method. The page_fault method is the one that
can create an illegal alias if it writes the userspace frame using
kernel address with a different page color than the page to which is
this frame mapped in userspace. When we detect this, we do D-cache
shootdown on all processors (!!!).

If we add code that accesses userspace memory from kernel address
space, we will have to check for illegal virtual aliases at all such
places.

I tested this on a 4-way simulated E6500 and a real-world Ultra 5,
which has unfortunatelly only one processor.

This solves ticket #26.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/sparc64/src/mm/cache.c

    r4638401 r454f1da  
    3232/**
    3333 * @file
     34 * @brief       D-cache shootdown algorithm.
    3435 */
    3536
    3637#include <arch/mm/cache.h>
    3738
     39#ifdef CONFIG_SMP
     40#ifdef CONFIG_VIRT_IDX_DCACHE
     41
     42#include <smp/ipi.h>
     43#include <arch/interrupt.h>
     44#include <synch/spinlock.h>
     45#include <arch.h>
     46#include <debug.h>
     47
     48/**
     49 * This spinlock is used by the processors to synchronize during the D-cache
     50 * shootdown.
     51 */
     52SPINLOCK_INITIALIZE(dcachelock);
     53
     54/** Initialize the D-cache shootdown sequence.
     55 *
     56 * Start the shootdown sequence by sending out an IPI and wait until all
     57 * processors spin on the dcachelock spinlock.
     58 *
     59 * @param type  Scope of the D-cache shootdown.
     60 * @param color Color to be invalidated; applicable only for DCACHE_INVL_COLOR
     61 *              and DCACHE_INVL_FRAME invalidation types.
     62 * @param frame Frame to be invalidated; applicable only for DCACHE_INVL_FRAME
     63 *              invalidation types.
     64 */
     65void dcache_shootdown_start(dcache_invalidate_type_t type, int color,
     66    uintptr_t frame)
     67{
     68        int i;
     69
     70        CPU->arch.dcache_active = 0;
     71        spinlock_lock(&dcachelock);
     72
     73        for (i = 0; i < config.cpu_count; i++) {
     74                cpu_t *cpu;
     75
     76                if (i == CPU->id)
     77                        continue;
     78
     79                cpu = &cpus[i];
     80                spinlock_lock(&cpu->lock);
     81                if (cpu->arch.dcache_message_count ==
     82                    DCACHE_MSG_QUEUE_LEN) {
     83                        /*
     84                         * The queue is full, flush the cache entirely.
     85                         */
     86                        cpu->arch.dcache_message_count = 1;
     87                        cpu->arch.dcache_messages[0].type = DCACHE_INVL_ALL;
     88                        cpu->arch.dcache_messages[0].color = 0; /* ignored */
     89                        cpu->arch.dcache_messages[0].frame = 0; /* ignored */
     90                } else {
     91                        index_t idx = cpu->arch.dcache_message_count++;
     92                        cpu->arch.dcache_messages[idx].type = type;
     93                        cpu->arch.dcache_messages[idx].color = color;
     94                        cpu->arch.dcache_messages[idx].frame = frame;
     95                }
     96                spinlock_unlock(&cpu->lock);
     97        }
     98
     99        ipi_broadcast(IPI_DCACHE_SHOOTDOWN);   
     100
     101busy_wait:
     102        for (i = 0; i < config.cpu_count; i++)
     103                if (cpus[i].arch.dcache_active)
     104                        goto busy_wait;
     105}
     106
     107/** Finish the D-cache shootdown sequence. */
     108void dcache_shootdown_finalize(void)
     109{
     110        spinlock_unlock(&dcachelock);
     111        CPU->arch.dcache_active = 1;
     112}
     113
     114/** Process the D-cache shootdown IPI. */
     115void dcache_shootdown_ipi_recv(void)
     116{
     117        int i;
     118
     119        ASSERT(CPU);
     120
     121        CPU->arch.dcache_active = 0;
     122        spinlock_lock(&dcachelock);
     123        spinlock_unlock(&dcachelock);
     124       
     125        spinlock_lock(&CPU->lock);
     126        ASSERT(CPU->arch.dcache_message_count < DCACHE_MSG_QUEUE_LEN);
     127        for (i = 0; i < CPU->arch.dcache_message_count; i++) {
     128                switch (CPU->arch.dcache_messages[i].type) {
     129                case DCACHE_INVL_ALL:
     130                        dcache_flush();
     131                        goto flushed;
     132                        break;
     133                case DCACHE_INVL_COLOR:
     134                        dcache_flush_color(CPU->arch.dcache_messages[i].color);
     135                        break;
     136                case DCACHE_INVL_FRAME:
     137                        dcache_flush_frame(CPU->arch.dcache_messages[i].color,
     138                            CPU->arch.dcache_messages[i].frame);
     139                        break;
     140                default:
     141                        panic("unknown type (%d)\n",
     142                            CPU->arch.dcache_messages[i].type);
     143                }
     144        }
     145flushed:
     146        CPU->arch.dcache_message_count = 0;
     147        spinlock_unlock(&CPU->lock);
     148
     149        CPU->arch.dcache_active = 1;
     150}
     151
     152#endif /* CONFIG_VIRT_IDX_DCACHE */
     153#endif /* CONFIG_SMP */
     154
    38155/** @}
    39156 */
Note: See TracChangeset for help on using the changeset viewer.