Пример #1
0
/*
 * Apply patch if appropriate, return length of new instruction
 * sequence.  The callee does nop padding for us.
 */
static unsigned vmi_patch(u8 type, u16 clobbers, void *insns,
			  unsigned long ip, unsigned len)
{
	switch (type) {
		case PARAVIRT_PATCH(pv_irq_ops.irq_disable):
			return patch_internal(VMI_CALL_DisableInterrupts, len,
					      insns, ip);
		case PARAVIRT_PATCH(pv_irq_ops.irq_enable):
			return patch_internal(VMI_CALL_EnableInterrupts, len,
					      insns, ip);
		case PARAVIRT_PATCH(pv_irq_ops.restore_fl):
			return patch_internal(VMI_CALL_SetInterruptMask, len,
					      insns, ip);
		case PARAVIRT_PATCH(pv_irq_ops.save_fl):
			return patch_internal(VMI_CALL_GetInterruptMask, len,
					      insns, ip);
		case PARAVIRT_PATCH(pv_cpu_ops.iret):
			return patch_internal(VMI_CALL_IRET, len, insns, ip);
		case PARAVIRT_PATCH(pv_cpu_ops.nmi_return):
			return patch_internal(VMI_CALL_IRET, len, insns, ip);
		case PARAVIRT_PATCH(pv_cpu_ops.irq_enable_sysexit):
			return patch_internal(VMI_CALL_SYSEXIT, len, insns, ip);
		default:
			break;
	}
	return len;
}
Пример #2
0
/*
 * Apply patch if appropriate, return length of new instruction
 * sequence.  The callee does nop padding for us.
 */
static unsigned vmi_patch(u8 type, u16 clobbers, void *insns, unsigned len)
{
	switch (type) {
		case PARAVIRT_IRQ_DISABLE:
			return patch_internal(VMI_CALL_DisableInterrupts, len, insns);
		case PARAVIRT_IRQ_ENABLE:
			return patch_internal(VMI_CALL_EnableInterrupts, len, insns);
		case PARAVIRT_RESTORE_FLAGS:
			return patch_internal(VMI_CALL_SetInterruptMask, len, insns);
		case PARAVIRT_SAVE_FLAGS:
			return patch_internal(VMI_CALL_GetInterruptMask, len, insns);
        	case PARAVIRT_SAVE_FLAGS_IRQ_DISABLE:
			if (len >= 10) {
				patch_internal(VMI_CALL_GetInterruptMask, len, insns);
				patch_internal(VMI_CALL_DisableInterrupts, len-5, insns+5);
				return 10;
			} else {
				/*
				 * You bastards didn't leave enough room to
				 * patch save_flags_irq_disable inline.  Patch
				 * to a helper
				 */
				BUG_ON(len < 5);
				*(char *)insns = MNEM_CALL;
				patch_offset(insns, irq_save_disable_callout);
				return 5;
			}
		case PARAVIRT_INTERRUPT_RETURN:
			return patch_internal(VMI_CALL_IRET, len, insns);
		case PARAVIRT_STI_SYSEXIT:
			return patch_internal(VMI_CALL_SYSEXIT, len, insns);
		default:
			break;
	}
	return len;
}