Sharable/shared pages need to be unshared in responce to a write attempt. This

is handled through custom gfn_to_mfn transation functions called from generic
host page table page fault handler. This should handle both SVM and VTX alike.

Signed-off-by: Grzegorz Milos <Grzegorz.Milos@citrix.com>
This commit is contained in:
Keir Fraser committed 2009-12-17 06:27:56 +00:00
1 parent 2bde77654a
commit e8a90e0ab1
2 files changed
+38 -2

No files matched your search

+13 -2
View File
@@ -1325,12 +1325,14 @@ static void *hvm_map_entry(unsigned long va)
gfn = paging_gva_to_gfn(current, va, &pfec);
if ( pfec == PFEC_page_paged )
return NULL;
mfn = mfn_x(gfn_to_mfn_current(gfn, &p2mt));
mfn = mfn_x(gfn_to_mfn_unshare(current->domain, gfn, &p2mt, 0));
if ( p2m_is_paging(p2mt) )
{
p2m_mem_paging_populate(current->domain, gfn);
return NULL;
}
if ( p2m_is_shared(p2mt) )
return NULL;
if ( !p2m_is_ram(p2mt) )
{
gdprintk(XENLOG_ERR, "Failed to look up descriptor table entry\n");
@@ -2986,6 +2988,10 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg)
rc = -EINVAL;
goto param_fail3;
}
if( p2m_is_shared(t) )
gdprintk(XENLOG_WARNING,
"shared pfn 0x%lx modified?\n", pfn);
if ( mfn_x(mfn) != INVALID_MFN )
{
paging_mark_dirty(d, mfn_x(mfn));
@@ -3038,7 +3044,7 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg)
p2m_type_t t;
p2m_type_t nt;
mfn_t mfn;
mfn = gfn_to_mfn(d, pfn, &t);
mfn = gfn_to_mfn_unshare(d, pfn, &t, 0);
if ( p2m_is_paging(t) )
{
p2m_mem_paging_populate(d, pfn);
@@ -3046,6 +3052,11 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg)
rc = -EINVAL;
goto param_fail4;
}
if ( p2m_is_shared(t) )
{
rc = -EINVAL;
goto param_fail4;
}
if ( p2m_is_grant(t) )
{
gdprintk(XENLOG_WARNING,
+25
View File
@@ -308,6 +308,31 @@ static inline mfn_t _gfn_to_mfn_type(struct domain *d,
#define gfn_to_mfn_current(g, t) gfn_to_mfn_type_current((g), (t), p2m_alloc)
#define gfn_to_mfn_foreign(d, g, t) gfn_to_mfn_type_foreign((d), (g), (t), p2m_alloc)
static inline mfn_t gfn_to_mfn_unshare(struct domain *d,
unsigned long gfn,
p2m_type_t *p2mt,
int must_succeed)
{
mfn_t mfn;
int ret;
mfn = gfn_to_mfn(d, gfn, p2mt);
if(p2m_is_shared(*p2mt))
{
ret = mem_sharing_unshare_page(d, gfn,
must_succeed ? MEM_SHARING_MUST_SUCCEED : 0);
if(ret < 0)
{
BUG_ON(must_succeed);
return mfn;
}
mfn = gfn_to_mfn(d, gfn, p2mt);
}
return mfn;
}
/* Compatibility function exporting the old untyped interface */
static inline unsigned long gmfn_to_mfn(struct domain *d, unsigned long gpfn)
{
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.