Merge with ia64 tree.

This commit is contained in:
Keir Fraser committed 2008-01-15 14:39:23 +00:00
commit a547ca19e1
17 files changed
+430 -157

No files matched your search

+12 -11
View File
@@ -28,28 +28,29 @@ LIBS += -L$(XEN_XENSTORE) -lxenstore
AIOLIBS := $(LIBAIO_DIR)/libaio.a
BLK-OBJS := block-aio.o
BLK-OBJS += block-sync.o
BLK-OBJS += block-vmdk.o
BLK-OBJS += block-ram.o
BLK-OBJS += block-qcow.o
BLK-OBJS += aes.o
BLK-OBJS += tapaio.o
BLK-OBJS-y := block-aio.o
BLK-OBJS-y += block-sync.o
BLK-OBJS-y += block-vmdk.o
BLK-OBJS-y += block-ram.o
BLK-OBJS-y += block-qcow.o
BLK-OBJS-y += aes.o
BLK-OBJS-y += tapaio.o
BLK-OBJS-$(CONFIG_Linux) += blk_linux.c
all: $(IBIN) qcow-util
blktapctrl: blktapctrl.c
$(CC) $(CFLAGS) -o blktapctrl $(LIBS) blktapctrl.c
tapdisk: $(BLK-OBJS) tapdisk.c
$(CC) $(CFLAGS) -o tapdisk $(BLK-OBJS) tapdisk.c \
tapdisk: $(BLK-OBJS-y) tapdisk.c
$(CC) $(CFLAGS) -o tapdisk $(BLK-OBJS-y) tapdisk.c \
$(AIOLIBS) $(LIBS)
.PHONY: qcow-util
qcow-util: img2qcow qcow2raw qcow-create
img2qcow qcow2raw qcow-create: %: $(BLK-OBJS)
$(CC) $(CFLAGS) -o $* $(BLK-OBJS) $*.c $(AIOLIBS) $(LIBS)
img2qcow qcow2raw qcow-create: %: $(BLK-OBJS-y)
$(CC) $(CFLAGS) -o $* $(BLK-OBJS-y) $*.c $(AIOLIBS) $(LIBS)
install: all
$(INSTALL_PROG) $(IBIN) $(QCOW_UTIL) $(VHD_UTIL) $(DESTDIR)$(INST_DIR)
+3
View File
@@ -0,0 +1,3 @@
int blk_getimagesize(int fd, uint64_t *size);
int blk_getsectorsize(int fd, uint64_t *sector_size);
+42
View File
@@ -0,0 +1,42 @@
#include <inttypes.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include "tapdisk.h"
#include "blk.h"
int blk_getimagesize(int fd, uint64_t *size)
{
int rc;
*size = 0;
rc = ioctl(fd, BLKGETSIZE, size);
if (rc) {
DPRINTF("ERR: BLKGETSIZE failed, couldn't stat image");
return -EINVAL;
}
return 0;
}
int blk_getsectorsize(int fd, uint64_t *sector_size)
{
#if defined(BLKSSZGET)
int rc;
*sector_size = DEFAULT_SECTOR_SIZE;
rc = ioctl(fd, BLKSSZGET, sector_size);
if (rc) {
DPRINTF("ERR: BLKSSZGET failed. Falling back to use default sector size");
*sector_size = DEFAULT_SECTOR_SIZE;
}
if (*sector_size != DEFAULT_SECTOR_SIZE)
DPRINTF("Note: sector size is %"PRIu64" (not %u)\n",
*sector_size, DEFAULT_SECTOR_SIZE);
#else
*sector_size = DEFAULT_SECTOR_SIZE;
#endif
return 0;
}
+8 -17
View File
@@ -41,12 +41,17 @@
#include <sys/statvfs.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include "tapdisk.h"
#include "tapaio.h"
#include "blk.h"
#define MAX_AIO_REQS (MAX_REQUESTS * MAX_SEGMENTS_PER_REQ)
/* *BSD has no O_LARGEFILE */
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
#endif
struct pending_aio {
td_callback_t cb;
int id;
@@ -87,11 +92,8 @@ static int get_image_info(struct td_state *s, int fd)
if (S_ISBLK(stat.st_mode)) {
/*Accessing block device directly*/
s->size = 0;
if (ioctl(fd,BLKGETSIZE,&s->size)!=0) {
DPRINTF("ERR: BLKGETSIZE failed, couldn't stat image");
if (blk_getimagesize(fd, &s->size) != 0)
return -EINVAL;
}
DPRINTF("Image size: \n\tpre sector_shift [%llu]\n\tpost "
"sector_shift [%llu]\n",
@@ -99,19 +101,8 @@ static int get_image_info(struct td_state *s, int fd)
(long long unsigned)s->size);
/*Get the sector size*/
#if defined(BLKSSZGET)
{
int arg;
if (blk_getsectorsize(fd, &s->sector_size) != 0)
s->sector_size = DEFAULT_SECTOR_SIZE;
ioctl(fd, BLKSSZGET, &s->sector_size);
if (s->sector_size != DEFAULT_SECTOR_SIZE)
DPRINTF("Note: sector size is %ld (not %d)\n",
s->sector_size, DEFAULT_SECTOR_SIZE);
}
#else
s->sector_size = DEFAULT_SECTOR_SIZE;
#endif
} else {
/*Local file? try fstat instead*/
+10 -6
View File
@@ -29,7 +29,6 @@
#include <sys/statvfs.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <string.h>
#include <zlib.h>
#include <inttypes.h>
@@ -39,6 +38,12 @@
#include "aes.h"
#include "tapdisk.h"
#include "tapaio.h"
#include "blk.h"
/* *BSD has no O_LARGEFILE */
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
#endif
#if 1
#define ASSERT(_p) \
@@ -284,8 +289,7 @@ static int get_filesize(char *filename, uint64_t *size, struct stat *st)
fd = open(filename, O_RDONLY);
if (fd < 0)
return -1;
if (ioctl(fd,BLKGETSIZE,size)!=0) {
printf("Unable to get Block device size\n");
if (blk_getimagesize(fd, size) != 0) {
close(fd);
return -1;
}
@@ -990,8 +994,8 @@ int tdqcow_open (struct disk_driver *dd, const char *name, td_flag_t flags)
if (!final_cluster)
s->fd_end = s->l1_table_offset + l1_table_size;
else {
s->fd_end = lseek64(fd, 0, SEEK_END);
if (s->fd_end == (off64_t)-1)
s->fd_end = lseek(fd, 0, SEEK_END);
if (s->fd_end == (off_t)-1)
goto fail;
}
@@ -1230,7 +1234,7 @@ int qcow_create(const char *filename, uint64_t total_size,
DPRINTF("Qcow_create: size %llu\n",(long long unsigned)total_size);
fd = open(filename,
O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
0644);
if (fd < 0)
return -1;
+11 -19
View File
@@ -33,16 +33,22 @@
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <unistd.h>
#include <sys/statvfs.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <string.h>
#include "tapdisk.h"
#include "blk.h"
#define MAX_DISK_SIZE 1024000 /*500MB disk limit*/
/* *BSD has no O_LARGEFILE */
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
#endif
char *img;
long int disksector_size;
long int disksize;
@@ -71,11 +77,8 @@ static int get_image_info(struct td_state *s, int fd)
if (S_ISBLK(stat.st_mode)) {
/*Accessing block device directly*/
s->size = 0;
if (ioctl(fd,BLKGETSIZE,&s->size)!=0) {
DPRINTF("ERR: BLKGETSIZE failed, couldn't stat image");
if (blk_getimagesize(fd, &s->size) != 0)
return -EINVAL;
}
DPRINTF("Image size: \n\tpre sector_shift [%llu]\n\tpost "
"sector_shift [%llu]\n",
@@ -83,19 +86,8 @@ static int get_image_info(struct td_state *s, int fd)
(long long unsigned)s->size);
/*Get the sector size*/
#if defined(BLKSSZGET)
{
int arg;
if (blk_getsectorsize(fd, &s->sector_size) != 0)
s->sector_size = DEFAULT_SECTOR_SIZE;
ioctl(fd, BLKSSZGET, &s->sector_size);
if (s->sector_size != DEFAULT_SECTOR_SIZE)
DPRINTF("Note: sector size is %ld (not %d)\n",
s->sector_size, DEFAULT_SECTOR_SIZE);
}
#else
s->sector_size = DEFAULT_SECTOR_SIZE;
#endif
} else {
/*Local file? try fstat instead*/
@@ -117,7 +109,7 @@ static int get_image_info(struct td_state *s, int fd)
disksector_size = s->sector_size;
disksize = s->size;
diskinfo = s->info;
DPRINTF("Image sector_size: \n\t[%lu]\n",
DPRINTF("Image sector_size: \n\t[%"PRIu64"]\n",
s->sector_size);
return 0;
@@ -159,7 +151,7 @@ int tdram_open (struct disk_driver *dd, const char *name, td_flag_t flags)
"sector_shift [%llu]\n",
(long long unsigned)(s->size << SECTOR_SHIFT),
(long long unsigned)s->size);
DPRINTF("Image sector_size: \n\t[%lu]\n",
DPRINTF("Image sector_size: \n\t[%"PRIu64"]\n",
s->sector_size);
prv->fd = -1;
+8 -17
View File
@@ -37,8 +37,13 @@
#include <sys/statvfs.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include "tapdisk.h"
#include "blk.h"
/* *BSD has no O_LARGEFILE */
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
#endif
struct tdsync_state {
int fd;
@@ -62,11 +67,8 @@ static int get_image_info(struct td_state *s, int fd)
if (S_ISBLK(stat.st_mode)) {
/*Accessing block device directly*/
s->size = 0;
if (ioctl(fd,BLKGETSIZE,&s->size)!=0) {
DPRINTF("ERR: BLKGETSIZE failed, couldn't stat image");
if (blk_getimagesize(fd, &s->size) != 0)
return -EINVAL;
}
DPRINTF("Image size: \n\tpre sector_shift [%llu]\n\tpost "
"sector_shift [%llu]\n",
@@ -74,19 +76,8 @@ static int get_image_info(struct td_state *s, int fd)
(long long unsigned)s->size);
/*Get the sector size*/
#if defined(BLKSSZGET)
{
int arg;
if (blk_getsectorsize(fd, &s->sector_size) != 0)
s->sector_size = DEFAULT_SECTOR_SIZE;
ioctl(fd, BLKSSZGET, &s->sector_size);
if (s->sector_size != DEFAULT_SECTOR_SIZE)
DPRINTF("Note: sector size is %ld (not %d)\n",
s->sector_size, DEFAULT_SECTOR_SIZE);
}
#else
s->sector_size = DEFAULT_SECTOR_SIZE;
#endif
} else {
/*Local file? try fstat instead*/
+5 -1
View File
@@ -42,11 +42,15 @@
#include <sys/statvfs.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <string.h>
#include "tapdisk.h"
#include "bswap.h"
/* *BSD has no O_LARGEFILE */
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
#endif
#define safer_free(_x) \
do { \
if (NULL != _x) { \
+9 -18
View File
@@ -37,9 +37,9 @@
#include <sys/statvfs.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <string.h>
#include "tapdisk.h"
#include "blk.h"
#if 1
#define DFPRINTF(_f, _a...) fprintf ( stderr, _f , ## _a )
@@ -47,6 +47,12 @@
#define DFPRINTF(_f, _a...) ((void)0)
#endif
/* *BSD has no O_LARGEFILE */
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
#endif
#define TAPDISK 1
#define BLOCK_PROCESSSZ 4096
@@ -109,12 +115,8 @@ static int get_image_info(struct td_state *s, int fd)
if (S_ISBLK(stat.st_mode)) {
/*Accessing block device directly*/
s->size = 0;
if (ioctl(fd,BLKGETSIZE,&s->size)!=0) {
DFPRINTF("ERR: BLKGETSIZE failed, "
"couldn't stat image");
if (blk_getimagesize(fd, &s->size) != 0)
return -EINVAL;
}
DFPRINTF("Image size: \n\tpre sector_shift [%llu]\n\tpost "
"sector_shift [%llu]\n",
@@ -122,19 +124,8 @@ static int get_image_info(struct td_state *s, int fd)
(long long unsigned)s->size);
/*Get the sector size*/
#if defined(BLKSSZGET)
{
int arg;
if (blk_getsectorsize(fd, &s->sector_size) != 0)
s->sector_size = DEFAULT_SECTOR_SIZE;
ioctl(fd, BLKSSZGET, &s->sector_size);
if (s->sector_size != DEFAULT_SECTOR_SIZE)
DFPRINTF("Note: sector size is %ld (not %d)\n",
s->sector_size, DEFAULT_SECTOR_SIZE);
}
#else
s->sector_size = DEFAULT_SECTOR_SIZE;
#endif
} else {
/*Local file? try fstat instead*/
+14 -8
View File
@@ -33,13 +33,14 @@
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <unistd.h>
#include <sys/statvfs.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <string.h>
#include "tapdisk.h"
#include "blk.h"
#if 1
#define DFPRINTF(_f, _a...) fprintf ( stderr, _f , ## _a )
@@ -47,6 +48,12 @@
#define DFPRINTF(_f, _a...) ((void)0)
#endif
/* *BSD has no O_LARGEFILE */
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
#endif
#define TAPDISK 1
#define BLOCK_PROCESSSZ 4096
@@ -142,7 +149,7 @@ static int send_read_responses(struct disk_driver *dd, int res, uint64_t sec,
int main(int argc, char *argv[])
{
int ret = -1, fd, len,input;
long int size;
uint64_t size;
fd_set readfds;
struct timeval timeout;
uint64_t i;
@@ -227,16 +234,15 @@ int main(int argc, char *argv[])
}
if (S_ISBLK(finfo.st_mode)) {
if(ioctl(fd,BLKGETSIZE,&size)!=0) {
DFPRINTF("ERROR: BLKGETSIZE failed, "
"couldn't stat image [%s]\n",
argv[1]);
if (blk_getimagesize(fd, &size) != 0) {
close(fd);
exit(-1);
return -1;
}
if (size < ddqcow.td_state->size<<9) {
DFPRINTF("ERROR: Not enough space on device "
"%s (%lu bytes available, %llu bytes required\n",
"%s (%"PRIu64" bytes available, "
"%llu bytes required\n",
argv[1], size,
(long long unsigned)ddqcow.td_state->size<<9);
close(fd);
+2 -2
View File
@@ -108,8 +108,8 @@ struct td_state {
void *image;
void *ring_info;
void *fd_entry;
unsigned long sector_size;
unsigned long long size;
uint64_t sector_size;
uint64_t size;
unsigned int info;
};
+226 -1
View File
@@ -2031,6 +2031,229 @@ print_cdromboot_failure( code )
return;
}
#define WAIT_HZ 18
/**
* Check for keystroke.
* @returns True if keystroke available, False if not.
*/
Bit8u check_for_keystroke()
{
ASM_START
mov ax, #0x100
int #0x16
jz no_key
mov al, #1
jmp done
no_key:
xor al, al
done:
ASM_END
}
/**
* Get keystroke.
* @returns BIOS scan code.
*/
Bit8u get_keystroke()
{
ASM_START
mov ax, #0x0
int #0x16
xchg ah, al
ASM_END
}
/**
* Waits (sleeps) for the given number of ticks.
* Checks for keystroke.
*
* @returns BIOS scan code if available, 0 if not.
* @param ticks Number of ticks to sleep.
* @param stop_on_key Whether to stop immediately upon keypress.
*/
Bit8u wait(ticks, stop_on_key)
Bit16u ticks;
Bit8u stop_on_key;
{
long ticks_to_wait, delta;
Bit32u prev_ticks, t;
Bit8u scan_code = 0;
/*
* The 0:046c wraps around at 'midnight' according to a 18.2Hz clock.
* We also have to be careful about interrupt storms.
*/
ticks_to_wait = ticks;
prev_ticks = read_dword(0x0, 0x46c);
do
{
t = read_dword(0x0, 0x46c);
if (t > prev_ticks)
{
delta = t - prev_ticks; /* The temp var is required or bcc screws up. */
ticks_to_wait -= delta;
}
else if (t < prev_ticks)
ticks_to_wait -= t; /* wrapped */
prev_ticks = t;
if (check_for_keystroke())
{
scan_code = get_keystroke();
bios_printf(BIOS_PRINTF_DEBUG, "Key pressed: %x\n", scan_code);
if (stop_on_key)
return scan_code;
}
} while (ticks_to_wait > 0);
return scan_code;
}
static void clearscreen() {
/* Hide cursor, clear screen and move cursor to starting position */
ASM_START
push bx
push cx
push dx
mov ax, #0x100
mov cx, #0x1000
int #0x10
mov ax, #0x700
mov bh, #7
xor cx, cx
mov dx, #0x184f
int #0x10
mov ax, #0x200
xor bx, bx
xor dx, dx
int #0x10
pop dx
pop cx
pop bx
ASM_END
}
int bootmenu(selected)
int selected;
{
Bit8u scode;
int max;
/* get the number of boot devices */
max = read_word(IPL_SEG, IPL_COUNT_OFFSET);
for(;;) {
if (selected > max || selected < 1) selected = 1;
clearscreen();
bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, "\n\n\n\n\n\n\n");
bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, " Select boot device\n\n");
bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, " 1. Floppy\n");
bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, " 2. Hard drive\n");
bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, " 3. CD-ROM\n");
if (max == 4)
bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, " 4. Network\n");
bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, "\n\n Currently selected: %d\n", selected);
do {
scode = wait(WAIT_HZ, 1);
} while (scode == 0);
switch(scode) {
case 0x02:
case 0x03:
case 0x04:
selected = scode - 1;
break;
case 0x05:
if (max == 4)
selected = scode -1 ;
else
scode = 0;
break;
case 0x48:
selected -= 1;
if (selected < 1)
selected = 1;
scode = 0;
break;
case 0x50:
selected += 1;
if (selected > max)
selected = max;
scode = 0;
break;
case 0x1c:
break;
default:
scode = 0;
break;
}
if (scode != 0)
break;
}
switch (selected) {
case 1:
return 0x3D;
case 2:
return 0x3E;
case 3:
return 0x3F;
case 4:
return 0x58;
default:
return 0;
}
}
void interactive_bootkey()
{
Bit16u i;
Bit8u scan = 0;
bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, "\n\nPress F10 to select boot device.\n");
for (i = 3; i > 0; i--)
{
scan = wait(WAIT_HZ, 0);
switch (scan) {
case 0x3D:
case 0x3E:
case 0x3F:
case 0x58:
break;
case 0x44:
scan = bootmenu(inb_cmos(0x3d) & 0x0f);
break;
default:
scan = 0;
break;
}
if (scan != 0)
break;
}
/* set the default based on the keypress or menu */
switch(scan) {
case 0x3D:
outb_cmos(0x3d, 0x01);
break;
case 0x3E:
outb_cmos(0x3d, 0x02);
break;
case 0x3F:
outb_cmos(0x3d, 0x03);
break;
case 0x58:
outb_cmos(0x3d, 0x04);
break;
default:
break;
}
}
void
nmi_handler_msg()
{
@@ -9825,7 +10048,9 @@ post_default_ints:
call _cdemu_init
;;
#endif // BX_ELTORITO_BOOT
call _interactive_bootkey
#if BX_TCGBIOS
call _tcpa_calling_int19h /* specs: 8.2.3 step 1 */
call _tcpa_add_event_separators /* specs: 8.2.3 step 2 */
+1 -7
View File
@@ -377,13 +377,7 @@ class XendNode:
def xen_version(self):
info = self.xc.xeninfo()
try:
from xen import VERSION
info = {'Xen': '%(xen_major)d.%(xen_minor)d' % info,
'Xend': VERSION}
except (ImportError, AttributeError):
info = {'Xen': '%(xen_major)d.%(xen_minor)d' % info,
'Xend': '3.0.3'}
info = {'Xen': '%(xen_major)d.%(xen_minor)d' % info}
# Add xend_config_format
info.update(self.xendinfo_dict())
@@ -335,12 +335,6 @@ class Daemon:
log.info("Xend changeset: %s.", xinfo['xen_changeset'])
del xc
try:
from xen import VERSION
log.info("Xend version: %s", VERSION)
except ImportError:
log.info("Xend version: Unknown.")
relocate.listenRelocation()
servers = SrvServer.create()
servers.start(status)
+2 -2
View File
@@ -1,8 +1,8 @@
# This is the correct place to edit the build version.
# All other places this is stored (eg. compile.h) should be autogenerated.
export XEN_VERSION = 3
export XEN_SUBVERSION = 2
export XEN_EXTRAVERSION ?= .0-rc6$(XEN_VENDORVERSION)
export XEN_SUBVERSION = 3
export XEN_EXTRAVERSION ?= -unstable$(XEN_VENDORVERSION)
export XEN_FULLVERSION = $(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION)
-include xen-version
+70 -40
View File
@@ -1342,21 +1342,30 @@ static inline int update_intpte(intpte_t *p,
intpte_t old,
intpte_t new,
unsigned long mfn,
struct vcpu *v)
struct vcpu *v,
int preserve_ad)
{
int rv = 1;
#ifndef PTE_UPDATE_WITH_CMPXCHG
rv = paging_write_guest_entry(v, p, new, _mfn(mfn));
#else
if ( !preserve_ad )
{
rv = paging_write_guest_entry(v, p, new, _mfn(mfn));
}
else
#endif
{
intpte_t t = old;
for ( ; ; )
{
rv = paging_cmpxchg_guest_entry(v, p, &t, new, _mfn(mfn));
intpte_t _new = new;
if ( preserve_ad )
_new |= old & (_PAGE_ACCESSED | _PAGE_DIRTY);
rv = paging_cmpxchg_guest_entry(v, p, &t, _new, _mfn(mfn));
if ( unlikely(rv == 0) )
{
MEM_LOG("Failed to update %" PRIpte " -> %" PRIpte
": saw %" PRIpte, old, new, t);
": saw %" PRIpte, old, _new, t);
break;
}
@@ -1369,20 +1378,19 @@ static inline int update_intpte(intpte_t *p,
old = t;
}
}
#endif
return rv;
}
/* Macro that wraps the appropriate type-changes around update_intpte().
* Arguments are: type, ptr, old, new, mfn, vcpu */
#define UPDATE_ENTRY(_t,_p,_o,_n,_m,_v) \
#define UPDATE_ENTRY(_t,_p,_o,_n,_m,_v,_ad) \
update_intpte(&_t ## e_get_intpte(*(_p)), \
_t ## e_get_intpte(_o), _t ## e_get_intpte(_n), \
(_m), (_v))
(_m), (_v), (_ad))
/* Update the L1 entry at pl1e to new value nl1e. */
static int mod_l1_entry(l1_pgentry_t *pl1e, l1_pgentry_t nl1e,
unsigned long gl1mfn)
unsigned long gl1mfn, int preserve_ad)
{
l1_pgentry_t ol1e;
struct vcpu *curr = current;
@@ -1393,7 +1401,7 @@ static int mod_l1_entry(l1_pgentry_t *pl1e, l1_pgentry_t nl1e,
return 0;
if ( unlikely(paging_mode_refcounts(d)) )
return UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, curr);
return UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, curr, preserve_ad);
if ( l1e_get_flags(nl1e) & _PAGE_PRESENT )
{
@@ -1415,12 +1423,14 @@ static int mod_l1_entry(l1_pgentry_t *pl1e, l1_pgentry_t nl1e,
/* Fast path for identical mapping, r/w and presence. */
if ( !l1e_has_changed(ol1e, nl1e, _PAGE_RW | _PAGE_PRESENT) )
return UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, curr);
return UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, curr,
preserve_ad);
if ( unlikely(!get_page_from_l1e(nl1e, FOREIGNDOM)) )
return 0;
if ( unlikely(!UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, curr)) )
if ( unlikely(!UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, curr,
preserve_ad)) )
{
put_page_from_l1e(nl1e, d);
return 0;
@@ -1428,7 +1438,8 @@ static int mod_l1_entry(l1_pgentry_t *pl1e, l1_pgentry_t nl1e,
}
else
{
if ( unlikely(!UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, curr)) )
if ( unlikely(!UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, curr,
preserve_ad)) )
return 0;
}
@@ -1441,7 +1452,8 @@ static int mod_l1_entry(l1_pgentry_t *pl1e, l1_pgentry_t nl1e,
static int mod_l2_entry(l2_pgentry_t *pl2e,
l2_pgentry_t nl2e,
unsigned long pfn,
unsigned long type)
unsigned long type,
int preserve_ad)
{
l2_pgentry_t ol2e;
struct vcpu *curr = current;
@@ -1469,18 +1481,20 @@ static int mod_l2_entry(l2_pgentry_t *pl2e,
/* Fast path for identical mapping and presence. */
if ( !l2e_has_changed(ol2e, nl2e, _PAGE_PRESENT))
return UPDATE_ENTRY(l2, pl2e, ol2e, nl2e, pfn, curr);
return UPDATE_ENTRY(l2, pl2e, ol2e, nl2e, pfn, curr, preserve_ad);
if ( unlikely(!get_page_from_l2e(nl2e, pfn, d)) )
return 0;
if ( unlikely(!UPDATE_ENTRY(l2, pl2e, ol2e, nl2e, pfn, curr)) )
if ( unlikely(!UPDATE_ENTRY(l2, pl2e, ol2e, nl2e, pfn, curr,
preserve_ad)) )
{
put_page_from_l2e(nl2e, pfn);
return 0;
}
}
else if ( unlikely(!UPDATE_ENTRY(l2, pl2e, ol2e, nl2e, pfn, curr)) )
else if ( unlikely(!UPDATE_ENTRY(l2, pl2e, ol2e, nl2e, pfn, curr,
preserve_ad)) )
{
return 0;
}
@@ -1494,7 +1508,8 @@ static int mod_l2_entry(l2_pgentry_t *pl2e,
/* Update the L3 entry at pl3e to new value nl3e. pl3e is within frame pfn. */
static int mod_l3_entry(l3_pgentry_t *pl3e,
l3_pgentry_t nl3e,
unsigned long pfn)
unsigned long pfn,
int preserve_ad)
{
l3_pgentry_t ol3e;
struct vcpu *curr = current;
@@ -1532,18 +1547,20 @@ static int mod_l3_entry(l3_pgentry_t *pl3e,
/* Fast path for identical mapping and presence. */
if (!l3e_has_changed(ol3e, nl3e, _PAGE_PRESENT))
return UPDATE_ENTRY(l3, pl3e, ol3e, nl3e, pfn, curr);
return UPDATE_ENTRY(l3, pl3e, ol3e, nl3e, pfn, curr, preserve_ad);
if ( unlikely(!get_page_from_l3e(nl3e, pfn, d)) )
return 0;
if ( unlikely(!UPDATE_ENTRY(l3, pl3e, ol3e, nl3e, pfn, curr)) )
if ( unlikely(!UPDATE_ENTRY(l3, pl3e, ol3e, nl3e, pfn, curr,
preserve_ad)) )
{
put_page_from_l3e(nl3e, pfn);
return 0;
}
}
else if ( unlikely(!UPDATE_ENTRY(l3, pl3e, ol3e, nl3e, pfn, curr)) )
else if ( unlikely(!UPDATE_ENTRY(l3, pl3e, ol3e, nl3e, pfn, curr,
preserve_ad)) )
{
return 0;
}
@@ -1564,7 +1581,8 @@ static int mod_l3_entry(l3_pgentry_t *pl3e,
/* Update the L4 entry at pl4e to new value nl4e. pl4e is within frame pfn. */
static int mod_l4_entry(l4_pgentry_t *pl4e,
l4_pgentry_t nl4e,
unsigned long pfn)
unsigned long pfn,
int preserve_ad)
{
struct vcpu *curr = current;
struct domain *d = curr->domain;
@@ -1592,18 +1610,20 @@ static int mod_l4_entry(l4_pgentry_t *pl4e,
/* Fast path for identical mapping and presence. */
if (!l4e_has_changed(ol4e, nl4e, _PAGE_PRESENT))
return UPDATE_ENTRY(l4, pl4e, ol4e, nl4e, pfn, curr);
return UPDATE_ENTRY(l4, pl4e, ol4e, nl4e, pfn, curr, preserve_ad);
if ( unlikely(!get_page_from_l4e(nl4e, pfn, d)) )
return 0;
if ( unlikely(!UPDATE_ENTRY(l4, pl4e, ol4e, nl4e, pfn, curr)) )
if ( unlikely(!UPDATE_ENTRY(l4, pl4e, ol4e, nl4e, pfn, curr,
preserve_ad)) )
{
put_page_from_l4e(nl4e, pfn);
return 0;
}
}
else if ( unlikely(!UPDATE_ENTRY(l4, pl4e, ol4e, nl4e, pfn, curr)) )
else if ( unlikely(!UPDATE_ENTRY(l4, pl4e, ol4e, nl4e, pfn, curr,
preserve_ad)) )
{
return 0;
}
@@ -1946,7 +1966,7 @@ int new_guest_cr3(unsigned long mfn)
l4e_from_pfn(
mfn,
(_PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED)),
pagetable_get_pfn(v->arch.guest_table));
pagetable_get_pfn(v->arch.guest_table), 0);
if ( unlikely(!okay) )
{
MEM_LOG("Error while installing new compat baseptr %lx", mfn);
@@ -2458,13 +2478,16 @@ int do_mmu_update(
{
/*
* MMU_NORMAL_PT_UPDATE: Normal update to any level of page table.
* MMU_UPDATE_PT_PRESERVE_AD: As above but also preserve (OR)
* current A/D bits.
*/
case MMU_NORMAL_PT_UPDATE:
case MMU_PT_UPDATE_PRESERVE_AD:
rc = xsm_mmu_normal_update(d, req.val);
if ( rc )
break;
req.ptr -= cmd;
gmfn = req.ptr >> PAGE_SHIFT;
mfn = gmfn_to_mfn(d, gmfn);
@@ -2501,20 +2524,23 @@ int do_mmu_update(
case PGT_l1_page_table:
{
l1_pgentry_t l1e = l1e_from_intpte(req.val);
okay = mod_l1_entry(va, l1e, mfn);
okay = mod_l1_entry(va, l1e, mfn,
cmd == MMU_PT_UPDATE_PRESERVE_AD);
}
break;
case PGT_l2_page_table:
{
l2_pgentry_t l2e = l2e_from_intpte(req.val);
okay = mod_l2_entry(va, l2e, mfn, type_info);
okay = mod_l2_entry(va, l2e, mfn, type_info,
cmd == MMU_PT_UPDATE_PRESERVE_AD);
}
break;
#if CONFIG_PAGING_LEVELS >= 3
case PGT_l3_page_table:
{
l3_pgentry_t l3e = l3e_from_intpte(req.val);
okay = mod_l3_entry(va, l3e, mfn);
okay = mod_l3_entry(va, l3e, mfn,
cmd == MMU_PT_UPDATE_PRESERVE_AD);
}
break;
#endif
@@ -2522,7 +2548,8 @@ int do_mmu_update(
case PGT_l4_page_table:
{
l4_pgentry_t l4e = l4e_from_intpte(req.val);
okay = mod_l4_entry(va, l4e, mfn);
okay = mod_l4_entry(va, l4e, mfn,
cmd == MMU_PT_UPDATE_PRESERVE_AD);
}
break;
#endif
@@ -2652,7 +2679,7 @@ static int create_grant_pte_mapping(
}
ol1e = *(l1_pgentry_t *)va;
if ( !UPDATE_ENTRY(l1, (l1_pgentry_t *)va, ol1e, nl1e, mfn, v) )
if ( !UPDATE_ENTRY(l1, (l1_pgentry_t *)va, ol1e, nl1e, mfn, v, 0) )
{
put_page_type(page);
rc = GNTST_general_error;
@@ -2720,9 +2747,11 @@ static int destroy_grant_pte_mapping(
}
/* Delete pagetable entry. */
if ( unlikely(!UPDATE_ENTRY(l1,
(l1_pgentry_t *)va, ol1e, l1e_empty(), mfn,
d->vcpu[0] /* Change if we go to per-vcpu shadows. */)) )
if ( unlikely(!UPDATE_ENTRY
(l1,
(l1_pgentry_t *)va, ol1e, l1e_empty(), mfn,
d->vcpu[0] /* Change if we go to per-vcpu shadows. */,
0)) )
{
MEM_LOG("Cannot delete PTE entry at %p", va);
put_page_type(page);
@@ -2758,7 +2787,7 @@ static int create_grant_va_mapping(
return GNTST_general_error;
}
ol1e = *pl1e;
okay = UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, v);
okay = UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, v, 0);
guest_unmap_l1e(v, pl1e);
pl1e = NULL;
@@ -2796,7 +2825,7 @@ static int replace_grant_va_mapping(
}
/* Delete pagetable entry. */
if ( unlikely(!UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, v)) )
if ( unlikely(!UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, v, 0)) )
{
MEM_LOG("Cannot delete PTE entry at %p", (unsigned long *)pl1e);
rc = GNTST_general_error;
@@ -2860,7 +2889,8 @@ int replace_grant_host_mapping(
}
ol1e = *pl1e;
if ( unlikely(!UPDATE_ENTRY(l1, pl1e, ol1e, l1e_empty(), gl1mfn, curr)) )
if ( unlikely(!UPDATE_ENTRY(l1, pl1e, ol1e, l1e_empty(),
gl1mfn, curr, 0)) )
{
MEM_LOG("Cannot delete PTE entry at %p", (unsigned long *)pl1e);
guest_unmap_l1e(curr, pl1e);
@@ -2948,7 +2978,7 @@ int do_update_va_mapping(unsigned long va, u64 val64,
pl1e = guest_map_l1e(v, va, &gl1mfn);
if ( unlikely(!pl1e || !mod_l1_entry(pl1e, val, gl1mfn)) )
if ( unlikely(!pl1e || !mod_l1_entry(pl1e, val, gl1mfn, 0)) )
rc = -EINVAL;
if ( pl1e )
@@ -3517,7 +3547,7 @@ static int ptwr_emulated_update(
else
{
ol1e = *pl1e;
if ( !UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, mfn, v) )
if ( !UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, mfn, v, 0) )
BUG();
}
+7 -2
View File
@@ -168,9 +168,14 @@
* ptr[:2] -- Machine address within the frame whose mapping to modify.
* The frame must belong to the FD, if one is specified.
* val -- Value to write into the mapping entry.
*
* ptr[1:0] == MMU_PT_UPDATE_PRESERVE_AD:
* As MMU_NORMAL_PT_UPDATE above, but A/D bits currently in the PTE are ORed
* with those in @val.
*/
#define MMU_NORMAL_PT_UPDATE 0 /* checked '*ptr = val'. ptr is MA. */
#define MMU_MACHPHYS_UPDATE 1 /* ptr = MA of frame to modify entry for */
#define MMU_NORMAL_PT_UPDATE 0 /* checked '*ptr = val'. ptr is MA. */
#define MMU_MACHPHYS_UPDATE 1 /* ptr = MA of frame to modify entry for */
#define MMU_PT_UPDATE_PRESERVE_AD 2 /* atomically: *ptr = val | (*ptr&(A|D)) */
/*
* MMU EXTENDED OPERATIONS
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.