1 #include <blkfront.h>
2 #include <unistd.h>
3 #include <errno.h>
4 #include <string.h>
5 #include <inttypes.h>
6 #include <stdlib.h>
7 #include <stdbool.h>
8 #include <mini-os/byteorder.h>
9
10 #include "vtpm_manager.h"
11 #include "log.h"
12 #include "uuid.h"
13
14 #include "vtpmmgr.h"
15 #include "vtpm_disk.h"
16 #include "disk_tpm.h"
17 #include "disk_io.h"
18
19 static uint8_t disk_staging_buf[4096] __attribute__((aligned(4096)));
20
21 static struct blkfront_dev* blkdev;
22 static int blkfront_fd = -1;
23
vtpm_storage_init(void)24 int vtpm_storage_init(void) {
25 struct blkfront_info info;
26 blkdev = init_blkfront(NULL, &info);
27 if (blkdev == NULL)
28 return -1;
29 blkfront_fd = blkfront_open(blkdev);
30 if (blkfront_fd < 0)
31 return -1;
32 return 0;
33 }
34
disk_read_sector(sector_t sector)35 void* disk_read_sector(sector_t sector)
36 {
37 uint32_t pos = be32_native(sector);
38 int rc;
39 vtpmloginfo(VTPM_LOG_VTPM, "disk_read_sector %x\n", pos);
40 lseek(blkfront_fd, pos * 4096, SEEK_SET);
41 rc = read(blkfront_fd, disk_staging_buf, 4096);
42 if (rc != 4096)
43 abort();
44 return disk_staging_buf;
45 }
46
disk_write_buf(void)47 void* disk_write_buf(void) { return disk_staging_buf; }
48
disk_write_sector(sector_t sector,void * buf,size_t siz)49 void disk_write_sector(sector_t sector, void* buf, size_t siz)
50 {
51 int rc;
52 uint32_t pos = be32_native(sector);
53 lseek(blkfront_fd, pos * 4096, SEEK_SET);
54 if (siz < 4096) {
55 if (buf != disk_staging_buf)
56 memcpy(disk_staging_buf, buf, siz);
57 memset(disk_staging_buf + siz, 0, 4096 - siz);
58 buf = disk_staging_buf;
59 } else if (siz > 4096)
60 abort();
61
62 rc = write(blkfront_fd, buf, 4096);
63 if (rc != 4096)
64 abort();
65 }
66
disk_write_barrier(void)67 void disk_write_barrier(void)
68 {
69 blkfront_sync(blkdev);
70 }
71
72 enum inuse_value {
73 UNUSED,
74 SLOT_1,
75 SLOT_2,
76 SHARED
77 };
78
79 /* TODO make this dynamic to support using more than 2MB of disk */
80 #define DISK_MAX_SECTOR 0x200
81
82 /* The first 4 sectors are statically allocated:
83 * 0 - disk header (copy 1)
84 * 1 - disk header (copy 2)
85 * 2 - root sector (copy 1)
86 * 3 - root sector (copy 2)
87 */
88 #define FIRST_DYNAMIC_SECTOR 4
89
90 static uint8_t sector_inuse_map[DISK_MAX_SECTOR];
91
active_slot(const struct mem_tpm_mgr * mgr)92 static int active_slot(const struct mem_tpm_mgr *mgr)
93 {
94 return 1 + mgr->active_root;
95 }
96
disk_set_used(sector_t loc,const struct mem_tpm_mgr * mgr)97 void disk_set_used(sector_t loc, const struct mem_tpm_mgr *mgr)
98 {
99 uint32_t s = be32_native(loc);
100 if (s > DISK_MAX_SECTOR) {
101 printk("Attempted disk_set_used %x\n", s);
102 return;
103 }
104 sector_inuse_map[s] |= active_slot(mgr);
105 }
106
disk_flush_slot(const struct mem_tpm_mgr * mgr)107 void disk_flush_slot(const struct mem_tpm_mgr *mgr)
108 {
109 int i;
110 for(i = FIRST_DYNAMIC_SECTOR; i < DISK_MAX_SECTOR; i++)
111 sector_inuse_map[i] &= ~active_slot(mgr);
112 }
113
disk_find_free(const struct mem_tpm_mgr * mgr)114 sector_t disk_find_free(const struct mem_tpm_mgr *mgr)
115 {
116 int i;
117 for(i = FIRST_DYNAMIC_SECTOR; i < DISK_MAX_SECTOR; i++) {
118 if (sector_inuse_map[i])
119 continue;
120 sector_inuse_map[i] = active_slot(mgr);
121 return native_be32(i);
122 }
123 // TODO more graceful error handling (in callers)
124 abort();
125 }
126