Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


fixes for the virtio block device
[palacios.git] / palacios / src / devices / sym_swap.c
1 /* 
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
11  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Jack Lange <jarusl@cs.northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20 #include <palacios/vmm.h>
21 #include <palacios/vmm_dev_mgr.h>
22 #include <devices/lnx_virtio_blk.h>
23
24 #define SWAP_CAPACITY (150 * 1024 * 1024)
25
26 struct swap_state {
27     
28     struct vm_device * blk_dev;
29
30     uint_t swapped_pages;
31     uint_t unswapped_pages;
32
33     uint64_t capacity;
34     uint8_t * swap_space;
35     addr_t swap_base_addr;
36 };
37
38
39
40 static uint64_t swap_get_capacity(void * private_data) {
41     struct vm_device * dev = (struct vm_device *)private_data;
42     struct swap_state * swap = (struct swap_state *)(dev->private_data);
43
44     PrintDebug("SymSwap: Getting Capacity %d\n", (uint32_t)(swap->capacity));
45
46     return swap->capacity / HD_SECTOR_SIZE;
47 }
48
49 static int swap_read(uint8_t * buf, int sector_count, uint64_t lba,  void * private_data) {
50     struct vm_device * dev = (struct vm_device *)private_data;
51     struct swap_state * swap = (struct swap_state *)(dev->private_data);
52     int offset = lba * HD_SECTOR_SIZE;
53     int length = sector_count * HD_SECTOR_SIZE;
54
55     
56     PrintDebug("SymSwap: Reading %d bytes to %p from %p\n", length,
57                buf, (void *)(swap->swap_space + offset));
58     
59     if (length % 4096) {
60         PrintError("Swapping in length that is not a page multiple\n");
61     }
62
63     memcpy(buf, swap->swap_space + offset, length);
64
65     swap->unswapped_pages += (length / 4096);
66
67     PrintDebug("Swapped in %d pages\n", length / 4096);
68
69     return 0;
70 }
71
72 static int swap_write(uint8_t * buf, int sector_count, uint64_t lba, void * private_data) {
73     struct vm_device * dev = (struct vm_device *)private_data;
74     struct swap_state * swap = (struct swap_state *)(dev->private_data);
75     int offset = lba * HD_SECTOR_SIZE;
76     int length = sector_count * HD_SECTOR_SIZE;
77     /*
78       PrintDebug("SymSwap: Writing %d bytes to %p from %p\n", length, 
79       (void *)(swap->swap_space + offset), buf);
80     */
81     if (length % 4096) {
82         PrintError("Swapping out length that is not a page multiple\n");
83     }
84
85     memcpy(swap->swap_space + offset, buf, length);
86
87     swap->swapped_pages += (length / 4096);
88
89     PrintDebug("Swapped out %d pages\n", length / 4096);
90
91     return 0;
92 }
93
94
95 static int swap_free(struct vm_device * dev) {
96     return -1;
97 }
98
99
100 static struct v3_hd_ops hd_ops = {
101     .read = swap_read, 
102     .write = swap_write, 
103     .get_capacity = swap_get_capacity,
104 };
105
106
107
108 static struct v3_device_ops dev_ops = {
109     .free = swap_free,
110     .reset = NULL,
111     .start = NULL,
112     .stop = NULL,
113 };
114
115
116
117
118 static int swap_init(struct guest_info * vm, void * cfg_data) {
119     struct swap_state * swap = NULL;
120     struct vm_device * virtio_blk = v3_find_dev(vm, (char *)cfg_data);
121
122     if (!virtio_blk) {
123         PrintError("could not find Virtio backend\n");
124         return -1;
125     }
126
127     PrintDebug("Creating Swap Device\n");
128
129     if (virtio_blk == NULL) {
130         PrintError("Swap device requires a virtio block device\n");
131         return -1;
132     }
133
134     swap = (struct swap_state *)V3_Malloc(sizeof(struct swap_state));
135
136     swap->blk_dev = virtio_blk;
137     swap->capacity = SWAP_CAPACITY;
138
139     swap->swapped_pages = 0;
140     swap->unswapped_pages = 0;
141
142     swap->swap_base_addr = (addr_t)V3_AllocPages(swap->capacity / 4096);
143     swap->swap_space = (uint8_t *)V3_VAddr((void *)(swap->swap_base_addr));
144     memset(swap->swap_space, 0, SWAP_CAPACITY);
145
146
147     struct vm_device * dev = v3_allocate_device("SYM_SWAP", &dev_ops, swap);
148
149     if (v3_attach_device(vm, dev) == -1) {
150         PrintError("Could not attach device %s\n", "SYM_SWAP");
151         return -1;
152     }
153
154
155     v3_virtio_register_harddisk(virtio_blk, &hd_ops, dev);
156
157     return 0;
158 }
159
160
161
162 device_register("SYM_SWAP", swap_init)