[XEN] Get rid of many uses of domain_crash_synchronous().

It is much more dangerous than domain_crash() because it
stops execution of teh current context regardless of
current state (e.g., IRQs disabled, locks held).

The preferred method to crash a domain is domain_crash()
and error return to the caller.

Signed-off-by: Keir Fraser <keir@xensource.com>
This commit is contained in:
kfraser@localhost.localdomain committed 2006-11-13 12:01:43 +00:00
1 parent db34d2aaa5
commit 7fd0873637
12 files changed
+173 -170

No files matched your search

+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)
+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)
+79 -66
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;
}
@@ -2072,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);
@@ -2186,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;
@@ -2195,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);
@@ -2261,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:
@@ -2282,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;
}
}
+1 -1
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) )
{
+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:
+12 -7
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>
+7 -2
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);
-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)
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.