Exemplo n.º 1
0
static unsigned xen_patch(u8 type, u16 clobbers, void *insnbuf,
			  unsigned long addr, unsigned len)
{
	char *start, *end, *reloc;
	unsigned ret;

	start = end = reloc = NULL;

#define SITE(op, x)							\
	case PARAVIRT_PATCH(op.x):					\
	if (have_vcpu_info_placement) {					\
		start = (char *)xen_##x##_direct;			\
		end = xen_##x##_direct_end;				\
		reloc = xen_##x##_direct_reloc;				\
	}								\
	goto patch_site

	switch (type) {
		SITE(pv_irq_ops, irq_enable);
		SITE(pv_irq_ops, irq_disable);
		SITE(pv_irq_ops, save_fl);
		SITE(pv_irq_ops, restore_fl);
#undef SITE

	patch_site:
		if (start == NULL || (end-start) > len)
			goto default_patch;

		ret = paravirt_patch_insns(insnbuf, len, start, end);

		/* Note: because reloc is assigned from something that
		   appears to be an array, gcc assumes it's non-null,
		   but doesn't know its relationship with start and
		   end. */
		if (reloc > start && reloc < end) {
			int reloc_off = reloc - start;
			long *relocp = (long *)(insnbuf + reloc_off);
			long delta = start - (char *)addr;

			*relocp += delta;
		}
		break;

	default_patch:
	default:
		ret = paravirt_patch_default(type, clobbers, insnbuf,
					     addr, len);
		break;
	}

	return ret;
}
static unsigned xen_patch(u8 type, u16 clobbers, void *insnbuf,
			  unsigned long addr, unsigned len)
{
	char *start, *end, *reloc;
	unsigned ret;

	start = end = reloc = NULL;

#define SITE(op, x)							\
	case PARAVIRT_PATCH(op.x):					\
	if (have_vcpu_info_placement) {					\
		start = (char *)xen_##x##_direct;			\
		end = xen_##x##_direct_end;				\
		reloc = xen_##x##_direct_reloc;				\
	}								\
	goto patch_site

	switch (type) {
		SITE(pv_irq_ops, irq_enable);
		SITE(pv_irq_ops, irq_disable);
		SITE(pv_irq_ops, save_fl);
		SITE(pv_irq_ops, restore_fl);
#undef SITE

	patch_site:
		if (start == NULL || (end-start) > len)
			goto default_patch;

		ret = paravirt_patch_insns(insnbuf, len, start, end);

		if (reloc > start && reloc < end) {
			int reloc_off = reloc - start;
			long *relocp = (long *)(insnbuf + reloc_off);
			long delta = start - (char *)addr;

			*relocp += delta;
		}
		break;

	default_patch:
	default:
		ret = paravirt_patch_default(type, clobbers, insnbuf,
					     addr, len);
		break;
	}

	return ret;
}
Exemplo n.º 3
0
static unsigned native_patch(u8 type, u16 clobbers, void *ibuf,
			     unsigned long addr, unsigned len)
{
	const unsigned char *start, *end;
	unsigned ret;

	switch(type) {
#define SITE(x)	case PARAVIRT_PATCH(x):	start = start_##x; end = end_##x; goto patch_site
		SITE(irq_disable);
		SITE(irq_enable);
		SITE(restore_fl);
		SITE(save_fl);
		SITE(iret);
		SITE(irq_enable_sysexit);
		SITE(read_cr2);
		SITE(read_cr3);
		SITE(write_cr3);
		SITE(clts);
		SITE(read_tsc);
#undef SITE

	patch_site:
		ret = paravirt_patch_insns(ibuf, len, start, end);
		break;

	case PARAVIRT_PATCH(make_pgd):
	case PARAVIRT_PATCH(make_pte):
	case PARAVIRT_PATCH(pgd_val):
	case PARAVIRT_PATCH(pte_val):
#ifdef CONFIG_X86_PAE
	case PARAVIRT_PATCH(make_pmd):
	case PARAVIRT_PATCH(pmd_val):
#endif
		/* These functions end up returning exactly what
		   they're passed, in the same registers. */
		ret = paravirt_patch_nop();
		break;

	default:
		ret = paravirt_patch_default(type, clobbers, ibuf, addr, len);
		break;
	}

	return ret;
}
Exemplo n.º 4
0
static unsigned native_patch(u8 type, u16 clobbers, void *ibuf,
			     unsigned long addr, unsigned len)
{
	const unsigned char *start, *end;
	unsigned ret;

	switch(type) {
#define SITE(ops, x)						\
	case PARAVIRT_PATCH(ops.x):				\
		start = start_##ops##_##x;			\
		end = end_##ops##_##x;				\
		goto patch_site

	SITE(pv_irq_ops, irq_disable);
	SITE(pv_irq_ops, irq_enable);
	SITE(pv_irq_ops, restore_fl);
	SITE(pv_irq_ops, save_fl);
	SITE(pv_cpu_ops, iret);
	SITE(pv_cpu_ops, irq_enable_sysexit);
	SITE(pv_mmu_ops, read_cr2);
	SITE(pv_mmu_ops, read_cr3);
	SITE(pv_mmu_ops, write_cr3);
	SITE(pv_cpu_ops, clts);
	SITE(pv_cpu_ops, read_tsc);
#undef SITE

	patch_site:
		ret = paravirt_patch_insns(ibuf, len, start, end);
		break;

	default:
		ret = paravirt_patch_default(type, clobbers, ibuf, addr, len);
		break;
	}

	return ret;
}