summaryrefslogtreecommitdiff
path: root/xen/common/pmap.c
blob: 14517198aae3417a1cdbeb25d0e43cfc904f0158 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <xen/bitops.h>
#include <xen/init.h>
#include <xen/irq.h>
#include <xen/pmap.h>

#include <asm/pmap.h>
#include <asm/fixmap.h>

/*
 * Simple mapping infrastructure to map / unmap pages in fixed map.
 * This is used to set the page table before the map domain page infrastructure
 * is initialized.
 *
 * This structure is not protected by any locks, so it must not be used after
 * smp bring-up.
 */

/* Bitmap to track which slot is used */
static __initdata DECLARE_BITMAP(inuse, NUM_FIX_PMAP);

void *__init pmap_map(mfn_t mfn)
{
    unsigned int idx;
    unsigned int slot;

    ASSERT(system_state < SYS_STATE_smp_boot);
    ASSERT(!in_irq());

    idx = find_first_zero_bit(inuse, NUM_FIX_PMAP);
    if ( idx == NUM_FIX_PMAP )
        panic("Out of PMAP slots\n");

    __set_bit(idx, inuse);

    slot = idx + FIXMAP_PMAP_BEGIN;
    ASSERT(slot >= FIXMAP_PMAP_BEGIN && slot <= FIXMAP_PMAP_END);

    /*
     * We cannot use set_fixmap() here. We use PMAP when the domain map
     * page infrastructure is not yet initialized, so map_pages_to_xen() called
     * by set_fixmap() needs to map pages on demand, which then calls pmap()
     * again, resulting in a loop. Modify the PTEs directly instead. The same
     * is true for pmap_unmap().
     */
    arch_pmap_map(slot, mfn);

    return fix_to_virt(slot);
}

void __init pmap_unmap(const void *p)
{
    unsigned int idx;
    unsigned int slot = virt_to_fix((unsigned long)p);

    ASSERT(system_state < SYS_STATE_smp_boot);
    ASSERT(slot >= FIXMAP_PMAP_BEGIN && slot <= FIXMAP_PMAP_END);
    ASSERT(!in_irq());

    idx = slot - FIXMAP_PMAP_BEGIN;

    __clear_bit(idx, inuse);
    arch_pmap_unmap(slot);
}

/*
 * Local variables:
 * mode: C
 * c-file-style: "BSD"
 * c-basic-offset: 4
 * indent-tabs-mode: nil
 * End:
 */