mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
merge with xen-unstable.hg
This commit is contained in:
commit
f1734953c7
6 files changed
+73
-11
No files matched your search
@@ -101,7 +101,7 @@ int pci_device_load(PCIDevice *s, QEMUFile *f)
|
||||
int i;
|
||||
qemu_get_buffer(f, &irq_state, 1);
|
||||
for (i = 0; i < 4; i++)
|
||||
pci_set_irq(s, i, !!(irq_state >> i));
|
||||
pci_set_irq(s, i, (irq_state >> i) & 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1096,7 +1096,7 @@ def xm_vcpu_list(args):
|
||||
|
||||
# normalize cpumap by modulus nr_cpus, and drop duplicates
|
||||
cpumap = dict.fromkeys(
|
||||
map(lambda x: x % nr_cpus, cpumap)).keys()
|
||||
filter(lambda x: x < nr_cpus, cpumap)).keys()
|
||||
if len(cpumap) == nr_cpus:
|
||||
return "any cpu"
|
||||
|
||||
|
||||
@@ -271,9 +271,9 @@ static uint8_t stdvga_mem_readb(uint64_t addr)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint32_t stdvga_mem_read(uint32_t addr, uint32_t size)
|
||||
static uint64_t stdvga_mem_read(uint64_t addr, uint64_t size)
|
||||
{
|
||||
uint32_t data = 0;
|
||||
uint64_t data = 0;
|
||||
|
||||
switch ( size )
|
||||
{
|
||||
@@ -293,8 +293,19 @@ static uint32_t stdvga_mem_read(uint32_t addr, uint32_t size)
|
||||
data |= stdvga_mem_readb(addr + 3) << 24;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
data = (uint64_t)(stdvga_mem_readb(addr));
|
||||
data |= (uint64_t)(stdvga_mem_readb(addr + 1)) << 8;
|
||||
data |= (uint64_t)(stdvga_mem_readb(addr + 2)) << 16;
|
||||
data |= (uint64_t)(stdvga_mem_readb(addr + 3)) << 24;
|
||||
data |= (uint64_t)(stdvga_mem_readb(addr + 4)) << 32;
|
||||
data |= (uint64_t)(stdvga_mem_readb(addr + 5)) << 40;
|
||||
data |= (uint64_t)(stdvga_mem_readb(addr + 6)) << 48;
|
||||
data |= (uint64_t)(stdvga_mem_readb(addr + 7)) << 56;
|
||||
break;
|
||||
|
||||
default:
|
||||
gdprintk(XENLOG_WARNING, "invalid io size:%d\n", size);
|
||||
gdprintk(XENLOG_WARNING, "invalid io size: %"PRId64"\n", size);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -409,7 +420,7 @@ static void stdvga_mem_writeb(uint64_t addr, uint32_t val)
|
||||
}
|
||||
}
|
||||
|
||||
static void stdvga_mem_write(uint32_t addr, uint32_t data, uint32_t size)
|
||||
static void stdvga_mem_write(uint64_t addr, uint64_t data, uint64_t size)
|
||||
{
|
||||
/* Intercept mmio write */
|
||||
switch ( size )
|
||||
@@ -430,8 +441,19 @@ static void stdvga_mem_write(uint32_t addr, uint32_t data, uint32_t size)
|
||||
stdvga_mem_writeb(addr+3, (data >> 24) & 0xff);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
stdvga_mem_writeb(addr+0, (data >> 0) & 0xff);
|
||||
stdvga_mem_writeb(addr+1, (data >> 8) & 0xff);
|
||||
stdvga_mem_writeb(addr+2, (data >> 16) & 0xff);
|
||||
stdvga_mem_writeb(addr+3, (data >> 24) & 0xff);
|
||||
stdvga_mem_writeb(addr+4, (data >> 32) & 0xff);
|
||||
stdvga_mem_writeb(addr+5, (data >> 40) & 0xff);
|
||||
stdvga_mem_writeb(addr+6, (data >> 48) & 0xff);
|
||||
stdvga_mem_writeb(addr+7, (data >> 56) & 0xff);
|
||||
break;
|
||||
|
||||
default:
|
||||
gdprintk(XENLOG_WARNING, "invalid io size:%d\n", size);
|
||||
gdprintk(XENLOG_WARNING, "invalid io size: %"PRId64"\n", size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -447,7 +469,7 @@ static int mmio_move(struct hvm_hw_stdvga *s, ioreq_t *p)
|
||||
{
|
||||
if ( p->dir == IOREQ_READ )
|
||||
{
|
||||
uint32_t addr = p->addr, data = p->data, tmp;
|
||||
uint64_t addr = p->addr, data = p->data, tmp;
|
||||
for ( i = 0; i < p->count; i++ )
|
||||
{
|
||||
tmp = stdvga_mem_read(addr, p->size);
|
||||
|
||||
@@ -51,6 +51,12 @@ static void svm_inject_nmi(struct vcpu *v)
|
||||
|
||||
ASSERT(vmcb->eventinj.fields.v == 0);
|
||||
vmcb->eventinj = event;
|
||||
|
||||
/*
|
||||
* SVM does not virtualise the NMI mask, so we emulate it by intercepting
|
||||
* the next IRET and blocking NMI injection until the intercept triggers.
|
||||
*/
|
||||
vmcb->general1_intercepts |= GENERAL1_INTERCEPT_IRET;
|
||||
}
|
||||
|
||||
static void svm_inject_extint(struct vcpu *v, int vector)
|
||||
|
||||
@@ -367,15 +367,27 @@ static void svm_fpu_leave(struct vcpu *v)
|
||||
static unsigned int svm_get_interrupt_shadow(struct vcpu *v)
|
||||
{
|
||||
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
|
||||
return (vmcb->interrupt_shadow ?
|
||||
(HVM_INTR_SHADOW_MOV_SS|HVM_INTR_SHADOW_STI) : 0);
|
||||
unsigned int intr_shadow = 0;
|
||||
|
||||
if ( vmcb->interrupt_shadow )
|
||||
intr_shadow |= HVM_INTR_SHADOW_MOV_SS | HVM_INTR_SHADOW_STI;
|
||||
|
||||
if ( vmcb->general1_intercepts & GENERAL1_INTERCEPT_IRET )
|
||||
intr_shadow |= HVM_INTR_SHADOW_NMI;
|
||||
|
||||
return intr_shadow;
|
||||
}
|
||||
|
||||
static void svm_set_interrupt_shadow(struct vcpu *v, unsigned int intr_shadow)
|
||||
{
|
||||
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
|
||||
|
||||
vmcb->interrupt_shadow =
|
||||
!!(intr_shadow & (HVM_INTR_SHADOW_MOV_SS|HVM_INTR_SHADOW_STI));
|
||||
|
||||
vmcb->general1_intercepts &= ~GENERAL1_INTERCEPT_IRET;
|
||||
if ( intr_shadow & HVM_INTR_SHADOW_NMI )
|
||||
vmcb->general1_intercepts |= GENERAL1_INTERCEPT_IRET;
|
||||
}
|
||||
|
||||
static int svm_guest_x86_mode(struct vcpu *v)
|
||||
@@ -1266,6 +1278,15 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs *regs)
|
||||
reason = TSW_call_or_int;
|
||||
if ( (vmcb->exitinfo2 >> 44) & 1 )
|
||||
errcode = (uint32_t)vmcb->exitinfo2;
|
||||
|
||||
/*
|
||||
* Some processors set the EXITINTINFO field when the task switch
|
||||
* is caused by a task gate in the IDT. In this case we will be
|
||||
* emulating the event injection, so we do not want the processor
|
||||
* to re-inject the original event!
|
||||
*/
|
||||
vmcb->eventinj.bytes = 0;
|
||||
|
||||
hvm_task_switch((uint16_t)vmcb->exitinfo1, reason, errcode);
|
||||
break;
|
||||
}
|
||||
@@ -1331,6 +1352,19 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs *regs)
|
||||
svm_do_nested_pgfault(vmcb->exitinfo2, regs);
|
||||
break;
|
||||
|
||||
case VMEXIT_IRET:
|
||||
/*
|
||||
* IRET clears the NMI mask. However because we clear the mask
|
||||
* /before/ executing IRET, we set the interrupt shadow to prevent
|
||||
* a pending NMI from being injected immediately. This will work
|
||||
* perfectly unless the IRET instruction faults: in that case we
|
||||
* may inject an NMI before the NMI handler's IRET instruction is
|
||||
* retired.
|
||||
*/
|
||||
vmcb->general1_intercepts &= ~GENERAL1_INTERCEPT_IRET;
|
||||
vmcb->interrupt_shadow = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
exit_and_crash:
|
||||
gdprintk(XENLOG_ERR, "unexpected VMEXIT: exit reason = 0x%x, "
|
||||
|
||||
@@ -362,7 +362,7 @@ void __init kexec_reserve_area(struct e820map *e820)
|
||||
|
||||
is_reserved = 1;
|
||||
|
||||
if ( !reserve_e820_ram(e820, kdump_start, kdump_size) )
|
||||
if ( !reserve_e820_ram(e820, kdump_start, kdump_start + kdump_size) )
|
||||
{
|
||||
printk("Kdump: DISABLED (failed to reserve %luMB (%lukB) at 0x%lx)"
|
||||
"\n", kdump_size >> 20, kdump_size >> 10, kdump_start);
|
||||
|
||||