* [PATCH] xen: factor out hvm_map_frame
@ 2010-10-06 9:17 Christoph Egger
0 siblings, 0 replies; only message in thread
From: Christoph Egger @ 2010-10-06 9:17 UTC (permalink / raw)
To: xen-devel, Tim Deegan, Keir Fraser; +Cc: Dannowski, Uwe
[-- Attachment #1: Type: text/plain, Size: 533 bytes --]
Hi!
Factor out hvm_map_frame from hvm_map_entry.
This allows us to map pages from guest physical
addresses.
This will be used with nested virtualization.
Signed-off-by: Uwe Dannowski <Uwe.Dannowski@amd.com>
Signed-off-by: Christoph Egger <Christoph.Egger@amd.com>
--
---to satisfy European Law for business letters:
Advanced Micro Devices GmbH
Einsteinring 24, 85609 Dornach b. Muenchen
Geschaeftsfuehrer: Alberto Bozzo, Andrew Bowd
Sitz: Dornach, Gemeinde Aschheim, Landkreis Muenchen
Registergericht Muenchen, HRB Nr. 43632
[-- Attachment #2: xen_mapframe.diff --]
[-- Type: text/x-diff, Size: 4634 bytes --]
diff -r cdff378e61eb xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c Tue Oct 05 12:43:27 2010 +0200
+++ b/xen/arch/x86/hvm/hvm.c Wed Oct 06 11:09:20 2010 +0200
@@ -1356,30 +1356,16 @@ int hvm_virtual_to_linear_addr(
return 0;
}
-static void *hvm_map_entry(unsigned long va)
+void *hvm_map_frame(paddr_t pa, bool_t writable)
{
unsigned long gfn, mfn;
p2m_type_t p2mt;
- uint32_t pfec;
struct vcpu *v = current;
struct p2m_domain *p2m = p2m_get_hostp2m(v->domain);
- if ( ((va & ~PAGE_MASK) + 8) > PAGE_SIZE )
- {
- gdprintk(XENLOG_ERR, "Descriptor table entry "
- "straddles page boundary\n");
- domain_crash(current->domain);
- return NULL;
- }
-
- /* We're mapping on behalf of the segment-load logic, which might
- * write the accessed flags in the descriptors (in 32-bit mode), but
- * we still treat it as a kernel-mode read (i.e. no access checks). */
- pfec = PFEC_page_present;
- gfn = paging_gva_to_gfn(current, va, &pfec);
- if ( pfec == PFEC_page_paged || pfec == PFEC_page_shared )
- return NULL;
- mfn = mfn_x(gfn_to_mfn_unshare(p2m, gfn, &p2mt, 0));
+ gfn = pa >> PAGE_SHIFT;
+ mfn = mfn_x(writable ? gfn_to_mfn_unshare(p2m, gfn, &p2mt, 0)
+ : gfn_to_mfn(p2m, gfn, &p2mt));
if ( p2m_is_paging(p2mt) )
{
p2m_mem_paging_populate(p2m, gfn);
@@ -1389,24 +1375,52 @@ static void *hvm_map_entry(unsigned long
return NULL;
if ( !p2m_is_ram(p2mt) )
{
- gdprintk(XENLOG_ERR, "Failed to look up descriptor table entry\n");
- domain_crash(current->domain);
+ gdprintk(XENLOG_ERR, "Failed to look up frame\n");
return NULL;
}
ASSERT(mfn_valid(mfn));
- paging_mark_dirty(current->domain, mfn);
-
- return (char *)map_domain_page(mfn) + (va & ~PAGE_MASK);
+ if (writable)
+ paging_mark_dirty(v->domain, mfn);
+
+ return (char *)map_domain_page(mfn) + (pa & ~PAGE_MASK);
}
-static void hvm_unmap_entry(void *p)
+void hvm_unmap_frame(void *p)
{
if ( p )
unmap_domain_page(p);
}
+static void *hvm_map_entry(unsigned long va, bool_t writable)
+{
+ unsigned long gfn;
+ uint32_t pfec;
+ paddr_t pa;
+ struct vcpu *v = current;
+
+ if ( ((va & ~PAGE_MASK) + 8) > PAGE_SIZE )
+ {
+ gdprintk(XENLOG_ERR, "Descriptor table entry "
+ "straddles page boundary\n");
+ domain_crash(v->domain);
+ return NULL;
+ }
+
+ /* We're mapping on behalf of the segment-load logic, which might
+ * write the accessed flags in the descriptors (in 32-bit mode), but
+ * we still treat it as a kernel-mode read (i.e. no access checks). */
+ pfec = PFEC_page_present;
+ gfn = paging_gva_to_gfn(current, va, &pfec);
+ if ( pfec == PFEC_page_paged || pfec == PFEC_page_shared )
+ return NULL;
+ pa = (gfn << PAGE_SHIFT) + (va & ~PAGE_MASK);
+ return hvm_map_frame(pa, writable);
+}
+
+#define hvm_unmap_entry hvm_unmap_frame
+
static int hvm_load_segment_selector(
enum x86_segment seg, uint16_t sel)
{
@@ -1449,7 +1463,7 @@ static int hvm_load_segment_selector(
if ( ((sel & 0xfff8) + 7) > desctab.limit )
goto fail;
- pdesc = hvm_map_entry(desctab.base + (sel & 0xfff8));
+ pdesc = hvm_map_entry(desctab.base + (sel & 0xfff8), HVM_MAP_RW);
if ( pdesc == NULL )
goto hvm_map_fail;
@@ -1566,11 +1580,11 @@ void hvm_task_switch(
goto out;
}
- optss_desc = hvm_map_entry(gdt.base + (prev_tr.sel & 0xfff8));
+ optss_desc = hvm_map_entry(gdt.base + (prev_tr.sel & 0xfff8), HVM_MAP_RW);
if ( optss_desc == NULL )
goto out;
- nptss_desc = hvm_map_entry(gdt.base + (tss_sel & 0xfff8));
+ nptss_desc = hvm_map_entry(gdt.base + (tss_sel & 0xfff8), HVM_MAP_RW);
if ( nptss_desc == NULL )
goto out;
diff -r cdff378e61eb xen/include/asm-x86/hvm/hvm.h
--- a/xen/include/asm-x86/hvm/hvm.h Tue Oct 05 12:43:27 2010 +0200
+++ b/xen/include/asm-x86/hvm/hvm.h Wed Oct 06 11:09:20 2010 +0200
@@ -335,6 +335,7 @@ enum hvm_access_type {
hvm_access_read,
hvm_access_write
};
+
int hvm_virtual_to_linear_addr(
enum x86_segment seg,
struct segment_register *reg,
@@ -344,6 +345,11 @@ int hvm_virtual_to_linear_addr(
unsigned int addr_size,
unsigned long *linear_addr);
+#define HVM_MAP_RW 1
+#define HVM_MAP_RO 0
+void *hvm_map_frame(paddr_t pa, bool_t writable);
+void hvm_unmap_frame(void *p);
+
static inline void hvm_set_info_guest(struct vcpu *v)
{
if ( hvm_funcs.set_info_guest )
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2010-10-06 9:17 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-10-06 9:17 [PATCH] xen: factor out hvm_map_frame Christoph Egger
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.