[XEN] Rename shadow2 to shadow and move the various source

files into a sensible directory hierarchy.
Signed-off-by: Keir Fraser <keir@xensource.com>
This commit is contained in:
kaf24@localhost.localdomain committed 2006-08-28 12:09:36 +01:00
1 parent a1041848b5
commit 99deb3f2fb
25 files changed
+2585 -2630

No files matched your search

+1 -1
View File
@@ -441,7 +441,7 @@ static int xc_hvm_build_internal(int xc_handle,
goto error_out;
}
/* HVM domains must be put into shadow2 mode at the start of day */
/* HVM domains must be put into shadow mode at the start of day */
if ( xc_shadow_control(xc_handle, domid, XEN_DOMCTL_SHADOW_OP_ENABLE,
NULL, 0, NULL,
XEN_DOMCTL_SHADOW_ENABLE_REFCOUNT |
+1 -20
View File
@@ -2,6 +2,7 @@ subdir-y += acpi
subdir-y += cpu
subdir-y += genapic
subdir-y += hvm
subdir-y += mm
subdir-y += oprofile
subdir-$(x86_32) += x86_32
@@ -41,23 +42,6 @@ obj-y += traps.o
obj-y += usercopy.o
obj-y += x86_emulate.o
ifneq ($(pae),n)
obj-$(x86_32) += shadow2-common.o shadow2_g2_on_s3.o shadow2_g3_on_s3.o
else
obj-$(x86_32) += shadow2-common.o shadow2_g2_on_s2.o
endif
obj-$(x86_64) += shadow2-common.o shadow2_g4_on_s4.o shadow2_g3_on_s3.o \
shadow2_g2_on_s3.o
guest_levels = $(subst g,,$(filter g%,$(subst ., ,$(subst _, ,$(subst shadow2_,,$(1))))))
shadow_levels = $(subst s,,$(filter s%,$(subst ., ,$(subst _, ,$(subst shadow2_,,$(1))))))
shadow2_defns = -DGUEST_PAGING_LEVELS=$(call guest_levels,$(1)) \
-DSHADOW_PAGING_LEVELS=$(call shadow_levels,$(1))
shadow2_%.o: shadow2.c $(HDRS) Makefile
$(CC) $(CFLAGS) $(call shadow2_defns,$(@F)) -c $< -o $@
obj-$(crash_debug) += gdbstub.o
$(TARGET): $(TARGET)-syms boot/mkelf32
@@ -86,9 +70,6 @@ xen.lds: $(TARGET_SUBARCH)/xen.lds.S $(HDRS)
boot/mkelf32: boot/mkelf32.c
$(HOSTCC) $(HOSTCFLAGS) -o $@ $<
shadow_guest32.o: shadow.c
shadow_guest32pae.o: shadow.c
.PHONY: clean
clean::
rm -f asm-offsets.s xen.lds boot/*.o boot/*~ boot/core boot/mkelf32
+22 -22
View File
@@ -200,12 +200,12 @@ int arch_domain_create(struct domain *d)
#endif /* __x86_64__ */
shadow2_lock_init(d);
for ( i = 0; i <= SHADOW2_MAX_ORDER; i++ )
INIT_LIST_HEAD(&d->arch.shadow2.freelists[i]);
INIT_LIST_HEAD(&d->arch.shadow2.p2m_freelist);
INIT_LIST_HEAD(&d->arch.shadow2.p2m_inuse);
INIT_LIST_HEAD(&d->arch.shadow2.toplevel_shadows);
shadow_lock_init(d);
for ( i = 0; i <= SHADOW_MAX_ORDER; i++ )
INIT_LIST_HEAD(&d->arch.shadow.freelists[i]);
INIT_LIST_HEAD(&d->arch.shadow.p2m_freelist);
INIT_LIST_HEAD(&d->arch.shadow.p2m_inuse);
INIT_LIST_HEAD(&d->arch.shadow.toplevel_shadows);
if ( !is_idle_domain(d) )
{
@@ -236,7 +236,7 @@ int arch_domain_create(struct domain *d)
void arch_domain_destroy(struct domain *d)
{
shadow2_final_teardown(d);
shadow_final_teardown(d);
free_xenheap_pages(
d->arch.mm_perdomain_pt,
@@ -342,10 +342,10 @@ int arch_set_info_guest(
}
}
/* Shadow2: make sure the domain has enough shadow memory to
/* Shadow: make sure the domain has enough shadow memory to
* boot another vcpu */
if ( shadow2_mode_enabled(d)
&& d->arch.shadow2.total_pages < shadow2_min_acceptable_pages(d) )
if ( shadow_mode_enabled(d)
&& d->arch.shadow.total_pages < shadow_min_acceptable_pages(d) )
{
destroy_gdt(v);
return -ENOMEM;
@@ -357,8 +357,8 @@ int arch_set_info_guest(
/* Don't redo final setup */
set_bit(_VCPUF_initialised, &v->vcpu_flags);
if ( shadow2_mode_enabled(d) )
shadow2_update_paging_modes(v);
if ( shadow_mode_enabled(d) )
shadow_update_paging_modes(v);
update_cr3(v);
@@ -936,11 +936,11 @@ void domain_relinquish_resources(struct domain *d)
for_each_vcpu ( d, v )
{
/* Drop ref to guest_table (from new_guest_cr3(), svm/vmx cr3 handling,
* or sh2_update_paging_modes()) */
* or sh_update_paging_modes()) */
pfn = pagetable_get_pfn(v->arch.guest_table);
if ( pfn != 0 )
{
if ( shadow2_mode_refcounts(d) )
if ( shadow_mode_refcounts(d) )
put_page(mfn_to_page(pfn));
else
put_page_and_type(mfn_to_page(pfn));
@@ -962,7 +962,7 @@ void domain_relinquish_resources(struct domain *d)
hvm_relinquish_guest_resources(d);
/* Tear down shadow mode stuff. */
shadow2_teardown(d);
shadow_teardown(d);
/*
* Relinquish GDT mappings. No need for explicit unmapping of the LDT as
@@ -981,18 +981,18 @@ void domain_relinquish_resources(struct domain *d)
void arch_dump_domain_info(struct domain *d)
{
if ( shadow2_mode_enabled(d) )
if ( shadow_mode_enabled(d) )
{
printk(" shadow2 mode: ");
if ( d->arch.shadow2.mode & SHM2_enable )
printk(" shadow mode: ");
if ( d->arch.shadow.mode & SHM2_enable )
printk("enabled ");
if ( shadow2_mode_refcounts(d) )
if ( shadow_mode_refcounts(d) )
printk("refcounts ");
if ( shadow2_mode_log_dirty(d) )
if ( shadow_mode_log_dirty(d) )
printk("log_dirty ");
if ( shadow2_mode_translate(d) )
if ( shadow_mode_translate(d) )
printk("translate ");
if ( shadow2_mode_external(d) )
if ( shadow_mode_external(d) )
printk("external ");
printk("\n");
}
+4 -4
View File
@@ -679,8 +679,8 @@ int construct_dom0(struct domain *d,
(void)alloc_vcpu(d, i, i);
/* Set up CR3 value for write_ptbase */
if ( shadow2_mode_enabled(v->domain) )
shadow2_update_paging_modes(v);
if ( shadow_mode_enabled(v->domain) )
shadow_update_paging_modes(v);
else
update_cr3(v);
@@ -791,8 +791,8 @@ int construct_dom0(struct domain *d,
new_thread(v, dsi.v_kernentry, vstack_end, vstartinfo_start);
if ( opt_dom0_shadow )
if ( shadow2_test_enable(d) == 0 )
shadow2_update_paging_modes(v);
if ( shadow_test_enable(d) == 0 )
shadow_update_paging_modes(v);
if ( supervisor_mode_kernel )
{
+1 -1
View File
@@ -39,7 +39,7 @@ long arch_do_domctl(
d = find_domain_by_id(domctl->domain);
if ( d != NULL )
{
ret = shadow2_domctl(d, &domctl->u.shadow_op, u_domctl);
ret = shadow_domctl(d, &domctl->u.shadow_op, u_domctl);
put_domain(d);
copy_to_guest(u_domctl, domctl, 1);
}
+3 -3
View File
@@ -384,8 +384,8 @@ int hvm_copy(void *buf, unsigned long vaddr, int size, int dir)
if (count > size)
count = size;
gfn = shadow2_gva_to_gfn(v, vaddr);
mfn = mfn_x(sh2_vcpu_gfn_to_mfn(v, gfn));
gfn = shadow_gva_to_gfn(v, vaddr);
mfn = mfn_x(sh_vcpu_gfn_to_mfn(v, gfn));
if (mfn == INVALID_MFN)
return 0;
@@ -539,7 +539,7 @@ void hvm_do_hypercall(struct cpu_user_regs *pregs)
return;
}
if ( current->arch.shadow2.mode->guest_levels == 4 )
if ( current->arch.shadow.mode->guest_levels == 4 )
{
pregs->rax = hvm_hypercall64_table[pregs->rax](pregs->rdi,
pregs->rsi,
+2 -2
View File
@@ -721,7 +721,7 @@ void send_pio_req(struct cpu_user_regs *regs, unsigned long port,
if (pvalid) {
if (hvm_paging_enabled(current))
p->u.data = shadow2_gva_to_gpa(current, value);
p->u.data = shadow_gva_to_gpa(current, value);
else
p->u.pdata = (void *) value; /* guest VA == guest PA */
} else
@@ -771,7 +771,7 @@ void send_mmio_req(
if (pvalid) {
if (hvm_paging_enabled(v))
p->u.data = shadow2_gva_to_gpa(v, value);
p->u.data = shadow_gva_to_gpa(v, value);
else
p->u.pdata = (void *) value; /* guest VA == guest PA */
} else
+14 -14
View File
@@ -29,7 +29,7 @@
#include <xen/domain_page.h>
#include <asm/current.h>
#include <asm/io.h>
#include <asm/shadow2.h>
#include <asm/shadow.h>
#include <asm/regs.h>
#include <asm/cpufeature.h>
#include <asm/processor.h>
@@ -746,10 +746,10 @@ static void svm_final_setup_guest(struct vcpu *v)
if ( v != d->vcpu[0] )
return;
if ( !shadow2_mode_external(d) )
if ( !shadow_mode_external(d) )
{
DPRINTK("Can't init HVM for dom %u vcpu %u: "
"not in shadow2 external mode\n", d->domain_id, v->vcpu_id);
"not in shadow external mode\n", d->domain_id, v->vcpu_id);
domain_crash(d);
}
@@ -914,7 +914,7 @@ static int svm_do_page_fault(unsigned long va, struct cpu_user_regs *regs)
va, eip, (unsigned long)regs->error_code);
//#endif
result = shadow2_fault(va, regs);
result = shadow_fault(va, regs);
if( result ) {
/* Let's make sure that the Guest TLB is flushed */
@@ -1562,7 +1562,7 @@ static int svm_set_cr0(unsigned long value)
v->arch.guest_table = pagetable_from_pfn(mfn);
if ( old_base_mfn )
put_page(mfn_to_page(old_base_mfn));
shadow2_update_paging_modes(v);
shadow_update_paging_modes(v);
HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx",
(unsigned long) (mfn << PAGE_SHIFT));
@@ -1588,14 +1588,14 @@ static int svm_set_cr0(unsigned long value)
svm_inject_exception(v, TRAP_gp_fault, 1, 0);
return 0;
}
shadow2_update_paging_modes(v);
shadow_update_paging_modes(v);
vmcb->cr3 = v->arch.hvm_vcpu.hw_cr3;
set_bit(ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags);
}
else if ( (value & (X86_CR0_PE | X86_CR0_PG)) == X86_CR0_PE )
{
/* we should take care of this kind of situation */
shadow2_update_paging_modes(v);
shadow_update_paging_modes(v);
vmcb->cr3 = v->arch.hvm_vcpu.hw_cr3;
set_bit(ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags);
}
@@ -1706,7 +1706,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);
shadow2_update_cr3(v);
shadow_update_cr3(v);
}
else
{
@@ -1771,7 +1771,7 @@ static int mov_to_cr(int gpreg, int cr, struct cpu_user_regs *regs)
v->arch.guest_table = pagetable_from_pfn(mfn);
if ( old_base_mfn )
put_page(mfn_to_page(old_base_mfn));
shadow2_update_paging_modes(v);
shadow_update_paging_modes(v);
HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx",
(unsigned long) (mfn << PAGE_SHIFT));
@@ -1808,7 +1808,7 @@ static int mov_to_cr(int gpreg, int cr, struct cpu_user_regs *regs)
if ((old_cr ^ value) & (X86_CR4_PSE | X86_CR4_PGE | X86_CR4_PAE))
{
set_bit(ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags);
shadow2_update_paging_modes(v);
shadow_update_paging_modes(v);
}
break;
}
@@ -2149,7 +2149,7 @@ void svm_handle_invlpg(const short invlpga, struct cpu_user_regs *regs)
/* Overkill, we may not this */
set_bit(ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags);
shadow2_invlpg(v, g_vaddr);
shadow_invlpg(v, g_vaddr);
}
@@ -2520,7 +2520,7 @@ void walk_shadow_and_guest_pt(unsigned long gva)
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
unsigned long gpa;
gpa = shadow2_gva_to_gpa(current, gva);
gpa = shadow_gva_to_gpa(current, gva);
printk( "gva = %lx, gpa=%lx, gCR3=%x\n", gva, gpa, (u32)vmcb->cr3 );
if( !svm_paging_enabled(v) || mmio_space(gpa) )
return;
@@ -2591,7 +2591,7 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs regs)
if (svm_dbg_on && exit_reason == VMEXIT_EXCEPTION_PF)
{
if (svm_paging_enabled(v) &&
!mmio_space(shadow2_gva_to_gpa(current, vmcb->exitinfo2)))
!mmio_space(shadow_gva_to_gpa(current, vmcb->exitinfo2)))
{
printk("I%08ld,ExC=%s(%d),IP=%x:%llx,"
"I1=%llx,I2=%llx,INT=%llx, "
@@ -2601,7 +2601,7 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs regs)
(unsigned long long) vmcb->exitinfo1,
(unsigned long long) vmcb->exitinfo2,
(unsigned long long) vmcb->exitintinfo.bytes,
(unsigned long long) shadow2_gva_to_gpa(current, vmcb->exitinfo2));
(unsigned long long) shadow_gva_to_gpa(current, vmcb->exitinfo2));
}
else
{
+2 -2
View File
@@ -35,7 +35,7 @@
#include <xen/event.h>
#include <xen/kernel.h>
#include <xen/keyhandler.h>
#include <asm/shadow2.h>
#include <asm/shadow.h>
static int vmcs_size;
static int vmcs_order;
@@ -272,7 +272,7 @@ static void vmx_do_launch(struct vcpu *v)
error |= __vmwrite(GUEST_TR_BASE, 0);
error |= __vmwrite(GUEST_TR_LIMIT, 0xff);
shadow2_update_paging_modes(v);
shadow_update_paging_modes(v);
printk("%s(): GUEST_CR3<=%08lx, HOST_CR3<=%08lx\n",
__func__, v->arch.hvm_vcpu.hw_cr3, v->arch.cr3);
__vmwrite(GUEST_CR3, v->arch.hvm_vcpu.hw_cr3);
+10 -10
View File
@@ -40,7 +40,7 @@
#include <asm/hvm/vmx/vmx.h>
#include <asm/hvm/vmx/vmcs.h>
#include <asm/hvm/vmx/cpu.h>
#include <asm/shadow2.h>
#include <asm/shadow.h>
#include <public/sched.h>
#include <public/hvm/ioreq.h>
#include <asm/hvm/vpic.h>
@@ -66,10 +66,10 @@ static int vmx_initialize_guest_resources(struct vcpu *v)
if ( v->vcpu_id != 0 )
return 1;
if ( !shadow2_mode_external(d) )
if ( !shadow_mode_external(d) )
{
DPRINTK("Can't init HVM for dom %u vcpu %u: "
"not in shadow2 external mode\n",
"not in shadow external mode\n",
d->domain_id, v->vcpu_id);
domain_crash(d);
}
@@ -865,7 +865,7 @@ static int vmx_do_page_fault(unsigned long va, struct cpu_user_regs *regs)
}
#endif
result = shadow2_fault(va, regs);
result = shadow_fault(va, regs);
TRACE_VMEXIT (2,result);
#if 0
@@ -1039,7 +1039,7 @@ static void vmx_vmexit_do_invlpg(unsigned long va)
* We do the safest things first, then try to update the shadow
* copying from guest
*/
shadow2_invlpg(v, va);
shadow_invlpg(v, va);
}
@@ -1301,7 +1301,7 @@ vmx_world_restore(struct vcpu *v, struct vmx_assist_context *c)
skip_cr3:
shadow2_update_paging_modes(v);
shadow_update_paging_modes(v);
if (!vmx_paging_enabled(v))
HVM_DBG_LOG(DBG_LEVEL_VMMU, "switching to vmxassist. use phys table");
else
@@ -1504,7 +1504,7 @@ static int vmx_set_cr0(unsigned long value)
v->arch.guest_table = pagetable_from_pfn(mfn);
if (old_base_mfn)
put_page(mfn_to_page(old_base_mfn));
shadow2_update_paging_modes(v);
shadow_update_paging_modes(v);
HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx",
(unsigned long) (mfn << PAGE_SHIFT));
@@ -1577,7 +1577,7 @@ static int vmx_set_cr0(unsigned long value)
else if ( (value & (X86_CR0_PE | X86_CR0_PG)) == X86_CR0_PE )
{
__vmwrite(GUEST_CR3, v->arch.hvm_vcpu.hw_cr3);
shadow2_update_paging_modes(v);
shadow_update_paging_modes(v);
}
return 1;
@@ -1662,7 +1662,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);
shadow2_update_cr3(v);
shadow_update_cr3(v);
} else {
/*
* If different, make a shadow. Check if the PDBR is valid
@@ -1755,7 +1755,7 @@ static int mov_to_cr(int gp, int cr, struct cpu_user_regs *regs)
* all TLB entries except global entries.
*/
if ( (old_cr ^ value) & (X86_CR4_PSE | X86_CR4_PGE | X86_CR4_PAE) )
shadow2_update_paging_modes(v);
shadow_update_paging_modes(v);
break;
}
default:
+68 -68
View File
@@ -454,12 +454,12 @@ int map_ldt_shadow_page(unsigned int off)
res = get_page_and_type(mfn_to_page(mfn), d, PGT_ldt_page);
if ( !res && unlikely(shadow2_mode_refcounts(d)) )
if ( !res && unlikely(shadow_mode_refcounts(d)) )
{
shadow2_lock(d);
shadow2_remove_write_access(d->vcpu[0], _mfn(mfn), 0, 0);
shadow_lock(d);
shadow_remove_write_access(d->vcpu[0], _mfn(mfn), 0, 0);
res = get_page_and_type(mfn_to_page(mfn), d, PGT_ldt_page);
shadow2_unlock(d);
shadow_unlock(d);
}
if ( unlikely(!res) )
@@ -527,7 +527,7 @@ get_linear_pagetable(
struct page_info *page;
unsigned long pfn;
ASSERT( !shadow2_mode_refcounts(d) );
ASSERT( !shadow_mode_refcounts(d) );
if ( (root_get_flags(re) & _PAGE_RW) )
{
@@ -602,12 +602,12 @@ get_page_from_l1e(
d = dom_io;
}
/* Foreign mappings into guests in shadow2 external mode don't
/* Foreign mappings into guests in shadow external mode don't
* contribute to writeable mapping refcounts. (This allows the
* qemu-dm helper process in dom0 to map the domain's memory without
* messing up the count of "real" writable mappings.) */
okay = (((l1e_get_flags(l1e) & _PAGE_RW) &&
!(unlikely(shadow2_mode_external(d) && (d != current->domain))))
!(unlikely(shadow_mode_external(d) && (d != current->domain))))
? get_page_and_type(page, d, PGT_writable_page)
: get_page(page, d));
if ( !okay )
@@ -771,9 +771,9 @@ void put_page_from_l1e(l1_pgentry_t l1e, struct domain *d)
}
/* Remember we didn't take a type-count of foreign writable mappings
* to shadow2 external domains */
* to shadow external domains */
if ( (l1e_get_flags(l1e) & _PAGE_RW) &&
!(unlikely((e != d) && shadow2_mode_external(e))) )
!(unlikely((e != d) && shadow_mode_external(e))) )
{
put_page_and_type(page);
}
@@ -830,7 +830,7 @@ static int alloc_l1_table(struct page_info *page)
l1_pgentry_t *pl1e;
int i;
ASSERT(!shadow2_mode_refcounts(d));
ASSERT(!shadow_mode_refcounts(d));
pl1e = map_domain_page(pfn);
@@ -883,7 +883,7 @@ static int create_pae_xen_mappings(l3_pgentry_t *pl3e)
* a. alloc_l3_table() calls this function and this check will fail
* b. mod_l3_entry() disallows updates to slot 3 in an existing table
*
* XXX -- this needs revisiting for shadow2_mode_refcount()==true...
* XXX -- this needs revisiting for shadow_mode_refcount()==true...
*/
page = l3e_get_page(l3e3);
BUG_ON(page->u.inuse.type_info & PGT_pinned);
@@ -1007,7 +1007,7 @@ static int alloc_l2_table(struct page_info *page, unsigned long type)
l2_pgentry_t *pl2e;
int i;
ASSERT(!shadow2_mode_refcounts(d));
ASSERT(!shadow_mode_refcounts(d));
pl2e = map_domain_page(pfn);
@@ -1059,7 +1059,7 @@ static int alloc_l3_table(struct page_info *page, unsigned long type)
l3_pgentry_t *pl3e;
int i;
ASSERT(!shadow2_mode_refcounts(d));
ASSERT(!shadow_mode_refcounts(d));
#ifdef CONFIG_X86_PAE
/*
@@ -1120,7 +1120,7 @@ static int alloc_l4_table(struct page_info *page, unsigned long type)
unsigned long vaddr;
int i;
ASSERT(!shadow2_mode_refcounts(d));
ASSERT(!shadow_mode_refcounts(d));
for ( i = 0; i < L4_PAGETABLE_ENTRIES; i++ )
{
@@ -1234,8 +1234,8 @@ static inline int update_l1e(l1_pgentry_t *pl1e,
struct vcpu *v)
{
int rv = 1;
if ( unlikely(shadow2_mode_enabled(v->domain)) )
shadow2_lock(v->domain);
if ( unlikely(shadow_mode_enabled(v->domain)) )
shadow_lock(v->domain);
#ifndef PTE_UPDATE_WITH_CMPXCHG
rv = (!__copy_to_user(pl1e, &nl1e, sizeof(nl1e)));
#else
@@ -1266,10 +1266,10 @@ static inline int update_l1e(l1_pgentry_t *pl1e,
}
}
#endif
if ( unlikely(shadow2_mode_enabled(v->domain)) )
if ( unlikely(shadow_mode_enabled(v->domain)) )
{
shadow2_validate_guest_entry(v, _mfn(gl1mfn), pl1e);
shadow2_unlock(v->domain);
shadow_validate_guest_entry(v, _mfn(gl1mfn), pl1e);
shadow_unlock(v->domain);
}
return rv;
}
@@ -1339,13 +1339,13 @@ static int mod_l1_entry(l1_pgentry_t *pl1e, l1_pgentry_t nl1e,
#endif
#define UPDATE_ENTRY(_t,_p,_o,_n,_m) ({ \
int rv; \
if ( unlikely(shadow2_mode_enabled(current->domain)) ) \
shadow2_lock(current->domain); \
if ( unlikely(shadow_mode_enabled(current->domain)) ) \
shadow_lock(current->domain); \
rv = _UPDATE_ENTRY(_t, _p, _o, _n); \
if ( unlikely(shadow2_mode_enabled(current->domain)) ) \
if ( unlikely(shadow_mode_enabled(current->domain)) ) \
{ \
shadow2_validate_guest_entry(current, _mfn(_m), (_p)); \
shadow2_unlock(current->domain); \
shadow_validate_guest_entry(current, _mfn(_m), (_p)); \
shadow_unlock(current->domain); \
} \
rv; \
})
@@ -1581,21 +1581,21 @@ void free_page_type(struct page_info *page, unsigned long type)
*/
this_cpu(percpu_mm_info).deferred_ops |= DOP_FLUSH_ALL_TLBS;
if ( unlikely(shadow2_mode_enabled(owner)
&& !shadow2_lock_is_acquired(owner)) )
if ( unlikely(shadow_mode_enabled(owner)
&& !shadow_lock_is_acquired(owner)) )
{
/* Raw page tables are rewritten during save/restore. */
if ( !shadow2_mode_translate(owner) )
if ( !shadow_mode_translate(owner) )
mark_dirty(owner, page_to_mfn(page));
if ( shadow2_mode_refcounts(owner) )
if ( shadow_mode_refcounts(owner) )
return;
gmfn = mfn_to_gmfn(owner, page_to_mfn(page));
ASSERT(VALID_M2P(gmfn));
shadow2_lock(owner);
shadow2_remove_all_shadows(owner->vcpu[0], _mfn(gmfn));
shadow2_unlock(owner);
shadow_lock(owner);
shadow_remove_all_shadows(owner->vcpu[0], _mfn(gmfn));
shadow_unlock(owner);
}
}
@@ -1760,7 +1760,7 @@ int get_page_type(struct page_info *page, unsigned long type)
#endif
/* Fixme: add code to propagate va_unknown to subtables. */
if ( ((type & PGT_type_mask) >= PGT_l2_page_table) &&
!shadow2_mode_refcounts(page_get_owner(page)) )
!shadow_mode_refcounts(page_get_owner(page)) )
return 0;
/* This table is possibly mapped at multiple locations. */
nx &= ~PGT_va_mask;
@@ -1810,7 +1810,7 @@ int new_guest_cr3(unsigned long mfn)
if ( hvm_guest(v) && !hvm_paging_enabled(v) )
domain_crash_synchronous();
if ( shadow2_mode_refcounts(d) )
if ( shadow_mode_refcounts(d) )
{
okay = get_page_from_pagenr(mfn, d);
if ( unlikely(!okay) )
@@ -1858,7 +1858,7 @@ int new_guest_cr3(unsigned long mfn)
if ( likely(old_base_mfn != 0) )
{
if ( shadow2_mode_refcounts(d) )
if ( shadow_mode_refcounts(d) )
put_page(mfn_to_page(old_base_mfn));
else
put_page_and_type(mfn_to_page(old_base_mfn));
@@ -2043,7 +2043,7 @@ int do_mmuext_op(
type = PGT_root_page_table;
pin_page:
if ( shadow2_mode_refcounts(FOREIGNDOM) )
if ( shadow_mode_refcounts(FOREIGNDOM) )
break;
okay = get_page_and_type_from_pagenr(mfn, type, FOREIGNDOM);
@@ -2065,7 +2065,7 @@ int do_mmuext_op(
break;
case MMUEXT_UNPIN_TABLE:
if ( shadow2_mode_refcounts(d) )
if ( shadow_mode_refcounts(d) )
break;
if ( unlikely(!(okay = get_page_from_pagenr(mfn, d))) )
@@ -2078,11 +2078,11 @@ int do_mmuext_op(
{
put_page_and_type(page);
put_page(page);
if ( shadow2_mode_enabled(d) )
if ( shadow_mode_enabled(d) )
{
shadow2_lock(d);
shadow2_remove_all_shadows(v, _mfn(mfn));
shadow2_unlock(d);
shadow_lock(d);
shadow_remove_all_shadows(v, _mfn(mfn));
shadow_unlock(d);
}
}
else
@@ -2125,8 +2125,8 @@ int do_mmuext_op(
break;
case MMUEXT_INVLPG_LOCAL:
if ( !shadow2_mode_enabled(d)
|| shadow2_invlpg(v, op.arg1.linear_addr) != 0 )
if ( !shadow_mode_enabled(d)
|| shadow_invlpg(v, op.arg1.linear_addr) != 0 )
local_flush_tlb_one(op.arg1.linear_addr);
break;
@@ -2173,7 +2173,7 @@ int do_mmuext_op(
unsigned long ptr = op.arg1.linear_addr;
unsigned long ents = op.arg2.nr_ents;
if ( shadow2_mode_external(d) )
if ( shadow_mode_external(d) )
{
MEM_LOG("ignoring SET_LDT hypercall from external "
"domain %u", d->domain_id);
@@ -2319,7 +2319,7 @@ int do_mmu_update(
case PGT_l3_page_table:
case PGT_l4_page_table:
{
if ( shadow2_mode_refcounts(d) )
if ( shadow_mode_refcounts(d) )
{
DPRINTK("mmu update on shadow-refcounted domain!");
break;
@@ -2372,16 +2372,16 @@ int do_mmu_update(
if ( unlikely(!get_page_type(page, PGT_writable_page)) )
break;
if ( unlikely(shadow2_mode_enabled(d)) )
shadow2_lock(d);
if ( unlikely(shadow_mode_enabled(d)) )
shadow_lock(d);
*(intpte_t *)va = req.val;
okay = 1;
if ( unlikely(shadow2_mode_enabled(d)) )
if ( unlikely(shadow_mode_enabled(d)) )
{
shadow2_validate_guest_entry(v, _mfn(mfn), va);
shadow2_unlock(d);
shadow_validate_guest_entry(v, _mfn(mfn), va);
shadow_unlock(d);
}
put_page_type(page);
@@ -2405,8 +2405,8 @@ int do_mmu_update(
break;
}
if ( shadow2_mode_translate(FOREIGNDOM) )
shadow2_guest_physmap_add_page(FOREIGNDOM, gpfn, mfn);
if ( shadow_mode_translate(FOREIGNDOM) )
shadow_guest_physmap_add_page(FOREIGNDOM, gpfn, mfn);
else
set_gpfn_from_mfn(mfn, gpfn);
okay = 1;
@@ -2492,7 +2492,7 @@ static int create_grant_pte_mapping(
goto failed;
}
if ( !shadow2_mode_refcounts(d) )
if ( !shadow_mode_refcounts(d) )
put_page_from_l1e(ol1e, d);
put_page_type(page);
@@ -2590,7 +2590,7 @@ static int create_grant_va_mapping(
l2e_get_pfn(__linear_l2_table[l2_linear_offset(va)]), v) )
return GNTST_general_error;
if ( !shadow2_mode_refcounts(d) )
if ( !shadow_mode_refcounts(d) )
put_page_from_l1e(ol1e, d);
return GNTST_okay;
@@ -2714,10 +2714,10 @@ int do_update_va_mapping(unsigned long va, u64 val64,
perfc_incrc(calls_to_update_va);
if ( unlikely(!__addr_ok(va) && !shadow2_mode_external(d)) )
if ( unlikely(!__addr_ok(va) && !shadow_mode_external(d)) )
return -EINVAL;
if ( unlikely(shadow2_mode_refcounts(d)) )
if ( unlikely(shadow_mode_refcounts(d)) )
{
DPRINTK("Grant op on a shadow-refcounted domain\n");
return -EINVAL;
@@ -2725,11 +2725,11 @@ int do_update_va_mapping(unsigned long va, u64 val64,
LOCK_BIGLOCK(d);
if ( likely(rc == 0) && unlikely(shadow2_mode_enabled(d)) )
if ( likely(rc == 0) && unlikely(shadow_mode_enabled(d)) )
{
if ( unlikely(this_cpu(percpu_mm_info).foreign &&
(shadow2_mode_translate(d) ||
shadow2_mode_translate(
(shadow_mode_translate(d) ||
shadow_mode_translate(
this_cpu(percpu_mm_info).foreign))) )
{
/*
@@ -2770,8 +2770,8 @@ int do_update_va_mapping(unsigned long va, u64 val64,
switch ( (bmap_ptr = flags & ~UVMF_FLUSHTYPE_MASK) )
{
case UVMF_LOCAL:
if ( !shadow2_mode_enabled(d)
|| (shadow2_invlpg(current, va) != 0) )
if ( !shadow_mode_enabled(d)
|| (shadow_invlpg(current, va) != 0) )
local_flush_tlb_one(va);
break;
case UVMF_ALL:
@@ -3006,7 +3006,7 @@ long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg)
break;
}
if ( !shadow2_mode_translate(d) || (mfn == 0) )
if ( !shadow_mode_translate(d) || (mfn == 0) )
{
put_domain(d);
return -EINVAL;
@@ -3196,21 +3196,21 @@ static int ptwr_emulated_update(
pl1e = (l1_pgentry_t *)((unsigned long)pl1e + (addr & ~PAGE_MASK));
if ( do_cmpxchg )
{
if ( shadow2_mode_enabled(d) )
shadow2_lock(d);
if ( shadow_mode_enabled(d) )
shadow_lock(d);
ol1e = l1e_from_intpte(old);
if ( cmpxchg((intpte_t *)pl1e, old, val) != old )
{
if ( shadow2_mode_enabled(d) )
shadow2_unlock(d);
if ( shadow_mode_enabled(d) )
shadow_unlock(d);
unmap_domain_page(pl1e);
put_page_from_l1e(nl1e, d);
return X86EMUL_CMPXCHG_FAILED;
}
if ( unlikely(shadow2_mode_enabled(v->domain)) )
if ( unlikely(shadow_mode_enabled(v->domain)) )
{
shadow2_validate_guest_entry(v, _mfn(page_to_mfn(page)), pl1e);
shadow2_unlock(v->domain);
shadow_validate_guest_entry(v, _mfn(page_to_mfn(page)), pl1e);
shadow_unlock(v->domain);
}
}
else
+1
View File
@@ -0,0 +1 @@
subdir-y += shadow
+15
View File
@@ -0,0 +1,15 @@
ifneq ($(pae),n)
obj-$(x86_32) += common.o g2_on_s3.o g3_on_s3.o
else
obj-$(x86_32) += common.o g2_on_s2.o
endif
obj-$(x86_64) += common.o g4_on_s4.o g3_on_s3.o g2_on_s3.o
guest_levels = $(subst g,,$(filter g%,$(subst ., ,$(subst _, ,$(1)))))
shadow_levels = $(subst s,,$(filter s%,$(subst ., ,$(subst _, ,$(1)))))
shadow_defns = -DGUEST_PAGING_LEVELS=$(call guest_levels,$(1)) \
-DSHADOW_PAGING_LEVELS=$(call shadow_levels,$(1))
g%.o: multi.c $(HDRS) Makefile
$(CC) $(CFLAGS) $(call shadow_defns,$(@F)) -c $< -o $@
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -1,7 +1,7 @@
/******************************************************************************
* arch/x86/shadow2-multi.h
* arch/x86/mm/shadow/multi.h
*
* Shadow2 declarations which will be multiply compiled.
* Shadow declarations which will be multiply compiled.
* Parts of this code are Copyright (c) 2006 by XenSource Inc.
* Parts of this code are Copyright (c) 2006 by Michael A Fetterman
* Parts based on earlier work by Michael A Fetterman, Ian Pratt et al.
@@ -22,95 +22,95 @@
*/
extern int
SHADOW2_INTERNAL_NAME(sh2_map_and_validate_gl1e, SHADOW_LEVELS, GUEST_LEVELS)(
SHADOW_INTERNAL_NAME(sh_map_and_validate_gl1e, SHADOW_LEVELS, GUEST_LEVELS)(
struct vcpu *v, mfn_t gl1mfn, void *new_gl1p, u32 size);
extern int
SHADOW2_INTERNAL_NAME(sh2_map_and_validate_gl2e, SHADOW_LEVELS, GUEST_LEVELS)(
SHADOW_INTERNAL_NAME(sh_map_and_validate_gl2e, SHADOW_LEVELS, GUEST_LEVELS)(
struct vcpu *v, mfn_t gl2mfn, void *new_gl2p, u32 size);
extern int
SHADOW2_INTERNAL_NAME(sh2_map_and_validate_gl2he, SHADOW_LEVELS, GUEST_LEVELS)(
SHADOW_INTERNAL_NAME(sh_map_and_validate_gl2he, SHADOW_LEVELS, GUEST_LEVELS)(
struct vcpu *v, mfn_t gl2mfn, void *new_gl2p, u32 size);
extern int
SHADOW2_INTERNAL_NAME(sh2_map_and_validate_gl3e, SHADOW_LEVELS, GUEST_LEVELS)(
SHADOW_INTERNAL_NAME(sh_map_and_validate_gl3e, SHADOW_LEVELS, GUEST_LEVELS)(
struct vcpu *v, mfn_t gl3mfn, void *new_gl3p, u32 size);
extern int
SHADOW2_INTERNAL_NAME(sh2_map_and_validate_gl4e, SHADOW_LEVELS, GUEST_LEVELS)(
SHADOW_INTERNAL_NAME(sh_map_and_validate_gl4e, SHADOW_LEVELS, GUEST_LEVELS)(
struct vcpu *v, mfn_t gl4mfn, void *new_gl4p, u32 size);
extern void
SHADOW2_INTERNAL_NAME(sh2_destroy_l1_shadow, SHADOW_LEVELS, GUEST_LEVELS)(
SHADOW_INTERNAL_NAME(sh_destroy_l1_shadow, SHADOW_LEVELS, GUEST_LEVELS)(
struct vcpu *v, mfn_t smfn);
extern void
SHADOW2_INTERNAL_NAME(sh2_destroy_l2_shadow, SHADOW_LEVELS, GUEST_LEVELS)(
SHADOW_INTERNAL_NAME(sh_destroy_l2_shadow, SHADOW_LEVELS, GUEST_LEVELS)(
struct vcpu *v, mfn_t smfn);
extern void
SHADOW2_INTERNAL_NAME(sh2_destroy_l3_shadow, SHADOW_LEVELS, GUEST_LEVELS)(
SHADOW_INTERNAL_NAME(sh_destroy_l3_shadow, SHADOW_LEVELS, GUEST_LEVELS)(
struct vcpu *v, mfn_t smfn);
extern void
SHADOW2_INTERNAL_NAME(sh2_destroy_l4_shadow, SHADOW_LEVELS, GUEST_LEVELS)(
SHADOW_INTERNAL_NAME(sh_destroy_l4_shadow, SHADOW_LEVELS, GUEST_LEVELS)(
struct vcpu *v, mfn_t smfn);
extern void
SHADOW2_INTERNAL_NAME(sh2_unpin_all_l3_subshadows, 3, 3)
SHADOW_INTERNAL_NAME(sh_unpin_all_l3_subshadows, 3, 3)
(struct vcpu *v, mfn_t smfn);
extern void
SHADOW2_INTERNAL_NAME(sh2_unhook_32b_mappings, SHADOW_LEVELS, GUEST_LEVELS)
SHADOW_INTERNAL_NAME(sh_unhook_32b_mappings, SHADOW_LEVELS, GUEST_LEVELS)
(struct vcpu *v, mfn_t sl2mfn);
extern void
SHADOW2_INTERNAL_NAME(sh2_unhook_pae_mappings, SHADOW_LEVELS, GUEST_LEVELS)
SHADOW_INTERNAL_NAME(sh_unhook_pae_mappings, SHADOW_LEVELS, GUEST_LEVELS)
(struct vcpu *v, mfn_t sl3mfn);
extern void
SHADOW2_INTERNAL_NAME(sh2_unhook_64b_mappings, SHADOW_LEVELS, GUEST_LEVELS)
SHADOW_INTERNAL_NAME(sh_unhook_64b_mappings, SHADOW_LEVELS, GUEST_LEVELS)
(struct vcpu *v, mfn_t sl4mfn);
extern int
SHADOW2_INTERNAL_NAME(sh2_remove_write_access, SHADOW_LEVELS, GUEST_LEVELS)
SHADOW_INTERNAL_NAME(sh_remove_write_access, SHADOW_LEVELS, GUEST_LEVELS)
(struct vcpu *v, mfn_t sl1mfn, mfn_t readonly_mfn);
extern int
SHADOW2_INTERNAL_NAME(sh2_remove_all_mappings, SHADOW_LEVELS, GUEST_LEVELS)
SHADOW_INTERNAL_NAME(sh_remove_all_mappings, SHADOW_LEVELS, GUEST_LEVELS)
(struct vcpu *v, mfn_t sl1mfn, mfn_t target_mfn);
extern void
SHADOW2_INTERNAL_NAME(sh2_clear_shadow_entry, SHADOW_LEVELS, GUEST_LEVELS)
SHADOW_INTERNAL_NAME(sh_clear_shadow_entry, SHADOW_LEVELS, GUEST_LEVELS)
(struct vcpu *v, void *ep, mfn_t smfn);
extern int
SHADOW2_INTERNAL_NAME(sh2_remove_l1_shadow, SHADOW_LEVELS, GUEST_LEVELS)
SHADOW_INTERNAL_NAME(sh_remove_l1_shadow, SHADOW_LEVELS, GUEST_LEVELS)
(struct vcpu *v, mfn_t sl2mfn, mfn_t sl1mfn);
extern int
SHADOW2_INTERNAL_NAME(sh2_remove_l2_shadow, SHADOW_LEVELS, GUEST_LEVELS)
SHADOW_INTERNAL_NAME(sh_remove_l2_shadow, SHADOW_LEVELS, GUEST_LEVELS)
(struct vcpu *v, mfn_t sl3mfn, mfn_t sl2mfn);
extern int
SHADOW2_INTERNAL_NAME(sh2_remove_l3_shadow, SHADOW_LEVELS, GUEST_LEVELS)
SHADOW_INTERNAL_NAME(sh_remove_l3_shadow, SHADOW_LEVELS, GUEST_LEVELS)
(struct vcpu *v, mfn_t sl4mfn, mfn_t sl3mfn);
#if SHADOW2_AUDIT & SHADOW2_AUDIT_ENTRIES
#if SHADOW_AUDIT & SHADOW_AUDIT_ENTRIES
int
SHADOW2_INTERNAL_NAME(sh2_audit_l1_table, SHADOW_LEVELS, GUEST_LEVELS)
SHADOW_INTERNAL_NAME(sh_audit_l1_table, SHADOW_LEVELS, GUEST_LEVELS)
(struct vcpu *v, mfn_t sl1mfn, mfn_t x);
int
SHADOW2_INTERNAL_NAME(sh2_audit_fl1_table, SHADOW_LEVELS, GUEST_LEVELS)
SHADOW_INTERNAL_NAME(sh_audit_fl1_table, SHADOW_LEVELS, GUEST_LEVELS)
(struct vcpu *v, mfn_t sl1mfn, mfn_t x);
int
SHADOW2_INTERNAL_NAME(sh2_audit_l2_table, SHADOW_LEVELS, GUEST_LEVELS)
SHADOW_INTERNAL_NAME(sh_audit_l2_table, SHADOW_LEVELS, GUEST_LEVELS)
(struct vcpu *v, mfn_t sl2mfn, mfn_t x);
int
SHADOW2_INTERNAL_NAME(sh2_audit_l3_table, SHADOW_LEVELS, GUEST_LEVELS)
SHADOW_INTERNAL_NAME(sh_audit_l3_table, SHADOW_LEVELS, GUEST_LEVELS)
(struct vcpu *v, mfn_t sl3mfn, mfn_t x);
int
SHADOW2_INTERNAL_NAME(sh2_audit_l4_table, SHADOW_LEVELS, GUEST_LEVELS)
SHADOW_INTERNAL_NAME(sh_audit_l4_table, SHADOW_LEVELS, GUEST_LEVELS)
(struct vcpu *v, mfn_t sl4mfn, mfn_t x);
#endif
#if SHADOW_LEVELS == GUEST_LEVELS
extern mfn_t
SHADOW2_INTERNAL_NAME(sh2_make_monitor_table, SHADOW_LEVELS, GUEST_LEVELS)
SHADOW_INTERNAL_NAME(sh_make_monitor_table, SHADOW_LEVELS, GUEST_LEVELS)
(struct vcpu *v);
extern void
SHADOW2_INTERNAL_NAME(sh2_destroy_monitor_table, SHADOW_LEVELS, GUEST_LEVELS)
SHADOW_INTERNAL_NAME(sh_destroy_monitor_table, SHADOW_LEVELS, GUEST_LEVELS)
(struct vcpu *v, mfn_t mmfn);
#endif
extern struct shadow2_paging_mode
SHADOW2_INTERNAL_NAME(sh2_paging_mode, SHADOW_LEVELS, GUEST_LEVELS);
extern struct shadow_paging_mode
SHADOW_INTERNAL_NAME(sh_paging_mode, SHADOW_LEVELS, GUEST_LEVELS);
File renamed without changes.
@@ -1,7 +1,7 @@
/******************************************************************************
* arch/x86/shadow2-private.h
* arch/x86/mm/shadow/private.h
*
* Shadow2 code that is private, and does not need to be multiply compiled.
* Shadow code that is private, and does not need to be multiply compiled.
* Parts of this code are Copyright (c) 2006 by XenSource Inc.
* Parts of this code are Copyright (c) 2006 by Michael A Fetterman
* Parts based on earlier work by Michael A Fetterman, Ian Pratt et al.
@@ -21,8 +21,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _XEN_SHADOW2_PRIVATE_H
#define _XEN_SHADOW2_PRIVATE_H
#ifndef _XEN_SHADOW_PRIVATE_H
#define _XEN_SHADOW_PRIVATE_H
// In order to override the definition of mfn_to_page, we make sure page.h has
// been included...
@@ -140,40 +140,40 @@
/******************************************************************************
* Debug and error-message output
*/
#define SHADOW2_PRINTK(_f, _a...) \
debugtrace_printk("sh2: %s(): " _f, __func__, ##_a)
#define SHADOW2_ERROR(_f, _a...) \
printk("sh2 error: %s(): " _f, __func__, ##_a)
#define SHADOW2_DEBUG(flag, _f, _a...) \
#define SHADOW_PRINTK(_f, _a...) \
debugtrace_printk("sh: %s(): " _f, __func__, ##_a)
#define SHADOW_ERROR(_f, _a...) \
printk("sh error: %s(): " _f, __func__, ##_a)
#define SHADOW_DEBUG(flag, _f, _a...) \
do { \
if (SHADOW2_DEBUG_ ## flag) \
debugtrace_printk("sh2debug: %s(): " _f, __func__, ##_a); \
if (SHADOW_DEBUG_ ## flag) \
debugtrace_printk("shdebug: %s(): " _f, __func__, ##_a); \
} while (0)
// The flags for use with SHADOW2_DEBUG:
#define SHADOW2_DEBUG_PROPAGATE 0
#define SHADOW2_DEBUG_MAKE_SHADOW 0
#define SHADOW2_DEBUG_DESTROY_SHADOW 0
#define SHADOW2_DEBUG_P2M 0
#define SHADOW2_DEBUG_A_AND_D 0
#define SHADOW2_DEBUG_EMULATE 0
#define SHADOW2_DEBUG_LOGDIRTY 1
// The flags for use with SHADOW_DEBUG:
#define SHADOW_DEBUG_PROPAGATE 0
#define SHADOW_DEBUG_MAKE_SHADOW 0
#define SHADOW_DEBUG_DESTROY_SHADOW 0
#define SHADOW_DEBUG_P2M 0
#define SHADOW_DEBUG_A_AND_D 0
#define SHADOW_DEBUG_EMULATE 0
#define SHADOW_DEBUG_LOGDIRTY 1
/******************************************************************************
* Auditing routines
*/
#if SHADOW2_AUDIT & SHADOW2_AUDIT_ENTRIES_FULL
extern void shadow2_audit_tables(struct vcpu *v);
#if SHADOW_AUDIT & SHADOW_AUDIT_ENTRIES_FULL
extern void shadow_audit_tables(struct vcpu *v);
#else
#define shadow2_audit_tables(_v) do {} while(0)
#define shadow_audit_tables(_v) do {} while(0)
#endif
#if SHADOW2_AUDIT & SHADOW2_AUDIT_P2M
extern void shadow2_audit_p2m(struct domain *d);
#if SHADOW_AUDIT & SHADOW_AUDIT_P2M
extern void shadow_audit_p2m(struct domain *d);
#else
#define shadow2_audit_p2m(_d) do {} while(0)
#define shadow_audit_p2m(_d) do {} while(0)
#endif
@@ -185,82 +185,82 @@ extern void shadow2_audit_p2m(struct domain *d);
* path fills in another. When the fault handler finishes, the
* two are compared */
#ifdef SHADOW2_OPTIMIZATION_PARANOIA
#ifdef SHADOW_OPTIMIZATION_PARANOIA
typedef struct shadow2_action_log sh2_log_t;
struct shadow2_action_log {
typedef struct shadow_action_log sh_log_t;
struct shadow_action_log {
paddr_t ad[CONFIG_PAGING_LEVELS]; /* A & D bits propagated here */
paddr_t mmio; /* Address of an mmio operation */
int rv; /* Result of the fault handler */
};
/* There are two logs, one for the fast path, one for the normal path */
enum sh2_log_type { log_slow = 0, log_fast= 1 };
enum sh_log_type { log_slow = 0, log_fast= 1 };
/* Alloc and zero the logs */
static inline void sh2_init_log(struct vcpu *v)
static inline void sh_init_log(struct vcpu *v)
{
if ( unlikely(!v->arch.shadow2.action_log) )
v->arch.shadow2.action_log = xmalloc_array(sh2_log_t, 2);
ASSERT(v->arch.shadow2.action_log);
memset(v->arch.shadow2.action_log, 0, 2 * sizeof (sh2_log_t));
if ( unlikely(!v->arch.shadow.action_log) )
v->arch.shadow.action_log = xmalloc_array(sh_log_t, 2);
ASSERT(v->arch.shadow.action_log);
memset(v->arch.shadow.action_log, 0, 2 * sizeof (sh_log_t));
}
/* Log an A&D-bit update */
static inline void sh2_log_ad(struct vcpu *v, paddr_t e, unsigned int level)
static inline void sh_log_ad(struct vcpu *v, paddr_t e, unsigned int level)
{
v->arch.shadow2.action_log[v->arch.shadow2.action_index].ad[level] = e;
v->arch.shadow.action_log[v->arch.shadow.action_index].ad[level] = e;
}
/* Log an MMIO address */
static inline void sh2_log_mmio(struct vcpu *v, paddr_t m)
static inline void sh_log_mmio(struct vcpu *v, paddr_t m)
{
v->arch.shadow2.action_log[v->arch.shadow2.action_index].mmio = m;
v->arch.shadow.action_log[v->arch.shadow.action_index].mmio = m;
}
/* Log the result */
static inline void sh2_log_rv(struct vcpu *v, int rv)
static inline void sh_log_rv(struct vcpu *v, int rv)
{
v->arch.shadow2.action_log[v->arch.shadow2.action_index].rv = rv;
v->arch.shadow.action_log[v->arch.shadow.action_index].rv = rv;
}
/* Set which mode we're in */
static inline void sh2_set_log_mode(struct vcpu *v, enum sh2_log_type t)
static inline void sh_set_log_mode(struct vcpu *v, enum sh_log_type t)
{
v->arch.shadow2.action_index = t;
v->arch.shadow.action_index = t;
}
/* Know not to take action, because we're only checking the mechanism */
static inline int sh2_take_no_action(struct vcpu *v)
static inline int sh_take_no_action(struct vcpu *v)
{
return (v->arch.shadow2.action_index == log_fast);
return (v->arch.shadow.action_index == log_fast);
}
#else /* Non-paranoid mode: these logs do not exist */
#define sh2_init_log(_v) do { (void)(_v); } while(0)
#define sh2_set_log_mode(_v,_t) do { (void)(_v); } while(0)
#define sh2_log_ad(_v,_e,_l) do { (void)(_v),(void)(_e),(void)(_l); } while (0)
#define sh2_log_mmio(_v,_m) do { (void)(_v),(void)(_m); } while (0)
#define sh2_log_rv(_v,_r) do { (void)(_v),(void)(_r); } while (0)
#define sh2_take_no_action(_v) (((void)(_v)), 0)
#define sh_init_log(_v) do { (void)(_v); } while(0)
#define sh_set_log_mode(_v,_t) do { (void)(_v); } while(0)
#define sh_log_ad(_v,_e,_l) do { (void)(_v),(void)(_e),(void)(_l); } while (0)
#define sh_log_mmio(_v,_m) do { (void)(_v),(void)(_m); } while (0)
#define sh_log_rv(_v,_r) do { (void)(_v),(void)(_r); } while (0)
#define sh_take_no_action(_v) (((void)(_v)), 0)
#endif /* SHADOW2_OPTIMIZATION_PARANOIA */
#endif /* SHADOW_OPTIMIZATION_PARANOIA */
/******************************************************************************
* Macro for dealing with the naming of the internal names of the
* shadow code's external entry points.
*/
#define SHADOW2_INTERNAL_NAME_HIDDEN(name, shadow_levels, guest_levels) \
#define SHADOW_INTERNAL_NAME_HIDDEN(name, shadow_levels, guest_levels) \
name ## __shadow_ ## shadow_levels ## _guest_ ## guest_levels
#define SHADOW2_INTERNAL_NAME(name, shadow_levels, guest_levels) \
SHADOW2_INTERNAL_NAME_HIDDEN(name, shadow_levels, guest_levels)
#define SHADOW_INTERNAL_NAME(name, shadow_levels, guest_levels) \
SHADOW_INTERNAL_NAME_HIDDEN(name, shadow_levels, guest_levels)
#if CONFIG_PAGING_LEVELS == 2
#define GUEST_LEVELS 2
#define SHADOW_LEVELS 2
#include <asm/shadow2-multi.h>
#include "multi.h"
#undef GUEST_LEVELS
#undef SHADOW_LEVELS
#endif /* CONFIG_PAGING_LEVELS == 2 */
@@ -268,13 +268,13 @@ static inline int sh2_take_no_action(struct vcpu *v)
#if CONFIG_PAGING_LEVELS == 3
#define GUEST_LEVELS 2
#define SHADOW_LEVELS 3
#include <asm/shadow2-multi.h>
#include "multi.h"
#undef GUEST_LEVELS
#undef SHADOW_LEVELS
#define GUEST_LEVELS 3
#define SHADOW_LEVELS 3
#include <asm/shadow2-multi.h>
#include "multi.h"
#undef GUEST_LEVELS
#undef SHADOW_LEVELS
#endif /* CONFIG_PAGING_LEVELS == 3 */
@@ -282,25 +282,25 @@ static inline int sh2_take_no_action(struct vcpu *v)
#if CONFIG_PAGING_LEVELS == 4
#define GUEST_LEVELS 2
#define SHADOW_LEVELS 3
#include <asm/shadow2-multi.h>
#include "multi.h"
#undef GUEST_LEVELS
#undef SHADOW_LEVELS
#define GUEST_LEVELS 3
#define SHADOW_LEVELS 3
#include <asm/shadow2-multi.h>
#include "multi.h"
#undef GUEST_LEVELS
#undef SHADOW_LEVELS
#define GUEST_LEVELS 3
#define SHADOW_LEVELS 4
#include <asm/shadow2-multi.h>
#include "multi.h"
#undef GUEST_LEVELS
#undef SHADOW_LEVELS
#define GUEST_LEVELS 4
#define SHADOW_LEVELS 4
#include <asm/shadow2-multi.h>
#include "multi.h"
#undef GUEST_LEVELS
#undef SHADOW_LEVELS
#endif /* CONFIG_PAGING_LEVELS == 4 */
@@ -311,39 +311,39 @@ static inline int sh2_take_no_action(struct vcpu *v)
*/
/* x86 emulator support */
extern struct x86_emulate_ops shadow2_emulator_ops;
extern struct x86_emulate_ops shadow_emulator_ops;
/* Hash table functions */
mfn_t shadow2_hash_lookup(struct vcpu *v, unsigned long n, u8 t);
void shadow2_hash_insert(struct vcpu *v, unsigned long n, u8 t, mfn_t smfn);
void shadow2_hash_delete(struct vcpu *v, unsigned long n, u8 t, mfn_t smfn);
mfn_t shadow_hash_lookup(struct vcpu *v, unsigned long n, u8 t);
void shadow_hash_insert(struct vcpu *v, unsigned long n, u8 t, mfn_t smfn);
void shadow_hash_delete(struct vcpu *v, unsigned long n, u8 t, mfn_t smfn);
/* shadow promotion */
void shadow2_promote(struct vcpu *v, mfn_t gmfn, u32 type);
void shadow2_demote(struct vcpu *v, mfn_t gmfn, u32 type);
void shadow_promote(struct vcpu *v, mfn_t gmfn, u32 type);
void shadow_demote(struct vcpu *v, mfn_t gmfn, u32 type);
/* Shadow page allocation functions */
void shadow2_prealloc(struct domain *d, unsigned int order);
mfn_t shadow2_alloc(struct domain *d,
void shadow_prealloc(struct domain *d, unsigned int order);
mfn_t shadow_alloc(struct domain *d,
u32 shadow_type,
unsigned long backpointer);
void shadow2_free(struct domain *d, mfn_t smfn);
void shadow_free(struct domain *d, mfn_t smfn);
/* Function to convert a shadow to log-dirty */
void shadow2_convert_to_log_dirty(struct vcpu *v, mfn_t smfn);
void shadow_convert_to_log_dirty(struct vcpu *v, mfn_t smfn);
/* Dispatcher function: call the per-mode function that will unhook the
* non-Xen mappings in this top-level shadow mfn */
void shadow2_unhook_mappings(struct vcpu *v, mfn_t smfn);
void shadow_unhook_mappings(struct vcpu *v, mfn_t smfn);
/* Re-sync copies of PAE shadow L3 tables if they have been changed */
void sh2_pae_recopy(struct domain *d);
void sh_pae_recopy(struct domain *d);
/* Install the xen mappings in various flavours of shadow */
void sh2_install_xen_entries_in_l4(struct vcpu *v, mfn_t gl4mfn, mfn_t sl4mfn);
void sh2_install_xen_entries_in_l2h(struct vcpu *v, mfn_t sl2hmfn);
void sh2_install_xen_entries_in_l3(struct vcpu *v, mfn_t gl3mfn, mfn_t sl3mfn);
void sh2_install_xen_entries_in_l2(struct vcpu *v, mfn_t gl2mfn, mfn_t sl2mfn);
void sh_install_xen_entries_in_l4(struct vcpu *v, mfn_t gl4mfn, mfn_t sl4mfn);
void sh_install_xen_entries_in_l2h(struct vcpu *v, mfn_t sl2hmfn);
void sh_install_xen_entries_in_l3(struct vcpu *v, mfn_t gl3mfn, mfn_t sl3mfn);
void sh_install_xen_entries_in_l2(struct vcpu *v, mfn_t gl2mfn, mfn_t sl2mfn);
/******************************************************************************
@@ -367,53 +367,53 @@ void sh2_install_xen_entries_in_l2(struct vcpu *v, mfn_t gl2mfn, mfn_t sl2mfn);
// Provide mfn_t-aware versions of common xen functions
static inline void *
sh2_map_domain_page(mfn_t mfn)
sh_map_domain_page(mfn_t mfn)
{
/* XXX Using the monitor-table as a map will happen here */
return map_domain_page(mfn_x(mfn));
}
static inline void
sh2_unmap_domain_page(void *p)
sh_unmap_domain_page(void *p)
{
/* XXX Using the monitor-table as a map will happen here */
unmap_domain_page(p);
}
static inline void *
sh2_map_domain_page_global(mfn_t mfn)
sh_map_domain_page_global(mfn_t mfn)
{
/* XXX Using the monitor-table as a map will happen here */
return map_domain_page_global(mfn_x(mfn));
}
static inline void
sh2_unmap_domain_page_global(void *p)
sh_unmap_domain_page_global(void *p)
{
/* XXX Using the monitor-table as a map will happen here */
unmap_domain_page_global(p);
}
static inline int
sh2_mfn_is_dirty(struct domain *d, mfn_t gmfn)
sh_mfn_is_dirty(struct domain *d, mfn_t gmfn)
/* Is this guest page dirty? Call only in log-dirty mode. */
{
unsigned long pfn;
ASSERT(shadow2_mode_log_dirty(d));
ASSERT(d->arch.shadow2.dirty_bitmap != NULL);
ASSERT(shadow_mode_log_dirty(d));
ASSERT(d->arch.shadow.dirty_bitmap != NULL);
/* We /really/ mean PFN here, even for non-translated guests. */
pfn = get_gpfn_from_mfn(mfn_x(gmfn));
if ( likely(VALID_M2P(pfn))
&& likely(pfn < d->arch.shadow2.dirty_bitmap_size)
&& test_bit(pfn, d->arch.shadow2.dirty_bitmap) )
&& likely(pfn < d->arch.shadow.dirty_bitmap_size)
&& test_bit(pfn, d->arch.shadow.dirty_bitmap) )
return 1;
return 0;
}
static inline int
sh2_mfn_is_a_page_table(mfn_t gmfn)
sh_mfn_is_a_page_table(mfn_t gmfn)
{
struct page_info *page = mfn_to_page(gmfn);
struct domain *owner;
@@ -423,7 +423,7 @@ sh2_mfn_is_a_page_table(mfn_t gmfn)
return 0;
owner = page_get_owner(page);
if ( owner && shadow2_mode_refcounts(owner)
if ( owner && shadow_mode_refcounts(owner)
&& (page->count_info & PGC_page_table) )
return 1;
@@ -433,33 +433,33 @@ sh2_mfn_is_a_page_table(mfn_t gmfn)
/**************************************************************************/
/* Shadow-page refcounting. See comment in shadow2-common.c about the
/* Shadow-page refcounting. See comment in shadow-common.c about the
* use of struct page_info fields for shadow pages */
void sh2_destroy_shadow(struct vcpu *v, mfn_t smfn);
void sh_destroy_shadow(struct vcpu *v, mfn_t smfn);
/* Increase the refcount of a shadow page. Arguments are the mfn to refcount,
* and the physical address of the shadow entry that holds the ref (or zero
* if the ref is held by something else) */
static inline void sh2_get_ref(mfn_t smfn, paddr_t entry_pa)
static inline void sh_get_ref(mfn_t smfn, paddr_t entry_pa)
{
u32 x, nx;
struct page_info *page = mfn_to_page(smfn);
ASSERT(mfn_valid(smfn));
x = page->count_info & PGC_SH2_count_mask;
x = page->count_info & PGC_SH_count_mask;
nx = x + 1;
if ( unlikely(nx & ~PGC_SH2_count_mask) )
if ( unlikely(nx & ~PGC_SH_count_mask) )
{
SHADOW2_PRINTK("shadow ref overflow, gmfn=%" PRtype_info " smfn=%lx\n",
SHADOW_PRINTK("shadow ref overflow, gmfn=%" PRtype_info " smfn=%lx\n",
page->u.inuse.type_info, mfn_x(smfn));
domain_crash_synchronous();
}
/* Guarded by the shadow lock, so no need for atomic update */
page->count_info &= ~PGC_SH2_count_mask;
page->count_info &= ~PGC_SH_count_mask;
page->count_info |= nx;
/* We remember the first shadow entry that points to each shadow. */
@@ -470,7 +470,7 @@ static inline void sh2_get_ref(mfn_t smfn, paddr_t entry_pa)
/* Decrease the refcount of a shadow page. As for get_ref, takes the
* physical address of the shadow entry that held this reference. */
static inline void sh2_put_ref(struct vcpu *v, mfn_t smfn, paddr_t entry_pa)
static inline void sh_put_ref(struct vcpu *v, mfn_t smfn, paddr_t entry_pa)
{
u32 x, nx;
struct page_info *page = mfn_to_page(smfn);
@@ -482,53 +482,53 @@ static inline void sh2_put_ref(struct vcpu *v, mfn_t smfn, paddr_t entry_pa)
if ( entry_pa != 0 && page->up == entry_pa )
page->up = 0;
x = page->count_info & PGC_SH2_count_mask;
x = page->count_info & PGC_SH_count_mask;
nx = x - 1;
if ( unlikely(x == 0) )
{
SHADOW2_PRINTK("shadow ref underflow, smfn=%lx oc=%08x t=%"
SHADOW_PRINTK("shadow ref underflow, smfn=%lx oc=%08x t=%"
PRtype_info "\n",
mfn_x(smfn),
page->count_info & PGC_SH2_count_mask,
page->count_info & PGC_SH_count_mask,
page->u.inuse.type_info);
domain_crash_synchronous();
}
/* Guarded by the shadow lock, so no need for atomic update */
page->count_info &= ~PGC_SH2_count_mask;
page->count_info &= ~PGC_SH_count_mask;
page->count_info |= nx;
if ( unlikely(nx == 0) )
sh2_destroy_shadow(v, smfn);
sh_destroy_shadow(v, smfn);
}
/* Pin a shadow page: take an extra refcount and set the pin bit. */
static inline void sh2_pin(mfn_t smfn)
static inline void sh_pin(mfn_t smfn)
{
struct page_info *page;
ASSERT(mfn_valid(smfn));
page = mfn_to_page(smfn);
if ( !(page->count_info & PGC_SH2_pinned) )
if ( !(page->count_info & PGC_SH_pinned) )
{
sh2_get_ref(smfn, 0);
page->count_info |= PGC_SH2_pinned;
sh_get_ref(smfn, 0);
page->count_info |= PGC_SH_pinned;
}
}
/* Unpin a shadow page: unset the pin bit and release the extra ref. */
static inline void sh2_unpin(struct vcpu *v, mfn_t smfn)
static inline void sh_unpin(struct vcpu *v, mfn_t smfn)
{
struct page_info *page;
ASSERT(mfn_valid(smfn));
page = mfn_to_page(smfn);
if ( page->count_info & PGC_SH2_pinned )
if ( page->count_info & PGC_SH_pinned )
{
page->count_info &= ~PGC_SH2_pinned;
sh2_put_ref(v, smfn, 0);
page->count_info &= ~PGC_SH_pinned;
sh_put_ref(v, smfn, 0);
}
}
@@ -551,7 +551,7 @@ vcpu_gfn_to_mfn_nofault(struct vcpu *v, unsigned long gfn)
l1_pgentry_t *l1e;
ASSERT(current == v);
if ( !shadow2_vcpu_mode_translate(v) )
if ( !shadow_vcpu_mode_translate(v) )
return _mfn(gfn);
#if CONFIG_PAGING_LEVELS > 2
@@ -561,7 +561,7 @@ vcpu_gfn_to_mfn_nofault(struct vcpu *v, unsigned long gfn)
#endif
/* Walk the linear pagetables. Note that this is *not* the same as
* the walk in sh2_gfn_to_mfn_foreign, which is walking the p2m map */
* the walk in sh_gfn_to_mfn_foreign, which is walking the p2m map */
#if CONFIG_PAGING_LEVELS >= 4
l4e = __linear_l4_table + l4_linear_offset(entry_addr);
if ( !(l4e_get_flags(*l4e) & _PAGE_PRESENT) ) return _mfn(INVALID_MFN);
@@ -581,7 +581,7 @@ vcpu_gfn_to_mfn_nofault(struct vcpu *v, unsigned long gfn)
}
#endif /* _XEN_SHADOW2_PRIVATE_H */
#endif /* _XEN_SHADOW_PRIVATE_H */
/*
* Local variables:
@@ -1,5 +1,5 @@
/******************************************************************************
* include/asm-x86/shadow2-types.h
* arch/x86/mm/shadow/types.h
*
* Parts of this code are Copyright (c) 2006 by XenSource Inc.
* Parts of this code are Copyright (c) 2006 by Michael A Fetterman
@@ -20,8 +20,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _XEN_SHADOW2_TYPES_H
#define _XEN_SHADOW2_TYPES_H
#ifndef _XEN_SHADOW_TYPES_H
#define _XEN_SHADOW_TYPES_H
// Map a shadow page
static inline void *
@@ -34,14 +34,14 @@ map_shadow_page(mfn_t smfn)
// presumably using the reverse map hint in the page_info of this
// smfn, rather than calling map_domain_page()?
//
return sh2_map_domain_page(smfn);
return sh_map_domain_page(smfn);
}
// matching unmap for map_shadow_page()
static inline void
unmap_shadow_page(void *p)
{
sh2_unmap_domain_page(p);
sh_unmap_domain_page(p);
}
/*
@@ -188,52 +188,52 @@ static inline shadow_l4e_t shadow_l4e_from_mfn(mfn_t mfn, u32 flags)
* guests, the shadow doesn't have a linear-map self-entry so we must use
* the monitor-table's linear-map entry N-1 times and then the shadow-map
* entry once. */
#define __sh2_linear_l1_table ((shadow_l1e_t *)(SH_LINEAR_PT_VIRT_START))
#define __sh2_linear_l2_table ((shadow_l2e_t *) \
(__sh2_linear_l1_table + shadow_l1_linear_offset(SH_LINEAR_PT_VIRT_START)))
#define __sh_linear_l1_table ((shadow_l1e_t *)(SH_LINEAR_PT_VIRT_START))
#define __sh_linear_l2_table ((shadow_l2e_t *) \
(__sh_linear_l1_table + shadow_l1_linear_offset(SH_LINEAR_PT_VIRT_START)))
// shadow linear L3 and L4 tables only exist in 4 level paging...
#if SHADOW_PAGING_LEVELS == 4
#define __sh2_linear_l3_table ((shadow_l3e_t *) \
(__sh2_linear_l2_table + shadow_l2_linear_offset(SH_LINEAR_PT_VIRT_START)))
#define __sh2_linear_l4_table ((shadow_l4e_t *) \
(__sh2_linear_l3_table + shadow_l3_linear_offset(SH_LINEAR_PT_VIRT_START)))
#define __sh_linear_l3_table ((shadow_l3e_t *) \
(__sh_linear_l2_table + shadow_l2_linear_offset(SH_LINEAR_PT_VIRT_START)))
#define __sh_linear_l4_table ((shadow_l4e_t *) \
(__sh_linear_l3_table + shadow_l3_linear_offset(SH_LINEAR_PT_VIRT_START)))
#endif
#define sh2_linear_l1_table(v) ({ \
#define sh_linear_l1_table(v) ({ \
ASSERT(current == (v)); \
__sh2_linear_l1_table; \
__sh_linear_l1_table; \
})
#define sh2_linear_l2_table(v) ({ \
#define sh_linear_l2_table(v) ({ \
ASSERT(current == (v)); \
((shadow_l2e_t *) \
(hvm_guest(v) ? __linear_l1_table : __sh2_linear_l1_table) + \
(hvm_guest(v) ? __linear_l1_table : __sh_linear_l1_table) + \
shadow_l1_linear_offset(SH_LINEAR_PT_VIRT_START)); \
})
// shadow linear L3 and L4 tables only exist in 4 level paging...
#if SHADOW_PAGING_LEVELS == 4
#define sh2_linear_l3_table(v) ({ \
#define sh_linear_l3_table(v) ({ \
ASSERT(current == (v)); \
((shadow_l3e_t *) \
(hvm_guest(v) ? __linear_l2_table : __sh2_linear_l2_table) + \
(hvm_guest(v) ? __linear_l2_table : __sh_linear_l2_table) + \
shadow_l2_linear_offset(SH_LINEAR_PT_VIRT_START)); \
})
// we use l4_pgentry_t instead of shadow_l4e_t below because shadow_l4e_t is
// not defined for when xen_levels==4 & shadow_levels==3...
#define sh2_linear_l4_table(v) ({ \
#define sh_linear_l4_table(v) ({ \
ASSERT(current == (v)); \
((l4_pgentry_t *) \
(hvm_guest(v) ? __linear_l3_table : __sh2_linear_l3_table) + \
(hvm_guest(v) ? __linear_l3_table : __sh_linear_l3_table) + \
shadow_l3_linear_offset(SH_LINEAR_PT_VIRT_START)); \
})
#endif
#if GUEST_PAGING_LEVELS == 2
#include <asm/page-guest32.h>
#include "page-guest32.h"
#define GUEST_L1_PAGETABLE_ENTRIES 1024
#define GUEST_L2_PAGETABLE_ENTRIES 1024
@@ -243,7 +243,7 @@ static inline shadow_l4e_t shadow_l4e_from_mfn(mfn_t mfn, u32 flags)
/* Type of the guest's frame numbers */
TYPE_SAFE(u32,gfn)
#define INVALID_GFN ((u32)(-1u))
#define SH2_PRI_gfn "05x"
#define SH_PRI_gfn "05x"
/* Types of the guest's page tables */
typedef l1_pgentry_32_t guest_l1e_t;
@@ -279,9 +279,9 @@ static inline guest_l2e_t guest_l2e_from_gfn(gfn_t gfn, u32 flags)
#define guest_l2_table_offset(a) l2_table_offset_32(a)
/* The shadow types needed for the various levels. */
#define PGC_SH2_l1_shadow PGC_SH2_l1_32_shadow
#define PGC_SH2_l2_shadow PGC_SH2_l2_32_shadow
#define PGC_SH2_fl1_shadow PGC_SH2_fl1_32_shadow
#define PGC_SH_l1_shadow PGC_SH_l1_32_shadow
#define PGC_SH_l2_shadow PGC_SH_l2_32_shadow
#define PGC_SH_fl1_shadow PGC_SH_fl1_32_shadow
#else /* GUEST_PAGING_LEVELS != 2 */
@@ -306,7 +306,7 @@ static inline guest_l2e_t guest_l2e_from_gfn(gfn_t gfn, u32 flags)
/* Type of the guest's frame numbers */
TYPE_SAFE(unsigned long,gfn)
#define INVALID_GFN ((unsigned long)(-1ul))
#define SH2_PRI_gfn "05lx"
#define SH_PRI_gfn "05lx"
/* Types of the guest's page tables */
typedef l1_pgentry_t guest_l1e_t;
@@ -379,17 +379,17 @@ static inline guest_l4e_t guest_l4e_from_gfn(gfn_t gfn, u32 flags)
/* The shadow types needed for the various levels. */
#if GUEST_PAGING_LEVELS == 3
#define PGC_SH2_l1_shadow PGC_SH2_l1_pae_shadow
#define PGC_SH2_fl1_shadow PGC_SH2_fl1_pae_shadow
#define PGC_SH2_l2_shadow PGC_SH2_l2_pae_shadow
#define PGC_SH2_l2h_shadow PGC_SH2_l2h_pae_shadow
#define PGC_SH2_l3_shadow PGC_SH2_l3_pae_shadow
#define PGC_SH_l1_shadow PGC_SH_l1_pae_shadow
#define PGC_SH_fl1_shadow PGC_SH_fl1_pae_shadow
#define PGC_SH_l2_shadow PGC_SH_l2_pae_shadow
#define PGC_SH_l2h_shadow PGC_SH_l2h_pae_shadow
#define PGC_SH_l3_shadow PGC_SH_l3_pae_shadow
#else
#define PGC_SH2_l1_shadow PGC_SH2_l1_64_shadow
#define PGC_SH2_fl1_shadow PGC_SH2_fl1_64_shadow
#define PGC_SH2_l2_shadow PGC_SH2_l2_64_shadow
#define PGC_SH2_l3_shadow PGC_SH2_l3_64_shadow
#define PGC_SH2_l4_shadow PGC_SH2_l4_64_shadow
#define PGC_SH_l1_shadow PGC_SH_l1_64_shadow
#define PGC_SH_fl1_shadow PGC_SH_fl1_64_shadow
#define PGC_SH_l2_shadow PGC_SH_l2_64_shadow
#define PGC_SH_l3_shadow PGC_SH_l3_64_shadow
#define PGC_SH_l4_shadow PGC_SH_l4_64_shadow
#endif
#endif /* GUEST_PAGING_LEVELS != 2 */
@@ -403,24 +403,24 @@ valid_gfn(gfn_t m)
}
#if GUEST_PAGING_LEVELS == 2
#define PGC_SH2_guest_root_type PGC_SH2_l2_32_shadow
#define PGC_SH_guest_root_type PGC_SH_l2_32_shadow
#elif GUEST_PAGING_LEVELS == 3
#define PGC_SH2_guest_root_type PGC_SH2_l3_pae_shadow
#define PGC_SH_guest_root_type PGC_SH_l3_pae_shadow
#else
#define PGC_SH2_guest_root_type PGC_SH2_l4_64_shadow
#define PGC_SH_guest_root_type PGC_SH_l4_64_shadow
#endif
/* Translation between mfns and gfns */
static inline mfn_t
vcpu_gfn_to_mfn(struct vcpu *v, gfn_t gfn)
{
return sh2_vcpu_gfn_to_mfn(v, gfn_x(gfn));
return sh_vcpu_gfn_to_mfn(v, gfn_x(gfn));
}
static inline gfn_t
mfn_to_gfn(struct domain *d, mfn_t mfn)
{
return _gfn(sh2_mfn_to_gfn(d, mfn));
return _gfn(sh_mfn_to_gfn(d, mfn));
}
static inline paddr_t
@@ -438,8 +438,8 @@ gfn_to_paddr(gfn_t gfn)
* The "Effective l1e" field is used when there isn't an l1e to point to,
* but we have fabricated an l1e for propagation to the shadow (e.g.,
* for splintering guest superpages into many shadow l1 entries). */
typedef struct shadow2_walk_t walk_t;
struct shadow2_walk_t
typedef struct shadow_walk_t walk_t;
struct shadow_walk_t
{
unsigned long va; /* Address we were looking for */
#if GUEST_PAGING_LEVELS >= 3
@@ -465,55 +465,55 @@ struct shadow2_walk_t
* shadow code's external entry points.
*/
#define INTERNAL_NAME(name) \
SHADOW2_INTERNAL_NAME(name, SHADOW_PAGING_LEVELS, GUEST_PAGING_LEVELS)
SHADOW_INTERNAL_NAME(name, SHADOW_PAGING_LEVELS, GUEST_PAGING_LEVELS)
/* macros for renaming the primary entry points, so that they are more
* easily distinguished from a debugger
*/
#define sh2_page_fault INTERNAL_NAME(sh2_page_fault)
#define sh2_invlpg INTERNAL_NAME(sh2_invlpg)
#define sh2_gva_to_gpa INTERNAL_NAME(sh2_gva_to_gpa)
#define sh2_gva_to_gfn INTERNAL_NAME(sh2_gva_to_gfn)
#define sh2_update_cr3 INTERNAL_NAME(sh2_update_cr3)
#define sh2_remove_write_access INTERNAL_NAME(sh2_remove_write_access)
#define sh2_remove_all_mappings INTERNAL_NAME(sh2_remove_all_mappings)
#define sh2_remove_l1_shadow INTERNAL_NAME(sh2_remove_l1_shadow)
#define sh2_remove_l2_shadow INTERNAL_NAME(sh2_remove_l2_shadow)
#define sh2_remove_l3_shadow INTERNAL_NAME(sh2_remove_l3_shadow)
#define sh2_map_and_validate_gl4e INTERNAL_NAME(sh2_map_and_validate_gl4e)
#define sh2_map_and_validate_gl3e INTERNAL_NAME(sh2_map_and_validate_gl3e)
#define sh2_map_and_validate_gl2e INTERNAL_NAME(sh2_map_and_validate_gl2e)
#define sh2_map_and_validate_gl2he INTERNAL_NAME(sh2_map_and_validate_gl2he)
#define sh2_map_and_validate_gl1e INTERNAL_NAME(sh2_map_and_validate_gl1e)
#define sh2_destroy_l4_shadow INTERNAL_NAME(sh2_destroy_l4_shadow)
#define sh2_destroy_l3_shadow INTERNAL_NAME(sh2_destroy_l3_shadow)
#define sh2_destroy_l3_subshadow INTERNAL_NAME(sh2_destroy_l3_subshadow)
#define sh2_unpin_all_l3_subshadows INTERNAL_NAME(sh2_unpin_all_l3_subshadows)
#define sh2_destroy_l2_shadow INTERNAL_NAME(sh2_destroy_l2_shadow)
#define sh2_destroy_l1_shadow INTERNAL_NAME(sh2_destroy_l1_shadow)
#define sh2_unhook_32b_mappings INTERNAL_NAME(sh2_unhook_32b_mappings)
#define sh2_unhook_pae_mappings INTERNAL_NAME(sh2_unhook_pae_mappings)
#define sh2_unhook_64b_mappings INTERNAL_NAME(sh2_unhook_64b_mappings)
#define sh2_paging_mode INTERNAL_NAME(sh2_paging_mode)
#define sh2_detach_old_tables INTERNAL_NAME(sh2_detach_old_tables)
#define sh2_x86_emulate_write INTERNAL_NAME(sh2_x86_emulate_write)
#define sh2_x86_emulate_cmpxchg INTERNAL_NAME(sh2_x86_emulate_cmpxchg)
#define sh2_x86_emulate_cmpxchg8b INTERNAL_NAME(sh2_x86_emulate_cmpxchg8b)
#define sh2_audit_l1_table INTERNAL_NAME(sh2_audit_l1_table)
#define sh2_audit_fl1_table INTERNAL_NAME(sh2_audit_fl1_table)
#define sh2_audit_l2_table INTERNAL_NAME(sh2_audit_l2_table)
#define sh2_audit_l3_table INTERNAL_NAME(sh2_audit_l3_table)
#define sh2_audit_l4_table INTERNAL_NAME(sh2_audit_l4_table)
#define sh2_guess_wrmap INTERNAL_NAME(sh2_guess_wrmap)
#define sh2_clear_shadow_entry INTERNAL_NAME(sh2_clear_shadow_entry)
#define sh_page_fault INTERNAL_NAME(sh_page_fault)
#define sh_invlpg INTERNAL_NAME(sh_invlpg)
#define sh_gva_to_gpa INTERNAL_NAME(sh_gva_to_gpa)
#define sh_gva_to_gfn INTERNAL_NAME(sh_gva_to_gfn)
#define sh_update_cr3 INTERNAL_NAME(sh_update_cr3)
#define sh_remove_write_access INTERNAL_NAME(sh_remove_write_access)
#define sh_remove_all_mappings INTERNAL_NAME(sh_remove_all_mappings)
#define sh_remove_l1_shadow INTERNAL_NAME(sh_remove_l1_shadow)
#define sh_remove_l2_shadow INTERNAL_NAME(sh_remove_l2_shadow)
#define sh_remove_l3_shadow INTERNAL_NAME(sh_remove_l3_shadow)
#define sh_map_and_validate_gl4e INTERNAL_NAME(sh_map_and_validate_gl4e)
#define sh_map_and_validate_gl3e INTERNAL_NAME(sh_map_and_validate_gl3e)
#define sh_map_and_validate_gl2e INTERNAL_NAME(sh_map_and_validate_gl2e)
#define sh_map_and_validate_gl2he INTERNAL_NAME(sh_map_and_validate_gl2he)
#define sh_map_and_validate_gl1e INTERNAL_NAME(sh_map_and_validate_gl1e)
#define sh_destroy_l4_shadow INTERNAL_NAME(sh_destroy_l4_shadow)
#define sh_destroy_l3_shadow INTERNAL_NAME(sh_destroy_l3_shadow)
#define sh_destroy_l3_subshadow INTERNAL_NAME(sh_destroy_l3_subshadow)
#define sh_unpin_all_l3_subshadows INTERNAL_NAME(sh_unpin_all_l3_subshadows)
#define sh_destroy_l2_shadow INTERNAL_NAME(sh_destroy_l2_shadow)
#define sh_destroy_l1_shadow INTERNAL_NAME(sh_destroy_l1_shadow)
#define sh_unhook_32b_mappings INTERNAL_NAME(sh_unhook_32b_mappings)
#define sh_unhook_pae_mappings INTERNAL_NAME(sh_unhook_pae_mappings)
#define sh_unhook_64b_mappings INTERNAL_NAME(sh_unhook_64b_mappings)
#define sh_paging_mode INTERNAL_NAME(sh_paging_mode)
#define sh_detach_old_tables INTERNAL_NAME(sh_detach_old_tables)
#define sh_x86_emulate_write INTERNAL_NAME(sh_x86_emulate_write)
#define sh_x86_emulate_cmpxchg INTERNAL_NAME(sh_x86_emulate_cmpxchg)
#define sh_x86_emulate_cmpxchg8b INTERNAL_NAME(sh_x86_emulate_cmpxchg8b)
#define sh_audit_l1_table INTERNAL_NAME(sh_audit_l1_table)
#define sh_audit_fl1_table INTERNAL_NAME(sh_audit_fl1_table)
#define sh_audit_l2_table INTERNAL_NAME(sh_audit_l2_table)
#define sh_audit_l3_table INTERNAL_NAME(sh_audit_l3_table)
#define sh_audit_l4_table INTERNAL_NAME(sh_audit_l4_table)
#define sh_guess_wrmap INTERNAL_NAME(sh_guess_wrmap)
#define sh_clear_shadow_entry INTERNAL_NAME(sh_clear_shadow_entry)
/* sh2_make_monitor_table only depends on the number of shadow levels */
#define sh2_make_monitor_table \
SHADOW2_INTERNAL_NAME(sh2_make_monitor_table, \
/* sh_make_monitor_table only depends on the number of shadow levels */
#define sh_make_monitor_table \
SHADOW_INTERNAL_NAME(sh_make_monitor_table, \
SHADOW_PAGING_LEVELS, \
SHADOW_PAGING_LEVELS)
#define sh2_destroy_monitor_table \
SHADOW2_INTERNAL_NAME(sh2_destroy_monitor_table, \
#define sh_destroy_monitor_table \
SHADOW_INTERNAL_NAME(sh_destroy_monitor_table, \
SHADOW_PAGING_LEVELS, \
SHADOW_PAGING_LEVELS)
@@ -537,22 +537,22 @@ struct pae_l3_bookkeeping {
#define sl3p_to_info(_ptr) ((struct pae_l3_bookkeeping *) \
(((unsigned long)(_ptr) & ~31) + 32))
static void sh2_destroy_l3_subshadow(struct vcpu *v,
static void sh_destroy_l3_subshadow(struct vcpu *v,
shadow_l3e_t *sl3e);
/* Increment a subshadow ref
* Called with a pointer to the subshadow, and the mfn of the
* *first* page of the overall shadow. */
static inline void sh2_get_ref_l3_subshadow(shadow_l3e_t *sl3e, mfn_t smfn)
static inline void sh_get_ref_l3_subshadow(shadow_l3e_t *sl3e, mfn_t smfn)
{
struct pae_l3_bookkeeping *bk = sl3p_to_info(sl3e);
/* First ref to the subshadow takes a ref to the full shadow */
if ( bk->refcount == 0 )
sh2_get_ref(smfn, 0);
sh_get_ref(smfn, 0);
if ( unlikely(++(bk->refcount) == 0) )
{
SHADOW2_PRINTK("shadow l3 subshadow ref overflow, smfn=%" SH2_PRI_mfn " sh=%p\n",
SHADOW_PRINTK("shadow l3 subshadow ref overflow, smfn=%" SH_PRI_mfn " sh=%p\n",
mfn_x(smfn), sl3e);
domain_crash_synchronous();
}
@@ -563,7 +563,7 @@ static inline void sh2_get_ref_l3_subshadow(shadow_l3e_t *sl3e, mfn_t smfn)
* *first* page of the overall shadow. Calling this may cause the
* entire shadow to disappear, so the caller must immediately unmap
* the pointer after calling. */
static inline void sh2_put_ref_l3_subshadow(struct vcpu *v,
static inline void sh_put_ref_l3_subshadow(struct vcpu *v,
shadow_l3e_t *sl3e,
mfn_t smfn)
{
@@ -575,16 +575,16 @@ static inline void sh2_put_ref_l3_subshadow(struct vcpu *v,
if ( --(bk->refcount) == 0 )
{
/* Need to destroy this subshadow */
sh2_destroy_l3_subshadow(v, sl3e);
sh_destroy_l3_subshadow(v, sl3e);
/* Last ref to the subshadow had a ref to the full shadow */
sh2_put_ref(v, smfn, 0);
sh_put_ref(v, smfn, 0);
}
}
/* Pin a subshadow
* Called with a pointer to the subshadow, and the mfn of the
* *first* page of the overall shadow. */
static inline void sh2_pin_l3_subshadow(shadow_l3e_t *sl3e, mfn_t smfn)
static inline void sh_pin_l3_subshadow(shadow_l3e_t *sl3e, mfn_t smfn)
{
struct pae_l3_bookkeeping *bk = sl3p_to_info(sl3e);
@@ -597,7 +597,7 @@ static inline void sh2_pin_l3_subshadow(shadow_l3e_t *sl3e, mfn_t smfn)
if ( !bk->pinned )
{
bk->pinned = 1;
sh2_get_ref_l3_subshadow(sl3e, smfn);
sh_get_ref_l3_subshadow(sl3e, smfn);
}
}
@@ -606,7 +606,7 @@ static inline void sh2_pin_l3_subshadow(shadow_l3e_t *sl3e, mfn_t smfn)
* *first* page of the overall shadow. Calling this may cause the
* entire shadow to disappear, so the caller must immediately unmap
* the pointer after calling. */
static inline void sh2_unpin_l3_subshadow(struct vcpu *v,
static inline void sh_unpin_l3_subshadow(struct vcpu *v,
shadow_l3e_t *sl3e,
mfn_t smfn)
{
@@ -621,7 +621,7 @@ static inline void sh2_unpin_l3_subshadow(struct vcpu *v,
if ( bk->pinned )
{
bk->pinned = 0;
sh2_put_ref_l3_subshadow(v, sl3e, smfn);
sh_put_ref_l3_subshadow(v, sl3e, smfn);
}
}
@@ -632,22 +632,22 @@ static inline void sh2_unpin_l3_subshadow(struct vcpu *v,
#endif
#if SHADOW_PAGING_LEVELS == 2
#define SH2_PRI_pte "08x"
#define SH_PRI_pte "08x"
#else /* SHADOW_PAGING_LEVELS >= 3 */
#ifndef __x86_64__
#define SH2_PRI_pte "016llx"
#define SH_PRI_pte "016llx"
#else
#define SH2_PRI_pte "016lx"
#define SH_PRI_pte "016lx"
#endif
#endif /* SHADOW_PAGING_LEVELS >= 3 */
#if GUEST_PAGING_LEVELS == 2
#define SH2_PRI_gpte "08x"
#define SH_PRI_gpte "08x"
#else /* GUEST_PAGING_LEVELS >= 3 */
#ifndef __x86_64__
#define SH2_PRI_gpte "016llx"
#define SH_PRI_gpte "016llx"
#else
#define SH2_PRI_gpte "016lx"
#define SH_PRI_gpte "016lx"
#endif
#endif /* GUEST_PAGING_LEVELS >= 3 */
@@ -680,7 +680,7 @@ accumulate_guest_flags(walk_t *gw)
return accumulated_flags;
}
#endif /* _XEN_SHADOW2_TYPES_H */
#endif /* _XEN_SHADOW_TYPES_H */
/*
* Local variables:
+4 -4
View File
@@ -870,8 +870,8 @@ static int fixup_page_fault(unsigned long addr, struct cpu_user_regs *regs)
if ( unlikely(IN_HYPERVISOR_RANGE(addr)) )
{
if ( shadow2_mode_external(d) && guest_mode(regs) )
return shadow2_fault(addr, regs);
if ( shadow_mode_external(d) && guest_mode(regs) )
return shadow_fault(addr, regs);
if ( (addr >= GDT_LDT_VIRT_START) && (addr < GDT_LDT_VIRT_END) )
return handle_gdt_ldt_mapping_fault(
addr - GDT_LDT_VIRT_START, regs);
@@ -890,8 +890,8 @@ static int fixup_page_fault(unsigned long addr, struct cpu_user_regs *regs)
ptwr_do_page_fault(d, addr, regs) )
return EXCRET_fault_fixed;
if ( shadow2_mode_enabled(d) )
return shadow2_fault(addr, regs);
if ( shadow_mode_enabled(d) )
return shadow_fault(addr, regs);
return 0;
}
+9 -9
View File
@@ -59,10 +59,10 @@ extern void hypercall_page_initialise(struct domain *d, void *);
struct shadow_domain {
u32 mode; /* flags to control shadow operation */
spinlock_t lock; /* shadow2 domain lock */
spinlock_t lock; /* shadow domain lock */
int locker; /* processor which holds the lock */
const char *locker_function; /* Func that took it */
struct list_head freelists[SHADOW2_MAX_ORDER + 1];
struct list_head freelists[SHADOW_MAX_ORDER + 1];
struct list_head p2m_freelist;
struct list_head p2m_inuse;
struct list_head toplevel_shadows;
@@ -70,10 +70,10 @@ struct shadow_domain {
unsigned int free_pages; /* number of pages on freelists */
unsigned int p2m_pages; /* number of pages in p2m map */
/* Shadow2 hashtable */
struct shadow2_hash_entry *hash_table;
struct shadow2_hash_entry *hash_freelist;
struct shadow2_hash_entry *hash_allocations;
/* Shadow hashtable */
struct shadow_hash_entry *hash_table;
struct shadow_hash_entry *hash_freelist;
struct shadow_hash_entry *hash_allocations;
int hash_walking; /* Some function is walking the hash table */
/* Shadow log-dirty bitmap */
@@ -107,7 +107,7 @@ struct arch_domain
/* Shadow-translated guest: Pseudophys base address of reserved area. */
unsigned long first_reserved_pfn;
struct shadow_domain shadow2;
struct shadow_domain shadow;
/* Shadow translated domain: P2M mapping */
pagetable_t phys_table;
@@ -135,7 +135,7 @@ struct pae_l3_cache { };
struct shadow_vcpu {
/* Pointers to mode-specific entry points. */
struct shadow2_paging_mode *mode;
struct shadow_paging_mode *mode;
/* Last MFN that we emulated a write to. */
unsigned long last_emulated_mfn;
/* HVM guest: paging enabled (CR0.PG)? */
@@ -201,7 +201,7 @@ struct arch_vcpu
/* Current LDT details. */
unsigned long shadow_ldt_mapcnt;
struct shadow_vcpu shadow2;
struct shadow_vcpu shadow;
} __cacheline_aligned;
/* shorthands to improve code legibility */
+38 -38
View File
@@ -22,7 +22,7 @@ struct page_info
/* Each frame can be threaded onto a doubly-linked list. */
union {
struct list_head list;
/* Shadow2 uses this field as an up-pointer in lower-level shadows */
/* Shadow uses this field as an up-pointer in lower-level shadows */
paddr_t up;
};
@@ -59,7 +59,7 @@ struct page_info
/* Only used on guest pages with a shadow.
* Guest pages with a shadow must have a non-zero type count, so this
* does not conflict with the tlbflush timestamp. */
u32 shadow2_flags;
u32 shadow_flags;
// XXX -- we expect to add another field here, to be used for min/max
// purposes, which is only used for shadow pages.
@@ -76,7 +76,7 @@ struct page_info
#define PGT_ldt_page (6U<<29) /* using this page in an LDT? */
#define PGT_writable_page (7U<<29) /* has writable mappings of this page? */
#ifndef SHADOW2
#ifndef SHADOW
#define PGT_l1_shadow PGT_l1_page_table
#define PGT_l2_shadow PGT_l2_page_table
#define PGT_l3_shadow PGT_l3_page_table
@@ -117,7 +117,7 @@ struct page_info
/* 16-bit count of uses of this frame as its current type. */
#define PGT_count_mask ((1U<<16)-1)
#ifndef SHADOW2
#ifndef SHADOW
#ifdef __x86_64__
#define PGT_high_mfn_shift 52
#define PGT_high_mfn_mask (0xfffUL << PGT_high_mfn_shift)
@@ -132,7 +132,7 @@ struct page_info
#define PGT_score_shift 23
#define PGT_score_mask (((1U<<4)-1)<<PGT_score_shift)
#endif
#endif /* SHADOW2 */
#endif /* SHADOW */
/* Cleared when the owning guest 'frees' this page. */
#define _PGC_allocated 31
@@ -146,38 +146,38 @@ struct page_info
/* 29-bit count of references to this frame. */
#define PGC_count_mask ((1U<<29)-1)
/* shadow2 uses the count_info on shadow pages somewhat differently */
/* NB: please coordinate any changes here with the SH2F's in shadow2.h */
#define PGC_SH2_none (0U<<28) /* on the shadow2 free list */
#define PGC_SH2_min_shadow (1U<<28)
#define PGC_SH2_l1_32_shadow (1U<<28) /* shadowing a 32-bit L1 guest page */
#define PGC_SH2_fl1_32_shadow (2U<<28) /* L1 shadow for a 32b 4M superpage */
#define PGC_SH2_l2_32_shadow (3U<<28) /* shadowing a 32-bit L2 guest page */
#define PGC_SH2_l1_pae_shadow (4U<<28) /* shadowing a pae L1 page */
#define PGC_SH2_fl1_pae_shadow (5U<<28) /* L1 shadow for pae 2M superpg */
#define PGC_SH2_l2_pae_shadow (6U<<28) /* shadowing a pae L2-low page */
#define PGC_SH2_l2h_pae_shadow (7U<<28) /* shadowing a pae L2-high page */
#define PGC_SH2_l3_pae_shadow (8U<<28) /* shadowing a pae L3 page */
#define PGC_SH2_l1_64_shadow (9U<<28) /* shadowing a 64-bit L1 page */
#define PGC_SH2_fl1_64_shadow (10U<<28) /* L1 shadow for 64-bit 2M superpg */
#define PGC_SH2_l2_64_shadow (11U<<28) /* shadowing a 64-bit L2 page */
#define PGC_SH2_l3_64_shadow (12U<<28) /* shadowing a 64-bit L3 page */
#define PGC_SH2_l4_64_shadow (13U<<28) /* shadowing a 64-bit L4 page */
#define PGC_SH2_max_shadow (13U<<28)
#define PGC_SH2_p2m_table (14U<<28) /* in use as the p2m table */
#define PGC_SH2_monitor_table (15U<<28) /* in use as a monitor table */
#define PGC_SH2_unused (15U<<28)
/* shadow uses the count_info on shadow pages somewhat differently */
/* NB: please coordinate any changes here with the SHF's in shadow.h */
#define PGC_SH_none (0U<<28) /* on the shadow free list */
#define PGC_SH_min_shadow (1U<<28)
#define PGC_SH_l1_32_shadow (1U<<28) /* shadowing a 32-bit L1 guest page */
#define PGC_SH_fl1_32_shadow (2U<<28) /* L1 shadow for a 32b 4M superpage */
#define PGC_SH_l2_32_shadow (3U<<28) /* shadowing a 32-bit L2 guest page */
#define PGC_SH_l1_pae_shadow (4U<<28) /* shadowing a pae L1 page */
#define PGC_SH_fl1_pae_shadow (5U<<28) /* L1 shadow for pae 2M superpg */
#define PGC_SH_l2_pae_shadow (6U<<28) /* shadowing a pae L2-low page */
#define PGC_SH_l2h_pae_shadow (7U<<28) /* shadowing a pae L2-high page */
#define PGC_SH_l3_pae_shadow (8U<<28) /* shadowing a pae L3 page */
#define PGC_SH_l1_64_shadow (9U<<28) /* shadowing a 64-bit L1 page */
#define PGC_SH_fl1_64_shadow (10U<<28) /* L1 shadow for 64-bit 2M superpg */
#define PGC_SH_l2_64_shadow (11U<<28) /* shadowing a 64-bit L2 page */
#define PGC_SH_l3_64_shadow (12U<<28) /* shadowing a 64-bit L3 page */
#define PGC_SH_l4_64_shadow (13U<<28) /* shadowing a 64-bit L4 page */
#define PGC_SH_max_shadow (13U<<28)
#define PGC_SH_p2m_table (14U<<28) /* in use as the p2m table */
#define PGC_SH_monitor_table (15U<<28) /* in use as a monitor table */
#define PGC_SH_unused (15U<<28)
#define PGC_SH2_type_mask (15U<<28)
#define PGC_SH2_type_shift 28
#define PGC_SH_type_mask (15U<<28)
#define PGC_SH_type_shift 28
#define PGC_SH2_pinned (1U<<27)
#define PGC_SH_pinned (1U<<27)
#define _PGC_SH2_log_dirty 26
#define PGC_SH2_log_dirty (1U<<26)
#define _PGC_SH_log_dirty 26
#define PGC_SH_log_dirty (1U<<26)
/* 26 bit ref count for shadow pages */
#define PGC_SH2_count_mask ((1U<<26) - 1)
#define PGC_SH_count_mask ((1U<<26) - 1)
/* We trust the slab allocator in slab.c, and our use of it. */
#define PageSlab(page) (1)
@@ -201,9 +201,9 @@ static inline u32 pickle_domptr(struct domain *domain)
/* The order of the largest allocation unit we use for shadow pages */
#if CONFIG_PAGING_LEVELS == 2
#define SHADOW2_MAX_ORDER 0 /* Only ever need 4k allocations */
#define SHADOW_MAX_ORDER 0 /* Only ever need 4k allocations */
#else
#define SHADOW2_MAX_ORDER 2 /* Need up to 16k allocs for 32-bit on PAE/64 */
#define SHADOW_MAX_ORDER 2 /* Need up to 16k allocs for 32-bit on PAE/64 */
#endif
#define page_get_owner(_p) (unpickle_domptr((_p)->u.inuse._domain))
@@ -227,7 +227,7 @@ extern void invalidate_shadow_ldt(struct vcpu *d);
extern int shadow_remove_all_write_access(
struct domain *d, unsigned long gmfn, unsigned long mfn);
extern u32 shadow_remove_all_access( struct domain *d, unsigned long gmfn);
extern int _shadow2_mode_refcounts(struct domain *d);
extern int _shadow_mode_refcounts(struct domain *d);
static inline void put_page(struct page_info *page)
{
@@ -259,7 +259,7 @@ static inline int get_page(struct page_info *page,
unlikely((nx & PGC_count_mask) == 0) || /* Count overflow? */
unlikely(d != _domain) ) /* Wrong owner? */
{
if ( !_shadow2_mode_refcounts(domain) )
if ( !_shadow_mode_refcounts(domain) )
DPRINTK("Error pfn %lx: rd=%p, od=%p, caf=%08x, taf=%"
PRtype_info "\n",
page_to_mfn(page), domain, unpickle_domptr(d),
@@ -345,11 +345,11 @@ int check_descriptor(struct desc_struct *d);
#define mfn_to_gmfn(_d, mfn) \
( (shadow2_mode_translate(_d)) \
( (shadow_mode_translate(_d)) \
? get_gpfn_from_mfn(mfn) \
: (mfn) )
#define gmfn_to_mfn(_d, gpfn) mfn_x(sh2_gfn_to_mfn(_d, gpfn))
#define gmfn_to_mfn(_d, gpfn) mfn_x(sh_gfn_to_mfn(_d, gpfn))
/*
+51 -51
View File
@@ -30,59 +30,59 @@ PERFCOUNTER_CPU(ptwr_emulations, "writable pt emulations")
PERFCOUNTER_CPU(exception_fixed, "pre-exception fixed")
/* Shadow2 counters */
PERFCOUNTER_CPU(shadow2_alloc, "calls to shadow2_alloc")
PERFCOUNTER_CPU(shadow2_alloc_tlbflush, "shadow2_alloc flushed TLBs")
/* Shadow counters */
PERFCOUNTER_CPU(shadow_alloc, "calls to shadow_alloc")
PERFCOUNTER_CPU(shadow_alloc_tlbflush, "shadow_alloc flushed TLBs")
/* STATUS counters do not reset when 'P' is hit */
PERFSTATUS(shadow2_alloc_count, "number of shadow pages in use")
PERFCOUNTER_CPU(shadow2_free, "calls to shadow2_free")
PERFCOUNTER_CPU(shadow2_prealloc_1, "shadow2 recycles old shadows")
PERFCOUNTER_CPU(shadow2_prealloc_2, "shadow2 recycles in-use shadows")
PERFCOUNTER_CPU(shadow2_linear_map_failed, "shadow2 hit read-only linear map")
PERFCOUNTER_CPU(shadow2_a_update, "shadow2 A bit update")
PERFCOUNTER_CPU(shadow2_ad_update, "shadow2 A&D bit update")
PERFCOUNTER_CPU(shadow2_fault, "calls to shadow2_fault")
PERFCOUNTER_CPU(shadow2_fault_bail_bad_gfn, "shadow2_fault guest bad gfn")
PERFCOUNTER_CPU(shadow2_fault_bail_not_present,
"shadow2_fault guest not-present")
PERFCOUNTER_CPU(shadow2_fault_bail_nx, "shadow2_fault guest NX fault")
PERFCOUNTER_CPU(shadow2_fault_bail_ro_mapping, "shadow2_fault guest R/W fault")
PERFCOUNTER_CPU(shadow2_fault_bail_user_supervisor,
"shadow2_fault guest U/S fault")
PERFCOUNTER_CPU(shadow2_fault_emulate_read, "shadow2_fault emulates a read")
PERFCOUNTER_CPU(shadow2_fault_emulate_write, "shadow2_fault emulates a write")
PERFCOUNTER_CPU(shadow2_fault_emulate_failed, "shadow2_fault emulator fails")
PERFCOUNTER_CPU(shadow2_fault_mmio, "shadow2_fault handled as mmio")
PERFCOUNTER_CPU(shadow2_fault_fixed, "shadow2_fault fixed fault")
PERFCOUNTER_CPU(shadow2_ptwr_emulate, "shadow2 causes ptwr to emulate")
PERFCOUNTER_CPU(shadow2_validate_gl1e_calls, "calls to shadow2_validate_gl1e")
PERFCOUNTER_CPU(shadow2_validate_gl2e_calls, "calls to shadow2_validate_gl2e")
PERFCOUNTER_CPU(shadow2_validate_gl3e_calls, "calls to shadow2_validate_gl3e")
PERFCOUNTER_CPU(shadow2_validate_gl4e_calls, "calls to shadow2_validate_gl4e")
PERFCOUNTER_CPU(shadow2_hash_lookups, "calls to shadow2_hash_lookup")
PERFCOUNTER_CPU(shadow2_hash_lookup_head, "shadow2 hash hit in bucket head")
PERFCOUNTER_CPU(shadow2_hash_lookup_miss, "shadow2 hash misses")
PERFCOUNTER_CPU(shadow2_get_shadow_status, "calls to get_shadow_status")
PERFCOUNTER_CPU(shadow2_hash_inserts, "calls to shadow2_hash_insert")
PERFCOUNTER_CPU(shadow2_hash_deletes, "calls to shadow2_hash_delete")
PERFCOUNTER_CPU(shadow2_writeable, "shadow2 removes write access")
PERFCOUNTER_CPU(shadow2_writeable_h_1, "shadow2 writeable: 32b w2k3")
PERFCOUNTER_CPU(shadow2_writeable_h_2, "shadow2 writeable: 32pae w2k3")
PERFCOUNTER_CPU(shadow2_writeable_h_3, "shadow2 writeable: 64b w2k3")
PERFCOUNTER_CPU(shadow2_writeable_h_4, "shadow2 writeable: 32b linux low")
PERFCOUNTER_CPU(shadow2_writeable_bf, "shadow2 writeable brute-force")
PERFCOUNTER_CPU(shadow2_mappings, "shadow2 removes all mappings")
PERFCOUNTER_CPU(shadow2_mappings_bf, "shadow2 rm-mappings brute-force")
PERFCOUNTER_CPU(shadow2_early_unshadow, "shadow2 unshadows for fork/exit")
PERFCOUNTER_CPU(shadow2_early_unshadow_top, "shadow2 unhooks for fork/exit")
PERFCOUNTER_CPU(shadow2_unshadow, "shadow2 unshadows a page")
PERFCOUNTER_CPU(shadow2_up_pointer, "shadow2 unshadow by up-pointer")
PERFCOUNTER_CPU(shadow2_unshadow_bf, "shadow2 unshadow brute-force")
PERFCOUNTER_CPU(shadow2_get_page_fail, "shadow2_get_page_from_l1e failed")
PERFCOUNTER_CPU(shadow2_guest_walk, "shadow2 walks guest tables")
PERFCOUNTER_CPU(shadow2_walk_cache_hit, "shadow2 walk-cache hits")
PERFCOUNTER_CPU(shadow2_walk_cache_miss, "shadow2 walk-cache misses")
PERFSTATUS(shadow_alloc_count, "number of shadow pages in use")
PERFCOUNTER_CPU(shadow_free, "calls to shadow_free")
PERFCOUNTER_CPU(shadow_prealloc_1, "shadow recycles old shadows")
PERFCOUNTER_CPU(shadow_prealloc_2, "shadow recycles in-use shadows")
PERFCOUNTER_CPU(shadow_linear_map_failed, "shadow hit read-only linear map")
PERFCOUNTER_CPU(shadow_a_update, "shadow A bit update")
PERFCOUNTER_CPU(shadow_ad_update, "shadow A&D bit update")
PERFCOUNTER_CPU(shadow_fault, "calls to shadow_fault")
PERFCOUNTER_CPU(shadow_fault_bail_bad_gfn, "shadow_fault guest bad gfn")
PERFCOUNTER_CPU(shadow_fault_bail_not_present,
"shadow_fault guest not-present")
PERFCOUNTER_CPU(shadow_fault_bail_nx, "shadow_fault guest NX fault")
PERFCOUNTER_CPU(shadow_fault_bail_ro_mapping, "shadow_fault guest R/W fault")
PERFCOUNTER_CPU(shadow_fault_bail_user_supervisor,
"shadow_fault guest U/S fault")
PERFCOUNTER_CPU(shadow_fault_emulate_read, "shadow_fault emulates a read")
PERFCOUNTER_CPU(shadow_fault_emulate_write, "shadow_fault emulates a write")
PERFCOUNTER_CPU(shadow_fault_emulate_failed, "shadow_fault emulator fails")
PERFCOUNTER_CPU(shadow_fault_mmio, "shadow_fault handled as mmio")
PERFCOUNTER_CPU(shadow_fault_fixed, "shadow_fault fixed fault")
PERFCOUNTER_CPU(shadow_ptwr_emulate, "shadow causes ptwr to emulate")
PERFCOUNTER_CPU(shadow_validate_gl1e_calls, "calls to shadow_validate_gl1e")
PERFCOUNTER_CPU(shadow_validate_gl2e_calls, "calls to shadow_validate_gl2e")
PERFCOUNTER_CPU(shadow_validate_gl3e_calls, "calls to shadow_validate_gl3e")
PERFCOUNTER_CPU(shadow_validate_gl4e_calls, "calls to shadow_validate_gl4e")
PERFCOUNTER_CPU(shadow_hash_lookups, "calls to shadow_hash_lookup")
PERFCOUNTER_CPU(shadow_hash_lookup_head, "shadow hash hit in bucket head")
PERFCOUNTER_CPU(shadow_hash_lookup_miss, "shadow hash misses")
PERFCOUNTER_CPU(shadow_get_shadow_status, "calls to get_shadow_status")
PERFCOUNTER_CPU(shadow_hash_inserts, "calls to shadow_hash_insert")
PERFCOUNTER_CPU(shadow_hash_deletes, "calls to shadow_hash_delete")
PERFCOUNTER_CPU(shadow_writeable, "shadow removes write access")
PERFCOUNTER_CPU(shadow_writeable_h_1, "shadow writeable: 32b w2k3")
PERFCOUNTER_CPU(shadow_writeable_h_2, "shadow writeable: 32pae w2k3")
PERFCOUNTER_CPU(shadow_writeable_h_3, "shadow writeable: 64b w2k3")
PERFCOUNTER_CPU(shadow_writeable_h_4, "shadow writeable: 32b linux low")
PERFCOUNTER_CPU(shadow_writeable_bf, "shadow writeable brute-force")
PERFCOUNTER_CPU(shadow_mappings, "shadow removes all mappings")
PERFCOUNTER_CPU(shadow_mappings_bf, "shadow rm-mappings brute-force")
PERFCOUNTER_CPU(shadow_early_unshadow, "shadow unshadows for fork/exit")
PERFCOUNTER_CPU(shadow_early_unshadow_top, "shadow unhooks for fork/exit")
PERFCOUNTER_CPU(shadow_unshadow, "shadow unshadows a page")
PERFCOUNTER_CPU(shadow_up_pointer, "shadow unshadow by up-pointer")
PERFCOUNTER_CPU(shadow_unshadow_bf, "shadow unshadow brute-force")
PERFCOUNTER_CPU(shadow_get_page_fail, "shadow_get_page_from_l1e failed")
PERFCOUNTER_CPU(shadow_guest_walk, "shadow walks guest tables")
PERFCOUNTER_CPU(shadow_walk_cache_hit, "shadow walk-cache hits")
PERFCOUNTER_CPU(shadow_walk_cache_miss, "shadow walk-cache misses")
/*#endif*/ /* __XEN_PERFC_DEFN_H__ */
+598 -14
View File
@@ -1,7 +1,9 @@
/******************************************************************************
* include/asm-x86/shadow.h
*
* Copyright (c) 2006 by XenSource Inc.
* Parts of this code are Copyright (c) 2006 by XenSource Inc.
* Parts of this code are Copyright (c) 2006 by Michael A Fetterman
* Parts based on earlier work by Michael A Fetterman, Ian Pratt et al.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,26 +23,608 @@
#ifndef _XEN_SHADOW_H
#define _XEN_SHADOW_H
/* This file is just a wrapper around the new Shadow2 header,
* providing names that must be defined in any shadow implementation. */
#include <asm/shadow2.h>
#include <public/domctl.h>
#include <xen/sched.h>
#include <xen/perfc.h>
#include <asm/flushtlb.h>
/* How to make sure a page is not referred to in a shadow PT */
/* This will need to be a for_each_vcpu if we go to per-vcpu shadows */
#define shadow_drop_references(_d, _p) \
shadow2_remove_all_mappings((_d)->vcpu[0], _mfn(page_to_mfn(_p)))
shadow_remove_all_mappings((_d)->vcpu[0], _mfn(page_to_mfn(_p)))
#define shadow_sync_and_drop_references(_d, _p) \
shadow2_remove_all_mappings((_d)->vcpu[0], _mfn(page_to_mfn(_p)))
shadow_remove_all_mappings((_d)->vcpu[0], _mfn(page_to_mfn(_p)))
/* Whether we are translating the domain's frame numbers for it */
#define shadow_mode_translate(d) shadow2_mode_translate(d)
/* ...and if so, how to add and remove entries in the mapping */
/* How to add and remove entries in the p2m mapping. */
#define guest_physmap_add_page(_d, _p, _m) \
shadow2_guest_physmap_add_page((_d), (_p), (_m))
shadow_guest_physmap_add_page((_d), (_p), (_m))
#define guest_physmap_remove_page(_d, _p, _m ) \
shadow2_guest_physmap_remove_page((_d), (_p), (_m))
shadow_guest_physmap_remove_page((_d), (_p), (_m))
/* Shadow PT operation mode : shadow-mode variable in arch_domain. */
#define SHM2_shift 10
/* We're in one of the shadow modes */
#define SHM2_enable (1U << SHM2_shift)
/* Refcounts based on shadow tables instead of guest tables */
#define SHM2_refcounts (XEN_DOMCTL_SHADOW_ENABLE_REFCOUNT << SHM2_shift)
/* Enable log dirty mode */
#define SHM2_log_dirty (XEN_DOMCTL_SHADOW_ENABLE_LOG_DIRTY << SHM2_shift)
/* Xen does p2m translation, not guest */
#define SHM2_translate (XEN_DOMCTL_SHADOW_ENABLE_TRANSLATE << SHM2_shift)
/* Xen does not steal address space from the domain for its own booking;
* requires VT or similar mechanisms */
#define SHM2_external (XEN_DOMCTL_SHADOW_ENABLE_EXTERNAL << SHM2_shift)
#define shadow_mode_enabled(_d) ((_d)->arch.shadow.mode)
#define shadow_mode_refcounts(_d) ((_d)->arch.shadow.mode & SHM2_refcounts)
#define shadow_mode_log_dirty(_d) ((_d)->arch.shadow.mode & SHM2_log_dirty)
#define shadow_mode_translate(_d) ((_d)->arch.shadow.mode & SHM2_translate)
#define shadow_mode_external(_d) ((_d)->arch.shadow.mode & SHM2_external)
/* Xen traps & emulates all reads of all page table pages:
*not yet supported
*/
#define shadow_mode_trap_reads(_d) ({ (void)(_d); 0; })
// flags used in the return value of the shadow_set_lXe() functions...
#define SHADOW_SET_CHANGED 0x1
#define SHADOW_SET_FLUSH 0x2
#define SHADOW_SET_ERROR 0x4
#define SHADOW_SET_L3PAE_RECOPY 0x8
// How do we tell that we have a 32-bit PV guest in a 64-bit Xen?
#ifdef __x86_64__
#define pv_32bit_guest(_v) 0 // not yet supported
#else
#define pv_32bit_guest(_v) !hvm_guest(v)
#endif
/* The shadow lock.
*
* This lock is per-domain. It is intended to allow us to make atomic
* updates to the software TLB that the shadow tables provide.
*
* Specifically, it protects:
* - all changes to shadow page table pages
* - the shadow hash table
* - the shadow page allocator
* - all changes to guest page table pages; if/when the notion of
* out-of-sync pages is added to this code, then the shadow lock is
* protecting all guest page table pages which are not listed as
* currently as both guest-writable and out-of-sync...
* XXX -- need to think about this relative to writable page tables.
* - all changes to the page_info->tlbflush_timestamp
* - the page_info->count fields on shadow pages
* - the shadow dirty bit array and count
* - XXX
*/
#ifndef CONFIG_SMP
#error shadow.h currently requires CONFIG_SMP
#endif
#define shadow_lock_init(_d) \
do { \
spin_lock_init(&(_d)->arch.shadow.lock); \
(_d)->arch.shadow.locker = -1; \
(_d)->arch.shadow.locker_function = "nobody"; \
} while (0)
#define shadow_lock_is_acquired(_d) \
(current->processor == (_d)->arch.shadow.locker)
#define shadow_lock(_d) \
do { \
if ( unlikely((_d)->arch.shadow.locker == current->processor) ) \
{ \
printk("Error: shadow lock held by %s\n", \
(_d)->arch.shadow.locker_function); \
BUG(); \
} \
spin_lock(&(_d)->arch.shadow.lock); \
ASSERT((_d)->arch.shadow.locker == -1); \
(_d)->arch.shadow.locker = current->processor; \
(_d)->arch.shadow.locker_function = __func__; \
} while (0)
#define shadow_unlock(_d) \
do { \
ASSERT((_d)->arch.shadow.locker == current->processor); \
(_d)->arch.shadow.locker = -1; \
(_d)->arch.shadow.locker_function = "nobody"; \
spin_unlock(&(_d)->arch.shadow.lock); \
} while (0)
/*
* Levels of self-test and paranoia
* XXX should go in config files somewhere?
*/
#define SHADOW_AUDIT_HASH 0x01 /* Check current hash bucket */
#define SHADOW_AUDIT_HASH_FULL 0x02 /* Check every hash bucket */
#define SHADOW_AUDIT_ENTRIES 0x04 /* Check this walk's shadows */
#define SHADOW_AUDIT_ENTRIES_FULL 0x08 /* Check every shadow */
#define SHADOW_AUDIT_ENTRIES_MFNS 0x10 /* Check gfn-mfn map in shadows */
#define SHADOW_AUDIT_P2M 0x20 /* Check the p2m table */
#ifdef NDEBUG
#define SHADOW_AUDIT 0
#define SHADOW_AUDIT_ENABLE 0
#else
#define SHADOW_AUDIT 0x15 /* Basic audit of all except p2m. */
#define SHADOW_AUDIT_ENABLE shadow_audit_enable
extern int shadow_audit_enable;
#endif
/*
* Levels of optimization
* XXX should go in config files somewhere?
*/
#define SHOPT_WRITABLE_HEURISTIC 0x01 /* Guess at RW PTEs via linear maps */
#define SHOPT_EARLY_UNSHADOW 0x02 /* Unshadow l1s on fork or exit */
#define SHADOW_OPTIMIZATIONS 0x03
/* With shadow pagetables, the different kinds of address start
* to get get confusing.
*
* Virtual addresses are what they usually are: the addresses that are used
* to accessing memory while the guest is running. The MMU translates from
* virtual addresses to machine addresses.
*
* (Pseudo-)physical addresses are the abstraction of physical memory the
* guest uses for allocation and so forth. For the purposes of this code,
* we can largely ignore them.
*
* Guest frame numbers (gfns) are the entries that the guest puts in its
* pagetables. For normal paravirtual guests, they are actual frame numbers,
* with the translation done by the guest.
*
* Machine frame numbers (mfns) are the entries that the hypervisor puts
* in the shadow page tables.
*
* Elsewhere in the xen code base, the name "gmfn" is generally used to refer
* to a "machine frame number, from the guest's perspective", or in other
* words, pseudo-physical frame numbers. However, in the shadow code, the
* term "gmfn" means "the mfn of a guest page"; this combines naturally with
* other terms such as "smfn" (the mfn of a shadow page), gl2mfn (the mfn of a
* guest L2 page), etc...
*/
/* With this defined, we do some ugly things to force the compiler to
* give us type safety between mfns and gfns and other integers.
* TYPE_SAFE(int foo) defines a foo_t, and _foo() and foo_x() functions
* that translate beween int and foo_t.
*
* It does have some performance cost because the types now have
* a different storage attribute, so may not want it on all the time. */
#ifndef NDEBUG
#define TYPE_SAFETY 1
#endif
#ifdef TYPE_SAFETY
#define TYPE_SAFE(_type,_name) \
typedef struct { _type _name; } _name##_t; \
static inline _name##_t _##_name(_type n) { return (_name##_t) { n }; } \
static inline _type _name##_x(_name##_t n) { return n._name; }
#else
#define TYPE_SAFE(_type,_name) \
typedef _type _name##_t; \
static inline _name##_t _##_name(_type n) { return n; } \
static inline _type _name##_x(_name##_t n) { return n; }
#endif
TYPE_SAFE(unsigned long,mfn)
#define SH_PRI_mfn "05lx"
static inline int
valid_mfn(mfn_t m)
{
return VALID_MFN(mfn_x(m));
}
static inline mfn_t
pagetable_get_mfn(pagetable_t pt)
{
return _mfn(pagetable_get_pfn(pt));
}
static inline pagetable_t
pagetable_from_mfn(mfn_t mfn)
{
return pagetable_from_pfn(mfn_x(mfn));
}
static inline int
shadow_vcpu_mode_translate(struct vcpu *v)
{
// Returns true if this VCPU needs to be using the P2M table to translate
// between GFNs and MFNs.
//
// This is true of translated HVM domains on a vcpu which has paging
// enabled. (HVM vcpu's with paging disabled are using the p2m table as
// its paging table, so no translation occurs in this case.)
//
return v->arch.shadow.hvm_paging_enabled;
}
/**************************************************************************/
/* Mode-specific entry points into the shadow code */
struct x86_emulate_ctxt;
struct shadow_paging_mode {
int (*page_fault )(struct vcpu *v, unsigned long va,
struct cpu_user_regs *regs);
int (*invlpg )(struct vcpu *v, unsigned long va);
unsigned long (*gva_to_gpa )(struct vcpu *v, unsigned long va);
unsigned long (*gva_to_gfn )(struct vcpu *v, unsigned long va);
void (*update_cr3 )(struct vcpu *v);
int (*map_and_validate_gl1e )(struct vcpu *v, mfn_t gmfn,
void *new_guest_entry, u32 size);
int (*map_and_validate_gl2e )(struct vcpu *v, mfn_t gmfn,
void *new_guest_entry, u32 size);
int (*map_and_validate_gl2he)(struct vcpu *v, mfn_t gmfn,
void *new_guest_entry, u32 size);
int (*map_and_validate_gl3e )(struct vcpu *v, mfn_t gmfn,
void *new_guest_entry, u32 size);
int (*map_and_validate_gl4e )(struct vcpu *v, mfn_t gmfn,
void *new_guest_entry, u32 size);
void (*detach_old_tables )(struct vcpu *v);
int (*x86_emulate_write )(struct vcpu *v, unsigned long va,
void *src, u32 bytes,
struct x86_emulate_ctxt *ctxt);
int (*x86_emulate_cmpxchg )(struct vcpu *v, unsigned long va,
unsigned long old,
unsigned long new,
unsigned int bytes,
struct x86_emulate_ctxt *ctxt);
int (*x86_emulate_cmpxchg8b )(struct vcpu *v, unsigned long va,
unsigned long old_lo,
unsigned long old_hi,
unsigned long new_lo,
unsigned long new_hi,
struct x86_emulate_ctxt *ctxt);
mfn_t (*make_monitor_table )(struct vcpu *v);
void (*destroy_monitor_table )(struct vcpu *v, mfn_t mmfn);
#if SHADOW_OPTIMIZATIONS & SHOPT_WRITABLE_HEURISTIC
int (*guess_wrmap )(struct vcpu *v,
unsigned long vaddr, mfn_t gmfn);
#endif
/* For outsiders to tell what mode we're in */
unsigned int shadow_levels;
unsigned int guest_levels;
};
static inline int shadow_guest_paging_levels(struct vcpu *v)
{
ASSERT(v->arch.shadow.mode != NULL);
return v->arch.shadow.mode->guest_levels;
}
/**************************************************************************/
/* Entry points into the shadow code */
/* Turning on shadow test mode */
int shadow_test_enable(struct domain *d);
/* Handler for shadow control ops: enabling and disabling shadow modes,
* and log-dirty bitmap ops all happen through here. */
int shadow_domctl(struct domain *d,
xen_domctl_shadow_op_t *sc,
XEN_GUEST_HANDLE(xen_domctl_t) u_domctl);
/* Call when destroying a domain */
void shadow_teardown(struct domain *d);
/* Call once all of the references to the domain have gone away */
void shadow_final_teardown(struct domain *d);
/* Mark a page as dirty in the bitmap */
void sh_do_mark_dirty(struct domain *d, mfn_t gmfn);
static inline void mark_dirty(struct domain *d, unsigned long gmfn)
{
if ( shadow_mode_log_dirty(d) )
{
shadow_lock(d);
sh_do_mark_dirty(d, _mfn(gmfn));
shadow_unlock(d);
}
}
/* Internal version, for when the shadow lock is already held */
static inline void sh_mark_dirty(struct domain *d, mfn_t gmfn)
{
ASSERT(shadow_lock_is_acquired(d));
if ( shadow_mode_log_dirty(d) )
sh_do_mark_dirty(d, gmfn);
}
static inline int
shadow_fault(unsigned long va, struct cpu_user_regs *regs)
/* Called from pagefault handler in Xen, and from the HVM trap handlers
* for pagefaults. Returns 1 if this fault was an artefact of the
* shadow code (and the guest should retry) or 0 if it is not (and the
* fault should be handled elsewhere or passed to the guest). */
{
struct vcpu *v = current;
perfc_incrc(shadow_fault);
return v->arch.shadow.mode->page_fault(v, va, regs);
}
static inline int
shadow_invlpg(struct vcpu *v, unsigned long va)
/* Called when the guest requests an invlpg. Returns 1 if the invlpg
* instruction should be issued on the hardware, or 0 if it's safe not
* to do so. */
{
return v->arch.shadow.mode->invlpg(v, va);
}
static inline unsigned long
shadow_gva_to_gpa(struct vcpu *v, unsigned long va)
/* Called to translate a guest virtual address to what the *guest*
* pagetables would map it to. */
{
return v->arch.shadow.mode->gva_to_gpa(v, va);
}
static inline unsigned long
shadow_gva_to_gfn(struct vcpu *v, unsigned long va)
/* Called to translate a guest virtual address to what the *guest*
* pagetables would map it to. */
{
return v->arch.shadow.mode->gva_to_gfn(v, va);
}
static inline void
shadow_update_cr3(struct vcpu *v)
/* Updates all the things that are derived from the guest's CR3.
* Called when the guest changes CR3. */
{
shadow_lock(v->domain);
v->arch.shadow.mode->update_cr3(v);
shadow_unlock(v->domain);
}
/* Should be called after CR3 is updated.
* Updates vcpu->arch.cr3 and, for HVM guests, vcpu->arch.hvm_vcpu.cpu_cr3.
*
* Also updates other state derived from CR3 (vcpu->arch.guest_vtable,
* shadow_vtable, etc).
*
* Uses values found in vcpu->arch.(guest_table and guest_table_user), and
* for HVM guests, arch.monitor_table and hvm's guest CR3.
*
* Update ref counts to shadow tables appropriately.
* For PAE, relocate L3 entries, if necessary, into low memory.
*/
static inline void update_cr3(struct vcpu *v)
{
unsigned long cr3_mfn=0;
if ( shadow_mode_enabled(v->domain) )
{
shadow_update_cr3(v);
return;
}
#if CONFIG_PAGING_LEVELS == 4
if ( !(v->arch.flags & TF_kernel_mode) )
cr3_mfn = pagetable_get_pfn(v->arch.guest_table_user);
else
#endif
cr3_mfn = pagetable_get_pfn(v->arch.guest_table);
make_cr3(v, cr3_mfn);
}
extern void sh_update_paging_modes(struct vcpu *v);
/* Should be called to initialise paging structures if the paging mode
* has changed, and when bringing up a VCPU for the first time. */
static inline void shadow_update_paging_modes(struct vcpu *v)
{
ASSERT(shadow_mode_enabled(v->domain));
shadow_lock(v->domain);
sh_update_paging_modes(v);
shadow_unlock(v->domain);
}
static inline void
shadow_detach_old_tables(struct vcpu *v)
{
if ( v->arch.shadow.mode )
v->arch.shadow.mode->detach_old_tables(v);
}
static inline mfn_t
shadow_make_monitor_table(struct vcpu *v)
{
return v->arch.shadow.mode->make_monitor_table(v);
}
static inline void
shadow_destroy_monitor_table(struct vcpu *v, mfn_t mmfn)
{
v->arch.shadow.mode->destroy_monitor_table(v, mmfn);
}
/* Validate a pagetable change from the guest and update the shadows. */
extern int shadow_validate_guest_entry(struct vcpu *v, mfn_t gmfn,
void *new_guest_entry);
/* Update the shadows in response to a pagetable write from a HVM guest */
extern void shadow_validate_guest_pt_write(struct vcpu *v, mfn_t gmfn,
void *entry, u32 size);
/* Remove all writeable mappings of a guest frame from the shadows.
* Returns non-zero if we need to flush TLBs.
* level and fault_addr desribe how we found this to be a pagetable;
* level==0 means we have some other reason for revoking write access. */
extern int shadow_remove_write_access(struct vcpu *v, mfn_t readonly_mfn,
unsigned int level,
unsigned long fault_addr);
/* Remove all mappings of the guest mfn from the shadows.
* Returns non-zero if we need to flush TLBs. */
extern int shadow_remove_all_mappings(struct vcpu *v, mfn_t target_mfn);
void
shadow_remove_all_shadows_and_parents(struct vcpu *v, mfn_t gmfn);
/* This is a HVM page that we thing is no longer a pagetable.
* Unshadow it, and recursively unshadow pages that reference it. */
/* Remove all shadows of the guest mfn. */
extern void sh_remove_shadows(struct vcpu *v, mfn_t gmfn, int all);
static inline void shadow_remove_all_shadows(struct vcpu *v, mfn_t gmfn)
{
sh_remove_shadows(v, gmfn, 1);
}
/* Add a page to a domain */
void
shadow_guest_physmap_add_page(struct domain *d, unsigned long gfn,
unsigned long mfn);
/* Remove a page from a domain */
void
shadow_guest_physmap_remove_page(struct domain *d, unsigned long gfn,
unsigned long mfn);
/*
* Definitions for the shadow_flags field in page_info.
* These flags are stored on *guest* pages...
* Bits 1-13 are encodings for the shadow types.
*/
#define PGC_SH_type_to_index(_type) ((_type) >> PGC_SH_type_shift)
#define SHF_page_type_mask \
(((1u << (PGC_SH_type_to_index(PGC_SH_max_shadow) + 1u)) - 1u) - \
((1u << PGC_SH_type_to_index(PGC_SH_min_shadow)) - 1u))
#define SHF_L1_32 (1u << PGC_SH_type_to_index(PGC_SH_l1_32_shadow))
#define SHF_FL1_32 (1u << PGC_SH_type_to_index(PGC_SH_fl1_32_shadow))
#define SHF_L2_32 (1u << PGC_SH_type_to_index(PGC_SH_l2_32_shadow))
#define SHF_L1_PAE (1u << PGC_SH_type_to_index(PGC_SH_l1_pae_shadow))
#define SHF_FL1_PAE (1u << PGC_SH_type_to_index(PGC_SH_fl1_pae_shadow))
#define SHF_L2_PAE (1u << PGC_SH_type_to_index(PGC_SH_l2_pae_shadow))
#define SHF_L2H_PAE (1u << PGC_SH_type_to_index(PGC_SH_l2h_pae_shadow))
#define SHF_L3_PAE (1u << PGC_SH_type_to_index(PGC_SH_l3_pae_shadow))
#define SHF_L1_64 (1u << PGC_SH_type_to_index(PGC_SH_l1_64_shadow))
#define SHF_FL1_64 (1u << PGC_SH_type_to_index(PGC_SH_fl1_64_shadow))
#define SHF_L2_64 (1u << PGC_SH_type_to_index(PGC_SH_l2_64_shadow))
#define SHF_L3_64 (1u << PGC_SH_type_to_index(PGC_SH_l3_64_shadow))
#define SHF_L4_64 (1u << PGC_SH_type_to_index(PGC_SH_l4_64_shadow))
/* Used for hysteresis when automatically unhooking mappings on fork/exit */
#define SHF_unhooked_mappings (1u<<31)
/*
* Allocation of shadow pages
*/
/* Return the minumum acceptable number of shadow pages a domain needs */
unsigned int shadow_min_acceptable_pages(struct domain *d);
/* Set the pool of shadow pages to the required number of MB.
* Input will be rounded up to at least min_acceptable_shadow_pages().
* Returns 0 for success, 1 for failure. */
unsigned int shadow_set_allocation(struct domain *d,
unsigned int megabytes,
int *preempted);
/* Return the size of the shadow pool, rounded up to the nearest MB */
static inline unsigned int shadow_get_allocation(struct domain *d)
{
unsigned int pg = d->arch.shadow.total_pages;
return ((pg >> (20 - PAGE_SHIFT))
+ ((pg & ((1 << (20 - PAGE_SHIFT)) - 1)) ? 1 : 0));
}
/*
* Linked list for chaining entries in the shadow hash table.
*/
struct shadow_hash_entry {
struct shadow_hash_entry *next;
mfn_t smfn; /* MFN of the shadow */
#ifdef _x86_64_ /* Shorten 'n' so we don't waste a whole word on storing 't' */
unsigned long n:56; /* MFN of guest PT or GFN of guest superpage */
#else
unsigned long n; /* MFN of guest PT or GFN of guest superpage */
#endif
unsigned char t; /* shadow type bits, or 0 for empty */
};
#define SHADOW_HASH_BUCKETS 251
/* Other possibly useful primes are 509, 1021, 2039, 4093, 8191, 16381 */
#if SHADOW_OPTIMIZATIONS & SHOPT_CACHE_WALKS
/* Optimization: cache the results of guest walks. This helps with MMIO
* and emulated writes, which tend to issue very similar walk requests
* repeatedly. We keep the results of the last few walks, and blow
* away the cache on guest cr3 write, mode change, or page fault. */
#define SH_WALK_CACHE_ENTRIES 4
/* Rather than cache a guest walk, which would include mapped pointers
* to pages, we cache what a TLB would remember about the walk: the
* permissions and the l1 gfn */
struct shadow_walk_cache {
unsigned long va; /* The virtual address (or 0 == unused) */
unsigned long gfn; /* The gfn from the effective l1e */
u32 permissions; /* The aggregated permission bits */
};
#endif
/**************************************************************************/
/* Guest physmap (p2m) support */
/* Walk another domain's P2M table, mapping pages as we go */
extern mfn_t
sh_gfn_to_mfn_foreign(struct domain *d, unsigned long gpfn);
/* General conversion function from gfn to mfn */
static inline mfn_t
sh_gfn_to_mfn(struct domain *d, unsigned long gfn)
{
if ( !shadow_mode_translate(d) )
return _mfn(gfn);
else if ( likely(current->domain == d) )
return _mfn(get_mfn_from_gpfn(gfn));
else
return sh_gfn_to_mfn_foreign(d, gfn);
}
// vcpu-specific version of gfn_to_mfn(). This is where we hide the dirty
// little secret that, for hvm guests with paging disabled, nearly all of the
// shadow code actually think that the guest is running on *untranslated* page
// tables (which is actually domain->phys_table).
//
static inline mfn_t
sh_vcpu_gfn_to_mfn(struct vcpu *v, unsigned long gfn)
{
if ( !shadow_vcpu_mode_translate(v) )
return _mfn(gfn);
if ( likely(current->domain == v->domain) )
return _mfn(get_mfn_from_gpfn(gfn));
return sh_gfn_to_mfn_foreign(v->domain, gfn);
}
static inline unsigned long
sh_mfn_to_gfn(struct domain *d, mfn_t mfn)
{
if ( shadow_mode_translate(d) )
return get_gpfn_from_mfn(mfn_x(mfn));
else
return mfn_x(mfn);
}
#endif /* _XEN_SHADOW_H */
@@ -49,7 +633,7 @@
* mode: C
* c-set-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
-626
View File
@@ -1,626 +0,0 @@
/******************************************************************************
* include/asm-x86/shadow2.h
*
* Parts of this code are Copyright (c) 2006 by XenSource Inc.
* Parts of this code are Copyright (c) 2006 by Michael A Fetterman
* Parts based on earlier work by Michael A Fetterman, Ian Pratt et al.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _XEN_SHADOW2_H
#define _XEN_SHADOW2_H
#include <public/domctl.h>
#include <xen/sched.h>
#include <xen/perfc.h>
#include <asm/flushtlb.h>
/* Shadow PT operation mode : shadow-mode variable in arch_domain. */
#define SHM2_shift 10
/* We're in one of the shadow modes */
#define SHM2_enable (1U << SHM2_shift)
/* Refcounts based on shadow tables instead of guest tables */
#define SHM2_refcounts (XEN_DOMCTL_SHADOW_ENABLE_REFCOUNT << SHM2_shift)
/* Enable log dirty mode */
#define SHM2_log_dirty (XEN_DOMCTL_SHADOW_ENABLE_LOG_DIRTY << SHM2_shift)
/* Xen does p2m translation, not guest */
#define SHM2_translate (XEN_DOMCTL_SHADOW_ENABLE_TRANSLATE << SHM2_shift)
/* Xen does not steal address space from the domain for its own booking;
* requires VT or similar mechanisms */
#define SHM2_external (XEN_DOMCTL_SHADOW_ENABLE_EXTERNAL << SHM2_shift)
#define shadow2_mode_enabled(_d) ((_d)->arch.shadow2.mode)
#define shadow2_mode_refcounts(_d) ((_d)->arch.shadow2.mode & SHM2_refcounts)
#define shadow2_mode_log_dirty(_d) ((_d)->arch.shadow2.mode & SHM2_log_dirty)
#define shadow2_mode_translate(_d) ((_d)->arch.shadow2.mode & SHM2_translate)
#define shadow2_mode_external(_d) ((_d)->arch.shadow2.mode & SHM2_external)
/* Xen traps & emulates all reads of all page table pages:
*not yet supported
*/
#define shadow2_mode_trap_reads(_d) ({ (void)(_d); 0; })
// flags used in the return value of the shadow_set_lXe() functions...
#define SHADOW2_SET_CHANGED 0x1
#define SHADOW2_SET_FLUSH 0x2
#define SHADOW2_SET_ERROR 0x4
#define SHADOW2_SET_L3PAE_RECOPY 0x8
// How do we tell that we have a 32-bit PV guest in a 64-bit Xen?
#ifdef __x86_64__
#define pv_32bit_guest(_v) 0 // not yet supported
#else
#define pv_32bit_guest(_v) !hvm_guest(v)
#endif
/* The shadow2 lock.
*
* This lock is per-domain. It is intended to allow us to make atomic
* updates to the software TLB that the shadow tables provide.
*
* Specifically, it protects:
* - all changes to shadow page table pages
* - the shadow hash table
* - the shadow page allocator
* - all changes to guest page table pages; if/when the notion of
* out-of-sync pages is added to this code, then the shadow lock is
* protecting all guest page table pages which are not listed as
* currently as both guest-writable and out-of-sync...
* XXX -- need to think about this relative to writable page tables.
* - all changes to the page_info->tlbflush_timestamp
* - the page_info->count fields on shadow pages
* - the shadow dirty bit array and count
* - XXX
*/
#ifndef CONFIG_SMP
#error shadow2.h currently requires CONFIG_SMP
#endif
#define shadow2_lock_init(_d) \
do { \
spin_lock_init(&(_d)->arch.shadow2.lock); \
(_d)->arch.shadow2.locker = -1; \
(_d)->arch.shadow2.locker_function = "nobody"; \
} while (0)
#define shadow2_lock_is_acquired(_d) \
(current->processor == (_d)->arch.shadow2.locker)
#define shadow2_lock(_d) \
do { \
if ( unlikely((_d)->arch.shadow2.locker == current->processor) ) \
{ \
printk("Error: shadow2 lock held by %s\n", \
(_d)->arch.shadow2.locker_function); \
BUG(); \
} \
spin_lock(&(_d)->arch.shadow2.lock); \
ASSERT((_d)->arch.shadow2.locker == -1); \
(_d)->arch.shadow2.locker = current->processor; \
(_d)->arch.shadow2.locker_function = __func__; \
} while (0)
#define shadow2_unlock(_d) \
do { \
ASSERT((_d)->arch.shadow2.locker == current->processor); \
(_d)->arch.shadow2.locker = -1; \
(_d)->arch.shadow2.locker_function = "nobody"; \
spin_unlock(&(_d)->arch.shadow2.lock); \
} while (0)
/*
* Levels of self-test and paranoia
* XXX should go in config files somewhere?
*/
#define SHADOW2_AUDIT_HASH 0x01 /* Check current hash bucket */
#define SHADOW2_AUDIT_HASH_FULL 0x02 /* Check every hash bucket */
#define SHADOW2_AUDIT_ENTRIES 0x04 /* Check this walk's shadows */
#define SHADOW2_AUDIT_ENTRIES_FULL 0x08 /* Check every shadow */
#define SHADOW2_AUDIT_ENTRIES_MFNS 0x10 /* Check gfn-mfn map in shadows */
#define SHADOW2_AUDIT_P2M 0x20 /* Check the p2m table */
#ifdef NDEBUG
#define SHADOW2_AUDIT 0
#define SHADOW2_AUDIT_ENABLE 0
#else
#define SHADOW2_AUDIT 0x15 /* Basic audit of all except p2m. */
#define SHADOW2_AUDIT_ENABLE shadow2_audit_enable
extern int shadow2_audit_enable;
#endif
/*
* Levels of optimization
* XXX should go in config files somewhere?
*/
#define SH2OPT_WRITABLE_HEURISTIC 0x01 /* Guess at RW PTEs via linear maps */
#define SH2OPT_EARLY_UNSHADOW 0x02 /* Unshadow l1s on fork or exit */
#define SHADOW2_OPTIMIZATIONS 0x03
/* With shadow pagetables, the different kinds of address start
* to get get confusing.
*
* Virtual addresses are what they usually are: the addresses that are used
* to accessing memory while the guest is running. The MMU translates from
* virtual addresses to machine addresses.
*
* (Pseudo-)physical addresses are the abstraction of physical memory the
* guest uses for allocation and so forth. For the purposes of this code,
* we can largely ignore them.
*
* Guest frame numbers (gfns) are the entries that the guest puts in its
* pagetables. For normal paravirtual guests, they are actual frame numbers,
* with the translation done by the guest.
*
* Machine frame numbers (mfns) are the entries that the hypervisor puts
* in the shadow page tables.
*
* Elsewhere in the xen code base, the name "gmfn" is generally used to refer
* to a "machine frame number, from the guest's perspective", or in other
* words, pseudo-physical frame numbers. However, in the shadow code, the
* term "gmfn" means "the mfn of a guest page"; this combines naturally with
* other terms such as "smfn" (the mfn of a shadow page), gl2mfn (the mfn of a
* guest L2 page), etc...
*/
/* With this defined, we do some ugly things to force the compiler to
* give us type safety between mfns and gfns and other integers.
* TYPE_SAFE(int foo) defines a foo_t, and _foo() and foo_x() functions
* that translate beween int and foo_t.
*
* It does have some performance cost because the types now have
* a different storage attribute, so may not want it on all the time. */
#ifndef NDEBUG
#define TYPE_SAFETY 1
#endif
#ifdef TYPE_SAFETY
#define TYPE_SAFE(_type,_name) \
typedef struct { _type _name; } _name##_t; \
static inline _name##_t _##_name(_type n) { return (_name##_t) { n }; } \
static inline _type _name##_x(_name##_t n) { return n._name; }
#else
#define TYPE_SAFE(_type,_name) \
typedef _type _name##_t; \
static inline _name##_t _##_name(_type n) { return n; } \
static inline _type _name##_x(_name##_t n) { return n; }
#endif
TYPE_SAFE(unsigned long,mfn)
#define SH2_PRI_mfn "05lx"
static inline int
valid_mfn(mfn_t m)
{
return VALID_MFN(mfn_x(m));
}
static inline mfn_t
pagetable_get_mfn(pagetable_t pt)
{
return _mfn(pagetable_get_pfn(pt));
}
static inline pagetable_t
pagetable_from_mfn(mfn_t mfn)
{
return pagetable_from_pfn(mfn_x(mfn));
}
static inline int
shadow2_vcpu_mode_translate(struct vcpu *v)
{
// Returns true if this VCPU needs to be using the P2M table to translate
// between GFNs and MFNs.
//
// This is true of translated HVM domains on a vcpu which has paging
// enabled. (HVM vcpu's with paging disabled are using the p2m table as
// its paging table, so no translation occurs in this case.)
//
return v->arch.shadow2.hvm_paging_enabled;
}
/**************************************************************************/
/* Mode-specific entry points into the shadow code */
struct x86_emulate_ctxt;
struct shadow2_paging_mode {
int (*page_fault )(struct vcpu *v, unsigned long va,
struct cpu_user_regs *regs);
int (*invlpg )(struct vcpu *v, unsigned long va);
unsigned long (*gva_to_gpa )(struct vcpu *v, unsigned long va);
unsigned long (*gva_to_gfn )(struct vcpu *v, unsigned long va);
void (*update_cr3 )(struct vcpu *v);
int (*map_and_validate_gl1e )(struct vcpu *v, mfn_t gmfn,
void *new_guest_entry, u32 size);
int (*map_and_validate_gl2e )(struct vcpu *v, mfn_t gmfn,
void *new_guest_entry, u32 size);
int (*map_and_validate_gl2he)(struct vcpu *v, mfn_t gmfn,
void *new_guest_entry, u32 size);
int (*map_and_validate_gl3e )(struct vcpu *v, mfn_t gmfn,
void *new_guest_entry, u32 size);
int (*map_and_validate_gl4e )(struct vcpu *v, mfn_t gmfn,
void *new_guest_entry, u32 size);
void (*detach_old_tables )(struct vcpu *v);
int (*x86_emulate_write )(struct vcpu *v, unsigned long va,
void *src, u32 bytes,
struct x86_emulate_ctxt *ctxt);
int (*x86_emulate_cmpxchg )(struct vcpu *v, unsigned long va,
unsigned long old,
unsigned long new,
unsigned int bytes,
struct x86_emulate_ctxt *ctxt);
int (*x86_emulate_cmpxchg8b )(struct vcpu *v, unsigned long va,
unsigned long old_lo,
unsigned long old_hi,
unsigned long new_lo,
unsigned long new_hi,
struct x86_emulate_ctxt *ctxt);
mfn_t (*make_monitor_table )(struct vcpu *v);
void (*destroy_monitor_table )(struct vcpu *v, mfn_t mmfn);
#if SHADOW2_OPTIMIZATIONS & SH2OPT_WRITABLE_HEURISTIC
int (*guess_wrmap )(struct vcpu *v,
unsigned long vaddr, mfn_t gmfn);
#endif
/* For outsiders to tell what mode we're in */
unsigned int shadow_levels;
unsigned int guest_levels;
};
static inline int shadow2_guest_paging_levels(struct vcpu *v)
{
ASSERT(v->arch.shadow2.mode != NULL);
return v->arch.shadow2.mode->guest_levels;
}
/**************************************************************************/
/* Entry points into the shadow code */
/* Turning on shadow2 test mode */
int shadow2_test_enable(struct domain *d);
/* Handler for shadow control ops: enabling and disabling shadow modes,
* and log-dirty bitmap ops all happen through here. */
int shadow2_domctl(struct domain *d,
xen_domctl_shadow_op_t *sc,
XEN_GUEST_HANDLE(xen_domctl_t) u_domctl);
/* Call when destroying a domain */
void shadow2_teardown(struct domain *d);
/* Call once all of the references to the domain have gone away */
void shadow2_final_teardown(struct domain *d);
/* Mark a page as dirty in the bitmap */
void sh2_do_mark_dirty(struct domain *d, mfn_t gmfn);
static inline void mark_dirty(struct domain *d, unsigned long gmfn)
{
if ( shadow2_mode_log_dirty(d) )
{
shadow2_lock(d);
sh2_do_mark_dirty(d, _mfn(gmfn));
shadow2_unlock(d);
}
}
/* Internal version, for when the shadow lock is already held */
static inline void sh2_mark_dirty(struct domain *d, mfn_t gmfn)
{
ASSERT(shadow2_lock_is_acquired(d));
if ( shadow2_mode_log_dirty(d) )
sh2_do_mark_dirty(d, gmfn);
}
static inline int
shadow2_fault(unsigned long va, struct cpu_user_regs *regs)
/* Called from pagefault handler in Xen, and from the HVM trap handlers
* for pagefaults. Returns 1 if this fault was an artefact of the
* shadow code (and the guest should retry) or 0 if it is not (and the
* fault should be handled elsewhere or passed to the guest). */
{
struct vcpu *v = current;
perfc_incrc(shadow2_fault);
return v->arch.shadow2.mode->page_fault(v, va, regs);
}
static inline int
shadow2_invlpg(struct vcpu *v, unsigned long va)
/* Called when the guest requests an invlpg. Returns 1 if the invlpg
* instruction should be issued on the hardware, or 0 if it's safe not
* to do so. */
{
return v->arch.shadow2.mode->invlpg(v, va);
}
static inline unsigned long
shadow2_gva_to_gpa(struct vcpu *v, unsigned long va)
/* Called to translate a guest virtual address to what the *guest*
* pagetables would map it to. */
{
return v->arch.shadow2.mode->gva_to_gpa(v, va);
}
static inline unsigned long
shadow2_gva_to_gfn(struct vcpu *v, unsigned long va)
/* Called to translate a guest virtual address to what the *guest*
* pagetables would map it to. */
{
return v->arch.shadow2.mode->gva_to_gfn(v, va);
}
static inline void
shadow2_update_cr3(struct vcpu *v)
/* Updates all the things that are derived from the guest's CR3.
* Called when the guest changes CR3. */
{
shadow2_lock(v->domain);
v->arch.shadow2.mode->update_cr3(v);
shadow2_unlock(v->domain);
}
/* Should be called after CR3 is updated.
* Updates vcpu->arch.cr3 and, for HVM guests, vcpu->arch.hvm_vcpu.cpu_cr3.
*
* Also updates other state derived from CR3 (vcpu->arch.guest_vtable,
* shadow_vtable, etc).
*
* Uses values found in vcpu->arch.(guest_table and guest_table_user), and
* for HVM guests, arch.monitor_table and hvm's guest CR3.
*
* Update ref counts to shadow tables appropriately.
* For PAE, relocate L3 entries, if necessary, into low memory.
*/
static inline void update_cr3(struct vcpu *v)
{
unsigned long cr3_mfn=0;
if ( shadow2_mode_enabled(v->domain) )
{
shadow2_update_cr3(v);
return;
}
#if CONFIG_PAGING_LEVELS == 4
if ( !(v->arch.flags & TF_kernel_mode) )
cr3_mfn = pagetable_get_pfn(v->arch.guest_table_user);
else
#endif
cr3_mfn = pagetable_get_pfn(v->arch.guest_table);
make_cr3(v, cr3_mfn);
}
extern void sh2_update_paging_modes(struct vcpu *v);
/* Should be called to initialise paging structures if the paging mode
* has changed, and when bringing up a VCPU for the first time. */
static inline void shadow2_update_paging_modes(struct vcpu *v)
{
ASSERT(shadow2_mode_enabled(v->domain));
shadow2_lock(v->domain);
sh2_update_paging_modes(v);
shadow2_unlock(v->domain);
}
static inline void
shadow2_detach_old_tables(struct vcpu *v)
{
if ( v->arch.shadow2.mode )
v->arch.shadow2.mode->detach_old_tables(v);
}
static inline mfn_t
shadow2_make_monitor_table(struct vcpu *v)
{
return v->arch.shadow2.mode->make_monitor_table(v);
}
static inline void
shadow2_destroy_monitor_table(struct vcpu *v, mfn_t mmfn)
{
v->arch.shadow2.mode->destroy_monitor_table(v, mmfn);
}
/* Validate a pagetable change from the guest and update the shadows. */
extern int shadow2_validate_guest_entry(struct vcpu *v, mfn_t gmfn,
void *new_guest_entry);
/* Update the shadows in response to a pagetable write from a HVM guest */
extern void shadow2_validate_guest_pt_write(struct vcpu *v, mfn_t gmfn,
void *entry, u32 size);
/* Remove all writeable mappings of a guest frame from the shadows.
* Returns non-zero if we need to flush TLBs.
* level and fault_addr desribe how we found this to be a pagetable;
* level==0 means we have some other reason for revoking write access. */
extern int shadow2_remove_write_access(struct vcpu *v, mfn_t readonly_mfn,
unsigned int level,
unsigned long fault_addr);
/* Remove all mappings of the guest mfn from the shadows.
* Returns non-zero if we need to flush TLBs. */
extern int shadow2_remove_all_mappings(struct vcpu *v, mfn_t target_mfn);
void
shadow2_remove_all_shadows_and_parents(struct vcpu *v, mfn_t gmfn);
/* This is a HVM page that we thing is no longer a pagetable.
* Unshadow it, and recursively unshadow pages that reference it. */
/* Remove all shadows of the guest mfn. */
extern void sh2_remove_shadows(struct vcpu *v, mfn_t gmfn, int all);
static inline void shadow2_remove_all_shadows(struct vcpu *v, mfn_t gmfn)
{
sh2_remove_shadows(v, gmfn, 1);
}
/* Add a page to a domain */
void
shadow2_guest_physmap_add_page(struct domain *d, unsigned long gfn,
unsigned long mfn);
/* Remove a page from a domain */
void
shadow2_guest_physmap_remove_page(struct domain *d, unsigned long gfn,
unsigned long mfn);
/*
* Definitions for the shadow2_flags field in page_info.
* These flags are stored on *guest* pages...
* Bits 1-13 are encodings for the shadow types.
*/
#define PGC_SH2_type_to_index(_type) ((_type) >> PGC_SH2_type_shift)
#define SH2F_page_type_mask \
(((1u << (PGC_SH2_type_to_index(PGC_SH2_max_shadow) + 1u)) - 1u) - \
((1u << PGC_SH2_type_to_index(PGC_SH2_min_shadow)) - 1u))
#define SH2F_L1_32 (1u << PGC_SH2_type_to_index(PGC_SH2_l1_32_shadow))
#define SH2F_FL1_32 (1u << PGC_SH2_type_to_index(PGC_SH2_fl1_32_shadow))
#define SH2F_L2_32 (1u << PGC_SH2_type_to_index(PGC_SH2_l2_32_shadow))
#define SH2F_L1_PAE (1u << PGC_SH2_type_to_index(PGC_SH2_l1_pae_shadow))
#define SH2F_FL1_PAE (1u << PGC_SH2_type_to_index(PGC_SH2_fl1_pae_shadow))
#define SH2F_L2_PAE (1u << PGC_SH2_type_to_index(PGC_SH2_l2_pae_shadow))
#define SH2F_L2H_PAE (1u << PGC_SH2_type_to_index(PGC_SH2_l2h_pae_shadow))
#define SH2F_L3_PAE (1u << PGC_SH2_type_to_index(PGC_SH2_l3_pae_shadow))
#define SH2F_L1_64 (1u << PGC_SH2_type_to_index(PGC_SH2_l1_64_shadow))
#define SH2F_FL1_64 (1u << PGC_SH2_type_to_index(PGC_SH2_fl1_64_shadow))
#define SH2F_L2_64 (1u << PGC_SH2_type_to_index(PGC_SH2_l2_64_shadow))
#define SH2F_L3_64 (1u << PGC_SH2_type_to_index(PGC_SH2_l3_64_shadow))
#define SH2F_L4_64 (1u << PGC_SH2_type_to_index(PGC_SH2_l4_64_shadow))
/* Used for hysteresis when automatically unhooking mappings on fork/exit */
#define SH2F_unhooked_mappings (1u<<31)
/*
* Allocation of shadow pages
*/
/* Return the minumum acceptable number of shadow pages a domain needs */
unsigned int shadow2_min_acceptable_pages(struct domain *d);
/* Set the pool of shadow pages to the required number of MB.
* Input will be rounded up to at least min_acceptable_shadow_pages().
* Returns 0 for success, 1 for failure. */
unsigned int shadow2_set_allocation(struct domain *d,
unsigned int megabytes,
int *preempted);
/* Return the size of the shadow2 pool, rounded up to the nearest MB */
static inline unsigned int shadow2_get_allocation(struct domain *d)
{
unsigned int pg = d->arch.shadow2.total_pages;
return ((pg >> (20 - PAGE_SHIFT))
+ ((pg & ((1 << (20 - PAGE_SHIFT)) - 1)) ? 1 : 0));
}
/*
* Linked list for chaining entries in the shadow hash table.
*/
struct shadow2_hash_entry {
struct shadow2_hash_entry *next;
mfn_t smfn; /* MFN of the shadow */
#ifdef _x86_64_ /* Shorten 'n' so we don't waste a whole word on storing 't' */
unsigned long n:56; /* MFN of guest PT or GFN of guest superpage */
#else
unsigned long n; /* MFN of guest PT or GFN of guest superpage */
#endif
unsigned char t; /* shadow type bits, or 0 for empty */
};
#define SHADOW2_HASH_BUCKETS 251
/* Other possibly useful primes are 509, 1021, 2039, 4093, 8191, 16381 */
#if SHADOW2_OPTIMIZATIONS & SH2OPT_CACHE_WALKS
/* Optimization: cache the results of guest walks. This helps with MMIO
* and emulated writes, which tend to issue very similar walk requests
* repeatedly. We keep the results of the last few walks, and blow
* away the cache on guest cr3 write, mode change, or page fault. */
#define SH2_WALK_CACHE_ENTRIES 4
/* Rather than cache a guest walk, which would include mapped pointers
* to pages, we cache what a TLB would remember about the walk: the
* permissions and the l1 gfn */
struct shadow2_walk_cache {
unsigned long va; /* The virtual address (or 0 == unused) */
unsigned long gfn; /* The gfn from the effective l1e */
u32 permissions; /* The aggregated permission bits */
};
#endif
/**************************************************************************/
/* Guest physmap (p2m) support */
/* Walk another domain's P2M table, mapping pages as we go */
extern mfn_t
sh2_gfn_to_mfn_foreign(struct domain *d, unsigned long gpfn);
/* General conversion function from gfn to mfn */
static inline mfn_t
sh2_gfn_to_mfn(struct domain *d, unsigned long gfn)
{
if ( !shadow2_mode_translate(d) )
return _mfn(gfn);
else if ( likely(current->domain == d) )
return _mfn(get_mfn_from_gpfn(gfn));
else
return sh2_gfn_to_mfn_foreign(d, gfn);
}
// vcpu-specific version of gfn_to_mfn(). This is where we hide the dirty
// little secret that, for hvm guests with paging disabled, nearly all of the
// shadow code actually think that the guest is running on *untranslated* page
// tables (which is actually domain->phys_table).
//
static inline mfn_t
sh2_vcpu_gfn_to_mfn(struct vcpu *v, unsigned long gfn)
{
if ( !shadow2_vcpu_mode_translate(v) )
return _mfn(gfn);
if ( likely(current->domain == v->domain) )
return _mfn(get_mfn_from_gpfn(gfn));
return sh2_gfn_to_mfn_foreign(v->domain, gfn);
}
static inline unsigned long
sh2_mfn_to_gfn(struct domain *d, mfn_t mfn)
{
if ( shadow2_mode_translate(d) )
return get_gpfn_from_mfn(mfn_x(mfn));
else
return mfn_x(mfn);
}
#endif /* _XEN_SHADOW2_H */
/*
* Local variables:
* mode: C
* c-set-style: "BSD"
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/
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.