merge with xen-unstable.hg

This commit is contained in:
awilliam@xenbuild.aw committed 2006-11-13 09:58:23 -07:00
commit a63ce0c65d
57 files changed
+694 -427

No files matched your search

@@ -9,7 +9,7 @@
#include <asm/page.h>
#include <asm/thread_info.h>
#include <asm/asm-offsets.h>
#include <xen/interface/arch-x86_32.h>
#include <xen/interface/xen.h>
#include <xen/interface/elfnote.h>
/*
@@ -192,6 +192,7 @@ ENTRY(cpu_gdt_table)
#endif /* !CONFIG_XEN_COMPAT_030002 */
ELFNOTE(Xen, XEN_ELFNOTE_ENTRY, .long, startup_32)
ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .long, hypercall_page)
ELFNOTE(Xen, XEN_ELFNOTE_HV_START_LOW, .long, HYPERVISOR_VIRT_START)
ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .asciz, "writable_page_tables|writable_descriptor_tables|auto_translated_physmap|pae_pgdir_above_4gb|supervisor_mode_kernel")
#ifdef CONFIG_X86_PAE
ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz, "yes")
@@ -282,12 +282,6 @@ static int spurious_fault(struct pt_regs *regs,
pmd_t *pmd;
pte_t *pte;
#ifdef CONFIG_XEN
/* Faults in hypervisor area are never spurious. */
if (address >= HYPERVISOR_VIRT_START)
return 0;
#endif
/* Reserved-bit violation or user access to kernel space? */
if (error_code & 0x0c)
return 0;
@@ -372,7 +366,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs,
if (unlikely(address >= TASK_SIZE)) {
#ifdef CONFIG_XEN
/* Faults in hypervisor area can never be patched up. */
if (address >= HYPERVISOR_VIRT_START)
if (address >= hypervisor_virt_start)
goto bad_area_nosemaphore;
#endif
if (!(error_code & 5))
+3 -3
View File
@@ -130,7 +130,7 @@ static void __init page_table_range_init (unsigned long start, unsigned long end
pud = pud_offset(pgd, vaddr);
pmd = pmd_offset(pud, vaddr);
for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) {
if (vaddr < HYPERVISOR_VIRT_START && pmd_none(*pmd))
if (vaddr < hypervisor_virt_start && pmd_none(*pmd))
one_page_table_init(pmd);
vaddr += PMD_SIZE;
@@ -187,7 +187,7 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
pmd += pmd_idx;
for (; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_idx++) {
unsigned int address = pfn * PAGE_SIZE + PAGE_OFFSET;
if (address >= HYPERVISOR_VIRT_START)
if (address >= hypervisor_virt_start)
continue;
/* Map with big pages if possible, otherwise create normal page tables. */
@@ -410,7 +410,7 @@ static void __init pagetable_init (void)
* created - mappings will be set by set_fixmap():
*/
vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
page_table_range_init(vaddr, 0, pgd_base);
page_table_range_init(vaddr, hypervisor_virt_start, pgd_base);
permanent_kmaps_init(pgd_base);
}
+17 -10
View File
@@ -102,8 +102,11 @@ static void set_pte_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags)
return;
}
pte = pte_offset_kernel(pmd, vaddr);
/* <pfn,flags> stored as-is, to permit clearing entries */
set_pte(pte, pfn_pte(pfn, flags));
if (pgprot_val(flags))
/* <pfn,flags> stored as-is, to permit clearing entries */
set_pte(pte, pfn_pte(pfn, flags));
else
pte_clear(&init_mm, vaddr, pte);
/*
* It's enough to flush this one mapping.
@@ -140,8 +143,11 @@ static void set_pte_pfn_ma(unsigned long vaddr, unsigned long pfn,
return;
}
pte = pte_offset_kernel(pmd, vaddr);
/* <pfn,flags> stored as-is, to permit clearing entries */
set_pte(pte, pfn_pte_ma(pfn, flags));
if (pgprot_val(flags))
/* <pfn,flags> stored as-is, to permit clearing entries */
set_pte(pte, pfn_pte_ma(pfn, flags));
else
pte_clear(&init_mm, vaddr, pte);
/*
* It's enough to flush this one mapping.
@@ -186,9 +192,16 @@ void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags)
}
static int nr_fixmaps = 0;
unsigned long hypervisor_virt_start = HYPERVISOR_VIRT_START;
unsigned long __FIXADDR_TOP = (HYPERVISOR_VIRT_START - 2 * PAGE_SIZE);
EXPORT_SYMBOL(__FIXADDR_TOP);
void __init set_fixaddr_top()
{
BUG_ON(nr_fixmaps > 0);
__FIXADDR_TOP = hypervisor_virt_start - 2 * PAGE_SIZE;
}
void __set_fixmap (enum fixed_addresses idx, maddr_t phys, pgprot_t flags)
{
unsigned long address = __fix_to_virt(idx);
@@ -211,12 +224,6 @@ void __set_fixmap (enum fixed_addresses idx, maddr_t phys, pgprot_t flags)
nr_fixmaps++;
}
void set_fixaddr_top(unsigned long top)
{
BUG_ON(nr_fixmaps > 0);
__FIXADDR_TOP = top - PAGE_SIZE;
}
pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
{
pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
@@ -260,7 +260,10 @@ static void set_pte_phys(unsigned long vaddr,
return;
}
}
new_pte = pfn_pte(phys >> PAGE_SHIFT, prot);
if (pgprot_val(prot))
new_pte = pfn_pte(phys >> PAGE_SHIFT, prot);
else
new_pte = __pte(0);
pte = pte_offset_kernel(pmd, vaddr);
if (!pte_none(*pte) &&
@@ -165,7 +165,7 @@ static int privcmd_ioctl(struct inode *inode, struct file *file,
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
xen_pfn_t __user *p;
unsigned long addr, mfn;
unsigned long addr, mfn, nr_pages;
int i;
if (!is_initial_xendomain())
@@ -174,7 +174,8 @@ static int privcmd_ioctl(struct inode *inode, struct file *file,
if (copy_from_user(&m, udata, sizeof(m)))
return -EFAULT;
if ((m.num <= 0) || (m.num > (LONG_MAX >> PAGE_SHIFT)))
nr_pages = m.num;
if ((m.num <= 0) || (nr_pages > (LONG_MAX >> PAGE_SHIFT)))
return -EINVAL;
down_read(&mm->mmap_sem);
@@ -182,8 +183,7 @@ static int privcmd_ioctl(struct inode *inode, struct file *file,
vma = find_vma(mm, m.addr);
if (!vma ||
(m.addr != vma->vm_start) ||
((m.addr + ((unsigned long)m.num<<PAGE_SHIFT)) !=
vma->vm_end) ||
((m.addr + (nr_pages << PAGE_SHIFT)) != vma->vm_end) ||
!privcmd_enforce_singleshot_mapping(vma)) {
up_read(&mm->mmap_sem);
return -EINVAL;
@@ -191,7 +191,7 @@ static int privcmd_ioctl(struct inode *inode, struct file *file,
p = m.arr;
addr = m.addr;
for (i = 0; i < m.num; i++, addr += PAGE_SIZE, p++) {
for (i = 0; i < nr_pages; i++, addr += PAGE_SIZE, p++) {
if (get_user(mfn, p)) {
up_read(&mm->mmap_sem);
return -EFAULT;
@@ -98,7 +98,7 @@ enum fixed_addresses {
extern void __set_fixmap(enum fixed_addresses idx,
maddr_t phys, pgprot_t flags);
extern void set_fixaddr_top(unsigned long top);
extern void set_fixaddr_top(void);
#define set_fixmap(idx, phys) \
__set_fixmap(idx, phys, PAGE_KERNEL)
@@ -56,6 +56,10 @@
extern shared_info_t *HYPERVISOR_shared_info;
#ifdef CONFIG_X86_32
extern unsigned long hypervisor_virt_start;
#endif
/* arch/xen/i386/kernel/setup.c */
extern start_info_t *xen_start_info;
#ifdef CONFIG_XEN_PRIVILEGED_GUEST
@@ -9,7 +9,6 @@
#define PGDIR_SHIFT 22
#define PTRS_PER_PGD 1024
#define PTRS_PER_PGD_NO_HV (HYPERVISOR_VIRT_START >> PGDIR_SHIFT)
/*
* the i386 is two-level, so we don't really have any
@@ -8,7 +8,6 @@
*/
#define PGDIR_SHIFT 30
#define PTRS_PER_PGD 4
#define PTRS_PER_PGD_NO_HV 4
/*
* PMD_SHIFT determines the size of the area a middle-level
@@ -92,8 +92,10 @@ static void __init machine_specific_arch_setup(void)
#endif
if (HYPERVISOR_xen_version(XENVER_platform_parameters,
&pp) == 0)
set_fixaddr_top(pp.virt_start - PAGE_SIZE);
&pp) == 0) {
hypervisor_virt_start = pp.virt_start;
set_fixaddr_top();
}
machine_to_phys_mapping = (unsigned long *)MACH2PHYS_VIRT_START;
machine_to_phys_nr_ents = MACH2PHYS_NR_ENTRIES;
+11
View File
@@ -0,0 +1,11 @@
#!/bin/bash
# CHECK-BUILD CHECK-INSTALL
function error {
echo
echo " *** Check for crypto library FAILED"
exit 1
}
set -e
ldconfig -p | grep -q libcrypto.so || error
+11
View File
@@ -0,0 +1,11 @@
#!/bin/bash
# CHECK-BUILD
function error {
echo
echo " *** Check for openssl headers FAILED"
exit 1
}
set -e
[ -e /usr/include/openssl/md5.h ] || error
+11
View File
@@ -0,0 +1,11 @@
#!/bin/bash
# CHECK-BUILD
function error {
echo
echo " *** Check for x11 headers FAILED"
exit 1
}
set -e
[ -e /usr/include/X11/keysymdef.h ] || error
+70 -5
View File
@@ -813,6 +813,58 @@ pop(struct regs *regs, unsigned prefix, unsigned opc)
return 1;
}
static int
mov_to_seg(struct regs *regs, unsigned prefix, unsigned opc)
{
unsigned eip = regs->eip - 1;
unsigned modrm = fetch8(regs);
unsigned addr = operand(prefix, regs, modrm);
/* Only need to emulate segment loads in real->protected mode. */
if (mode != VM86_REAL_TO_PROTECTED)
return 0;
/* Register source only. */
if ((modrm & 0xC0) != 0xC0)
goto fail;
switch ((modrm & 0x38) >> 3) {
case 0: /* es */
regs->ves = getreg16(regs, modrm);
saved_rm_regs.ves = 0;
oldctx.es_sel = regs->ves;
return 1;
/* case 1: cs */
case 2: /* ss */
regs->uss = getreg16(regs, modrm);
saved_rm_regs.uss = 0;
oldctx.ss_sel = regs->uss;
return 1;
case 3: /* ds */
regs->vds = getreg16(regs, modrm);
saved_rm_regs.vds = 0;
oldctx.ds_sel = regs->vds;
return 1;
case 4: /* fs */
regs->vfs = getreg16(regs, modrm);
saved_rm_regs.vfs = 0;
oldctx.fs_sel = regs->vfs;
return 1;
case 5: /* gs */
regs->vgs = getreg16(regs, modrm);
saved_rm_regs.vgs = 0;
oldctx.gs_sel = regs->vgs;
return 1;
}
fail:
printf("%s:%d: missed opcode %02x %02x\n",
__FUNCTION__, __LINE__, opc, modrm);
return 0;
}
/*
* Emulate a segment load in protected mode
*/
@@ -1257,11 +1309,9 @@ opcode(struct regs *regs)
for (;;) {
switch ((opc = fetch8(regs))) {
case 0x07:
if (prefix & DATA32)
regs->ves = pop32(regs);
else
regs->ves = pop16(regs);
case 0x07: /* pop %es */
regs->ves = (prefix & DATA32) ?
pop32(regs) : pop16(regs);
TRACE((regs, regs->eip - eip, "pop %%es"));
if (mode == VM86_REAL_TO_PROTECTED) {
saved_rm_regs.ves = 0;
@@ -1316,6 +1366,16 @@ opcode(struct regs *regs)
}
goto invalid;
case 0x1F: /* pop %ds */
regs->vds = (prefix & DATA32) ?
pop32(regs) : pop16(regs);
TRACE((regs, regs->eip - eip, "pop %%ds"));
if (mode == VM86_REAL_TO_PROTECTED) {
saved_rm_regs.vds = 0;
oldctx.ds_sel = regs->vds;
}
return OPC_EMULATED;
case 0x26:
TRACE((regs, regs->eip - eip, "%%es:"));
prefix |= SEG_ES;
@@ -1402,6 +1462,11 @@ opcode(struct regs *regs)
goto invalid;
return OPC_EMULATED;
case 0x8E: /* mov r16, sreg */
if (!mov_to_seg(regs, prefix, opc))
goto invalid;
return OPC_EMULATED;
case 0x8F: /* addr32 pop r/m16 */
if ((prefix & ADDR32) == 0)
goto invalid;
+10 -2
View File
@@ -398,8 +398,16 @@ void pci_piix4_acpi_init(PCIBus *bus, int devfn)
pci_conf[0x0e] = 0x00;
pci_conf[0x3d] = 0x01; /* Hardwired to PIRQA is used */
pci_register_io_region((PCIDevice *)d, 4, 0x10,
PCI_ADDRESS_SPACE_IO, acpi_map);
/* PMBA POWER MANAGEMENT BASE ADDRESS, hardcoded to 0x1f40
* to make shutdown work for IPF, due to IPF Guest Firmware
* will enumerate pci devices.
*
* TODO: if Guest Firmware or Guest OS will change this PMBA,
* More logic will be added.
*/
pci_conf[0x40] = 0x41; /* Special device-specific BAR at 0x40 */
pci_conf[0x41] = 0x1f;
acpi_map(d, 0, 0x1f40, 0x10, PCI_ADDRESS_SPACE_IO);
acpi_reset(d);
}
+7 -11
View File
@@ -338,10 +338,14 @@ static void pci_bios_init_device(PCIDevice *d)
break;
case 0x0680:
if (vendor_id == 0x8086 && device_id == 0x7113) {
/* PIIX4 ACPI PM */
pci_config_writew(d, 0x20, 0x0000); /* NO smb bus IO enable in PIIX4 */
/*
* PIIX4 ACPI PM.
* Special device with special PCI config space. No ordinary BARs.
*/
pci_config_writew(d, 0x20, 0x0000); // No smb bus IO enable
pci_config_writew(d, 0x22, 0x0000);
goto default_map;
pci_config_writew(d, 0x3c, 0x0009); // Hardcoded IRQ9
pci_config_writew(d, 0x3d, 0x0001);
}
break;
case 0x0300:
@@ -394,14 +398,6 @@ static void pci_bios_init_device(PCIDevice *d)
pic_irq = pci_irqs[pin];
pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq);
}
if (class== 0x0680&& vendor_id == 0x8086 && device_id == 0x7113) {
// PIIX4 ACPI PM
pci_config_writew(d, 0x20, 0x0000); // NO smb bus IO enable in PIIX4
pci_config_writew(d, 0x22, 0x0000);
pci_config_writew(d, 0x3c, 0x0009); // Hardcodeed IRQ9
pci_config_writew(d, 0x3d, 0x0001);
}
}
/*
+20 -6
View File
@@ -73,6 +73,11 @@
#define UART_LSR_OE 0x02 /* Overrun error indicator */
#define UART_LSR_DR 0x01 /* Receiver data ready */
/* Maximum retries for a single byte transmit. */
#define WRITE_MAX_SINGLE_RETRIES 3
/* Maximum retries for a sequence of back-to-back unsuccessful transmits. */
#define WRITE_MAX_TOTAL_RETRIES 10
struct SerialState {
uint8_t divider;
uint8_t rbr; /* receive register */
@@ -98,8 +103,12 @@ struct SerialState {
* If a character transmitted via UART cannot be written to its
* destination immediately we remember it here and retry a few times via
* a polling timer.
* - write_single_retries: Number of write retries for current byte.
* - write_total_retries: Number of write retries for back-to-back
* unsuccessful transmits.
*/
int write_retries;
int write_single_retries;
int write_total_retries;
char write_chr;
QEMUTimer *write_retry_timer;
};
@@ -217,16 +226,21 @@ static void serial_chr_write(void *opaque)
{
SerialState *s = opaque;
/* Cancel any outstanding retry if this is a new byte. */
qemu_del_timer(s->write_retry_timer);
/* Retry every 100ms for 300ms total. */
if (qemu_chr_write(s->chr, &s->write_chr, 1) == -1) {
if (s->write_retries++ >= 3)
printf("serial: write error\n");
else
s->write_total_retries++;
if (s->write_single_retries++ >= WRITE_MAX_SINGLE_RETRIES)
fprintf(stderr, "serial: write error\n");
else if (s->write_total_retries <= WRITE_MAX_TOTAL_RETRIES) {
qemu_mod_timer(s->write_retry_timer,
qemu_get_clock(vm_clock) + ticks_per_sec / 10);
return;
return;
}
} else {
s->write_total_retries = 0; /* if successful then reset counter */
}
/* Success: Notify guest that THR is empty. */
@@ -255,7 +269,7 @@ static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
s->lsr &= ~UART_LSR_THRE;
serial_update_irq(s);
s->write_chr = val;
s->write_retries = 0;
s->write_single_retries = 0;
serial_chr_write(s);
}
break;
+2 -1
View File
@@ -6424,7 +6424,8 @@ int main(int argc, char **argv)
page_array[i] = i;
if (xc_domain_translate_gpfn_list(xc_handle, domid, tmp_nr_pages,
page_array, page_array)) {
fprintf(logfile, "xc_get_pfn_list returned error %d\n", errno);
fprintf(logfile, "xc_domain_translate_gpfn_list returned error %d\n",
errno);
exit(-1);
}
+1 -1
View File
@@ -126,7 +126,7 @@ int
fsig_devread(fsi_file_t *ffi, unsigned int sector, unsigned int offset,
unsigned int bufsize, char *buf)
{
uint64_t off = ffi->ff_fsi->f_off + ((uint64_t)(sector * 512)) + offset;
uint64_t off = ffi->ff_fsi->f_off + ((uint64_t)sector * 512) + offset;
ssize_t bytes_read = 0;
while (bufsize) {
+61
View File
@@ -232,6 +232,7 @@ struct ext2_dir_entry
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#if defined(__i386__) || defined(__x86_64__)
/* include/asm-i386/bitops.h */
/*
* ffz = Find First Zero in word. Undefined if no zero exists,
@@ -251,6 +252,66 @@ ffz (unsigned long word)
return word;
}
#elif defined(__ia64__)
typedef unsigned long __u64;
#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
# define ia64_popcnt(x) __builtin_popcountl(x)
#else
# define ia64_popcnt(x) \
({ \
__u64 ia64_intri_res; \
asm ("popcnt %0=%1" : "=r" (ia64_intri_res) : "r" (x)); \
ia64_intri_res; \
})
#endif
static __inline__ unsigned long
ffz (unsigned long word)
{
unsigned long result;
result = ia64_popcnt(word & (~word - 1));
return result;
}
#elif defined(__powerpc__)
static __inline__ int
__ilog2(unsigned long x)
{
int lz;
asm (PPC_CNTLZL "%0,%1" : "=r" (lz) : "r" (x));
return BITS_PER_LONG - 1 - lz;
}
static __inline__ unsigned long
ffz (unsigned long word)
{
if ((word = ~word) == 0)
return BITS_PER_LONG;
return __ilog2(word & -word);
}
#else /* Unoptimized */
static __inline__ unsigned long
ffz (unsigned long word)
{
unsigned long result;
result = 0;
while(word & 1)
{
result++;
word >>= 1;
}
return result;
}
#endif
/* check filesystem types and read superblock into memory buffer */
int
ext2fs_mount (fsi_file_t *ffi)
+57
View File
@@ -363,6 +363,8 @@ struct fsys_reiser_info
#define JOURNAL_START ((__u32 *) (INFO + 1))
#define JOURNAL_END ((__u32 *) (FSYS_BUF + FSYS_BUFLEN))
#if defined(__i386__) || defined(__x86_64__)
#ifdef __amd64
#define BSF "bsfq"
#else
@@ -376,6 +378,61 @@ grub_log2 (unsigned long word)
: "r" (word));
return word;
}
#elif defined(__ia64__)
#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
# define ia64_popcnt(x) __builtin_popcountl(x)
#else
# define ia64_popcnt(x) \
({ \
__u64 ia64_intri_res; \
asm ("popcnt %0=%1" : "=r" (ia64_intri_res) : "r" (x)); \
ia64_intri_res; \
})
#endif
static __inline__ unsigned long
grub_log2 (unsigned long word)
{
unsigned long result;
result = ia64_popcnt((word - 1) & ~word);
return result;
}
#elif defined(__powerpc__)
static __inline__ int
__ilog2(unsigned long x)
{
int lz;
asm (PPC_CNTLZL "%0,%1" : "=r" (lz) : "r" (x));
return BITS_PER_LONG - 1 - lz;
}
static __inline__ unsigned long
grub_log2 (unsigned long word)
{
return __ilog2(word & -word);
}
#else /* Unoptimized */
static __inline__ unsigned long
grub_log2 (unsigned long word)
{
unsigned long result = 0;
while (!(word & 1UL))
{
result++;
word >>= 1;
}
return result;
}
#endif
#define log2 grub_log2
static __inline__ int
+22 -7
View File
@@ -575,8 +575,10 @@ struct node *get_node(struct connection *conn,
/* If we don't have permission, we don't have node. */
if (node) {
if ((perm_for_conn(conn, node->perms, node->num_perms) & perm)
!= perm)
!= perm) {
errno = EACCES;
node = NULL;
}
}
/* Clean up errno if they weren't supposed to know. */
if (!node)
@@ -789,7 +791,7 @@ static void delete_node_single(struct connection *conn, struct node *node)
corrupt(conn, "Could not delete '%s'", node->name);
return;
}
domain_entry_dec(conn);
domain_entry_dec(conn, node);
}
/* Must not be / */
@@ -840,7 +842,7 @@ static struct node *construct_node(struct connection *conn, const char *name)
node->children = node->data = NULL;
node->childlen = node->datalen = 0;
node->parent = parent;
domain_entry_inc(conn);
domain_entry_inc(conn, node);
return node;
}
@@ -876,7 +878,7 @@ static struct node *create_node(struct connection *conn,
* something goes wrong. */
for (i = node; i; i = i->parent) {
if (!write_node(conn, i)) {
domain_entry_dec(conn);
domain_entry_dec(conn, i);
return NULL;
}
talloc_set_destructor(i, destroy_node);
@@ -1106,6 +1108,7 @@ static void do_get_perms(struct connection *conn, const char *name)
static void do_set_perms(struct connection *conn, struct buffered_data *in)
{
unsigned int num;
struct xs_permissions *perms;
char *name, *permstr;
struct node *node;
@@ -1127,12 +1130,24 @@ static void do_set_perms(struct connection *conn, struct buffered_data *in)
return;
}
node->perms = talloc_array(node, struct xs_permissions, num);
node->num_perms = num;
if (!xs_strings_to_perms(node->perms, num, permstr)) {
perms = talloc_array(node, struct xs_permissions, num);
if (!xs_strings_to_perms(perms, num, permstr)) {
send_error(conn, errno);
return;
}
/* Unprivileged domains may not change the owner. */
if (domain_is_unprivileged(conn) &&
perms[0].id != node->perms[0].id) {
send_error(conn, EPERM);
return;
}
domain_entry_dec(conn, node);
node->perms = perms;
node->num_perms = num;
domain_entry_inc(conn, node);
if (!write_node(conn, node)) {
send_error(conn, errno);
return;
+23 -6
View File
@@ -501,18 +501,35 @@ int domain_init(void)
return xce_handle;
}
void domain_entry_inc(struct connection *conn)
void domain_entry_inc(struct connection *conn, struct node *node)
{
if (!conn || !conn->domain)
struct domain *d;
if (!conn)
return;
conn->domain->nbentry++;
if (node->perms && node->perms[0].id != conn->id) {
d = find_domain_by_domid(node->perms[0].id);
if (d)
d->nbentry++;
}
else if (conn->domain) {
conn->domain->nbentry++;
}
}
void domain_entry_dec(struct connection *conn)
void domain_entry_dec(struct connection *conn, struct node *node)
{
if (!conn || !conn->domain)
struct domain *d;
if (!conn)
return;
if (conn->domain->nbentry)
if (node->perms && node->perms[0].id != conn->id) {
d = find_domain_by_domid(node->perms[0].id);
if (d && d->nbentry)
d->nbentry--;
} else if (conn->domain && conn->domain->nbentry)
conn->domain->nbentry--;
}
+2 -2
View File
@@ -50,8 +50,8 @@ bool domain_can_write(struct connection *conn);
bool domain_is_unprivileged(struct connection *conn);
/* Quota manipulation */
void domain_entry_inc(struct connection *conn);
void domain_entry_dec(struct connection *conn);
void domain_entry_inc(struct connection *conn, struct node *);
void domain_entry_dec(struct connection *conn, struct node *);
int domain_entry(struct connection *conn);
void domain_watch_inc(struct connection *conn);
void domain_watch_dec(struct connection *conn);
-5
View File
@@ -196,21 +196,16 @@ ENTRY(stack_start)
/*** DESCRIPTOR TABLES ***/
.globl idt
.globl gdt
ALIGN
.word 0
idt_descr:
.word 256*8-1
idt:
.long idt_table
.word 0
gdt_descr:
.word LAST_RESERVED_GDT_BYTE
gdt:
.long gdt_table - FIRST_RESERVED_GDT_BYTE
.word 0
-5
View File
@@ -192,9 +192,6 @@ ignore_int:
/*** DESCRIPTOR TABLES ***/
.globl idt
.globl gdt
.align 8, 0xCC
multiboot_ptr:
.long 0
@@ -210,13 +207,11 @@ cpuid_ext_features:
.word 0
gdt_descr:
.word LAST_RESERVED_GDT_BYTE
gdt:
.quad gdt_table - FIRST_RESERVED_GDT_BYTE
.word 0,0,0
idt_descr:
.word 256*16-1
idt:
.quad idt_table
ENTRY(stack_start)
+3 -3
View File
@@ -2,6 +2,6 @@ obj-y += k7.o
obj-y += mce.o
obj-y += non-fatal.o
obj-y += p4.o
obj-y += p5.o
obj-y += p6.o
obj-y += winchip.o
obj-$(x86_32) += p5.o
obj-$(x86_32) += p6.o
obj-$(x86_32) += winchip.o
+4
View File
@@ -39,18 +39,22 @@ void mcheck_init(struct cpuinfo_x86 *c)
break;
case X86_VENDOR_INTEL:
#ifndef CONFIG_X86_64
if (c->x86==5)
intel_p5_mcheck_init(c);
if (c->x86==6)
intel_p6_mcheck_init(c);
#endif
if (c->x86==15)
intel_p4_mcheck_init(c);
break;
#ifndef CONFIG_X86_64
case X86_VENDOR_CENTAUR:
if (c->x86==5)
winchip_mcheck_init(c);
break;
#endif
default:
break;
+3 -3
View File
@@ -1,6 +1,6 @@
obj-y += amd.o
obj-y += centaur.o
obj-y += cyrix.o
obj-$(x86_32) += amd.o
obj-$(x86_32) += centaur.o
obj-$(x86_32) += cyrix.o
obj-y += generic.o
obj-y += main.o
obj-y += state.o
+8
View File
@@ -64,7 +64,11 @@ struct mtrr_ops * mtrr_if = NULL;
static void set_mtrr(unsigned int reg, unsigned long base,
unsigned long size, mtrr_type type);
#ifndef CONFIG_X86_64
extern int arr3_protected;
#else
#define arr3_protected 0
#endif
static char *mtrr_strings[MTRR_NUM_TYPES] =
{
@@ -539,9 +543,11 @@ extern void centaur_init_mtrr(void);
static void __init init_ifs(void)
{
#ifndef CONFIG_X86_64
amd_init_mtrr();
cyrix_init_mtrr();
centaur_init_mtrr();
#endif
}
/* The suspend/resume methods are only for CPU without MTRR. CPU using generic
@@ -593,6 +599,7 @@ void __init mtrr_bp_init(void)
size_and_mask = 0;
}
} else {
#ifndef CONFIG_X86_64
switch (boot_cpu_data.x86_vendor) {
case X86_VENDOR_AMD:
if (cpu_has_k6_mtrr) {
@@ -619,6 +626,7 @@ void __init mtrr_bp_init(void)
default:
break;
}
#endif
}
if (mtrr_if) {
+14 -13
View File
@@ -166,6 +166,9 @@ void vcpu_destroy(struct vcpu *v)
int arch_domain_create(struct domain *d)
{
#ifdef __x86_64__
struct page_info *pg;
#endif
l1_pgentry_t gdt_l1e;
int vcpuid, pdpt_order;
int i, rc = -ENOMEM;
@@ -194,19 +197,17 @@ int arch_domain_create(struct domain *d)
#else /* __x86_64__ */
d->arch.mm_perdomain_l2 = alloc_xenheap_page();
d->arch.mm_perdomain_l3 = alloc_xenheap_page();
if ( (d->arch.mm_perdomain_l2 == NULL) ||
(d->arch.mm_perdomain_l3 == NULL) )
if ( (pg = alloc_domheap_page(NULL)) == NULL )
goto fail;
memset(d->arch.mm_perdomain_l2, 0, PAGE_SIZE);
d->arch.mm_perdomain_l2 = clear_page(page_to_virt(pg));
for ( i = 0; i < (1 << pdpt_order); i++ )
d->arch.mm_perdomain_l2[l2_table_offset(PERDOMAIN_VIRT_START)+i] =
l2e_from_page(virt_to_page(d->arch.mm_perdomain_pt)+i,
__PAGE_HYPERVISOR);
memset(d->arch.mm_perdomain_l3, 0, PAGE_SIZE);
if ( (pg = alloc_domheap_page(NULL)) == NULL )
goto fail;
d->arch.mm_perdomain_l3 = clear_page(page_to_virt(pg));
d->arch.mm_perdomain_l3[l3_table_offset(PERDOMAIN_VIRT_START)] =
l3e_from_page(virt_to_page(d->arch.mm_perdomain_l2),
__PAGE_HYPERVISOR);
@@ -240,8 +241,8 @@ int arch_domain_create(struct domain *d)
fail:
free_xenheap_page(d->shared_info);
#ifdef __x86_64__
free_xenheap_page(d->arch.mm_perdomain_l2);
free_xenheap_page(d->arch.mm_perdomain_l3);
free_domheap_page(virt_to_page(d->arch.mm_perdomain_l2));
free_domheap_page(virt_to_page(d->arch.mm_perdomain_l3));
#endif
free_xenheap_pages(d->arch.mm_perdomain_pt, pdpt_order);
return rc;
@@ -265,8 +266,8 @@ void arch_domain_destroy(struct domain *d)
get_order_from_bytes(PDPT_L1_ENTRIES * sizeof(l1_pgentry_t)));
#ifdef __x86_64__
free_xenheap_page(d->arch.mm_perdomain_l2);
free_xenheap_page(d->arch.mm_perdomain_l3);
free_domheap_page(virt_to_page(d->arch.mm_perdomain_l2));
free_domheap_page(virt_to_page(d->arch.mm_perdomain_l3));
#endif
free_xenheap_page(d->shared_info);
@@ -587,9 +588,9 @@ static void load_segments(struct vcpu *n)
regs->entry_vector = TRAP_syscall;
regs->rflags &= ~(X86_EFLAGS_AC|X86_EFLAGS_VM|X86_EFLAGS_RF|
X86_EFLAGS_NT|X86_EFLAGS_TF);
regs->ss = __GUEST_SS;
regs->ss = FLAT_KERNEL_SS;
regs->rsp = (unsigned long)(rsp-11);
regs->cs = __GUEST_CS;
regs->cs = FLAT_KERNEL_CS;
regs->rip = nctxt->failsafe_callback_eip;
}
}
+2 -1
View File
@@ -517,7 +517,8 @@ int hvm_bringup_ap(int vcpuid, int trampoline_vector)
if ( bsp->vcpu_id != 0 )
{
gdprintk(XENLOG_ERR, "Not calling hvm_bringup_ap from BSP context.\n");
domain_crash_synchronous();
domain_crash(bsp->domain);
return -EINVAL;
}
if ( (v = d->vcpu[vcpuid]) == NULL )
+1 -5
View File
@@ -253,11 +253,7 @@ int register_io_handler(
struct hvm_io_handler *handler = &d->arch.hvm_domain.io_handler;
int num = handler->num_slot;
if ( num >= MAX_IO_HANDLER )
{
printk("no extra space, register io interceptor failed!\n");
domain_crash_synchronous();
}
BUG_ON(num >= MAX_IO_HANDLER);
handler->hdl_list[num].addr = addr;
handler->hdl_list[num].size = size;
+9 -14
View File
@@ -81,9 +81,7 @@ static void set_reg_value (int size, int index, int seg, struct cpu_user_regs *r
regs->ebx |= ((value & 0xFF) << 8);
break;
default:
printk("Error: size:%x, index:%x are invalid!\n", size, index);
domain_crash_synchronous();
break;
goto crash;
}
break;
case WORD:
@@ -121,9 +119,7 @@ static void set_reg_value (int size, int index, int seg, struct cpu_user_regs *r
regs->edi |= (value & 0xFFFF);
break;
default:
printk("Error: size:%x, index:%x are invalid!\n", size, index);
domain_crash_synchronous();
break;
goto crash;
}
break;
case LONG:
@@ -153,15 +149,13 @@ static void set_reg_value (int size, int index, int seg, struct cpu_user_regs *r
regs->edi = value;
break;
default:
printk("Error: size:%x, index:%x are invalid!\n", size, index);
domain_crash_synchronous();
break;
goto crash;
}
break;
default:
printk("Error: size:%x, index:%x are invalid!\n", size, index);
crash:
gdprintk(XENLOG_ERR, "size:%x, index:%x are invalid!\n", size, index);
domain_crash_synchronous();
break;
}
}
#else
@@ -184,7 +178,7 @@ static inline void __set_reg_value(unsigned long *reg, int size, long value)
*reg = value;
break;
default:
printk("Error: <__set_reg_value>: size:%x is invalid\n", size);
gdprintk(XENLOG_ERR, "size:%x is invalid\n", size);
domain_crash_synchronous();
}
}
@@ -226,7 +220,8 @@ static void set_reg_value (int size, int index, int seg, struct cpu_user_regs *r
regs->rbx |= ((value & 0xFF) << 8);
break;
default:
printk("Error: size:%x, index:%x are invalid!\n", size, index);
gdprintk(XENLOG_ERR, "size:%x, index:%x are invalid!\n",
size, index);
domain_crash_synchronous();
break;
}
@@ -283,7 +278,7 @@ static void set_reg_value (int size, int index, int seg, struct cpu_user_regs *r
__set_reg_value(&regs->r15, size, value);
break;
default:
printk("Error: <set_reg_value> Invalid index\n");
gdprintk(XENLOG_ERR, "Invalid index\n");
domain_crash_synchronous();
}
return;
+1 -2
View File
@@ -731,8 +731,7 @@ static void hvm_send_assist_req(struct vcpu *v)
{
/* This indicates a bug in the device model. Crash the domain. */
gdprintk(XENLOG_ERR, "Device model set bad IO state %d.\n", p->state);
domain_crash(v->domain);
return;
domain_crash_synchronous();
}
prepare_wait_on_xen_event_channel(v->arch.hvm_vcpu.xen_port);
+56 -62
View File
@@ -326,14 +326,14 @@ static inline int long_mode_do_msr_read(struct cpu_user_regs *regs)
static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
{
u64 msr_content = (u32)regs->eax | ((u64)regs->edx << 32);
struct vcpu *vc = current;
struct vmcb_struct *vmcb = vc->arch.hvm_svm.vmcb;
struct vcpu *v = current;
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
HVM_DBG_LOG(DBG_LEVEL_1, "mode_do_msr_write msr %lx "
"msr_content %"PRIx64"\n",
(unsigned long)regs->ecx, msr_content);
switch (regs->ecx)
switch ( regs->ecx )
{
case MSR_EFER:
#ifdef __x86_64__
@@ -342,24 +342,24 @@ static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
{
printk("Trying to set reserved bit in EFER: %"PRIx64"\n",
msr_content);
svm_inject_exception(vc, TRAP_gp_fault, 1, 0);
svm_inject_exception(v, TRAP_gp_fault, 1, 0);
return 0;
}
/* LME: 0 -> 1 */
if ( msr_content & EFER_LME &&
!test_bit(SVM_CPU_STATE_LME_ENABLED, &vc->arch.hvm_svm.cpu_state))
!test_bit(SVM_CPU_STATE_LME_ENABLED, &v->arch.hvm_svm.cpu_state))
{
if ( svm_paging_enabled(vc) ||
if ( svm_paging_enabled(v) ||
!test_bit(SVM_CPU_STATE_PAE_ENABLED,
&vc->arch.hvm_svm.cpu_state) )
&v->arch.hvm_svm.cpu_state) )
{
printk("Trying to set LME bit when "
"in paging mode or PAE bit is not set\n");
svm_inject_exception(vc, TRAP_gp_fault, 1, 0);
svm_inject_exception(v, TRAP_gp_fault, 1, 0);
return 0;
}
set_bit(SVM_CPU_STATE_LME_ENABLED, &vc->arch.hvm_svm.cpu_state);
set_bit(SVM_CPU_STATE_LME_ENABLED, &v->arch.hvm_svm.cpu_state);
}
/* We have already recorded that we want LME, so it will be set
@@ -374,13 +374,13 @@ static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
case MSR_FS_BASE:
case MSR_GS_BASE:
if ( !svm_long_mode_enabled(vc) )
domain_crash_synchronous();
if ( !svm_long_mode_enabled(v) )
goto exit_and_crash;
if (!IS_CANO_ADDRESS(msr_content))
{
HVM_DBG_LOG(DBG_LEVEL_1, "Not cano address of msr write\n");
svm_inject_exception(vc, TRAP_gp_fault, 1, 0);
svm_inject_exception(v, TRAP_gp_fault, 1, 0);
}
if (regs->ecx == MSR_FS_BASE)
@@ -412,7 +412,13 @@ static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
default:
return 0;
}
return 1;
exit_and_crash:
gdprintk(XENLOG_ERR, "Fatal error writing MSR %lx\n", (long)regs->ecx);
domain_crash(v->domain);
return 1; /* handled */
}
@@ -421,7 +427,6 @@ static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
#define savedebug(_v,_reg) \
__asm__ __volatile__ ("mov %%db" #_reg ",%0" : : "r" ((_v)->debugreg[_reg]))
static inline void svm_save_dr(struct vcpu *v)
{
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
@@ -938,7 +943,8 @@ static void svm_do_general_protection_fault(struct vcpu *v,
svm_dump_vmcb(__func__, vmcb);
svm_dump_regs(__func__, regs);
svm_dump_inst(vmcb->rip);
__hvm_bug(regs);
domain_crash(v->domain);
return;
}
HVM_DBG_LOG(DBG_LEVEL_1,
@@ -1169,8 +1175,9 @@ static void svm_get_prefix_info(
if (inst_copy_from_guest(inst, svm_rip2pointer(vmcb), sizeof(inst))
!= MAX_INST_LEN)
{
printk("%s: get guest instruction failed\n", __func__);
domain_crash_synchronous();
gdprintk(XENLOG_ERR, "get guest instruction failed\n");
domain_crash(current->domain);
return;
}
for (i = 0; i < MAX_INST_LEN; i++)
@@ -1266,9 +1273,7 @@ static inline int svm_get_io_address(
isize --;
if (isize > 1)
{
svm_get_prefix_info(vmcb, dir, &seg, &asize);
}
ASSERT(dir == IOREQ_READ || dir == IOREQ_WRITE);
@@ -1470,8 +1475,10 @@ static int svm_set_cr0(unsigned long value)
mfn = get_mfn_from_gpfn(v->arch.hvm_svm.cpu_cr3 >> PAGE_SHIFT);
if ( !VALID_MFN(mfn) || !get_page(mfn_to_page(mfn), v->domain))
{
printk("Invalid CR3 value = %lx\n", v->arch.hvm_svm.cpu_cr3);
domain_crash_synchronous(); /* need to take a clean path */
gdprintk(XENLOG_ERR, "Invalid CR3 value = %lx (mfn=%lx)\n",
v->arch.hvm_svm.cpu_cr3, mfn);
domain_crash(v->domain);
return 0;
}
#if defined(__x86_64__)
@@ -1556,7 +1563,7 @@ static void mov_from_cr(int cr, int gp, struct cpu_user_regs *regs)
vmcb = v->arch.hvm_svm.vmcb;
ASSERT(vmcb);
switch (cr)
switch ( cr )
{
case 0:
value = v->arch.hvm_svm.cpu_shadow_cr0;
@@ -1582,7 +1589,8 @@ static void mov_from_cr(int cr, int gp, struct cpu_user_regs *regs)
break;
default:
__hvm_bug(regs);
domain_crash(v->domain);
return;
}
set_reg(gp, value, regs, vmcb);
@@ -1602,14 +1610,11 @@ static inline int svm_pgbit_test(struct vcpu *v)
*/
static int mov_to_cr(int gpreg, int cr, struct cpu_user_regs *regs)
{
unsigned long value;
unsigned long old_cr;
unsigned long value, old_cr, old_base_mfn, mfn;
struct vcpu *v = current;
struct vlapic *vlapic = vcpu_vlapic(v);
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
ASSERT(vmcb);
value = get_reg(gpreg, regs, vmcb);
HVM_DBG_LOG(DBG_LEVEL_1, "mov_to_cr: CR%d, value = %lx,", cr, value);
@@ -1623,8 +1628,6 @@ static int mov_to_cr(int gpreg, int cr, struct cpu_user_regs *regs)
return svm_set_cr0(value);
case 3:
{
unsigned long old_base_mfn, mfn;
if (svm_dbg_on)
printk("CR3 write =%lx \n", value );
/* If paging is not enabled yet, simply copy the value to CR3. */
@@ -1644,7 +1647,7 @@ static int mov_to_cr(int gpreg, int cr, struct cpu_user_regs *regs)
*/
mfn = get_mfn_from_gpfn(value >> PAGE_SHIFT);
if (mfn != pagetable_get_pfn(v->arch.guest_table))
__hvm_bug(regs);
goto bad_cr3;
shadow_update_cr3(v);
}
else
@@ -1656,10 +1659,7 @@ static int mov_to_cr(int gpreg, int cr, struct cpu_user_regs *regs)
HVM_DBG_LOG(DBG_LEVEL_VMMU, "CR3 value = %lx", value);
mfn = get_mfn_from_gpfn(value >> PAGE_SHIFT);
if ( !VALID_MFN(mfn) || !get_page(mfn_to_page(mfn), v->domain))
{
printk("Invalid CR3 value=%lx\n", value);
domain_crash_synchronous(); /* need to take a clean path */
}
goto bad_cr3;
old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
v->arch.guest_table = pagetable_from_pfn(mfn);
@@ -1673,10 +1673,8 @@ static int mov_to_cr(int gpreg, int cr, struct cpu_user_regs *regs)
HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %lx", value);
}
break;
}
case 4: /* CR4 */
{
if (svm_dbg_on)
printk( "write cr4=%lx, cr0=%lx\n",
value, v->arch.hvm_svm.cpu_shadow_cr0 );
@@ -1692,10 +1690,7 @@ static int mov_to_cr(int gpreg, int cr, struct cpu_user_regs *regs)
mfn = get_mfn_from_gpfn(v->arch.hvm_svm.cpu_cr3 >> PAGE_SHIFT);
if ( !VALID_MFN(mfn) ||
!get_page(mfn_to_page(mfn), v->domain) )
{
printk("Invalid CR3 value = %lx", v->arch.hvm_svm.cpu_cr3);
domain_crash_synchronous(); /* need to take a clean path */
}
goto bad_cr3;
/*
* Now arch.guest_table points to machine physical.
@@ -1741,20 +1736,23 @@ static int mov_to_cr(int gpreg, int cr, struct cpu_user_regs *regs)
shadow_update_paging_modes(v);
}
break;
}
case 8:
{
vlapic_set_reg(vlapic, APIC_TASKPRI, ((value & 0x0F) << 4));
break;
}
default:
printk("invalid cr: %d\n", cr);
__hvm_bug(regs);
gdprintk(XENLOG_ERR, "invalid cr: %d\n", cr);
domain_crash(v->domain);
return 0;
}
return 1;
bad_cr3:
gdprintk(XENLOG_ERR, "Invalid CR3\n");
domain_crash(v->domain);
return 0;
}
@@ -1857,8 +1855,7 @@ static int svm_cr_access(struct vcpu *v, unsigned int cr, unsigned int type,
break;
default:
__hvm_bug(regs);
break;
BUG();
}
ASSERT(inst_len);
@@ -2037,16 +2034,15 @@ void svm_handle_invlpg(const short invlpga, struct cpu_user_regs *regs)
int inst_len;
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
ASSERT(vmcb);
/*
* Unknown how many bytes the invlpg instruction will take. Use the
* maximum instruction length here
*/
if (inst_copy_from_guest(opcode, svm_rip2pointer(vmcb), length) < length)
{
printk("svm_handle_invlpg (): Error reading memory %d bytes\n",
length);
__hvm_bug(regs);
gdprintk(XENLOG_ERR, "Error reading memory %d bytes\n", length);
domain_crash(v->domain);
return;
}
if (invlpga)
@@ -2510,7 +2506,7 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs *regs)
if (exit_reason == VMEXIT_INVALID)
{
svm_dump_vmcb(__func__, vmcb);
domain_crash_synchronous();
goto exit_and_crash;
}
#ifdef SVM_EXTRA_DEBUG
@@ -2734,8 +2730,7 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs *regs)
break;
case VMEXIT_TASK_SWITCH:
__hvm_bug(regs);
break;
goto exit_and_crash;
case VMEXIT_CPUID:
svm_vmexit_do_cpuid(vmcb, regs->eax, regs);
@@ -2811,15 +2806,16 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs *regs)
break;
case VMEXIT_SHUTDOWN:
printk("Guest shutdown exit\n");
domain_crash_synchronous();
break;
gdprintk(XENLOG_ERR, "Guest shutdown exit\n");
goto exit_and_crash;
default:
printk("unexpected VMEXIT: exit reason = 0x%x, exitinfo1 = %"PRIx64", "
"exitinfo2 = %"PRIx64"\n", exit_reason,
(u64)vmcb->exitinfo1, (u64)vmcb->exitinfo2);
__hvm_bug(regs); /* should not happen */
exit_and_crash:
gdprintk(XENLOG_ERR, "unexpected VMEXIT: exit reason = 0x%x, "
"exitinfo1 = %"PRIx64", exitinfo2 = %"PRIx64"\n",
exit_reason,
(u64)vmcb->exitinfo1, (u64)vmcb->exitinfo2);
domain_crash(v->domain);
break;
}
@@ -2840,8 +2836,6 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs *regs)
printk("svm_vmexit_handler: Returning\n");
}
#endif
return;
}
asmlinkage void svm_load_cr2(void)
+1 -36
View File
@@ -35,6 +35,7 @@
#include <public/hvm/ioreq.h>
#include <asm/hvm/io.h>
#include <asm/hvm/vpic.h>
#include <asm/hvm/vlapic.h>
#include <asm/hvm/support.h>
#include <asm/current.h>
#include <asm/event.h>
@@ -285,42 +286,6 @@ static int ioapic_inj_irq(struct vioapic *vioapic,
return result;
}
#ifndef __ia64__
static int vlapic_match_logical_addr(struct vlapic *vlapic, uint8_t dest)
{
int result = 0;
uint32_t logical_dest;
HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "vlapic_match_logical_addr "
"vcpu=%d vlapic_id=%x dest=%x\n",
vlapic_vcpu(vlapic)->vcpu_id, VLAPIC_ID(vlapic), dest);
logical_dest = vlapic_get_reg(vlapic, APIC_LDR);
switch ( vlapic_get_reg(vlapic, APIC_DFR) )
{
case APIC_DFR_FLAT:
result = ((dest & GET_APIC_LOGICAL_ID(logical_dest)) != 0);
break;
case APIC_DFR_CLUSTER:
/* Should we support flat cluster mode ?*/
if ( (GET_APIC_LOGICAL_ID(logical_dest) >> 4
== ((dest >> 0x4) & 0xf)) &&
(logical_dest & (dest & 0xf)) )
result = 1;
break;
default:
gdprintk(XENLOG_WARNING, "error DFR value for lapic of vcpu %d\n",
vlapic_vcpu(vlapic)->vcpu_id);
break;
}
return result;
}
#else
extern int vlapic_match_logical_addr(struct vlapic *vlapic, uint16_t dest);
#endif
static uint32_t ioapic_get_delivery_bitmask(struct vioapic *vioapic,
uint16_t dest,
uint8_t dest_mode,
+58 -61
View File
@@ -196,63 +196,56 @@ uint32_t vlapic_get_ppr(struct vlapic *vlapic)
return ppr;
}
/* This only for fixed delivery mode */
int vlapic_match_logical_addr(struct vlapic *vlapic, uint8_t mda)
{
int result = 0;
uint8_t logical_id;
logical_id = GET_APIC_LOGICAL_ID(vlapic_get_reg(vlapic, APIC_LDR));
switch ( vlapic_get_reg(vlapic, APIC_DFR) )
{
case APIC_DFR_FLAT:
if ( logical_id & mda )
result = 1;
break;
case APIC_DFR_CLUSTER:
if ( ((logical_id >> 4) == (mda >> 0x4)) && (logical_id & mda & 0xf) )
result = 1;
break;
default:
gdprintk(XENLOG_WARNING, "Bad DFR value for lapic of vcpu %d\n",
vlapic_vcpu(vlapic)->vcpu_id);
break;
}
return result;
}
static int vlapic_match_dest(struct vcpu *v, struct vlapic *source,
int short_hand, int dest, int dest_mode,
int delivery_mode)
int short_hand, int dest, int dest_mode)
{
int result = 0;
struct vlapic *target = vcpu_vlapic(v);
HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "target %p, source %p, dest 0x%x, "
"dest_mode 0x%x, short_hand 0x%x, delivery_mode 0x%x.",
target, source, dest, dest_mode, short_hand, delivery_mode);
if ( unlikely(target == NULL) &&
((delivery_mode != APIC_DM_INIT) &&
(delivery_mode != APIC_DM_STARTUP) &&
(delivery_mode != APIC_DM_NMI)) )
{
HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "uninitialized target vcpu %p, "
"delivery_mode 0x%x, dest 0x%x.\n",
v, delivery_mode, dest);
return result;
}
"dest_mode 0x%x, short_hand 0x%x\n",
target, source, dest, dest_mode, short_hand);
switch ( short_hand )
{
case APIC_DEST_NOSHORT: /* no shorthand */
if ( !dest_mode ) /* Physical */
case APIC_DEST_NOSHORT:
if ( dest_mode == 0 )
{
result = ( ((target != NULL) ?
GET_APIC_ID(vlapic_get_reg(target, APIC_ID)):
v->vcpu_id)) == dest;
/* Physical mode. */
if ( (dest == 0xFF) || /* broadcast? */
(GET_APIC_ID(vlapic_get_reg(target, APIC_ID)) == dest) )
result = 1;
}
else /* Logical */
else
{
uint32_t ldr;
if ( target == NULL )
break;
ldr = vlapic_get_reg(target, APIC_LDR);
/* Flat mode */
if ( vlapic_get_reg(target, APIC_DFR) == APIC_DFR_FLAT )
{
result = GET_APIC_LOGICAL_ID(ldr) & dest;
}
else
{
if ( (delivery_mode == APIC_DM_LOWEST) &&
(dest == 0xff) )
{
/* What shall we do now? */
gdprintk(XENLOG_ERR, "Broadcast IPI with lowest priority "
"delivery mode\n");
domain_crash_synchronous();
}
result = ((GET_APIC_LOGICAL_ID(ldr) == (dest & 0xf)) ?
(GET_APIC_LOGICAL_ID(ldr) >> 4) & (dest >> 4) : 0);
}
/* Logical mode. */
result = vlapic_match_logical_addr(target, dest);
}
break;
@@ -271,16 +264,14 @@ static int vlapic_match_dest(struct vcpu *v, struct vlapic *source,
break;
default:
gdprintk(XENLOG_WARNING, "Bad dest shorthand value %x\n", short_hand);
break;
}
return result;
}
/*
* Add a pending IRQ into lapic.
* Return 1 if successfully added and 0 if discarded.
*/
/* Add a pending IRQ into lapic. */
static int vlapic_accept_irq(struct vcpu *v, int delivery_mode,
int vector, int level, int trig_mode)
{
@@ -331,7 +322,7 @@ static int vlapic_accept_irq(struct vcpu *v, int delivery_mode,
if ( test_and_clear_bit(_VCPUF_initialised, &v->vcpu_flags) )
{
gdprintk(XENLOG_ERR, "Reset hvm vcpu not supported yet\n");
domain_crash_synchronous();
goto exit_and_crash;
}
v->arch.hvm_vcpu.init_sipi_sipi_state =
HVM_VCPU_INIT_SIPI_SIPI_STATE_WAIT_SIPI;
@@ -349,7 +340,7 @@ static int vlapic_accept_irq(struct vcpu *v, int delivery_mode,
if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
{
gdprintk(XENLOG_ERR, "SIPI for initialized vcpu %x\n", v->vcpu_id);
domain_crash_synchronous();
goto exit_and_crash;
}
if ( hvm_bringup_ap(v->vcpu_id, vector) != 0 )
@@ -359,11 +350,14 @@ static int vlapic_accept_irq(struct vcpu *v, int delivery_mode,
default:
gdprintk(XENLOG_ERR, "TODO: unsupported delivery mode %x\n",
delivery_mode);
domain_crash_synchronous();
break;
goto exit_and_crash;
}
return result;
exit_and_crash:
domain_crash(v->domain);
return 0;
}
/* This function is used by both ioapic and lapic.The bitmap is for vcpu_id. */
@@ -440,10 +434,9 @@ static void vlapic_ipi(struct vlapic *vlapic)
for_each_vcpu ( vlapic_domain(vlapic), v )
{
if ( vlapic_match_dest(v, vlapic, short_hand,
dest, dest_mode, delivery_mode) )
if ( vlapic_match_dest(v, vlapic, short_hand, dest, dest_mode) )
{
if ( delivery_mode == APIC_DM_LOWEST)
if ( delivery_mode == APIC_DM_LOWEST )
set_bit(v->vcpu_id, &lpr_map);
else
vlapic_accept_irq(v, delivery_mode,
@@ -578,14 +571,17 @@ static unsigned long vlapic_read(struct vcpu *v, unsigned long address,
default:
gdprintk(XENLOG_ERR, "Local APIC read with len=0x%lx, "
"should be 4 instead.\n", len);
domain_crash_synchronous();
break;
goto exit_and_crash;
}
HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "offset 0x%x with length 0x%lx, "
"and the result is 0x%lx.", offset, len, result);
return result;
exit_and_crash:
domain_crash(v->domain);
return 0;
}
static void vlapic_write(struct vcpu *v, unsigned long address,
@@ -625,7 +621,7 @@ static void vlapic_write(struct vcpu *v, unsigned long address,
{
gdprintk(XENLOG_ERR, "Uneven alignment error for "
"2-byte vlapic access\n");
domain_crash_synchronous();
goto exit_and_crash;
}
val = (tmp & ~(0xffff << (8*alignment))) |
@@ -635,8 +631,9 @@ static void vlapic_write(struct vcpu *v, unsigned long address,
default:
gdprintk(XENLOG_ERR, "Local APIC write with len = %lx, "
"should be 4 instead\n", len);
domain_crash_synchronous();
break;
exit_and_crash:
domain_crash(v->domain);
return;
}
}
+2 -2
View File
@@ -466,14 +466,14 @@ void vm_launch_fail(unsigned long eflags)
{
unsigned long error = __vmread(VM_INSTRUCTION_ERROR);
printk("<vm_launch_fail> error code %lx\n", error);
__hvm_bug(guest_cpu_user_regs());
domain_crash_synchronous();
}
void vm_resume_fail(unsigned long eflags)
{
unsigned long error = __vmread(VM_INSTRUCTION_ERROR);
printk("<vm_resume_fail> error code %lx\n", error);
__hvm_bug(guest_cpu_user_regs());
domain_crash_synchronous();
}
void arch_vmx_do_resume(struct vcpu *v)
+80 -74
View File
@@ -151,15 +151,14 @@ static inline int long_mode_do_msr_read(struct cpu_user_regs *regs)
case MSR_FS_BASE:
if ( !(vmx_long_mode_enabled(v)) )
/* XXX should it be GP fault */
domain_crash_synchronous();
goto exit_and_crash;
msr_content = __vmread(GUEST_FS_BASE);
break;
case MSR_GS_BASE:
if ( !(vmx_long_mode_enabled(v)) )
domain_crash_synchronous();
goto exit_and_crash;
msr_content = __vmread(GUEST_GS_BASE);
break;
@@ -183,6 +182,11 @@ static inline int long_mode_do_msr_read(struct cpu_user_regs *regs)
regs->edx = (u32)(msr_content >> 32);
return 1;
exit_and_crash:
gdprintk(XENLOG_ERR, "Fatal error reading MSR %lx\n", (long)regs->ecx);
domain_crash(v->domain);
return 1; /* handled */
}
static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
@@ -233,7 +237,7 @@ static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
case MSR_FS_BASE:
case MSR_GS_BASE:
if ( !(vmx_long_mode_enabled(v)) )
domain_crash_synchronous();
goto exit_and_crash;
if ( !IS_CANO_ADDRESS(msr_content) )
{
@@ -251,7 +255,7 @@ static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
case MSR_SHADOW_GS_BASE:
if ( !(vmx_long_mode_enabled(v)) )
domain_crash_synchronous();
goto exit_and_crash;
v->arch.hvm_vmx.msr_content.shadow_gs = msr_content;
wrmsrl(MSR_SHADOW_GS_BASE, msr_content);
@@ -267,6 +271,11 @@ static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
}
return 1;
exit_and_crash:
gdprintk(XENLOG_ERR, "Fatal error writing MSR %lx\n", (long)regs->ecx);
domain_crash(v->domain);
return 1; /* handled */
}
static void vmx_restore_msrs(struct vcpu *v)
@@ -726,8 +735,7 @@ static int __get_instruction_length(void)
{
int len;
len = __vmread(VM_EXIT_INSTRUCTION_LEN); /* Safe: callers audited */
if ( (len < 1) || (len > 15) )
__hvm_bug(guest_cpu_user_regs());
BUG_ON((len < 1) || (len > 15));
return len;
}
@@ -823,7 +831,10 @@ static void vmx_do_cpuid(struct cpu_user_regs *regs)
/* 8-byte aligned valid pseudophys address from vmxassist, please. */
if ( (value & 7) || (mfn == INVALID_MFN) ||
!v->arch.hvm_vmx.vmxassist_enabled )
domain_crash_synchronous();
{
domain_crash(v->domain);
return;
}
p = map_domain_page(mfn);
value = *((uint64_t *)(p + (value & (PAGE_SIZE - 1))));
@@ -966,8 +977,9 @@ static int check_for_null_selector(unsigned long eip, int inst_len, int dir)
memset(inst, 0, MAX_INST_LEN);
if ( inst_copy_from_guest(inst, eip, inst_len) != inst_len )
{
printk("check_for_null_selector: get guest instruction failed\n");
domain_crash_synchronous();
gdprintk(XENLOG_ERR, "Get guest instruction failed\n");
domain_crash(current->domain);
return 0;
}
for ( i = 0; i < inst_len; i++ )
@@ -1169,7 +1181,7 @@ static void vmx_world_save(struct vcpu *v, struct vmx_assist_context *c)
c->ldtr_arbytes.bytes = __vmread(GUEST_LDTR_AR_BYTES);
}
static void vmx_world_restore(struct vcpu *v, struct vmx_assist_context *c)
static int vmx_world_restore(struct vcpu *v, struct vmx_assist_context *c)
{
unsigned long mfn, old_base_mfn;
@@ -1192,10 +1204,7 @@ static void vmx_world_restore(struct vcpu *v, struct vmx_assist_context *c)
*/
mfn = get_mfn_from_gpfn(c->cr3 >> PAGE_SHIFT);
if ( mfn != pagetable_get_pfn(v->arch.guest_table) )
{
printk("Invalid CR3 value=%x", c->cr3);
domain_crash_synchronous();
}
goto bad_cr3;
}
else
{
@@ -1205,13 +1214,8 @@ static void vmx_world_restore(struct vcpu *v, struct vmx_assist_context *c)
*/
HVM_DBG_LOG(DBG_LEVEL_VMMU, "CR3 c->cr3 = %x", c->cr3);
mfn = get_mfn_from_gpfn(c->cr3 >> PAGE_SHIFT);
if ( !VALID_MFN(mfn) )
{
printk("Invalid CR3 value=%x", c->cr3);
domain_crash_synchronous();
}
if ( !get_page(mfn_to_page(mfn), v->domain) )
domain_crash_synchronous();
if ( !VALID_MFN(mfn) || !get_page(mfn_to_page(mfn), v->domain) )
goto bad_cr3;
old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
v->arch.guest_table = pagetable_from_pfn(mfn);
if (old_base_mfn)
@@ -1280,6 +1284,11 @@ static void vmx_world_restore(struct vcpu *v, struct vmx_assist_context *c)
shadow_update_paging_modes(v);
__vmwrite(GUEST_CR3, v->arch.hvm_vcpu.hw_cr3);
return 0;
bad_cr3:
gdprintk(XENLOG_ERR, "Invalid CR3 value=%x", c->cr3);
return -EINVAL;
}
enum { VMX_ASSIST_INVOKE = 0, VMX_ASSIST_RESTORE };
@@ -1320,7 +1329,8 @@ static int vmx_assist(struct vcpu *v, int mode)
if (cp != 0) {
if (hvm_copy_from_guest_phys(&c, cp, sizeof(c)))
goto error;
vmx_world_restore(v, &c);
if ( vmx_world_restore(v, &c) != 0 )
goto error;
v->arch.hvm_vmx.vmxassist_enabled = 1;
return 1;
}
@@ -1337,7 +1347,8 @@ static int vmx_assist(struct vcpu *v, int mode)
if (cp != 0) {
if (hvm_copy_from_guest_phys(&c, cp, sizeof(c)))
goto error;
vmx_world_restore(v, &c);
if ( vmx_world_restore(v, &c) != 0 )
goto error;
v->arch.hvm_vmx.vmxassist_enabled = 0;
return 1;
}
@@ -1345,8 +1356,8 @@ static int vmx_assist(struct vcpu *v, int mode)
}
error:
printk("Failed to transfer to vmxassist\n");
domain_crash_synchronous();
gdprintk(XENLOG_ERR, "Failed to transfer to vmxassist\n");
domain_crash(v->domain);
return 0;
}
@@ -1390,9 +1401,10 @@ static int vmx_set_cr0(unsigned long value)
mfn = get_mfn_from_gpfn(v->arch.hvm_vmx.cpu_cr3 >> PAGE_SHIFT);
if ( !VALID_MFN(mfn) || !get_page(mfn_to_page(mfn), v->domain) )
{
printk("Invalid CR3 value = %lx (mfn=%lx)\n",
v->arch.hvm_vmx.cpu_cr3, mfn);
domain_crash_synchronous(); /* need to take a clean path */
gdprintk(XENLOG_ERR, "Invalid CR3 value = %lx (mfn=%lx)\n",
v->arch.hvm_vmx.cpu_cr3, mfn);
domain_crash(v->domain);
return 0;
}
#if defined(__x86_64__)
@@ -1536,12 +1548,12 @@ static int vmx_set_cr0(unsigned long value)
*/
static int mov_to_cr(int gp, int cr, struct cpu_user_regs *regs)
{
unsigned long value;
unsigned long old_cr;
unsigned long value, old_cr, old_base_mfn, mfn;
struct vcpu *v = current;
struct vlapic *vlapic = vcpu_vlapic(v);
switch ( gp ) {
switch ( gp )
{
CASE_GET_REG(EAX, eax);
CASE_GET_REG(ECX, ecx);
CASE_GET_REG(EDX, edx);
@@ -1554,8 +1566,8 @@ static int mov_to_cr(int gp, int cr, struct cpu_user_regs *regs)
value = __vmread(GUEST_RSP);
break;
default:
printk("invalid gp: %d\n", gp);
__hvm_bug(regs);
gdprintk(XENLOG_ERR, "invalid gp: %d\n", gp);
goto exit_and_crash;
}
TRACE_VMEXIT(1, TYPE_MOV_TO_CR);
@@ -1564,13 +1576,12 @@ static int mov_to_cr(int gp, int cr, struct cpu_user_regs *regs)
HVM_DBG_LOG(DBG_LEVEL_1, "CR%d, value = %lx", cr, value);
switch ( cr ) {
switch ( cr )
{
case 0:
return vmx_set_cr0(value);
case 3:
{
unsigned long old_base_mfn, mfn;
case 3:
/*
* If paging is not enabled yet, simply copy the value to CR3.
*/
@@ -1590,7 +1601,7 @@ static int mov_to_cr(int gp, int cr, struct cpu_user_regs *regs)
*/
mfn = get_mfn_from_gpfn(value >> PAGE_SHIFT);
if (mfn != pagetable_get_pfn(v->arch.guest_table))
__hvm_bug(regs);
goto bad_cr3;
shadow_update_cr3(v);
} else {
/*
@@ -1600,10 +1611,7 @@ static int mov_to_cr(int gp, int cr, struct cpu_user_regs *regs)
HVM_DBG_LOG(DBG_LEVEL_VMMU, "CR3 value = %lx", value);
mfn = get_mfn_from_gpfn(value >> PAGE_SHIFT);
if ( !VALID_MFN(mfn) || !get_page(mfn_to_page(mfn), v->domain) )
{
printk("Invalid CR3 value=%lx\n", value);
domain_crash_synchronous(); /* need to take a clean path */
}
goto bad_cr3;
old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
v->arch.guest_table = pagetable_from_pfn(mfn);
if (old_base_mfn)
@@ -1618,9 +1626,8 @@ static int mov_to_cr(int gp, int cr, struct cpu_user_regs *regs)
__vmwrite(GUEST_CR3, v->arch.hvm_vcpu.hw_cr3);
}
break;
}
case 4: /* CR4 */
{
old_cr = v->arch.hvm_vmx.cpu_shadow_cr4;
if ( (value & X86_CR4_PAE) && !(old_cr & X86_CR4_PAE) )
@@ -1633,10 +1640,7 @@ static int mov_to_cr(int gp, int cr, struct cpu_user_regs *regs)
mfn = get_mfn_from_gpfn(v->arch.hvm_vmx.cpu_cr3 >> PAGE_SHIFT);
if ( !VALID_MFN(mfn) ||
!get_page(mfn_to_page(mfn), v->domain) )
{
printk("Invalid CR3 value = %lx", v->arch.hvm_vmx.cpu_cr3);
domain_crash_synchronous(); /* need to take a clean path */
}
goto bad_cr3;
/*
* Now arch.guest_table points to machine physical.
@@ -1682,18 +1686,24 @@ static int mov_to_cr(int gp, int cr, struct cpu_user_regs *regs)
if ( (old_cr ^ value) & (X86_CR4_PSE | X86_CR4_PGE | X86_CR4_PAE) )
shadow_update_paging_modes(v);
break;
}
case 8:
{
vlapic_set_reg(vlapic, APIC_TASKPRI, ((value & 0x0F) << 4));
break;
}
default:
printk("invalid cr: %d\n", gp);
__hvm_bug(regs);
gdprintk(XENLOG_ERR, "invalid cr: %d\n", cr);
domain_crash(v->domain);
return 0;
}
return 1;
bad_cr3:
gdprintk(XENLOG_ERR, "Invalid CR3\n");
exit_and_crash:
domain_crash(v->domain);
return 0;
}
/*
@@ -1715,7 +1725,9 @@ static void mov_from_cr(int cr, int gp, struct cpu_user_regs *regs)
value = (value & 0xF0) >> 4;
break;
default:
__hvm_bug(regs);
gdprintk(XENLOG_ERR, "invalid cr: %d\n", cr);
domain_crash(v->domain);
break;
}
switch ( gp ) {
@@ -1733,7 +1745,8 @@ static void mov_from_cr(int cr, int gp, struct cpu_user_regs *regs)
break;
default:
printk("invalid gp: %d\n", gp);
__hvm_bug(regs);
domain_crash(v->domain);
break;
}
TRACE_VMEXIT(1, TYPE_MOV_FROM_CR);
@@ -1782,9 +1795,9 @@ static int vmx_cr_access(unsigned long exit_qualification,
return vmx_set_cr0(value);
break;
default:
__hvm_bug(regs);
break;
BUG();
}
return 1;
}
@@ -1814,7 +1827,7 @@ static inline void vmx_do_msr_read(struct cpu_user_regs *regs)
msr_content = vcpu_vlapic(v)->apic_base_msr;
break;
default:
if (long_mode_do_msr_read(regs))
if ( long_mode_do_msr_read(regs) )
return;
if ( rdmsr_hypervisor_regs(regs->ecx, &eax, &edx) )
@@ -2045,11 +2058,6 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs)
perfc_incra(vmexits, exit_reason);
if ( (exit_reason != EXIT_REASON_EXTERNAL_INTERRUPT) &&
(exit_reason != EXIT_REASON_VMCALL) &&
(exit_reason != EXIT_REASON_IO_INSTRUCTION) )
HVM_DBG_LOG(DBG_LEVEL_0, "exit reason = %x", exit_reason);
if ( exit_reason != EXIT_REASON_EXTERNAL_INTERRUPT )
local_irq_enable();
@@ -2077,7 +2085,7 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs)
printk("************* VMCS Area **************\n");
vmcs_dump_vcpu();
printk("**************************************\n");
domain_crash_synchronous();
goto exit_and_crash;
}
TRACE_VMEXIT(0, exit_reason);
@@ -2121,8 +2129,6 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs)
#else
case TRAP_debug:
{
void store_cpu_user_regs(struct cpu_user_regs *regs);
if ( test_bit(_DOMF_debugging, &v->domain->domain_flags) )
{
store_cpu_user_regs(regs);
@@ -2193,8 +2199,7 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs)
vmx_do_extint(regs);
break;
case EXIT_REASON_TRIPLE_FAULT:
domain_crash_synchronous();
break;
goto exit_and_crash;
case EXIT_REASON_PENDING_INTERRUPT:
/* Disable the interrupt window. */
v->arch.hvm_vcpu.u.vmx.exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
@@ -2202,8 +2207,7 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs)
v->arch.hvm_vcpu.u.vmx.exec_control);
break;
case EXIT_REASON_TASK_SWITCH:
domain_crash_synchronous();
break;
goto exit_and_crash;
case EXIT_REASON_CPUID:
inst_len = __get_instruction_length(); /* Safe: CPUID */
__update_guest_eip(inst_len);
@@ -2268,8 +2272,7 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs)
case EXIT_REASON_MWAIT_INSTRUCTION:
case EXIT_REASON_MONITOR_INSTRUCTION:
case EXIT_REASON_PAUSE_INSTRUCTION:
domain_crash_synchronous();
break;
goto exit_and_crash;
case EXIT_REASON_VMCLEAR:
case EXIT_REASON_VMLAUNCH:
case EXIT_REASON_VMPTRLD:
@@ -2289,7 +2292,10 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs)
break;
default:
domain_crash_synchronous(); /* should not happen */
exit_and_crash:
gdprintk(XENLOG_ERR, "Bad vmexit (reason %x)\n", exit_reason);
domain_crash(v->domain);
break;
}
}
+13 -6
View File
@@ -1717,7 +1717,7 @@ int new_guest_cr3(unsigned long mfn)
unsigned long old_base_mfn;
if ( is_hvm_domain(d) && !hvm_paging_enabled(v) )
domain_crash_synchronous();
return 0;
if ( shadow_mode_refcounts(d) )
{
@@ -2134,13 +2134,14 @@ int do_mmuext_op(
default:
MEM_LOG("Invalid extended pt command 0x%x", op.cmd);
rc = -ENOSYS;
okay = 0;
break;
}
if ( unlikely(!okay) )
{
rc = -EINVAL;
rc = rc ? rc : -EINVAL;
break;
}
@@ -2151,9 +2152,11 @@ int do_mmuext_op(
process_deferred_ops();
/* Add incremental work we have done to the @done output parameter. */
done += i;
if ( unlikely(!guest_handle_is_null(pdone)) )
{
done += i;
copy_to_guest(pdone, &done, 1);
}
UNLOCK_BIGLOCK(d);
return rc;
@@ -2351,12 +2354,14 @@ int do_mmu_update(
default:
MEM_LOG("Invalid page update command %x", cmd);
rc = -ENOSYS;
okay = 0;
break;
}
if ( unlikely(!okay) )
{
rc = -EINVAL;
rc = rc ? rc : -EINVAL;
break;
}
@@ -2370,9 +2375,11 @@ int do_mmu_update(
process_deferred_ops();
/* Add incremental work we have done to the @done output parameter. */
done += i;
if ( unlikely(!guest_handle_is_null(pdone)) )
{
done += i;
copy_to_guest(pdone, &done, 1);
}
UNLOCK_BIGLOCK(d);
return rc;
@@ -3106,7 +3113,7 @@ static int ptwr_emulated_update(
* zap the PRESENT bit on the assumption the bottom half will be
* written immediately after we return to the guest.
*/
MEM_LOG("ptwr_emulate: fixing up invalid PAE PTE %"PRIpte"\n",
MEM_LOG("ptwr_emulate: fixing up invalid PAE PTE %"PRIpte,
l1e_get_intpte(nl1e));
l1e_remove_flags(nl1e, _PAGE_PRESENT);
}
+1 -1
View File
@@ -684,7 +684,7 @@ int do_xenoprof_op(int op, XEN_GUEST_HANDLE(void) arg)
break;
default:
ret = -EINVAL;
ret = -ENOSYS;
}
spin_unlock(&xenoprof_lock);
+1 -1
View File
@@ -135,7 +135,7 @@ long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg)
}
default:
ret = -EINVAL;
ret = -ENOSYS;
break;
}
+3 -1
View File
@@ -1310,8 +1310,10 @@ static int emulate_privileged_op(struct cpu_user_regs *regs)
case 3: /* Write CR3 */
LOCK_BIGLOCK(v->domain);
(void)new_guest_cr3(gmfn_to_mfn(v->domain, xen_cr3_to_pfn(*reg)));
rc = new_guest_cr3(gmfn_to_mfn(v->domain, xen_cr3_to_pfn(*reg)));
UNLOCK_BIGLOCK(v->domain);
if ( rc == 0 ) /* not okay */
goto fail;
break;
case 4:
+23 -10
View File
@@ -179,16 +179,16 @@ unsigned long do_iret(void)
/* Check worst-case stack frame for overlap with Xen protected area. */
if ( unlikely(!access_ok(regs->esp, 40)) )
domain_crash_synchronous();
goto exit_and_crash;
/* Pop and restore EAX (clobbered by hypercall). */
if ( unlikely(__copy_from_user(&regs->eax, (void __user *)regs->esp, 4)) )
domain_crash_synchronous();
goto exit_and_crash;
regs->esp += 4;
/* Pop and restore CS and EIP. */
if ( unlikely(__copy_from_user(&regs->eip, (void __user *)regs->esp, 8)) )
domain_crash_synchronous();
goto exit_and_crash;
regs->esp += 8;
/*
@@ -196,7 +196,7 @@ unsigned long do_iret(void)
* to avoid firing the BUG_ON(IOPL) check in arch_getdomaininfo_ctxt.
*/
if ( unlikely(__copy_from_user(&eflags, (void __user *)regs->esp, 4)) )
domain_crash_synchronous();
goto exit_and_crash;
regs->esp += 4;
regs->eflags = (eflags & ~X86_EFLAGS_IOPL) | X86_EFLAGS_IF;
@@ -204,17 +204,17 @@ unsigned long do_iret(void)
{
/* Return to VM86 mode: pop and restore ESP,SS,ES,DS,FS and GS. */
if ( __copy_from_user(&regs->esp, (void __user *)regs->esp, 24) )
domain_crash_synchronous();
goto exit_and_crash;
}
else if ( unlikely(ring_0(regs)) )
{
domain_crash_synchronous();
goto exit_and_crash;
}
else if ( !ring_1(regs) )
{
/* Return to ring 2/3: pop and restore ESP and SS. */
if ( __copy_from_user(&regs->esp, (void __user *)regs->esp, 8) )
domain_crash_synchronous();
goto exit_and_crash;
}
/* No longer in NMI context. */
@@ -228,6 +228,11 @@ unsigned long do_iret(void)
* value.
*/
return regs->eax;
exit_and_crash:
gdprintk(XENLOG_ERR, "Fatal error\n");
domain_crash(current->domain);
return 0;
}
#include <asm/asm_defns.h>
@@ -355,7 +360,7 @@ static long register_guest_callback(struct callback_register *reg)
break;
default:
ret = -EINVAL;
ret = -ENOSYS;
break;
}
@@ -368,12 +373,20 @@ static long unregister_guest_callback(struct callback_unregister *unreg)
switch ( unreg->type )
{
case CALLBACKTYPE_event:
case CALLBACKTYPE_failsafe:
#ifdef CONFIG_X86_SUPERVISOR_MODE_KERNEL
case CALLBACKTYPE_sysenter:
#endif
ret = -EINVAL;
break;
case CALLBACKTYPE_nmi:
ret = unregister_guest_nmi_callback();
break;
default:
ret = -EINVAL;
ret = -ENOSYS;
break;
}
@@ -412,7 +425,7 @@ long do_callback_op(int cmd, XEN_GUEST_HANDLE(void) arg)
break;
default:
ret = -EINVAL;
ret = -ENOSYS;
break;
}
+4 -4
View File
@@ -45,7 +45,7 @@ restore_all_guest:
addq $8,%rsp
popq %rcx # RIP
popq %r11 # CS
cmpw $__GUEST_CS32,%r11
cmpw $FLAT_KERNEL_CS32,%r11
popq %r11 # RFLAGS
popq %rsp # RSP
je 1f
@@ -119,7 +119,7 @@ restore_all_xen:
ALIGN
ENTRY(syscall_enter)
sti
movl $__GUEST_SS,24(%rsp)
movl $FLAT_KERNEL_SS,24(%rsp)
pushq %rcx
pushq $0
movl $TRAP_syscall,4(%rsp)
@@ -298,9 +298,9 @@ FLT13: movq %rax,(%rsi) # RCX
movl $TRAP_syscall,UREGS_entry_vector+8(%rsp)
andl $~(X86_EFLAGS_AC|X86_EFLAGS_VM|X86_EFLAGS_RF|\
X86_EFLAGS_NT|X86_EFLAGS_TF),UREGS_eflags+8(%rsp)
movq $__GUEST_SS,UREGS_ss+8(%rsp)
movq $FLAT_KERNEL_SS,UREGS_ss+8(%rsp)
movq %rsi,UREGS_rsp+8(%rsp)
movq $__GUEST_CS,UREGS_cs+8(%rsp)
movq $FLAT_KERNEL_CS,UREGS_cs+8(%rsp)
movq TRAPBOUNCE_eip(%rdx),%rax
testq %rax,%rax
jz domain_crash_synchronous
+20 -16
View File
@@ -76,17 +76,17 @@ l2_pgentry_t *virt_to_xen_l2e(unsigned long v)
void __init paging_init(void)
{
unsigned long i, mpt_size;
unsigned long i, mpt_size, va;
l3_pgentry_t *l3_ro_mpt;
l2_pgentry_t *l2_ro_mpt = NULL;
struct page_info *pg;
struct page_info *l1_pg, *l2_pg;
/* Create user-accessible L2 directory to map the MPT for guests. */
l3_ro_mpt = alloc_xenheap_page();
clear_page(l3_ro_mpt);
if ( (l2_pg = alloc_domheap_page(NULL)) == NULL )
goto nomem;
l3_ro_mpt = clear_page(page_to_virt(l2_pg));
idle_pg_table[l4_table_offset(RO_MPT_VIRT_START)] =
l4e_from_page(
virt_to_page(l3_ro_mpt), __PAGE_HYPERVISOR | _PAGE_USER);
l4e_from_page(l2_pg, __PAGE_HYPERVISOR | _PAGE_USER);
/*
* Allocate and map the machine-to-phys table.
@@ -96,33 +96,37 @@ void __init paging_init(void)
mpt_size &= ~((1UL << L2_PAGETABLE_SHIFT) - 1UL);
for ( i = 0; i < (mpt_size >> L2_PAGETABLE_SHIFT); i++ )
{
if ( (pg = alloc_domheap_pages(NULL, PAGETABLE_ORDER, 0)) == NULL )
panic("Not enough memory for m2p table\n");
if ( (l1_pg = alloc_domheap_pages(NULL, PAGETABLE_ORDER, 0)) == NULL )
goto nomem;
map_pages_to_xen(
RDWR_MPT_VIRT_START + (i << L2_PAGETABLE_SHIFT), page_to_mfn(pg),
RDWR_MPT_VIRT_START + (i << L2_PAGETABLE_SHIFT),
page_to_mfn(l1_pg),
1UL << PAGETABLE_ORDER,
PAGE_HYPERVISOR);
memset((void *)(RDWR_MPT_VIRT_START + (i << L2_PAGETABLE_SHIFT)), 0x55,
1UL << L2_PAGETABLE_SHIFT);
if ( !((unsigned long)l2_ro_mpt & ~PAGE_MASK) )
{
unsigned long va = RO_MPT_VIRT_START + (i << L2_PAGETABLE_SHIFT);
l2_ro_mpt = alloc_xenheap_page();
clear_page(l2_ro_mpt);
if ( (l2_pg = alloc_domheap_page(NULL)) == NULL )
goto nomem;
va = RO_MPT_VIRT_START + (i << L2_PAGETABLE_SHIFT);
l2_ro_mpt = clear_page(page_to_virt(l2_pg));
l3_ro_mpt[l3_table_offset(va)] =
l3e_from_page(
virt_to_page(l2_ro_mpt), __PAGE_HYPERVISOR | _PAGE_USER);
l3e_from_page(l2_pg, __PAGE_HYPERVISOR | _PAGE_USER);
l2_ro_mpt += l2_table_offset(va);
}
/* NB. Cannot be GLOBAL as shadow_mode_translate reuses this area. */
*l2_ro_mpt++ = l2e_from_page(
pg, /*_PAGE_GLOBAL|*/_PAGE_PSE|_PAGE_USER|_PAGE_PRESENT);
l1_pg, /*_PAGE_GLOBAL|*/_PAGE_PSE|_PAGE_USER|_PAGE_PRESENT);
}
/* Set up linear page table mapping. */
idle_pg_table[l4_table_offset(LINEAR_PT_VIRT_START)] =
l4e_from_paddr(__pa(idle_pg_table), __PAGE_HYPERVISOR);
return;
nomem:
panic("Not enough memory for m2p table\n");
}
void __init setup_idle_pagetable(void)
+20 -9
View File
@@ -200,7 +200,7 @@ unsigned long do_iret(void)
{
gdprintk(XENLOG_ERR, "Fault while reading IRET context from "
"guest stack\n");
domain_crash_synchronous();
goto exit_and_crash;
}
/* Returning to user mode? */
@@ -210,7 +210,7 @@ unsigned long do_iret(void)
{
gdprintk(XENLOG_ERR, "Guest switching to user mode with no "
"user page tables\n");
domain_crash_synchronous();
goto exit_and_crash;
}
toggle_guest_mode(v);
}
@@ -236,6 +236,11 @@ unsigned long do_iret(void)
/* Saved %rax gets written back to regs->rax in entry.S. */
return iret_saved.rax;
exit_and_crash:
gdprintk(XENLOG_ERR, "Fatal error\n");
domain_crash(v->domain);
return 0;
}
asmlinkage void syscall_enter(void);
@@ -285,9 +290,9 @@ void __init percpu_traps_init(void)
stack[14] = 0x41;
stack[15] = 0x53;
/* pushq $__GUEST_CS64 */
/* pushq $FLAT_KERNEL_CS64 */
stack[16] = 0x68;
*(u32 *)&stack[17] = __GUEST_CS64;
*(u32 *)&stack[17] = FLAT_KERNEL_CS64;
/* jmp syscall_enter */
stack[21] = 0xe9;
@@ -317,9 +322,9 @@ void __init percpu_traps_init(void)
stack[14] = 0x41;
stack[15] = 0x53;
/* pushq $__GUEST_CS32 */
/* pushq $FLAT_KERNEL_CS32 */
stack[16] = 0x68;
*(u32 *)&stack[17] = __GUEST_CS32;
*(u32 *)&stack[17] = FLAT_KERNEL_CS32;
/* jmp syscall_enter */
stack[21] = 0xe9;
@@ -369,7 +374,7 @@ static long register_guest_callback(struct callback_register *reg)
break;
default:
ret = -EINVAL;
ret = -ENOSYS;
break;
}
@@ -382,12 +387,18 @@ static long unregister_guest_callback(struct callback_unregister *unreg)
switch ( unreg->type )
{
case CALLBACKTYPE_event:
case CALLBACKTYPE_failsafe:
case CALLBACKTYPE_syscall:
ret = -EINVAL;
break;
case CALLBACKTYPE_nmi:
ret = unregister_guest_nmi_callback();
break;
default:
ret = -EINVAL;
ret = -ENOSYS;
break;
}
@@ -426,7 +437,7 @@ long do_callback_op(int cmd, XEN_GUEST_HANDLE(void) arg)
break;
default:
ret = -EINVAL;
ret = -ENOSYS;
break;
}
+5
View File
@@ -22,6 +22,7 @@
#include <xen/delay.h>
#include <xen/shutdown.h>
#include <xen/percpu.h>
#include <xen/multicall.h>
#include <asm/debugger.h>
#include <public/sched.h>
#include <public/vcpu.h>
@@ -256,6 +257,10 @@ void __domain_crash(struct domain *d)
void __domain_crash_synchronous(void)
{
__domain_crash(current->domain);
/* Flush multicall state before dying. */
this_cpu(mc_state).flags = 0;
for ( ; ; )
do_softirq();
}
+1 -1
View File
@@ -246,7 +246,7 @@ static __inline__ int constant_test_bit(int nr, const volatile void * addr)
return ((1U << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
}
static __inline__ int variable_test_bit(int nr, volatile void * addr)
static __inline__ int variable_test_bit(int nr, const volatile void * addr)
{
int oldbit;
-6
View File
@@ -194,12 +194,6 @@ extern unsigned long _end; /* standard ELF symbol */
#define __HYPERVISOR_DS32 0xe018
#define __HYPERVISOR_DS __HYPERVISOR_DS64
#define __GUEST_CS64 0xe033
#define __GUEST_CS32 0xe023
#define __GUEST_CS __GUEST_CS64
#define __GUEST_DS 0x0000
#define __GUEST_SS 0xe02b
/* For generic assembly code: use macros to define operation/operand sizes. */
#define __OS "q" /* Operation Suffix */
#define __OP "r" /* Operand Prefix */
-5
View File
@@ -155,17 +155,12 @@ __asm__ __volatile__ ("movw %w3,0(%2)\n\t" \
#endif
extern struct desc_struct gdt_table[];
extern struct desc_struct *gdt;
extern idt_entry_t *idt;
struct Xgt_desc_struct {
unsigned short size;
unsigned long address __attribute__((packed));
};
#define idt_descr (*(struct Xgt_desc_struct *)((char *)&idt - 2))
#define gdt_descr (*(struct Xgt_desc_struct *)((char *)&gdt - 2))
extern void set_intr_gate(unsigned int irq, void * addr);
extern void set_system_gate(unsigned int n, void *addr);
extern void set_task_gate(unsigned int n, unsigned int sel);
-7
View File
@@ -118,13 +118,6 @@ extern unsigned int opt_hvm_debug_level;
#define HVM_DBG_LOG(level, _f, _a...)
#endif
#define __hvm_bug(regs) \
do { \
printk("__hvm_bug at %s:%d\n", __FILE__, __LINE__); \
show_execution_state(regs); \
domain_crash_synchronous(); \
} while (0)
#define TRACE_VMEXIT(index, value) \
current->arch.hvm_vcpu.hvm_trace_values[index] = (value)
+2
View File
@@ -90,4 +90,6 @@ struct vlapic *apic_round_robin(
s_time_t get_apictime_scheduled(struct vcpu *v);
int vlapic_match_logical_addr(struct vlapic *vlapic, uint8_t mda);
#endif /* __ASM_X86_HVM_VLAPIC_H__ */
+9
View File
@@ -138,6 +138,15 @@
*/
#define XEN_ELFNOTE_BSD_SYMTAB 11
/*
* The lowest address the hypervisor hole can begin at (numeric).
*
* This must not be set higher than HYPERVISOR_VIRT_START. Its presence
* also indicates to the hypervisor that the kernel can deal with the
* hole starting at a higher address.
*/
#define XEN_ELFNOTE_HV_START_LOW 12
#endif /* __XEN_PUBLIC_ELFNOTE_H__ */
/*
+1 -1
View File
@@ -80,7 +80,7 @@ struct buffered_iopage {
}; /* sizeof this structure must be in one page */
typedef struct buffered_iopage buffered_iopage_t;
#define ACPI_PM1A_EVT_BLK_ADDRESS 0x000000000000c010
#define ACPI_PM1A_EVT_BLK_ADDRESS 0x0000000000001f40
#define ACPI_PM1A_CNT_BLK_ADDRESS (ACPI_PM1A_EVT_BLK_ADDRESS + 0x04)
#define ACPI_PM_TMR_BLK_ADDRESS (ACPI_PM1A_EVT_BLK_ADDRESS + 0x08)
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.