Accepting request 136173 from Virtualization

(to fix build with linux-3.6)

- pygrub: always append --args
  25941-pygrub_always_append_--args.patch

- use BuildRequires: gcc46 only in sles11sp2 or 12.1 to fix build
  in 11.4

- Upstream patches from Jan
  25833-32on64-bogus-pt_base-adjust.patch                                                                                                                
  25835-adjust-rcu-lock-domain.patch                                                                                                                     
  25836-VT-d-S3-MSI-resume.patch                                                                                                                         
  25850-tmem-xsa-15-1.patch                                                                                                                              
  25851-tmem-xsa-15-2.patch                                                                                                                              
  25852-tmem-xsa-15-3.patch                                                                                                                              
  25853-tmem-xsa-15-4.patch                                                                                                                              
  25854-tmem-xsa-15-5.patch                                                                                                                              
  25855-tmem-xsa-15-6.patch                                                                                                                              
  25856-tmem-xsa-15-7.patch                                                                                                                              
  25857-tmem-xsa-15-8.patch                                                                                                                              
  25858-tmem-xsa-15-9.patch                                                                                                                              
  25859-tmem-missing-break.patch                                                                                                                         
  25860-tmem-cleanup.patch                                                                                                                               
  25861-x86-early-fixmap.patch                                                                                                                           
  25862-sercon-non-com.patch                                                                                                                             
  25863-sercon-ehci-dbgp.patch                                                                                                                           
  25864-sercon-unused.patch                                                                                                                              
  25866-sercon-ns16550-pci-irq.patch                                                                                                                     
  25867-sercon-ns16550-parse.patch                                                                                                                       
  25874-x86-EFI-chain-cfg.patch                                                                                                                          
  25909-xenpm-consistent.patch

- Fixed the 32bit build.

- Update to Xen 4.2.0 FCS c/s 25844 

- unmodified_drivers: handle IRQF_SAMPLE_RANDOM, it was removed
  in 3.6-rc1

- bnc#778105 - first XEN-PV VM fails to spawn
  xend: Increase wait time for disk to appear in host bootloader
  Modified existing xen-domUloader.diff

- Disable the snapshot patches. Snapshot only supported the qcow2
  image format which was poorly implemented qemu 0.10.2. Snapshot
  support may be restored in the future when the newer upstream
  qemu is used by Xen.

- bnc#776995 - attaching scsi control luns with pvscsi
  - xend/pvscsi: fix passing of SCSI control LUNs
  xen-bug776995-pvscsi-no-devname.patch
  - xend/pvscsi: fix usage of persistant device names for SCSI devices
  xen-bug776995-pvscsi-persistent-names.patch
  - xend/pvscsi: update sysfs parser for Linux 3.0
  xen-bug776995-pvscsi-sysfs-parser.patch

- Update to Xen 4.2.0 RC3+ c/s 25779 

- Update to Xen 4.2.0 RC2+ c/s 25765

OBS-URL: https://build.opensuse.org/request/show/136173
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/xen?expand=0&rev=162
This commit is contained in:
Stephan Kulow 2012-09-27 11:55:51 +00:00 committed by Git OBS Bridge
commit 9cea70a022
369 changed files with 6395 additions and 41913 deletions

View File

@ -1,255 +0,0 @@
References: bnc#675363
# HG changeset patch
# User Keir Fraser <keir@xen.org>
# Date 1299687371 0
# Node ID e9fab50d7b61d151d51a4b1088930c9e1ca2da47
# Parent 5f28dcea13555f7ab948c9cb95de3e79e0fbfc4b
x86: make get_page_from_l1e() return a proper error code
... so that the guest can actually know the reason for the (hypercall)
failure.
ptwr_do_page_fault() could propagate the error indicator received from
get_page_from_l1e() back to the guest in the high half of the error
code (entry_vector), provided we're sure all existing guests can deal
with that (or indicate so by means of a to-be-added guest feature
flag). Alternatively, a second virtual status register (like CR2)
could be introduced.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
# HG changeset patch
# User Jan Beulich <jbeulich@suse.com>
# Date 1340271059 -7200
# Node ID baa85434d0ec16629ca30b7c07deaa9beb3ea9c5
# Parent d4cdcf4d541cc4ce72c48df2e26c2b506c5b04bd
x86/mm: fix mod_l1_entry() return value when encountering r/o MMIO page
While putting together the workaround announced in
http://lists.xen.org/archives/html/xen-devel/2012-06/msg00709.html, I
found that mod_l1_entry(), upon encountering a set bit in
mmio_ro_ranges, would return 1 instead of 0 (the removal of the write
permission is supposed to be entirely transparent to the caller, even
more so to the calling guest).
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
--- a/xen/arch/x86/mm/shadow/multi.c
+++ b/xen/arch/x86/mm/shadow/multi.c
@@ -872,7 +872,7 @@ shadow_get_page_from_l1e(shadow_l1e_t sl
// If a privileged domain is attempting to install a map of a page it does
// not own, we let it succeed anyway.
//
- if ( unlikely(!res) &&
+ if ( unlikely(res < 0) &&
!shadow_mode_translate(d) &&
mfn_valid(mfn = shadow_l1e_get_mfn(sl1e)) &&
(owner = page_get_owner(mfn_to_page(mfn))) &&
@@ -883,11 +883,11 @@ shadow_get_page_from_l1e(shadow_l1e_t sl
SHADOW_PRINTK("privileged domain %d installs map of mfn %05lx "
"which is owned by domain %d: %s\n",
d->domain_id, mfn_x(mfn), owner->domain_id,
- res ? "success" : "failed");
+ res >= 0 ? "success" : "failed");
}
/* Okay, it might still be a grant mapping PTE. Try it. */
- if ( unlikely(!res) &&
+ if ( unlikely(res < 0) &&
(type == p2m_grant_map_rw ||
(type == p2m_grant_map_ro &&
!(shadow_l1e_get_flags(sl1e) & _PAGE_RW))) )
@@ -900,7 +900,7 @@ shadow_get_page_from_l1e(shadow_l1e_t sl
res = get_page_from_l1e(sl1e, d, page_get_owner(mfn_to_page(mfn)));
}
- if ( unlikely(!res) )
+ if ( unlikely(res < 0) )
{
perfc_incr(shadow_get_page_fail);
SHADOW_PRINTK("failed: l1e=" SH_PRI_pte "\n");
@@ -1229,15 +1229,15 @@ static int shadow_set_l1e(struct vcpu *v
TRACE_SHADOW_PATH_FLAG(TRCE_SFLAG_SHADOW_L1_GET_REF);
switch ( shadow_get_page_from_l1e(new_sl1e, d, new_type) )
{
- case 0:
+ default:
/* Doesn't look like a pagetable. */
flags |= SHADOW_SET_ERROR;
new_sl1e = shadow_l1e_empty();
break;
- case -1:
+ case 1:
shadow_l1e_remove_flags(new_sl1e, _PAGE_RW);
/* fall through */
- default:
+ case 0:
shadow_vram_get_l1e(new_sl1e, sl1e, sl1mfn, d);
break;
}
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -800,12 +800,12 @@ get_page_from_l1e(
bool_t write;
if ( !(l1f & _PAGE_PRESENT) )
- return 1;
+ return 0;
if ( unlikely(l1f & l1_disallow_mask(l1e_owner)) )
{
MEM_LOG("Bad L1 flags %x", l1f & l1_disallow_mask(l1e_owner));
- return 0;
+ return -EINVAL;
}
if ( !mfn_valid(mfn) ||
@@ -822,18 +822,21 @@ get_page_from_l1e(
if ( !iomem_access_permitted(pg_owner, mfn, mfn) )
{
if ( mfn != (PADDR_MASK >> PAGE_SHIFT) ) /* INVALID_MFN? */
+ {
MEM_LOG("Non-privileged (%u) attempt to map I/O space %08lx",
pg_owner->domain_id, mfn);
- return 0;
+ return -EPERM;
+ }
+ return -EINVAL;
}
if ( !(l1f & _PAGE_RW) || IS_PRIV(pg_owner) ||
!rangeset_contains_singleton(mmio_ro_ranges, mfn) )
- return 1;
+ return 0;
dprintk(XENLOG_G_WARNING,
"d%d: Forcing read-only access to MFN %lx\n",
l1e_owner->domain_id, mfn);
- return -1;
+ return 1;
}
if ( unlikely(real_pg_owner != pg_owner) )
@@ -864,6 +867,7 @@ get_page_from_l1e(
{
unsigned long x, nx, y = page->count_info;
unsigned long cacheattr = pte_flags_to_cacheattr(l1f);
+ int err;
if ( is_xen_heap_page(page) )
{
@@ -871,7 +875,7 @@ get_page_from_l1e(
put_page_type(page);
put_page(page);
MEM_LOG("Attempt to change cache attributes of Xen heap page");
- return 0;
+ return -EACCES;
}
do {
@@ -879,7 +883,8 @@ get_page_from_l1e(
nx = (x & ~PGC_cacheattr_mask) | (cacheattr << PGC_cacheattr_base);
} while ( (y = cmpxchg(&page->count_info, x, nx)) != x );
- if ( unlikely(update_xen_mappings(mfn, cacheattr) != 0) )
+ err = update_xen_mappings(mfn, cacheattr);
+ if ( unlikely(err) )
{
cacheattr = y & PGC_cacheattr_mask;
do {
@@ -895,11 +900,11 @@ get_page_from_l1e(
" from L1 entry %" PRIpte ") for %d",
mfn, get_gpfn_from_mfn(mfn),
l1e_get_intpte(l1e), l1e_owner->domain_id);
- return 0;
+ return err;
}
}
- return 1;
+ return 0;
could_not_pin:
MEM_LOG("Error getting mfn %lx (pfn %lx) from L1 entry %" PRIpte
@@ -908,7 +913,7 @@ get_page_from_l1e(
l1e_get_intpte(l1e), l1e_owner->domain_id, pg_owner->domain_id);
if ( real_pg_owner != NULL )
put_page(page);
- return 0;
+ return -EBUSY;
}
@@ -1198,17 +1203,20 @@ static int alloc_l1_table(struct page_in
unsigned long pfn = page_to_mfn(page);
l1_pgentry_t *pl1e;
unsigned int i;
+ int ret = 0;
pl1e = map_domain_page(pfn);
for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ )
{
if ( is_guest_l1_slot(i) )
- switch ( get_page_from_l1e(pl1e[i], d, d) )
+ switch ( ret = get_page_from_l1e(pl1e[i], d, d) )
{
- case 0:
+ default:
goto fail;
- case -1:
+ case 0:
+ break;
+ case 1:
l1e_remove_flags(pl1e[i], _PAGE_RW);
break;
}
@@ -1226,7 +1234,7 @@ static int alloc_l1_table(struct page_in
put_page_from_l1e(pl1e[i], d);
unmap_domain_page(pl1e);
- return -EINVAL;
+ return ret;
}
static int create_pae_xen_mappings(struct domain *d, l3_pgentry_t *pl3e)
@@ -1795,12 +1803,15 @@ static int mod_l1_entry(l1_pgentry_t *pl
return rc;
}
- switch ( get_page_from_l1e(nl1e, pt_dom, pg_dom) )
+ switch ( rc = get_page_from_l1e(nl1e, pt_dom, pg_dom) )
{
- case 0:
+ default:
return 0;
- case -1:
+ case 0:
+ break;
+ case 1:
l1e_remove_flags(nl1e, _PAGE_RW);
+ rc = 0;
break;
}
@@ -4976,7 +4987,7 @@ static int ptwr_emulated_update(
nl1e = l1e_from_intpte(val);
switch ( get_page_from_l1e(nl1e, d, d) )
{
- case 0:
+ default:
if ( is_pv_32bit_domain(d) && (bytes == 4) && (unaligned_addr & 4) &&
!do_cmpxchg && (l1e_get_flags(nl1e) & _PAGE_PRESENT) )
{
@@ -4996,7 +5007,9 @@ static int ptwr_emulated_update(
return X86EMUL_UNHANDLEABLE;
}
break;
- case -1:
+ case 0:
+ break;
+ case 1:
l1e_remove_flags(nl1e, _PAGE_RW);
break;
}

View File

@ -1,114 +0,0 @@
References: bnc#675363
# HG changeset patch
# User Jan Beulich <jbeulich@novell.com>
# Date 1299687409 0
# Node ID 82b5f8d12903e140f957ae8d13d66e44be076b05
# Parent e9fab50d7b61d151d51a4b1088930c9e1ca2da47
x86: make mod_l1_entry() return a proper error code
... again is so that the guest can actually know the reason for the
(hypercall) failure.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -1766,15 +1766,16 @@ static int mod_l1_entry(l1_pgentry_t *pl
struct domain *pt_dom = pt_vcpu->domain;
unsigned long mfn;
p2m_type_t p2mt;
- int rc = 1;
+ int rc = 0;
if ( unlikely(__copy_from_user(&ol1e, pl1e, sizeof(ol1e)) != 0) )
- return 0;
+ return -EFAULT;
if ( unlikely(paging_mode_refcounts(pt_dom)) )
{
- rc = UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, pt_vcpu, preserve_ad);
- return rc;
+ if ( UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, pt_vcpu, preserve_ad) )
+ return 0;
+ return -EBUSY;
}
if ( l1e_get_flags(nl1e) & _PAGE_PRESENT )
@@ -1783,7 +1784,7 @@ static int mod_l1_entry(l1_pgentry_t *pl
mfn = mfn_x(gfn_to_mfn(p2m_get_hostp2m(pg_dom),
l1e_get_pfn(nl1e), &p2mt));
if ( !p2m_is_ram(p2mt) || unlikely(mfn == INVALID_MFN) )
- return 0;
+ return -EINVAL;
ASSERT((mfn & ~(PADDR_MASK >> PAGE_SHIFT)) == 0);
nl1e = l1e_from_pfn(mfn, l1e_get_flags(nl1e));
@@ -1791,22 +1792,23 @@ static int mod_l1_entry(l1_pgentry_t *pl
{
MEM_LOG("Bad L1 flags %x",
l1e_get_flags(nl1e) & l1_disallow_mask(pt_dom));
- return 0;
+ return -EINVAL;
}
/* Fast path for identical mapping, r/w and presence. */
if ( !l1e_has_changed(ol1e, nl1e, _PAGE_RW | _PAGE_PRESENT) )
{
adjust_guest_l1e(nl1e, pt_dom);
- rc = UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, pt_vcpu,
- preserve_ad);
- return rc;
+ if ( UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, pt_vcpu,
+ preserve_ad) )
+ return 0;
+ return -EBUSY;
}
switch ( rc = get_page_from_l1e(nl1e, pt_dom, pg_dom) )
{
default:
- return 0;
+ return rc;
case 0:
break;
case 1:
@@ -1820,13 +1822,13 @@ static int mod_l1_entry(l1_pgentry_t *pl
preserve_ad)) )
{
ol1e = nl1e;
- rc = 0;
+ rc = -EBUSY;
}
}
else if ( unlikely(!UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, pt_vcpu,
preserve_ad)) )
{
- return 0;
+ return -EBUSY;
}
put_page_from_l1e(ol1e, pt_dom);
@@ -3518,9 +3520,10 @@ int do_mmu_update(
}
#endif
- okay = mod_l1_entry(va, l1e, mfn,
- cmd == MMU_PT_UPDATE_PRESERVE_AD, v,
- pg_owner);
+ rc = mod_l1_entry(va, l1e, mfn,
+ cmd == MMU_PT_UPDATE_PRESERVE_AD, v,
+ pg_owner);
+ okay = !rc;
}
break;
case PGT_l2_page_table:
@@ -4302,7 +4305,7 @@ static int __do_update_va_mapping(
goto out;
}
- rc = mod_l1_entry(pl1e, val, gl1mfn, 0, v, pg_owner) ? 0 : -EINVAL;
+ rc = mod_l1_entry(pl1e, val, gl1mfn, 0, v, pg_owner);
page_unlock(gl1pg);
put_page(gl1pg);

View File

@ -1,210 +0,0 @@
# HG changeset patch
# User Jan Beulich <jbeulich@novell.com>
# Date 1299687446 0
# Node ID d428fa67abaa0db20b915a697f1d5ba16e554185
# Parent 82b5f8d12903e140f957ae8d13d66e44be076b05
x86: make mod_l2_entry() return a proper error code
... so that finally all mod_lN_entry() functions behave identically,
allowing some cleanup in do_mmu_update() (which no longer needs to
track both an okay status and an error code).
Signed-off-by: Jan Beulich <jbeulich@novell.com>
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -1847,16 +1847,16 @@ static int mod_l2_entry(l2_pgentry_t *pl
struct domain *d = vcpu->domain;
struct page_info *l2pg = mfn_to_page(pfn);
unsigned long type = l2pg->u.inuse.type_info;
- int rc = 1;
+ int rc = 0;
if ( unlikely(!is_guest_l2_slot(d, type, pgentry_ptr_to_slot(pl2e))) )
{
MEM_LOG("Illegal L2 update attempt in Xen-private area %p", pl2e);
- return 0;
+ return -EPERM;
}
if ( unlikely(__copy_from_user(&ol2e, pl2e, sizeof(ol2e)) != 0) )
- return 0;
+ return -EFAULT;
if ( l2e_get_flags(nl2e) & _PAGE_PRESENT )
{
@@ -1864,32 +1864,33 @@ static int mod_l2_entry(l2_pgentry_t *pl
{
MEM_LOG("Bad L2 flags %x",
l2e_get_flags(nl2e) & L2_DISALLOW_MASK);
- return 0;
+ return -EINVAL;
}
/* Fast path for identical mapping and presence. */
if ( !l2e_has_changed(ol2e, nl2e, _PAGE_PRESENT) )
{
adjust_guest_l2e(nl2e, d);
- rc = UPDATE_ENTRY(l2, pl2e, ol2e, nl2e, pfn, vcpu, preserve_ad);
- return rc;
+ if ( UPDATE_ENTRY(l2, pl2e, ol2e, nl2e, pfn, vcpu, preserve_ad) )
+ return 0;
+ return -EBUSY;
}
- if ( unlikely(get_page_from_l2e(nl2e, pfn, d) < 0) )
- return 0;
+ if ( unlikely((rc = get_page_from_l2e(nl2e, pfn, d)) < 0) )
+ return rc;
adjust_guest_l2e(nl2e, d);
if ( unlikely(!UPDATE_ENTRY(l2, pl2e, ol2e, nl2e, pfn, vcpu,
preserve_ad)) )
{
ol2e = nl2e;
- rc = 0;
+ rc = -EBUSY;
}
}
else if ( unlikely(!UPDATE_ENTRY(l2, pl2e, ol2e, nl2e, pfn, vcpu,
preserve_ad)) )
{
- return 0;
+ return -EBUSY;
}
put_page_from_l2e(ol2e, pfn);
@@ -3369,7 +3370,7 @@ int do_mmu_update(
void *va;
unsigned long gpfn, gmfn, mfn;
struct page_info *page;
- int rc = 0, okay = 1, i = 0;
+ int rc = 0, i = 0;
unsigned int cmd, done = 0, pt_dom;
struct vcpu *v = current;
struct domain *d = v->domain, *pt_owner = d, *pg_owner;
@@ -3436,7 +3437,6 @@ int do_mmu_update(
}
cmd = req.ptr & (sizeof(l1_pgentry_t)-1);
- okay = 0;
switch ( cmd )
{
@@ -3453,6 +3453,7 @@ int do_mmu_update(
rc = xsm_mmu_normal_update(d, pg_owner, req.val);
if ( rc )
break;
+ rc = -EINVAL;
req.ptr -= cmd;
gmfn = req.ptr >> PAGE_SHIFT;
@@ -3523,7 +3524,6 @@ int do_mmu_update(
rc = mod_l1_entry(va, l1e, mfn,
cmd == MMU_PT_UPDATE_PRESERVE_AD, v,
pg_owner);
- okay = !rc;
}
break;
case PGT_l2_page_table:
@@ -3547,13 +3547,12 @@ int do_mmu_update(
else if ( p2m_ram_shared == l2e_p2mt )
{
MEM_LOG("Unexpected attempt to map shared page.\n");
- rc = -EINVAL;
break;
}
- okay = mod_l2_entry(va, l2e, mfn,
- cmd == MMU_PT_UPDATE_PRESERVE_AD, v);
+ rc = mod_l2_entry(va, l2e, mfn,
+ cmd == MMU_PT_UPDATE_PRESERVE_AD, v);
}
break;
case PGT_l3_page_table:
@@ -3577,13 +3576,11 @@ int do_mmu_update(
else if ( p2m_ram_shared == l3e_p2mt )
{
MEM_LOG("Unexpected attempt to map shared page.\n");
- rc = -EINVAL;
break;
}
rc = mod_l3_entry(va, l3e, mfn,
cmd == MMU_PT_UPDATE_PRESERVE_AD, 1, v);
- okay = !rc;
}
break;
#if CONFIG_PAGING_LEVELS >= 4
@@ -3609,20 +3606,18 @@ int do_mmu_update(
else if ( p2m_ram_shared == l4e_p2mt )
{
MEM_LOG("Unexpected attempt to map shared page.\n");
- rc = -EINVAL;
break;
}
rc = mod_l4_entry(va, l4e, mfn,
cmd == MMU_PT_UPDATE_PRESERVE_AD, 1, v);
- okay = !rc;
}
break;
#endif
case PGT_writable_page:
perfc_incr(writable_mmu_updates);
- okay = paging_write_guest_entry(
- v, va, req.val, _mfn(mfn));
+ if ( paging_write_guest_entry(v, va, req.val, _mfn(mfn)) )
+ rc = 0;
break;
}
page_unlock(page);
@@ -3632,8 +3627,8 @@ int do_mmu_update(
else if ( get_page_type(page, PGT_writable_page) )
{
perfc_incr(writable_mmu_updates);
- okay = paging_write_guest_entry(
- v, va, req.val, _mfn(mfn));
+ if ( paging_write_guest_entry(v, va, req.val, _mfn(mfn)) )
+ rc = 0;
put_page_type(page);
}
@@ -3654,17 +3649,18 @@ int do_mmu_update(
if ( unlikely(!get_page_from_pagenr(mfn, pg_owner)) )
{
MEM_LOG("Could not get page for mach->phys update");
+ rc = -EINVAL;
break;
}
if ( unlikely(paging_mode_translate(pg_owner)) )
{
MEM_LOG("Mach-phys update on auto-translate guest");
+ rc = -EINVAL;
break;
}
set_gpfn_from_mfn(mfn, gpfn);
- okay = 1;
paging_mark_dirty(pg_owner, mfn);
@@ -3674,15 +3670,11 @@ int do_mmu_update(
default:
MEM_LOG("Invalid page update command %x", cmd);
rc = -ENOSYS;
- okay = 0;
break;
}
- if ( unlikely(!okay) )
- {
- rc = rc ? rc : -EINVAL;
+ if ( unlikely(rc) )
break;
- }
guest_handle_add_offset(ureqs, 1);
}

View File

@ -1,406 +0,0 @@
changeset: 23050:4ebba54b666f
user: Olaf Hering <olaf@aepfle.de>
date: Thu Mar 17 13:29:01 2011 +0000
files: xen/common/trace.c
description:
xentrace: dynamic tracebuffer allocation
Allocate tracebuffers dynamically, based on the requested buffer size.
Calculate t_info_size from requested t_buf size.
Fix allocation failure path, free pages outside the spinlock.
Remove casts for rawbuf, it can be a void pointer since no math is
done.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Acked-by: George Dunlap <george.dunlap@eu.citrix.com>
---
xen/common/trace.c | 249 ++++++++++++++++++++++-------------------------------
1 file changed, 104 insertions(+), 145 deletions(-)
Index: xen-4.1.2-testing/xen/common/trace.c
===================================================================
--- xen-4.1.2-testing.orig/xen/common/trace.c
+++ xen-4.1.2-testing/xen/common/trace.c
@@ -42,14 +42,14 @@ CHECK_t_buf;
#define compat_t_rec t_rec
#endif
-/* opt_tbuf_size: trace buffer size (in pages) */
-static unsigned int opt_tbuf_size = 0;
+/* opt_tbuf_size: trace buffer size (in pages) for each cpu */
+static unsigned int opt_tbuf_size;
integer_param("tbuf_size", opt_tbuf_size);
/* Pointers to the meta-data objects for all system trace buffers */
static struct t_info *t_info;
-#define T_INFO_PAGES 2 /* Size fixed at 2 pages for now. */
-#define T_INFO_SIZE ((T_INFO_PAGES)*(PAGE_SIZE))
+static unsigned int t_info_pages;
+
static DEFINE_PER_CPU_READ_MOSTLY(struct t_buf *, t_bufs);
static DEFINE_PER_CPU_READ_MOSTLY(unsigned char *, t_data);
static DEFINE_PER_CPU_READ_MOSTLY(spinlock_t, t_lock);
@@ -78,6 +78,21 @@ static u32 tb_event_mask = TRC_ALL;
* i.e., sizeof(_type) * ans >= _x. */
#define fit_to_type(_type, _x) (((_x)+sizeof(_type)-1) / sizeof(_type))
+static int cpu_callback(
+ struct notifier_block *nfb, unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (unsigned long)hcpu;
+
+ if ( action == CPU_UP_PREPARE )
+ spin_lock_init(&per_cpu(t_lock, cpu));
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block cpu_nfb = {
+ .notifier_call = cpu_callback
+};
+
static void calc_tinfo_first_offset(void)
{
int offset_in_bytes = offsetof(struct t_info, mfn_offset[NR_CPUS]);
@@ -85,20 +100,34 @@ static void calc_tinfo_first_offset(void
}
/**
- * check_tbuf_size - check to make sure that the proposed size will fit
+ * calculate_tbuf_size - check to make sure that the proposed size will fit
* in the currently sized struct t_info and allows prod and cons to
* reach double the value without overflow.
+ * Initialize t_info_pages based on number of trace pages.
*/
-static int check_tbuf_size(u32 pages)
+static int calculate_tbuf_size(unsigned int pages)
{
struct t_buf dummy;
typeof(dummy.prod) size;
-
- size = ((typeof(dummy.prod))pages) * PAGE_SIZE;
-
- return (size / PAGE_SIZE != pages)
- || (size + size < size)
- || (num_online_cpus() * pages + t_info_first_offset > T_INFO_SIZE / sizeof(uint32_t));
+
+ /* force maximum value for an unsigned type */
+ size = -1;
+
+ /* max size holds up to n pages */
+ size /= PAGE_SIZE;
+ if ( pages > size )
+ {
+ gdprintk(XENLOG_INFO, "%s: requested number of %u pages reduced to %u\n",
+ __func__, pages, (unsigned int)size);
+ pages = size;
+ }
+
+ t_info_pages = num_online_cpus() * pages + t_info_first_offset;
+ t_info_pages *= sizeof(uint32_t);
+ t_info_pages /= PAGE_SIZE;
+ if ( t_info_pages % PAGE_SIZE )
+ t_info_pages++;
+ return pages;
}
/**
@@ -111,47 +140,28 @@ static int check_tbuf_size(u32 pages)
* This function may also be called later when enabling trace buffers
* via the SET_SIZE hypercall.
*/
-static int alloc_trace_bufs(void)
+static int alloc_trace_bufs(unsigned int pages)
{
- int i, cpu, order;
- unsigned long nr_pages;
+ int i, cpu, order;
/* Start after a fixed-size array of NR_CPUS */
uint32_t *t_info_mfn_list;
int offset;
- if ( opt_tbuf_size == 0 )
- return -EINVAL;
+ if ( t_info )
+ return -EBUSY;
- if ( check_tbuf_size(opt_tbuf_size) )
- {
- printk("Xen trace buffers: tb size %d too large. "
- "Tracing disabled.\n",
- opt_tbuf_size);
+ if ( pages == 0 )
return -EINVAL;
- }
- /* t_info size is fixed for now. Currently this works great, so there
- * seems to be no need to make it dynamic. */
- t_info = alloc_xenheap_pages(get_order_from_pages(T_INFO_PAGES), 0);
- if ( t_info == NULL )
- {
- printk("Xen trace buffers: t_info allocation failed! "
- "Tracing disabled.\n");
- return -ENOMEM;
- }
-
- for ( i = 0; i < T_INFO_PAGES; i++ )
- share_xen_page_with_privileged_guests(
- virt_to_page(t_info) + i, XENSHARE_readonly);
-
- t_info_mfn_list = (uint32_t *)t_info;
- offset = t_info_first_offset;
+ /* Calculate offset in u32 of first mfn */
+ calc_tinfo_first_offset();
- t_info->tbuf_size = opt_tbuf_size;
- printk(XENLOG_INFO "tbuf_size %d\n", t_info->tbuf_size);
+ pages = calculate_tbuf_size(pages);
+ order = get_order_from_pages(pages);
- nr_pages = opt_tbuf_size;
- order = get_order_from_pages(nr_pages);
+ t_info = alloc_xenheap_pages(get_order_from_pages(t_info_pages), 0);
+ if ( t_info == NULL )
+ goto out_dealloc;
/*
* First, allocate buffers for all of the cpus. If any
@@ -159,27 +169,29 @@ static int alloc_trace_bufs(void)
*/
for_each_online_cpu(cpu)
{
- int flags;
- char *rawbuf;
+ void *rawbuf;
struct t_buf *buf;
if ( (rawbuf = alloc_xenheap_pages(
order, MEMF_bits(32 + PAGE_SHIFT))) == NULL )
{
- printk("Xen trace buffers: memory allocation failed\n");
- opt_tbuf_size = 0;
+ printk("Xen trace buffers: memory allocation failed on cpu %d\n", cpu);
goto out_dealloc;
}
- spin_lock_irqsave(&per_cpu(t_lock, cpu), flags);
-
- per_cpu(t_bufs, cpu) = buf = (struct t_buf *)rawbuf;
+ per_cpu(t_bufs, cpu) = buf = rawbuf;
buf->cons = buf->prod = 0;
per_cpu(t_data, cpu) = (unsigned char *)(buf + 1);
+ }
- spin_unlock_irqrestore(&per_cpu(t_lock, cpu), flags);
+ offset = t_info_first_offset;
+ t_info_mfn_list = (uint32_t *)t_info;
- }
+ for(i = 0; i < t_info_pages; i++)
+ share_xen_page_with_privileged_guests(
+ virt_to_page(t_info) + i, XENSHARE_readonly);
+
+ t_info->tbuf_size = pages;
/*
* Now share the pages to xentrace can map them, and write them in
@@ -188,89 +200,75 @@ static int alloc_trace_bufs(void)
for_each_online_cpu(cpu)
{
/* Share pages so that xentrace can map them. */
- char *rawbuf;
+ void *rawbuf = per_cpu(t_bufs, cpu);
+ struct page_info *p = virt_to_page(rawbuf);
+ uint32_t mfn = virt_to_mfn(rawbuf);
- if ( (rawbuf = (char *)per_cpu(t_bufs, cpu)) )
+ for ( i = 0; i < pages; i++ )
{
- struct page_info *p = virt_to_page(rawbuf);
- uint32_t mfn = virt_to_mfn(rawbuf);
+ share_xen_page_with_privileged_guests(p + i, XENSHARE_writable);
- for ( i = 0; i < nr_pages; i++ )
- {
- share_xen_page_with_privileged_guests(
- p + i, XENSHARE_writable);
-
- t_info_mfn_list[offset + i]=mfn + i;
- }
- /* Write list first, then write per-cpu offset. */
- wmb();
- t_info->mfn_offset[cpu]=offset;
- printk(XENLOG_INFO "p%d mfn %"PRIx32" offset %d\n",
- cpu, mfn, offset);
- offset+=i;
+ t_info_mfn_list[offset + i]=mfn + i;
}
+ t_info->mfn_offset[cpu]=offset;
+ printk(XENLOG_INFO "p%d mfn %"PRIx32" offset %d\n",
+ cpu, mfn, offset);
+ offset+=i;
+
+ spin_lock_init(&per_cpu(t_lock, cpu));
}
- data_size = (opt_tbuf_size * PAGE_SIZE - sizeof(struct t_buf));
+ data_size = (pages * PAGE_SIZE - sizeof(struct t_buf));
t_buf_highwater = data_size >> 1; /* 50% high water */
+ opt_tbuf_size = pages;
+
+ register_cpu_notifier(&cpu_nfb);
+
+ printk("Xen trace buffers: initialised\n");
+ wmb(); /* above must be visible before tb_init_done flag set */
+ tb_init_done = 1;
return 0;
+
out_dealloc:
for_each_online_cpu(cpu)
{
- int flags;
- char * rawbuf;
-
- spin_lock_irqsave(&per_cpu(t_lock, cpu), flags);
- if ( (rawbuf = (char *)per_cpu(t_bufs, cpu)) )
+ void *rawbuf = per_cpu(t_bufs, cpu);
+ per_cpu(t_bufs, cpu) = NULL;
+ printk("Xen trace buffers: cpu %d p %p\n", cpu, rawbuf);
+ if ( rawbuf )
{
- per_cpu(t_bufs, cpu) = NULL;
ASSERT(!(virt_to_page(rawbuf)->count_info & PGC_allocated));
free_xenheap_pages(rawbuf, order);
}
- spin_unlock_irqrestore(&per_cpu(t_lock, cpu), flags);
}
-
+ free_xenheap_pages(t_info, get_order_from_pages(t_info_pages));
+ t_info = NULL;
+ printk("Xen trace buffers: allocation failed! Tracing disabled.\n");
return -ENOMEM;
}
/**
- * tb_set_size - handle the logic involved with dynamically
- * allocating and deallocating tbufs
+ * tb_set_size - handle the logic involved with dynamically allocating tbufs
*
* This function is called when the SET_SIZE hypercall is done.
*/
-static int tb_set_size(int size)
+static int tb_set_size(unsigned int pages)
{
/*
* Setting size is a one-shot operation. It can be done either at
* boot time or via control tools, but not by both. Once buffers
* are created they cannot be destroyed.
*/
- int ret = 0;
-
- if ( opt_tbuf_size != 0 )
+ if ( opt_tbuf_size && pages != opt_tbuf_size )
{
- if ( size != opt_tbuf_size )
- gdprintk(XENLOG_INFO, "tb_set_size from %d to %d not implemented\n",
- opt_tbuf_size, size);
+ gdprintk(XENLOG_INFO, "tb_set_size from %d to %d not implemented\n",
+ opt_tbuf_size, pages);
return -EINVAL;
}
- if ( size <= 0 )
- return -EINVAL;
-
- opt_tbuf_size = size;
-
- if ( (ret = alloc_trace_bufs()) != 0 )
- {
- opt_tbuf_size = 0;
- return ret;
- }
-
- printk("Xen trace buffers: initialized\n");
- return 0;
+ return alloc_trace_bufs(pages);
}
int trace_will_trace_event(u32 event)
@@ -299,21 +297,6 @@ int trace_will_trace_event(u32 event)
return 1;
}
-static int cpu_callback(
- struct notifier_block *nfb, unsigned long action, void *hcpu)
-{
- unsigned int cpu = (unsigned long)hcpu;
-
- if ( action == CPU_UP_PREPARE )
- spin_lock_init(&per_cpu(t_lock, cpu));
-
- return NOTIFY_DONE;
-}
-
-static struct notifier_block cpu_nfb = {
- .notifier_call = cpu_callback
-};
-
/**
* init_trace_bufs - performs initialization of the per-cpu trace buffers.
*
@@ -323,37 +306,13 @@ static struct notifier_block cpu_nfb = {
*/
void __init init_trace_bufs(void)
{
- int i;
-
- /* Calculate offset in u32 of first mfn */
- calc_tinfo_first_offset();
-
- /* Per-cpu t_lock initialisation. */
- for_each_online_cpu ( i )
- spin_lock_init(&per_cpu(t_lock, i));
- register_cpu_notifier(&cpu_nfb);
-
- if ( opt_tbuf_size == 0 )
- {
- printk("Xen trace buffers: disabled\n");
- goto fail;
- }
-
- if ( alloc_trace_bufs() != 0 )
+ if ( opt_tbuf_size && alloc_trace_bufs(opt_tbuf_size) )
{
- dprintk(XENLOG_INFO, "Xen trace buffers: "
- "allocation size %d failed, disabling\n",
- opt_tbuf_size);
- goto fail;
+ gdprintk(XENLOG_INFO, "Xen trace buffers: "
+ "allocation size %d failed, disabling\n",
+ opt_tbuf_size);
+ opt_tbuf_size = 0;
}
-
- printk("Xen trace buffers: initialised\n");
- wmb(); /* above must be visible before tb_init_done flag set */
- tb_init_done = 1;
- return;
-
- fail:
- opt_tbuf_size = 0;
}
/**
@@ -372,7 +331,7 @@ int tb_control(xen_sysctl_tbuf_op_t *tbc
case XEN_SYSCTL_TBUFOP_get_info:
tbc->evt_mask = tb_event_mask;
tbc->buffer_mfn = t_info ? virt_to_mfn(t_info) : 0;
- tbc->size = T_INFO_PAGES * PAGE_SIZE;
+ tbc->size = t_info_pages * PAGE_SIZE;
break;
case XEN_SYSCTL_TBUFOP_set_cpu_mask:
rc = xenctl_cpumap_to_cpumask(&tb_cpu_mask, &tbc->cpu_mask);

View File

@ -1,146 +0,0 @@
References: fate#311376, fate#311529, bnc#578927, bnc#628554
# HG changeset patch
# User Keir Fraser <keir@xen.org>
# Date 1300887295 0
# Node ID c80e0fb4fe932b4d8379ea5739af93ae22a30ea5
# Parent 3831bd253e02aa0536ed32e936777d026abb955e
Define new <pfn.h> header for PFN_{DOWN,UP} macros.
Signed-off-by: Keir Fraser <keir@xen.org>
Index: xen-4.1.3-testing/xen/arch/x86/domain_build.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/domain_build.c
+++ xen-4.1.3-testing/xen/arch/x86/domain_build.c
@@ -21,6 +21,7 @@
#include <xen/bitops.h>
#include <xen/compat.h>
#include <xen/libelf.h>
+#include <xen/pfn.h>
#include <asm/regs.h>
#include <asm/system.h>
#include <asm/io.h>
Index: xen-4.1.3-testing/xen/arch/x86/e820.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/e820.c
+++ xen-4.1.3-testing/xen/arch/x86/e820.c
@@ -4,6 +4,7 @@
#include <xen/mm.h>
#include <xen/compat.h>
#include <xen/dmi.h>
+#include <xen/pfn.h>
#include <asm/e820.h>
#include <asm/page.h>
#include <asm/processor.h>
Index: xen-4.1.3-testing/xen/arch/x86/mm.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/mm.c
+++ xen-4.1.3-testing/xen/arch/x86/mm.c
@@ -100,6 +100,7 @@
#include <xen/iocap.h>
#include <xen/guest_access.h>
#include <xen/xmalloc.h>
+#include <xen/pfn.h>
#include <asm/paging.h>
#include <asm/shadow.h>
#include <asm/page.h>
Index: xen-4.1.3-testing/xen/arch/x86/msi.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/msi.c
+++ xen-4.1.3-testing/xen/arch/x86/msi.c
@@ -18,6 +18,7 @@
#include <xen/pci_regs.h>
#include <xen/iocap.h>
#include <xen/keyhandler.h>
+#include <xen/pfn.h>
#include <asm/io.h>
#include <asm/smp.h>
#include <asm/desc.h>
Index: xen-4.1.3-testing/xen/arch/x86/numa.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/numa.c
+++ xen-4.1.3-testing/xen/arch/x86/numa.c
@@ -13,6 +13,7 @@
#include <xen/keyhandler.h>
#include <xen/time.h>
#include <xen/smp.h>
+#include <xen/pfn.h>
#include <asm/acpi.h>
#include <xen/sched.h>
Index: xen-4.1.3-testing/xen/arch/x86/setup.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/setup.c
+++ xen-4.1.3-testing/xen/arch/x86/setup.c
@@ -21,6 +21,7 @@
#include <xen/rcupdate.h>
#include <xen/vga.h>
#include <xen/dmi.h>
+#include <xen/pfn.h>
#include <xen/nodemask.h>
#include <public/version.h>
#ifdef CONFIG_COMPAT
Index: xen-4.1.3-testing/xen/arch/x86/srat.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/srat.c
+++ xen-4.1.3-testing/xen/arch/x86/srat.c
@@ -17,6 +17,7 @@
#include <xen/nodemask.h>
#include <xen/acpi.h>
#include <xen/numa.h>
+#include <xen/pfn.h>
#include <asm/e820.h>
#include <asm/page.h>
Index: xen-4.1.3-testing/xen/arch/x86/tboot.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/tboot.c
+++ xen-4.1.3-testing/xen/arch/x86/tboot.c
@@ -6,6 +6,7 @@
#include <xen/domain_page.h>
#include <xen/iommu.h>
#include <xen/acpi.h>
+#include <xen/pfn.h>
#include <asm/fixmap.h>
#include <asm/page.h>
#include <asm/processor.h>
Index: xen-4.1.3-testing/xen/include/asm-x86/page.h
===================================================================
--- xen-4.1.3-testing.orig/xen/include/asm-x86/page.h
+++ xen-4.1.3-testing/xen/include/asm-x86/page.h
@@ -396,8 +396,6 @@ static inline uint32_t cacheattr_to_pte_
#endif /* !__ASSEMBLY__ */
-#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
-#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
#define PAGE_ALIGN(x) (((x) + PAGE_SIZE - 1) & PAGE_MASK)
#endif /* __X86_PAGE_H__ */
Index: xen-4.1.3-testing/xen/include/xen/pci.h
===================================================================
--- xen-4.1.3-testing.orig/xen/include/xen/pci.h
+++ xen-4.1.3-testing/xen/include/xen/pci.h
@@ -13,6 +13,7 @@
#include <xen/spinlock.h>
#include <xen/irq.h>
#include <xen/pci_regs.h>
+#include <xen/pfn.h>
/*
* The PCI interface treats multi-function devices as independent
Index: xen-4.1.3-testing/xen/include/xen/pfn.h
===================================================================
--- /dev/null
+++ xen-4.1.3-testing/xen/include/xen/pfn.h
@@ -0,0 +1,9 @@
+#ifndef __XEN_PFN_H__
+#define __XEN_PFN_H__
+
+#include <asm/page.h>
+
+#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
+#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+
+#endif /* __XEN_PFN_H__ */

View File

@ -1,49 +0,0 @@
changeset: 23091:67632e5cf652
user: Olaf Hering <olaf@aepfle.de>
date: Fri Mar 25 08:56:33 2011 +0000
files: xen/common/trace.c
description:
xentrace: fix t_info_pages calculation.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
xen/common/trace.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
Index: xen-4.1.2-testing/xen/common/trace.c
===================================================================
--- xen-4.1.2-testing.orig/xen/common/trace.c
+++ xen-4.1.2-testing/xen/common/trace.c
@@ -29,6 +29,7 @@
#include <xen/init.h>
#include <xen/mm.h>
#include <xen/percpu.h>
+#include <xen/pfn.h>
#include <xen/cpu.h>
#include <asm/atomic.h>
#include <public/sysctl.h>
@@ -109,6 +110,7 @@ static int calculate_tbuf_size(unsigned
{
struct t_buf dummy;
typeof(dummy.prod) size;
+ unsigned int t_info_words, t_info_bytes;
/* force maximum value for an unsigned type */
size = -1;
@@ -122,11 +124,9 @@ static int calculate_tbuf_size(unsigned
pages = size;
}
- t_info_pages = num_online_cpus() * pages + t_info_first_offset;
- t_info_pages *= sizeof(uint32_t);
- t_info_pages /= PAGE_SIZE;
- if ( t_info_pages % PAGE_SIZE )
- t_info_pages++;
+ t_info_words = num_online_cpus() * pages + t_info_first_offset;
+ t_info_bytes = t_info_words * sizeof(uint32_t);
+ t_info_pages = PFN_UP(t_info_bytes);
return pages;
}

View File

@ -1,30 +0,0 @@
changeset: 23092:45dafa422812
user: Olaf Hering <olaf@aepfle.de>
date: Fri Mar 25 08:57:28 2011 +0000
files: xen/common/trace.c
description:
xentrace: print calculated numbers in calculate_tbuf_size()
Print number of pages to allocate for per-cpu tracebuffer and metadata
to ease debugging when allocation fails.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
xen/common/trace.c | 2 ++
1 file changed, 2 insertions(+)
Index: xen-4.1.2-testing/xen/common/trace.c
===================================================================
--- xen-4.1.2-testing.orig/xen/common/trace.c
+++ xen-4.1.2-testing/xen/common/trace.c
@@ -127,6 +127,8 @@ static int calculate_tbuf_size(unsigned
t_info_words = num_online_cpus() * pages + t_info_first_offset;
t_info_bytes = t_info_words * sizeof(uint32_t);
t_info_pages = PFN_UP(t_info_bytes);
+ printk(XENLOG_INFO "xentrace: requesting %u t_info pages for %u trace pages on %u cpus\n",
+ t_info_pages, pages, num_online_cpus());
return pages;
}

View File

@ -1,45 +0,0 @@
changeset: 23093:4b784605b089
user: Olaf Hering <olaf@aepfle.de>
date: Fri Mar 25 08:57:47 2011 +0000
files: xen/common/trace.c
description:
xentrace: remove gdprintk usage since they are not in guest context
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
xen/common/trace.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
Index: xen-4.1.2-testing/xen/common/trace.c
===================================================================
--- xen-4.1.2-testing.orig/xen/common/trace.c
+++ xen-4.1.2-testing/xen/common/trace.c
@@ -119,7 +119,7 @@ static int calculate_tbuf_size(unsigned
size /= PAGE_SIZE;
if ( pages > size )
{
- gdprintk(XENLOG_INFO, "%s: requested number of %u pages reduced to %u\n",
+ printk(XENLOG_INFO "%s: requested number of %u pages reduced to %u\n",
__func__, pages, (unsigned int)size);
pages = size;
}
@@ -265,7 +265,7 @@ static int tb_set_size(unsigned int page
*/
if ( opt_tbuf_size && pages != opt_tbuf_size )
{
- gdprintk(XENLOG_INFO, "tb_set_size from %d to %d not implemented\n",
+ printk(XENLOG_INFO "tb_set_size from %d to %d not implemented\n",
opt_tbuf_size, pages);
return -EINVAL;
}
@@ -310,7 +310,7 @@ void __init init_trace_bufs(void)
{
if ( opt_tbuf_size && alloc_trace_bufs(opt_tbuf_size) )
{
- gdprintk(XENLOG_INFO, "Xen trace buffers: "
+ printk(XENLOG_INFO "Xen trace buffers: "
"allocation size %d failed, disabling\n",
opt_tbuf_size);
opt_tbuf_size = 0;

View File

@ -1,34 +0,0 @@
changeset: 23094:d09e8885bc82
user: Olaf Hering <olaf@aepfle.de>
date: Fri Mar 25 08:58:04 2011 +0000
files: xen/common/trace.c
description:
xentrace: update comments
Fix a typo, remove redundant comment.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
xen/common/trace.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
Index: xen-4.1.2-testing/xen/common/trace.c
===================================================================
--- xen-4.1.2-testing.orig/xen/common/trace.c
+++ xen-4.1.2-testing/xen/common/trace.c
@@ -196,12 +196,11 @@ static int alloc_trace_bufs(unsigned int
t_info->tbuf_size = pages;
/*
- * Now share the pages to xentrace can map them, and write them in
+ * Now share the pages so xentrace can map them, and write them in
* the global t_info structure.
*/
for_each_online_cpu(cpu)
{
- /* Share pages so that xentrace can map them. */
void *rawbuf = per_cpu(t_bufs, cpu);
struct page_info *p = virt_to_page(rawbuf);
uint32_t mfn = virt_to_mfn(rawbuf);

View File

@ -1,111 +0,0 @@
changeset: 23095:941119d58655
user: Olaf Hering <olaf@aepfle.de>
date: Fri Mar 25 09:01:37 2011 +0000
files: xen/common/trace.c
description:
xentrace: use consistent printk prefix
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
xen/common/trace.c | 31 +++++++++++++++++--------------
1 file changed, 17 insertions(+), 14 deletions(-)
Index: xen-4.1.2-testing/xen/common/trace.c
===================================================================
--- xen-4.1.2-testing.orig/xen/common/trace.c
+++ xen-4.1.2-testing/xen/common/trace.c
@@ -119,16 +119,18 @@ static int calculate_tbuf_size(unsigned
size /= PAGE_SIZE;
if ( pages > size )
{
- printk(XENLOG_INFO "%s: requested number of %u pages reduced to %u\n",
- __func__, pages, (unsigned int)size);
+ printk(XENLOG_INFO "xentrace: requested number of %u pages "
+ "reduced to %u\n",
+ pages, (unsigned int)size);
pages = size;
}
t_info_words = num_online_cpus() * pages + t_info_first_offset;
t_info_bytes = t_info_words * sizeof(uint32_t);
t_info_pages = PFN_UP(t_info_bytes);
- printk(XENLOG_INFO "xentrace: requesting %u t_info pages for %u trace pages on %u cpus\n",
- t_info_pages, pages, num_online_cpus());
+ printk(XENLOG_INFO "xentrace: requesting %u t_info pages "
+ "for %u trace pages on %u cpus\n",
+ t_info_pages, pages, num_online_cpus());
return pages;
}
@@ -177,7 +179,8 @@ static int alloc_trace_bufs(unsigned int
if ( (rawbuf = alloc_xenheap_pages(
order, MEMF_bits(32 + PAGE_SHIFT))) == NULL )
{
- printk("Xen trace buffers: memory allocation failed on cpu %d\n", cpu);
+ printk(XENLOG_INFO "xentrace: memory allocation failed "
+ "on cpu %d\n", cpu);
goto out_dealloc;
}
@@ -212,7 +215,7 @@ static int alloc_trace_bufs(unsigned int
t_info_mfn_list[offset + i]=mfn + i;
}
t_info->mfn_offset[cpu]=offset;
- printk(XENLOG_INFO "p%d mfn %"PRIx32" offset %d\n",
+ printk(XENLOG_INFO "xentrace: p%d mfn %"PRIx32" offset %d\n",
cpu, mfn, offset);
offset+=i;
@@ -225,7 +228,7 @@ static int alloc_trace_bufs(unsigned int
register_cpu_notifier(&cpu_nfb);
- printk("Xen trace buffers: initialised\n");
+ printk("xentrace: initialised\n");
wmb(); /* above must be visible before tb_init_done flag set */
tb_init_done = 1;
@@ -236,7 +239,7 @@ out_dealloc:
{
void *rawbuf = per_cpu(t_bufs, cpu);
per_cpu(t_bufs, cpu) = NULL;
- printk("Xen trace buffers: cpu %d p %p\n", cpu, rawbuf);
+ printk(XENLOG_DEBUG "xentrace: cpu %d p %p\n", cpu, rawbuf);
if ( rawbuf )
{
ASSERT(!(virt_to_page(rawbuf)->count_info & PGC_allocated));
@@ -245,7 +248,7 @@ out_dealloc:
}
free_xenheap_pages(t_info, get_order_from_pages(t_info_pages));
t_info = NULL;
- printk("Xen trace buffers: allocation failed! Tracing disabled.\n");
+ printk(XENLOG_WARNING "xentrace: allocation failed! Tracing disabled.\n");
return -ENOMEM;
}
@@ -264,8 +267,9 @@ static int tb_set_size(unsigned int page
*/
if ( opt_tbuf_size && pages != opt_tbuf_size )
{
- printk(XENLOG_INFO "tb_set_size from %d to %d not implemented\n",
- opt_tbuf_size, pages);
+ printk(XENLOG_INFO "xentrace: tb_set_size from %d to %d "
+ "not implemented\n",
+ opt_tbuf_size, pages);
return -EINVAL;
}
@@ -309,9 +313,8 @@ void __init init_trace_bufs(void)
{
if ( opt_tbuf_size && alloc_trace_bufs(opt_tbuf_size) )
{
- printk(XENLOG_INFO "Xen trace buffers: "
- "allocation size %d failed, disabling\n",
- opt_tbuf_size);
+ printk(XENLOG_INFO "xentrace: allocation size %d failed, disabling\n",
+ opt_tbuf_size);
opt_tbuf_size = 0;
}
}

View File

@ -1,95 +0,0 @@
# HG changeset patch
# User Jan Beulich <jbeulich@novell.com>
# Date 1301043797 0
# Node ID a65612bcbb921e98a8843157bf365e4ab16e8144
# Parent 941119d58655f2b2df86d9ecc4cb502bbc5e783c
x86/hpet: eliminate cpumask_lock
According to the (now getting removed) comment in struct
hpet_event_channel, this was to prevent accessing a CPU's
timer_deadline after it got cleared from cpumask. This can be done
without a lock altogether - hpet_broadcast_exit() can simply clear
the bit, and handle_hpet_broadcast() can read timer_deadline before
looking at the mask a second time (the cpumask bit was already
found set by the surrounding loop).
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Acked-by: Gang Wei <gang.wei@intel.com>
Index: xen-4.1.2-testing/xen/arch/x86/hpet.c
===================================================================
--- xen-4.1.2-testing.orig/xen/arch/x86/hpet.c
+++ xen-4.1.2-testing/xen/arch/x86/hpet.c
@@ -34,18 +34,6 @@ struct hpet_event_channel
int shift;
s_time_t next_event;
cpumask_t cpumask;
- /*
- * cpumask_lock is used to prevent hpet intr handler from accessing other
- * cpu's timer_deadline after the other cpu's mask was cleared --
- * mask cleared means cpu waken up, then accessing timer_deadline from
- * other cpu is not safe.
- * It is not used for protecting cpumask, so set ops needn't take it.
- * Multiple cpus clear cpumask simultaneously is ok due to the atomic
- * feature of cpu_clear, so hpet_broadcast_exit() can take read lock for
- * clearing cpumask, and handle_hpet_broadcast() have to take write lock
- * for read cpumask & access timer_deadline.
- */
- rwlock_t cpumask_lock;
spinlock_t lock;
void (*event_handler)(struct hpet_event_channel *);
@@ -208,17 +196,18 @@ again:
/* find all expired events */
for_each_cpu_mask(cpu, ch->cpumask)
{
- write_lock_irq(&ch->cpumask_lock);
+ s_time_t deadline;
- if ( cpu_isset(cpu, ch->cpumask) )
- {
- if ( per_cpu(timer_deadline, cpu) <= now )
- cpu_set(cpu, mask);
- else if ( per_cpu(timer_deadline, cpu) < next_event )
- next_event = per_cpu(timer_deadline, cpu);
- }
+ rmb();
+ deadline = per_cpu(timer_deadline, cpu);
+ rmb();
+ if ( !cpu_isset(cpu, ch->cpumask) )
+ continue;
- write_unlock_irq(&ch->cpumask_lock);
+ if ( deadline <= now )
+ cpu_set(cpu, mask);
+ else if ( deadline < next_event )
+ next_event = deadline;
}
/* wakeup the cpus which have an expired event. */
@@ -598,7 +587,6 @@ void hpet_broadcast_init(void)
hpet_events[i].shift = 32;
hpet_events[i].next_event = STIME_MAX;
spin_lock_init(&hpet_events[i].lock);
- rwlock_init(&hpet_events[i].cpumask_lock);
wmb();
hpet_events[i].event_handler = handle_hpet_broadcast;
}
@@ -634,7 +622,6 @@ void hpet_broadcast_init(void)
legacy_hpet_event.idx = 0;
legacy_hpet_event.flags = 0;
spin_lock_init(&legacy_hpet_event.lock);
- rwlock_init(&legacy_hpet_event.cpumask_lock);
wmb();
legacy_hpet_event.event_handler = handle_hpet_broadcast;
@@ -716,9 +703,7 @@ void hpet_broadcast_exit(void)
if ( !reprogram_timer(this_cpu(timer_deadline)) )
raise_softirq(TIMER_SOFTIRQ);
- read_lock_irq(&ch->cpumask_lock);
cpu_clear(cpu, ch->cpumask);
- read_unlock_irq(&ch->cpumask_lock);
if ( ch != &legacy_hpet_event )
{

View File

@ -1,298 +0,0 @@
# HG changeset patch
# User Keir Fraser <keir@xen.org>
# Date 1301126601 0
# Node ID 612171ff82ea51aaf65d98fd1a551eb8d50fb481
# Parent c9f745c153ec8c3775e2ee03adc3cb30370b84f6
rwlock: Allow to scale to 2^31-1 readers on x86.
Also rework to match the 'trylock' style of raw function used for
spinlocks.
Inspired by Jan Beulich's patch to do similar improved scaling.
Signed-off-by: Keir Fraser <keir@xen.org>
# HG changeset patch
# User Keir Fraser <keir@xen.org>
# Date 1301214635 -3600
# Node ID 0bc1c4746c8939337f693a513fd837fc03477db1
# Parent 48dac730a93b27ff60a340564e9a7afd7f9385f4
x86_32: Fix _raw_read_trylock() build on some gcc versions.
Was broken by 23099:612171ff82ea.
A bool_t is a single byte, and needs a 'q' register constraint. Avoid
the whole issue by changing the variable to an int, and explicitly
specify the operand suffix as 'l' for good measure.
Signed-off-by: Keir Fraser <keir@xen.org>
Index: xen-4.1.2-testing/xen/common/spinlock.c
===================================================================
--- xen-4.1.2-testing.orig/xen/common/spinlock.c
+++ xen-4.1.2-testing/xen/common/spinlock.c
@@ -234,7 +234,11 @@ void _spin_unlock_recursive(spinlock_t *
void _read_lock(rwlock_t *lock)
{
check_lock(&lock->debug);
- _raw_read_lock(&lock->raw);
+ while ( unlikely(!_raw_read_trylock(&lock->raw)) )
+ {
+ while ( likely(_raw_rw_is_write_locked(&lock->raw)) )
+ cpu_relax();
+ }
preempt_disable();
}
@@ -243,7 +247,13 @@ void _read_lock_irq(rwlock_t *lock)
ASSERT(local_irq_is_enabled());
local_irq_disable();
check_lock(&lock->debug);
- _raw_read_lock(&lock->raw);
+ while ( unlikely(!_raw_read_trylock(&lock->raw)) )
+ {
+ local_irq_enable();
+ while ( likely(_raw_rw_is_write_locked(&lock->raw)) )
+ cpu_relax();
+ local_irq_disable();
+ }
preempt_disable();
}
@@ -252,11 +262,26 @@ unsigned long _read_lock_irqsave(rwlock_
unsigned long flags;
local_irq_save(flags);
check_lock(&lock->debug);
- _raw_read_lock(&lock->raw);
+ while ( unlikely(!_raw_read_trylock(&lock->raw)) )
+ {
+ local_irq_restore(flags);
+ while ( likely(_raw_rw_is_write_locked(&lock->raw)) )
+ cpu_relax();
+ local_irq_save(flags);
+ }
preempt_disable();
return flags;
}
+int _read_trylock(rwlock_t *lock)
+{
+ check_lock(&lock->debug);
+ if ( !_raw_read_trylock(&lock->raw) )
+ return 0;
+ preempt_disable();
+ return 1;
+}
+
void _read_unlock(rwlock_t *lock)
{
preempt_enable();
@@ -280,7 +305,11 @@ void _read_unlock_irqrestore(rwlock_t *l
void _write_lock(rwlock_t *lock)
{
check_lock(&lock->debug);
- _raw_write_lock(&lock->raw);
+ while ( unlikely(!_raw_write_trylock(&lock->raw)) )
+ {
+ while ( likely(_raw_rw_is_locked(&lock->raw)) )
+ cpu_relax();
+ }
preempt_disable();
}
@@ -289,7 +318,13 @@ void _write_lock_irq(rwlock_t *lock)
ASSERT(local_irq_is_enabled());
local_irq_disable();
check_lock(&lock->debug);
- _raw_write_lock(&lock->raw);
+ while ( unlikely(!_raw_write_trylock(&lock->raw)) )
+ {
+ local_irq_enable();
+ while ( likely(_raw_rw_is_locked(&lock->raw)) )
+ cpu_relax();
+ local_irq_disable();
+ }
preempt_disable();
}
@@ -298,7 +333,13 @@ unsigned long _write_lock_irqsave(rwlock
unsigned long flags;
local_irq_save(flags);
check_lock(&lock->debug);
- _raw_write_lock(&lock->raw);
+ while ( unlikely(!_raw_write_trylock(&lock->raw)) )
+ {
+ local_irq_restore(flags);
+ while ( likely(_raw_rw_is_locked(&lock->raw)) )
+ cpu_relax();
+ local_irq_save(flags);
+ }
preempt_disable();
return flags;
}
Index: xen-4.1.2-testing/xen/include/asm-ia64/linux-xen/asm/spinlock.h
===================================================================
--- xen-4.1.2-testing.orig/xen/include/asm-ia64/linux-xen/asm/spinlock.h
+++ xen-4.1.2-testing/xen/include/asm-ia64/linux-xen/asm/spinlock.h
@@ -35,17 +35,6 @@ typedef struct {
} raw_rwlock_t;
#define _RAW_RW_LOCK_UNLOCKED /*(raw_rwlock_t)*/ { 0, 0 }
-#define _raw_read_lock(rw) \
-do { \
- raw_rwlock_t *__read_lock_ptr = (rw); \
- \
- while (unlikely(ia64_fetchadd(1, (int *) __read_lock_ptr, acq) < 0)) { \
- ia64_fetchadd(-1, (int *) __read_lock_ptr, rel); \
- while (*(volatile int *)__read_lock_ptr < 0) \
- cpu_relax(); \
- } \
-} while (0)
-
#define _raw_read_unlock(rw) \
do { \
raw_rwlock_t *__read_lock_ptr = (rw); \
@@ -53,20 +42,6 @@ do { \
} while (0)
#ifdef ASM_SUPPORTED
-#define _raw_write_lock(rw) \
-do { \
- __asm__ __volatile__ ( \
- "mov ar.ccv = r0\n" \
- "dep r29 = -1, r0, 31, 1;;\n" \
- "1:\n" \
- "ld4 r2 = [%0];;\n" \
- "cmp4.eq p0,p7 = r0,r2\n" \
- "(p7) br.cond.spnt.few 1b \n" \
- "cmpxchg4.acq r2 = [%0], r29, ar.ccv;;\n" \
- "cmp4.eq p0,p7 = r0, r2\n" \
- "(p7) br.cond.spnt.few 1b;;\n" \
- :: "r"(rw) : "ar.ccv", "p7", "r2", "r29", "memory"); \
-} while(0)
#define _raw_write_trylock(rw) \
({ \
@@ -82,16 +57,6 @@ do { \
#else /* !ASM_SUPPORTED */
-#define _raw_write_lock(l) \
-({ \
- __u64 ia64_val, ia64_set_val = ia64_dep_mi(-1, 0, 31, 1); \
- __u32 *ia64_write_lock_ptr = (__u32 *) (l); \
- do { \
- while (*ia64_write_lock_ptr) \
- ia64_barrier(); \
- ia64_val = ia64_cmpxchg4_acq(ia64_write_lock_ptr, ia64_set_val, 0); \
- } while (ia64_val); \
-})
#define _raw_write_trylock(rw) \
({ \
Index: xen-4.1.2-testing/xen/include/asm-x86/spinlock.h
===================================================================
--- xen-4.1.2-testing.orig/xen/include/asm-x86/spinlock.h
+++ xen-4.1.2-testing/xen/include/asm-x86/spinlock.h
@@ -35,51 +35,29 @@ typedef struct {
volatile int lock;
} raw_rwlock_t;
-#define RW_LOCK_BIAS 0x01000000
-#define _RAW_RW_LOCK_UNLOCKED /*(raw_rwlock_t)*/ { RW_LOCK_BIAS }
+#define RW_WRITE_BIAS 0x7fffffff
+#define _RAW_RW_LOCK_UNLOCKED /*(raw_rwlock_t)*/ { 0 }
-static always_inline void _raw_read_lock(raw_rwlock_t *rw)
+static always_inline int _raw_read_trylock(raw_rwlock_t *rw)
{
- asm volatile (
- "1: lock; decl %0 \n"
- " jns 3f \n"
- " lock; incl %0 \n"
- "2: rep; nop \n"
- " cmpl $1,%0 \n"
- " js 2b \n"
- " jmp 1b \n"
- "3:"
- : "=m" (rw->lock) : : "memory" );
-}
+ int acquired;
-static always_inline void _raw_write_lock(raw_rwlock_t *rw)
-{
asm volatile (
- "1: lock; subl %1,%0 \n"
- " jz 3f \n"
- " lock; addl %1,%0 \n"
- "2: rep; nop \n"
- " cmpl %1,%0 \n"
- " jne 2b \n"
+ " lock; decl %0 \n"
+ " jns 2f \n"
+ "1: .subsection 1 \n"
+ "2: lock; incl %0 \n"
+ " decl %1 \n"
" jmp 1b \n"
- "3:"
- : "=m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory" );
+ " .subsection 0 \n"
+ : "=m" (rw->lock), "=r" (acquired) : "1" (1) : "memory" );
+
+ return acquired;
}
static always_inline int _raw_write_trylock(raw_rwlock_t *rw)
{
- int rc;
-
- asm volatile (
- " lock; subl %2,%0 \n"
- " jz 1f \n"
- " lock; addl %2,%0 \n"
- " dec %1 \n"
- "1:"
- : "=m" (rw->lock), "=r" (rc) : "i" (RW_LOCK_BIAS), "1" (1)
- : "memory" );
-
- return rc;
+ return (cmpxchg(&rw->lock, 0, RW_WRITE_BIAS) == 0);
}
static always_inline void _raw_read_unlock(raw_rwlock_t *rw)
@@ -92,11 +70,11 @@ static always_inline void _raw_read_unlo
static always_inline void _raw_write_unlock(raw_rwlock_t *rw)
{
asm volatile (
- "lock ; addl %1,%0"
- : "=m" ((rw)->lock) : "i" (RW_LOCK_BIAS) : "memory" );
+ "lock ; subl %1,%0"
+ : "=m" ((rw)->lock) : "i" (RW_WRITE_BIAS) : "memory" );
}
-#define _raw_rw_is_locked(x) ((x)->lock < RW_LOCK_BIAS)
-#define _raw_rw_is_write_locked(x) ((x)->lock <= 0)
+#define _raw_rw_is_locked(x) ((x)->lock != 0)
+#define _raw_rw_is_write_locked(x) ((x)->lock > 0)
#endif /* __ASM_SPINLOCK_H */
Index: xen-4.1.2-testing/xen/include/xen/spinlock.h
===================================================================
--- xen-4.1.2-testing.orig/xen/include/xen/spinlock.h
+++ xen-4.1.2-testing/xen/include/xen/spinlock.h
@@ -157,6 +157,7 @@ unsigned long _read_lock_irqsave(rwlock_
void _read_unlock(rwlock_t *lock);
void _read_unlock_irq(rwlock_t *lock);
void _read_unlock_irqrestore(rwlock_t *lock, unsigned long flags);
+int _read_trylock(rwlock_t *lock);
void _write_lock(rwlock_t *lock);
void _write_lock_irq(rwlock_t *lock);
@@ -210,6 +211,7 @@ int _rw_is_write_locked(rwlock_t *lock);
#define read_unlock(l) _read_unlock(l)
#define read_unlock_irq(l) _read_unlock_irq(l)
#define read_unlock_irqrestore(l, f) _read_unlock_irqrestore(l, f)
+#define read_trylock(l) _read_trylock(l)
#define write_lock(l) _write_lock(l)
#define write_lock_irq(l) _write_lock_irq(l)

View File

@ -1,27 +0,0 @@
# HG changeset patch
# User Keir Fraser <keir@xen.org>
# Date 1301132521 0
# Node ID 48dac730a93b27ff60a340564e9a7afd7f9385f4
# Parent 8f001d864fefac689b7662bc9979eaddf4fd6e9c
x86: __pirq_guest_eoi() must check it is called for a fully
guest-bound irq before accessing desc->action.
Signed-off-by: Keir Fraser <keir@xen.org>
Index: xen-4.1.3-testing/xen/arch/x86/irq.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/irq.c
+++ xen-4.1.3-testing/xen/arch/x86/irq.c
@@ -1143,6 +1143,12 @@ static void __pirq_guest_eoi(struct doma
return;
}
+ if ( !(desc->status & IRQ_GUEST) )
+ {
+ spin_unlock_irq(&desc->lock);
+ return;
+ }
+
action = (irq_guest_action_t *)desc->action;
irq = desc - irq_desc;

View File

@ -1,208 +0,0 @@
# HG changeset patch
# User Allen Kay <allen.m.kay@intel.com>
# Date 1301755765 -3600
# Node ID 1046830079376a4b29fcad0cd037a834e808ed06
# Parent 89c23f58aa986092da0c9a7dfac1c41befbe1f3f
[VTD] check BIOS settings before enabling interrupt remapping or x2apic
Check flags field in ACPI DMAR structure before enabling interrupt
remapping or x2apic. This allows platform vendors to disable
interrupt remapping or x2apic features if on board BIOS does not
support them.
Signed-off-by: Allen Kay <allen.m.kay@intel.com>
# HG changeset patch
# User Allen Kay <allen.m.kay@intel.com>
# Date 1302077462 -3600
# Node ID c7916d6f4dfba9d6c7eeb0fc2796068d75e2fb4a
# Parent 42fa70e0761bbb0596618ca5323664f31a2faa76
[VTD] Fixes to ACPI DMAR flag checks.
* platform_supports_{intremap,x2apic} should not be marked __init as
they are used during S3 resume.
* DMAR flags should be taken from the table passed to
acpi_parse_dmar() -- this is the trusted copy of the DMAR, when
running in TXT mode.
Signed-off-by: Allen Kay <allen.m.kay@intel.com>
Index: xen-4.1.3-testing/xen/arch/x86/apic.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/apic.c
+++ xen-4.1.3-testing/xen/arch/x86/apic.c
@@ -572,7 +572,7 @@ static void resume_x2apic(void)
mask_8259A();
mask_IO_APIC_setup(ioapic_entries);
- iommu_enable_IR();
+ iommu_enable_x2apic_IR();
__enable_x2apic();
restore_IO_APIC_setup(ioapic_entries);
@@ -789,7 +789,7 @@ int lapic_suspend(void)
local_irq_save(flags);
disable_local_APIC();
- iommu_disable_IR();
+ iommu_disable_x2apic_IR();
local_irq_restore(flags);
return 0;
}
@@ -1035,7 +1035,7 @@ void __init x2apic_bsp_setup(void)
mask_8259A();
mask_IO_APIC_setup(ioapic_entries);
- if ( iommu_enable_IR() )
+ if ( iommu_enable_x2apic_IR() )
{
if ( x2apic_enabled )
panic("Interrupt remapping could not be enabled while "
Index: xen-4.1.3-testing/xen/drivers/passthrough/vtd/dmar.c
===================================================================
--- xen-4.1.3-testing.orig/xen/drivers/passthrough/vtd/dmar.c
+++ xen-4.1.3-testing/xen/drivers/passthrough/vtd/dmar.c
@@ -46,6 +46,7 @@ LIST_HEAD(acpi_rmrr_units);
LIST_HEAD(acpi_atsr_units);
LIST_HEAD(acpi_rhsa_units);
+static int __read_mostly dmar_flags;
static u64 igd_drhd_address;
u8 dmar_host_address_width;
@@ -684,6 +685,7 @@ static int __init acpi_parse_dmar(struct
int ret = 0;
dmar = (struct acpi_table_dmar *)table;
+ dmar_flags = dmar->flags;
if ( !iommu_enabled )
{
@@ -804,3 +806,22 @@ void acpi_dmar_zap(void)
dmar_table->signature[0] = 'X';
dmar_table->checksum -= 'X'-'D';
}
+
+int platform_supports_intremap(void)
+{
+ unsigned int flags = 0;
+
+ flags = DMAR_INTR_REMAP;
+ return ((dmar_flags & flags) == DMAR_INTR_REMAP);
+}
+
+int platform_supports_x2apic(void)
+{
+ unsigned int flags = 0;
+
+ if (!cpu_has_x2apic)
+ return 0;
+
+ flags = DMAR_INTR_REMAP | DMAR_X2APIC_OPT_OUT;
+ return ((dmar_flags & flags) == DMAR_INTR_REMAP);
+}
Index: xen-4.1.3-testing/xen/drivers/passthrough/vtd/extern.h
===================================================================
--- xen-4.1.3-testing.orig/xen/drivers/passthrough/vtd/extern.h
+++ xen-4.1.3-testing/xen/drivers/passthrough/vtd/extern.h
@@ -87,5 +87,7 @@ void vtd_ops_preamble_quirk(struct iommu
void vtd_ops_postamble_quirk(struct iommu* iommu);
void me_wifi_quirk(struct domain *domain, u8 bus, u8 devfn, int map);
void pci_vtd_quirk(struct pci_dev *pdev);
+int platform_supports_intremap(void);
+int platform_supports_x2apic(void);
#endif // _VTD_EXTERN_H_
Index: xen-4.1.3-testing/xen/drivers/passthrough/vtd/intremap.c
===================================================================
--- xen-4.1.3-testing.orig/xen/drivers/passthrough/vtd/intremap.c
+++ xen-4.1.3-testing/xen/drivers/passthrough/vtd/intremap.c
@@ -741,6 +741,13 @@ int enable_intremap(struct iommu *iommu,
ASSERT(ecap_intr_remap(iommu->ecap) && iommu_intremap);
+ if ( !platform_supports_intremap() )
+ {
+ dprintk(XENLOG_ERR VTDPREFIX,
+ "Platform firmware does not support interrupt remapping\n");
+ return -EINVAL;
+ }
+
ir_ctrl = iommu_ir_ctrl(iommu);
sts = dmar_readl(iommu->reg, DMAR_GSTS_REG);
@@ -847,10 +854,10 @@ out:
}
/*
- * This function is used to enable Interrutp remapping when
+ * This function is used to enable Interrupt remapping when
* enable x2apic
*/
-int iommu_enable_IR(void)
+int iommu_enable_x2apic_IR(void)
{
struct acpi_drhd_unit *drhd;
struct iommu *iommu;
@@ -858,6 +865,9 @@ int iommu_enable_IR(void)
if ( !iommu_supports_eim() )
return -1;
+ if ( !platform_supports_x2apic() )
+ return -1;
+
for_each_drhd_unit ( drhd )
{
struct qi_ctrl *qi_ctrl = NULL;
@@ -907,7 +917,7 @@ int iommu_enable_IR(void)
* This function is used to disable Interrutp remapping when
* suspend local apic
*/
-void iommu_disable_IR(void)
+void iommu_disable_x2apic_IR(void)
{
struct acpi_drhd_unit *drhd;
Index: xen-4.1.3-testing/xen/drivers/passthrough/vtd/iommu.c
===================================================================
--- xen-4.1.3-testing.orig/xen/drivers/passthrough/vtd/iommu.c
+++ xen-4.1.3-testing/xen/drivers/passthrough/vtd/iommu.c
@@ -2091,7 +2091,7 @@ static int init_vtd_hw(void)
{
iommu_intremap = 0;
dprintk(XENLOG_WARNING VTDPREFIX,
- "Failed to enable Interrupt Remapping!\n");
+ "Interrupt Remapping not enabled\n");
break;
}
}
Index: xen-4.1.3-testing/xen/drivers/passthrough/vtd/iommu.h
===================================================================
--- xen-4.1.3-testing.orig/xen/drivers/passthrough/vtd/iommu.h
+++ xen-4.1.3-testing/xen/drivers/passthrough/vtd/iommu.h
@@ -22,6 +22,10 @@
#include <xen/types.h>
+/* DMAR Flags bits */
+#define DMAR_INTR_REMAP 0x1
+#define DMAR_X2APIC_OPT_OUT 0x2
+
/*
* Intel IOMMU register specification per version 1.0 public spec.
*/
Index: xen-4.1.3-testing/xen/include/xen/iommu.h
===================================================================
--- xen-4.1.3-testing.orig/xen/include/xen/iommu.h
+++ xen-4.1.3-testing/xen/include/xen/iommu.h
@@ -66,8 +66,8 @@ struct iommu {
int iommu_setup(void);
int iommu_supports_eim(void);
-int iommu_enable_IR(void);
-void iommu_disable_IR(void);
+int iommu_enable_x2apic_IR(void);
+void iommu_disable_x2apic_IR(void);
int iommu_add_device(struct pci_dev *pdev);
int iommu_remove_device(struct pci_dev *pdev);

View File

@ -1,45 +0,0 @@
changeset: 23128:4a335f1000ea
user: Olaf Hering <olaf@aepfle.de>
date: Sat Apr 02 15:50:19 2011 +0100
files: xen/common/trace.c
description:
xentrace: correct formula to calculate t_info_pages
The current formula to calculate t_info_pages, based on the initial
code, is slightly incorrect. It may allocate more than needed.
Each cpu has some pages/mfns stored as uint32_t.
That list is stored with an offset at tinfo.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Acked-by: George Dunlap <george.dunlap@eu.citrix.com>
---
xen/common/trace.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
Index: xen-4.1.2-testing/xen/common/trace.c
===================================================================
--- xen-4.1.2-testing.orig/xen/common/trace.c
+++ xen-4.1.2-testing/xen/common/trace.c
@@ -110,7 +110,7 @@ static int calculate_tbuf_size(unsigned
{
struct t_buf dummy;
typeof(dummy.prod) size;
- unsigned int t_info_words, t_info_bytes;
+ unsigned int t_info_words;
/* force maximum value for an unsigned type */
size = -1;
@@ -125,9 +125,8 @@ static int calculate_tbuf_size(unsigned
pages = size;
}
- t_info_words = num_online_cpus() * pages + t_info_first_offset;
- t_info_bytes = t_info_words * sizeof(uint32_t);
- t_info_pages = PFN_UP(t_info_bytes);
+ t_info_words = num_online_cpus() * pages * sizeof(uint32_t);
+ t_info_pages = PFN_UP(t_info_first_offset + t_info_words);
printk(XENLOG_INFO "xentrace: requesting %u t_info pages "
"for %u trace pages on %u cpus\n",
t_info_pages, pages, num_online_cpus());

View File

@ -1,30 +0,0 @@
changeset: 23129:219ba19aedeb
user: Olaf Hering <olaf@aepfle.de>
date: Sat Apr 02 15:50:47 2011 +0100
files: xen/common/trace.c
description:
xentrace: remove unneeded debug printk
The pointer value in case of an allocation failure is rather
uninteresting.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Acked-by: George Dunlap <george.dunlap@eu.citrix.com>
---
xen/common/trace.c | 1 -
1 file changed, 1 deletion(-)
Index: xen-4.1.2-testing/xen/common/trace.c
===================================================================
--- xen-4.1.2-testing.orig/xen/common/trace.c
+++ xen-4.1.2-testing/xen/common/trace.c
@@ -238,7 +238,6 @@ out_dealloc:
{
void *rawbuf = per_cpu(t_bufs, cpu);
per_cpu(t_bufs, cpu) = NULL;
- printk(XENLOG_DEBUG "xentrace: cpu %d p %p\n", cpu, rawbuf);
if ( rawbuf )
{
ASSERT(!(virt_to_page(rawbuf)->count_info & PGC_allocated));

View File

@ -1,39 +0,0 @@
changeset: 23173:94cef9aaf0cd
user: Keir Fraser <keir@xen.org>
date: Wed Apr 06 15:52:50 2011 +0100
files: xen/common/trace.c
description:
xentrace: Move register_cpu_notifier() call into boot-time init.
We can't do it lazily from alloc_trace_bufs() as that gets called
later if tracing is enabled later by dom0.
Signed-off-by: Keir Fraser <keir@xen.org>
---
xen/common/trace.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
Index: xen-4.1.2-testing/xen/common/trace.c
===================================================================
--- xen-4.1.2-testing.orig/xen/common/trace.c
+++ xen-4.1.2-testing/xen/common/trace.c
@@ -225,8 +225,6 @@ static int alloc_trace_bufs(unsigned int
t_buf_highwater = data_size >> 1; /* 50% high water */
opt_tbuf_size = pages;
- register_cpu_notifier(&cpu_nfb);
-
printk("xentrace: initialised\n");
wmb(); /* above must be visible before tb_init_done flag set */
tb_init_done = 1;
@@ -309,6 +307,8 @@ int trace_will_trace_event(u32 event)
*/
void __init init_trace_bufs(void)
{
+ register_cpu_notifier(&cpu_nfb);
+
if ( opt_tbuf_size && alloc_trace_bufs(opt_tbuf_size) )
{
printk(XENLOG_INFO "xentrace: allocation size %d failed, disabling\n",

View File

@ -1,27 +0,0 @@
# HG changeset patch
# User Wei Wang <wei.wang2@amd.com>
# Date 1302610857 -3600
# Node ID dbd98ab2f87facba8117bb881fa2ea5dfdb92960
# Parent 697ac895c11c6d5d82524de56796cee98fded2a5
amd iommu: Unmapped interrupt should generate IO page faults.
This helps us to debug interrupt issues.
Signed-off-by: Wei Wang <wei.wang2@amd.com>
Index: xen-4.1.2-testing/xen/drivers/passthrough/amd/iommu_map.c
===================================================================
--- xen-4.1.2-testing.orig/xen/drivers/passthrough/amd/iommu_map.c
+++ xen-4.1.2-testing/xen/drivers/passthrough/amd/iommu_map.c
@@ -327,8 +327,9 @@ void amd_iommu_set_intremap_table(u32 *d
set_field_in_reg_u32(0xB, entry,
IOMMU_DEV_TABLE_INT_TABLE_LENGTH_MASK,
IOMMU_DEV_TABLE_INT_TABLE_LENGTH_SHIFT, &entry);
- /* ignore unmapped interrupts */
- set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, entry,
+
+ /* unmapped interrupt results io page faults*/
+ set_field_in_reg_u32(IOMMU_CONTROL_DISABLED, entry,
IOMMU_DEV_TABLE_INT_TABLE_IGN_UNMAPPED_MASK,
IOMMU_DEV_TABLE_INT_TABLE_IGN_UNMAPPED_SHIFT, &entry);
set_field_in_reg_u32(int_valid ? IOMMU_CONTROL_ENABLED :

View File

@ -1,121 +0,0 @@
References: FATE#309900
# HG changeset patch
# User Christoph Egger <Christoph.Egger@amd.com>
# Date 1302700499 -3600
# Node ID 3b2182100ba2fa5c4a3a450e473717e2300aa8f1
# Parent 2284c79b606ac14ef5c5bc2c1cce62188b5bd9ee
x86/svm/asid: Introduce svm_invlpga()
Signed-off-by: Christoph Egger <Christoph.Egger@amd.com>
# HG changeset patch
# User Andre Przywara <andre.przywara@amd.com>
# Date 1303117597 -3600
# Node ID e324c4d1dd6eeb9417fec513640ca795bd0f5dd4
# Parent 2c8ad607ece18b4740b9fc4ffe267a0e0893c141
svm: implement INVLPG part of DecodeAssist
Newer SVM implementations (Bulldozer) give the desired address on
a INVLPG intercept explicitly in the EXITINFO1 field of the VMCB.
Use this address to avoid a costly instruction fetch and decode
cycle.
Signed-off-by: Andre Przywara <andre.przywara@amd.com>
# HG changeset patch
# User Christoph Egger <Christoph.Egger@amd.com>
# Date 1305187246 -3600
# Node ID 19d6541c4abec3486c83de76102ec46d7fe22a16
# Parent b6e8e916ed2827fb1329de0de2e23ee5b6b78662
nestedsvm: update rip on invlpga intercept
Fixes endless loop.
Signed-off-by: Christoph Egger <Christoph.Egger@amd.com>
Index: xen-4.1.3-testing/xen/arch/x86/hvm/svm/emulate.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/hvm/svm/emulate.c
+++ xen-4.1.3-testing/xen/arch/x86/hvm/svm/emulate.c
@@ -102,6 +102,7 @@ MAKE_INSTR(INT3, 1, 0xcc);
MAKE_INSTR(RDTSC, 2, 0x0f, 0x31);
MAKE_INSTR(PAUSE, 1, 0x90);
MAKE_INSTR(XSETBV, 3, 0x0f, 0x01, 0xd1);
+MAKE_INSTR(INVLPGA,3, 0x0f, 0x01, 0xdf);
static const u8 *opc_bytes[INSTR_MAX_COUNT] =
{
@@ -116,6 +117,7 @@ static const u8 *opc_bytes[INSTR_MAX_COU
[INSTR_RDTSC] = OPCODE_RDTSC,
[INSTR_PAUSE] = OPCODE_PAUSE,
[INSTR_XSETBV] = OPCODE_XSETBV,
+ [INSTR_INVLPGA] = OPCODE_INVLPGA,
};
static int fetch(struct vcpu *v, u8 *buf, unsigned long addr, int len)
Index: xen-4.1.3-testing/xen/arch/x86/hvm/svm/svm.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/hvm/svm/svm.c
+++ xen-4.1.3-testing/xen/arch/x86/hvm/svm/svm.c
@@ -1748,8 +1748,10 @@ asmlinkage void svm_vmexit_handler(struc
break;
case VMEXIT_INVLPGA:
- if ( !handle_mmio() )
- hvm_inject_exception(TRAP_gp_fault, 0, 0);
+ if ( (inst_len = __get_instruction_length(v, INSTR_INVLPGA)) == 0 )
+ break;
+ svm_invlpga(regs->eax, v->arch.hvm_vcpu.asid);
+ __update_guest_eip(regs, inst_len);
break;
case VMEXIT_VMMCALL:
Index: xen-4.1.3-testing/xen/include/asm-x86/hvm/svm/asid.h
===================================================================
--- xen-4.1.3-testing.orig/xen/include/asm-x86/hvm/svm/asid.h
+++ xen-4.1.3-testing/xen/include/asm-x86/hvm/svm/asid.h
@@ -34,10 +34,7 @@ static inline void svm_asid_g_invlpg(str
{
#if 0
/* Optimization? */
- asm volatile (".byte 0x0F,0x01,0xDF \n"
- : /* output */
- : /* input */
- "a" (g_vaddr), "c"(v->arch.hvm_svm.vmcb->guest_asid) );
+ svm_invlpga(g_vaddr, v->arch.hvm_svm.vmcb->guest_asid);
#endif
/* Safe fallback. Take a new ASID. */
Index: xen-4.1.3-testing/xen/include/asm-x86/hvm/svm/emulate.h
===================================================================
--- xen-4.1.3-testing.orig/xen/include/asm-x86/hvm/svm/emulate.h
+++ xen-4.1.3-testing/xen/include/asm-x86/hvm/svm/emulate.h
@@ -33,6 +33,7 @@ enum instruction_index {
INSTR_RDTSC,
INSTR_PAUSE,
INSTR_XSETBV,
+ INSTR_INVLPGA,
INSTR_MAX_COUNT /* Must be last - Number of instructions supported */
};
Index: xen-4.1.3-testing/xen/include/asm-x86/hvm/svm/svm.h
===================================================================
--- xen-4.1.3-testing.orig/xen/include/asm-x86/hvm/svm/svm.h
+++ xen-4.1.3-testing/xen/include/asm-x86/hvm/svm/svm.h
@@ -62,6 +62,15 @@ static inline void svm_vmsave(void *vmcb
: : "a" (__pa(vmcb)) : "memory" );
}
+static inline void svm_invlpga(unsigned long vaddr, uint32_t asid)
+{
+ asm volatile (
+ ".byte 0x0f,0x01,0xdf"
+ : /* output */
+ : /* input */
+ "a" (vaddr), "c" (asid));
+}
+
extern u32 svm_feature_flags;
#define SVM_FEATURE_NPT 0 /* Nested page table support */

View File

@ -1,69 +0,0 @@
changeset: 23239:51d89366c859
user: Olaf Hering <olaf@aepfle.de>
date: Mon Apr 18 15:12:04 2011 +0100
files: xen/common/trace.c
description:
xentrace: correct overflow check for number of per-cpu trace pages
The calculated number of per-cpu trace pages is stored in t_info and
shared with tools like xentrace. Since its an u16 the value may
overflow because the current check is based on u32. Using the u16
means each cpu could in theory use up to 256MB as trace
buffer. However such a large allocation will currently fail on x86 due
to the MAX_ORDER limit. Check both max theoretical number of pages
per cpu and max number of pages reachable by struct t_buf->prod/cons
variables with requested number of pages.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Acked-by: George Dunlap <george.dunlap@eu.citrix.com>
---
xen/common/trace.c | 22 +++++++++++++++-------
1 file changed, 15 insertions(+), 7 deletions(-)
Index: xen-4.1.2-testing/xen/common/trace.c
===================================================================
--- xen-4.1.2-testing.orig/xen/common/trace.c
+++ xen-4.1.2-testing/xen/common/trace.c
@@ -104,25 +104,33 @@ static void calc_tinfo_first_offset(void
* calculate_tbuf_size - check to make sure that the proposed size will fit
* in the currently sized struct t_info and allows prod and cons to
* reach double the value without overflow.
+ * The t_info layout is fixed and cant be changed without breaking xentrace.
* Initialize t_info_pages based on number of trace pages.
*/
static int calculate_tbuf_size(unsigned int pages)
{
- struct t_buf dummy;
- typeof(dummy.prod) size;
+ struct t_buf dummy_size;
+ typeof(dummy_size.prod) max_size;
+ struct t_info dummy_pages;
+ typeof(dummy_pages.tbuf_size) max_pages;
unsigned int t_info_words;
/* force maximum value for an unsigned type */
- size = -1;
+ max_size = -1;
+ max_pages = -1;
/* max size holds up to n pages */
- size /= PAGE_SIZE;
- if ( pages > size )
+ max_size /= PAGE_SIZE;
+
+ if ( max_size < max_pages )
+ max_pages = max_size;
+
+ if ( pages > max_pages )
{
printk(XENLOG_INFO "xentrace: requested number of %u pages "
"reduced to %u\n",
- pages, (unsigned int)size);
- pages = size;
+ pages, max_pages);
+ pages = max_pages;
}
t_info_words = num_online_cpus() * pages * sizeof(uint32_t);

View File

@ -1,24 +0,0 @@
References: bnc#718668
# HG changeset patch
# User Tim Deegan <Tim.Deegan@citrix.com>
# Date 1303297371 -3600
# Node ID eb4505f8dd97f894ee4b4e1b55ea1272c05e6759
# Parent 3539ef956a378ad7fe39654ff9aca5b0e7bf8843
xen/x86: re-enable xsave by default now that it supports live migration.
Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com>
Index: xen-4.1.3-testing/xen/arch/x86/cpu/common.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/cpu/common.c
+++ xen-4.1.3-testing/xen/arch/x86/cpu/common.c
@@ -25,7 +25,7 @@ boolean_param("nofxsr", disable_x86_fxsr
static bool_t __cpuinitdata disable_x86_serial_nr;
boolean_param("noserialnumber", disable_x86_serial_nr);
-static bool_t __cpuinitdata use_xsave;
+static bool_t __cpuinitdata use_xsave = 1;
boolean_param("xsave", use_xsave);
unsigned int __devinitdata opt_cpuid_mask_ecx = ~0u;

View File

@ -1,209 +0,0 @@
# HG changeset patch
# User Jan Beulich <jbeulich@novell.com>
# Date 1304930762 -3600
# Node ID 82180954eda9cfe279e7ecf8c9ed4ffa29796bfb
# Parent c822888f36568f26e95f9844c7f0c5e06df7aa20
misc cpufreq cleanup
- proper handling of governor command line options when using the
default governor
- warning message for unrecognized command line options
- replacing a NR_CPUS sized array with per-CPU data
- a couple of __read_mostly annotations
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Index: xen-4.1.2-testing/xen/drivers/cpufreq/cpufreq.c
===================================================================
--- xen-4.1.2-testing.orig/xen/drivers/cpufreq/cpufreq.c
+++ xen-4.1.2-testing/xen/drivers/cpufreq/cpufreq.c
@@ -47,7 +47,8 @@
#include <acpi/acpi.h>
#include <acpi/cpufreq/cpufreq.h>
-static unsigned int usr_max_freq, usr_min_freq;
+static unsigned int __read_mostly usr_min_freq;
+static unsigned int __read_mostly usr_max_freq;
static void cpufreq_cmdline_common_para(struct cpufreq_policy *new_policy);
struct cpufreq_dom {
@@ -57,7 +58,7 @@ struct cpufreq_dom {
};
static LIST_HEAD(cpufreq_dom_list_head);
-struct cpufreq_governor *cpufreq_opt_governor;
+struct cpufreq_governor *__read_mostly cpufreq_opt_governor;
LIST_HEAD(cpufreq_governor_list);
bool_t __read_mostly cpufreq_verbose;
@@ -543,6 +544,7 @@ void __init cpufreq_cmdline_parse(char *
{
static struct cpufreq_governor *__initdata cpufreq_governors[] =
{
+ CPUFREQ_DEFAULT_GOVERNOR,
&cpufreq_gov_userspace,
&cpufreq_gov_dbs,
&cpufreq_gov_performance,
@@ -576,8 +578,10 @@ void __init cpufreq_cmdline_parse(char *
}
if (str && !cpufreq_handle_common_option(str, val) &&
- cpufreq_governors[gov_index]->handle_option)
- cpufreq_governors[gov_index]->handle_option(str, val);
+ (!cpufreq_governors[gov_index]->handle_option ||
+ !cpufreq_governors[gov_index]->handle_option(str, val)))
+ printk(XENLOG_WARNING "cpufreq/%s: option '%s' not recognized\n",
+ cpufreq_governors[gov_index]->name, str);
str = end;
} while (str);
Index: xen-4.1.2-testing/xen/drivers/cpufreq/cpufreq_misc_governors.c
===================================================================
--- xen-4.1.2-testing.orig/xen/drivers/cpufreq/cpufreq_misc_governors.c
+++ xen-4.1.2-testing/xen/drivers/cpufreq/cpufreq_misc_governors.c
@@ -14,14 +14,17 @@
*
*/
+#include <xen/cpu.h>
#include <xen/init.h>
+#include <xen/percpu.h>
#include <xen/sched.h>
#include <acpi/cpufreq/cpufreq.h>
/*
* cpufreq userspace governor
*/
-static unsigned int cpu_set_freq[NR_CPUS];
+static unsigned int __read_mostly userspace_cmdline_freq;
+static DEFINE_PER_CPU(unsigned int, cpu_set_freq);
static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
unsigned int event)
@@ -35,21 +38,21 @@ static int cpufreq_governor_userspace(st
switch (event) {
case CPUFREQ_GOV_START:
- if (!cpu_set_freq[cpu])
- cpu_set_freq[cpu] = policy->cur;
+ if (!per_cpu(cpu_set_freq, cpu))
+ per_cpu(cpu_set_freq, cpu) = policy->cur;
break;
case CPUFREQ_GOV_STOP:
- cpu_set_freq[cpu] = 0;
+ per_cpu(cpu_set_freq, cpu) = 0;
break;
case CPUFREQ_GOV_LIMITS:
- if (policy->max < cpu_set_freq[cpu])
+ if (policy->max < per_cpu(cpu_set_freq, cpu))
ret = __cpufreq_driver_target(policy, policy->max,
CPUFREQ_RELATION_H);
- else if (policy->min > cpu_set_freq[cpu])
+ else if (policy->min > per_cpu(cpu_set_freq, cpu))
ret = __cpufreq_driver_target(policy, policy->min,
CPUFREQ_RELATION_L);
else
- ret = __cpufreq_driver_target(policy, cpu_set_freq[cpu],
+ ret = __cpufreq_driver_target(policy, per_cpu(cpu_set_freq, cpu),
CPUFREQ_RELATION_L);
break;
@@ -68,7 +71,7 @@ int write_userspace_scaling_setspeed(uns
if (!cpu_online(cpu) || !(policy = per_cpu(cpufreq_cpu_policy, cpu)))
return -EINVAL;
- cpu_set_freq[cpu] = freq;
+ per_cpu(cpu_set_freq, cpu) = freq;
if (freq < policy->min)
freq = policy->min;
@@ -78,19 +81,35 @@ int write_userspace_scaling_setspeed(uns
return __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L);
}
-static void __init
+static bool_t __init
cpufreq_userspace_handle_option(const char *name, const char *val)
{
if (!strcmp(name, "speed") && val) {
- unsigned int usr_cmdline_freq;
- unsigned int cpu;
+ userspace_cmdline_freq = simple_strtoul(val, NULL, 0);
+ return 1;
+ }
+ return 0;
+}
- usr_cmdline_freq = simple_strtoul(val, NULL, 0);
- for (cpu = 0; cpu < NR_CPUS; cpu++)
- cpu_set_freq[cpu] = usr_cmdline_freq;
+static int cpufreq_userspace_cpu_callback(
+ struct notifier_block *nfb, unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (unsigned long)hcpu;
+
+ switch (action)
+ {
+ case CPU_UP_PREPARE:
+ per_cpu(cpu_set_freq, cpu) = userspace_cmdline_freq;
+ break;
}
+
+ return NOTIFY_DONE;
}
+static struct notifier_block cpufreq_userspace_cpu_nfb = {
+ .notifier_call = cpufreq_userspace_cpu_callback
+};
+
struct cpufreq_governor cpufreq_gov_userspace = {
.name = "userspace",
.governor = cpufreq_governor_userspace,
@@ -99,6 +118,11 @@ struct cpufreq_governor cpufreq_gov_user
static int __init cpufreq_gov_userspace_init(void)
{
+ unsigned int cpu;
+
+ for_each_online_cpu(cpu)
+ per_cpu(cpu_set_freq, cpu) = userspace_cmdline_freq;
+ register_cpu_notifier(&cpufreq_userspace_cpu_nfb);
return cpufreq_register_governor(&cpufreq_gov_userspace);
}
__initcall(cpufreq_gov_userspace_init);
Index: xen-4.1.2-testing/xen/drivers/cpufreq/cpufreq_ondemand.c
===================================================================
--- xen-4.1.2-testing.orig/xen/drivers/cpufreq/cpufreq_ondemand.c
+++ xen-4.1.2-testing/xen/drivers/cpufreq/cpufreq_ondemand.c
@@ -296,7 +296,7 @@ int cpufreq_governor_dbs(struct cpufreq_
return 0;
}
-static void __init cpufreq_dbs_handle_option(const char *name, const char *val)
+static bool_t __init cpufreq_dbs_handle_option(const char *name, const char *val)
{
if ( !strcmp(name, "rate") && val )
{
@@ -334,6 +334,9 @@ static void __init cpufreq_dbs_handle_op
}
dbs_tuners_ins.powersave_bias = tmp;
}
+ else
+ return 0;
+ return 1;
}
struct cpufreq_governor cpufreq_gov_dbs = {
Index: xen-4.1.2-testing/xen/include/acpi/cpufreq/cpufreq.h
===================================================================
--- xen-4.1.2-testing.orig/xen/include/acpi/cpufreq/cpufreq.h
+++ xen-4.1.2-testing/xen/include/acpi/cpufreq/cpufreq.h
@@ -93,7 +93,7 @@ struct cpufreq_governor {
char name[CPUFREQ_NAME_LEN];
int (*governor)(struct cpufreq_policy *policy,
unsigned int event);
- void (*handle_option)(const char *name, const char *value);
+ bool_t (*handle_option)(const char *name, const char *value);
struct list_head governor_list;
};

View File

@ -1,72 +0,0 @@
changeset: 23308:fb5313e64335
user: Olaf Hering <olaf@aepfle.de>
date: Mon May 09 09:58:36 2011 +0100
files: xen/common/trace.c
description:
xentrace: Move the global variable t_info_first_offset into calculate_tbuf_size()
Move the global variable t_info_first_offset into
calculate_tbuf_size() because it is only used there. Change the type
from u32 to uint32_t to match type in other places.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
xen/common/trace.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
Index: xen-4.1.2-testing/xen/common/trace.c
===================================================================
--- xen-4.1.2-testing.orig/xen/common/trace.c
+++ xen-4.1.2-testing/xen/common/trace.c
@@ -55,7 +55,6 @@ static DEFINE_PER_CPU_READ_MOSTLY(struct
static DEFINE_PER_CPU_READ_MOSTLY(unsigned char *, t_data);
static DEFINE_PER_CPU_READ_MOSTLY(spinlock_t, t_lock);
static u32 data_size;
-static u32 t_info_first_offset __read_mostly;
/* High water mark for trace buffers; */
/* Send virtual interrupt when buffer level reaches this point */
@@ -94,10 +93,10 @@ static struct notifier_block cpu_nfb = {
.notifier_call = cpu_callback
};
-static void calc_tinfo_first_offset(void)
+static uint32_t calc_tinfo_first_offset(void)
{
int offset_in_bytes = offsetof(struct t_info, mfn_offset[NR_CPUS]);
- t_info_first_offset = fit_to_type(uint32_t, offset_in_bytes);
+ return fit_to_type(uint32_t, offset_in_bytes);
}
/**
@@ -107,7 +106,7 @@ static void calc_tinfo_first_offset(void
* The t_info layout is fixed and cant be changed without breaking xentrace.
* Initialize t_info_pages based on number of trace pages.
*/
-static int calculate_tbuf_size(unsigned int pages)
+static int calculate_tbuf_size(unsigned int pages, uint32_t t_info_first_offset)
{
struct t_buf dummy_size;
typeof(dummy_size.prod) max_size;
@@ -156,6 +155,7 @@ static int alloc_trace_bufs(unsigned int
int i, cpu, order;
/* Start after a fixed-size array of NR_CPUS */
uint32_t *t_info_mfn_list;
+ uint32_t t_info_first_offset;
int offset;
if ( t_info )
@@ -165,9 +165,9 @@ static int alloc_trace_bufs(unsigned int
return -EINVAL;
/* Calculate offset in u32 of first mfn */
- calc_tinfo_first_offset();
+ t_info_first_offset = calc_tinfo_first_offset();
- pages = calculate_tbuf_size(pages);
+ pages = calculate_tbuf_size(pages, t_info_first_offset);
order = get_order_from_pages(pages);
t_info = alloc_xenheap_pages(get_order_from_pages(t_info_pages), 0);

View File

@ -1,27 +0,0 @@
changeset: 23309:0ddcc8063690
user: Olaf Hering <olaf@aepfle.de>
date: Mon May 09 09:59:13 2011 +0100
files: xen/common/trace.c
description:
xentrace: Mark data_size __read_mostly because it's only written once
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
xen/common/trace.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: xen-4.1.2-testing/xen/common/trace.c
===================================================================
--- xen-4.1.2-testing.orig/xen/common/trace.c
+++ xen-4.1.2-testing/xen/common/trace.c
@@ -54,7 +54,7 @@ static unsigned int t_info_pages;
static DEFINE_PER_CPU_READ_MOSTLY(struct t_buf *, t_bufs);
static DEFINE_PER_CPU_READ_MOSTLY(unsigned char *, t_data);
static DEFINE_PER_CPU_READ_MOSTLY(spinlock_t, t_lock);
-static u32 data_size;
+static u32 data_size __read_mostly;
/* High water mark for trace buffers; */
/* Send virtual interrupt when buffer level reaches this point */

View File

@ -1,46 +0,0 @@
changeset: 23310:b7ca55907bd3
user: Olaf Hering <olaf@aepfle.de>
date: Mon May 09 09:59:50 2011 +0100
files: xen/common/trace.c
description:
xentrace: Remove unneeded cast when assigning pointer value to dst
Remove unneeded cast when assigning pointer value to dst.
Both arrays are uint32_t and memcpy takes a void pointer.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
xen/common/trace.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
Index: xen-4.1.2-testing/xen/common/trace.c
===================================================================
--- xen-4.1.2-testing.orig/xen/common/trace.c
+++ xen-4.1.2-testing/xen/common/trace.c
@@ -483,7 +483,7 @@ static inline void __insert_record(struc
const void *extra_data)
{
struct t_rec *rec;
- unsigned char *dst;
+ uint32_t *dst;
unsigned int extra_word = extra / sizeof(u32);
unsigned int local_rec_size = calc_rec_size(cycles, extra);
uint32_t next;
@@ -508,13 +508,13 @@ static inline void __insert_record(struc
rec->event = event;
rec->extra_u32 = extra_word;
- dst = (unsigned char *)rec->u.nocycles.extra_u32;
+ dst = rec->u.nocycles.extra_u32;
if ( (rec->cycles_included = cycles) != 0 )
{
u64 tsc = (u64)get_cycles();
rec->u.cycles.cycles_lo = (uint32_t)tsc;
rec->u.cycles.cycles_hi = (uint32_t)(tsc >> 32);
- dst = (unsigned char *)rec->u.cycles.extra_u32;
+ dst = rec->u.cycles.extra_u32;
}
if ( extra_data && extra )

View File

@ -1,40 +0,0 @@
References: FATE#309902, FATE#309903
# HG changeset patch
# User Jacob Shin <jacob.shin@amd.com>
# Date 1305188046 -3600
# Node ID 23e33ea79cac0303c729d4e82905054cded16348
# Parent fabdd682420c0c7b5e81f07f2f54211ebc11babe
hvm: vpmu: Enable HVM VPMU for AMD Family 12h and 14h processors
HVM VPMU support can be enabled for AMD Family 12h and 14h processors
by taking the same code path as 10h.
Signed-off-by: Jacob Shin <jacob.shin@amd.com>
Index: xen-4.1.2-testing/xen/arch/x86/hvm/svm/vpmu.c
===================================================================
--- xen-4.1.2-testing.orig/xen/arch/x86/hvm/svm/vpmu.c
+++ xen-4.1.2-testing/xen/arch/x86/hvm/svm/vpmu.c
@@ -317,6 +317,8 @@ static void amd_vpmu_initialise(struct v
k7_counters_mirrored = 1;
break;
case 0x10:
+ case 0x12:
+ case 0x14:
default:
num_counters = F10H_NUM_COUNTERS;
counters = AMD_F10H_COUNTERS;
Index: xen-4.1.2-testing/xen/arch/x86/hvm/vpmu.c
===================================================================
--- xen-4.1.2-testing.orig/xen/arch/x86/hvm/vpmu.c
+++ xen-4.1.2-testing/xen/arch/x86/hvm/vpmu.c
@@ -101,6 +101,8 @@ void vpmu_initialise(struct vcpu *v)
switch ( family )
{
case 0x10:
+ case 0x12:
+ case 0x14:
case 0x15:
vpmu->arch_vpmu_ops = &amd_vpmu_ops;
break;

View File

@ -1,78 +0,0 @@
# HG changeset patch
# User Ian Campbell <ian.campbell@citrix.com>
# Date 1306228450 -3600
# Node ID 23b423a3955785c9a8679c3a877c3472066a2e1f
# Parent ba8da39c67298b19c2c277e5794981b7f23bedf2
libxc: save/restore: remove static context variables
20544:ad9d75d74bd5 and 20545:cc7d66ba0dad seemingly intended to change these
global static variables into stack variables but didn't remove the static
qualifier.
Also zero the entire struct once with memset rather than clearing fields
piecemeal in two different places.
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Ian Jackson <ian.jackson.citrix.com>
Committed-by: Ian Jackson <ian.jackson.citrix.com>
Acked-by: Vincent Hanquez <vincent.hanquez@eu.citrix.com>
Index: xen-4.1.3-testing/tools/libxc/xc_domain_restore.c
===================================================================
--- xen-4.1.3-testing.orig/tools/libxc/xc_domain_restore.c
+++ xen-4.1.3-testing/tools/libxc/xc_domain_restore.c
@@ -1145,23 +1145,19 @@ int xc_domain_restore(xc_interface *xch,
int orig_io_fd_flags;
- static struct restore_ctx _ctx = {
- .live_p2m = NULL,
- .p2m = NULL,
- };
- static struct restore_ctx *ctx = &_ctx;
+ struct restore_ctx _ctx;
+ struct restore_ctx *ctx = &_ctx;
struct domain_info_context *dinfo = &ctx->dinfo;
pagebuf_init(&pagebuf);
memset(&tailbuf, 0, sizeof(tailbuf));
tailbuf.ishvm = hvm;
- /* For info only */
- ctx->nr_pfns = 0;
-
if ( superpages )
return 1;
+ memset(ctx, 0, sizeof(*ctx));
+
ctxt = xc_hypercall_buffer_alloc(xch, ctxt, sizeof(*ctxt));
if ( ctxt == NULL )
Index: xen-4.1.3-testing/tools/libxc/xc_domain_save.c
===================================================================
--- xen-4.1.3-testing.orig/tools/libxc/xc_domain_save.c
+++ xen-4.1.3-testing/tools/libxc/xc_domain_save.c
@@ -958,11 +958,8 @@ int xc_domain_save(xc_interface *xch, in
unsigned long mfn;
struct outbuf ob;
- static struct save_ctx _ctx = {
- .live_p2m = NULL,
- .live_m2p = NULL,
- };
- static struct save_ctx *ctx = &_ctx;
+ struct save_ctx _ctx;
+ struct save_ctx *ctx = &_ctx;
struct domain_info_context *dinfo = &ctx->dinfo;
int completed = 0;
@@ -976,6 +973,8 @@ int xc_domain_save(xc_interface *xch, in
outbuf_init(xch, &ob, OUTBUF_SIZE);
+ memset(ctx, 0, sizeof(*ctx));
+
/* If no explicit control parameters given, use defaults */
max_iters = max_iters ? : DEF_MAX_ITERS;
max_factor = max_factor ? : DEF_MAX_FACTOR;

View File

@ -1,61 +0,0 @@
changeset: 23404:dd0eb070ee44
user: Olaf Hering <olaf@aepfle.de>
date: Thu May 26 12:34:44 2011 +0100
files: xen/common/trace.c
description:
xentrace: reduce trace buffer size to something mfn_offset can reach
The start of the array which holds the list of mfns for each cpus
tracebuffer is stored in an unsigned short. This limits the total
amount of pages for each cpu as the number of active cpus increases.
Update the math in calculate_tbuf_size() to apply also this rule to
the max number of trace pages. Without this change the index can
overflow.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Acked-by: George Dunlap <george.dunlap@eu.citrix.com>
---
xen/common/trace.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
Index: xen-4.1.2-testing/xen/common/trace.c
===================================================================
--- xen-4.1.2-testing.orig/xen/common/trace.c
+++ xen-4.1.2-testing/xen/common/trace.c
@@ -112,11 +112,14 @@ static int calculate_tbuf_size(unsigned
typeof(dummy_size.prod) max_size;
struct t_info dummy_pages;
typeof(dummy_pages.tbuf_size) max_pages;
+ typeof(dummy_pages.mfn_offset[0]) max_mfn_offset;
+ unsigned int max_cpus = num_online_cpus();
unsigned int t_info_words;
/* force maximum value for an unsigned type */
max_size = -1;
max_pages = -1;
+ max_mfn_offset = -1;
/* max size holds up to n pages */
max_size /= PAGE_SIZE;
@@ -124,6 +127,18 @@ static int calculate_tbuf_size(unsigned
if ( max_size < max_pages )
max_pages = max_size;
+ /*
+ * max mfn_offset holds up to n pages per cpu
+ * The array of mfns for the highest cpu can start at the maximum value
+ * mfn_offset can hold. So reduce the number of cpus and also the mfn_offset.
+ */
+ max_mfn_offset -= t_info_first_offset - 1;
+ max_cpus--;
+ if ( max_cpus )
+ max_mfn_offset /= max_cpus;
+ if ( max_mfn_offset < max_pages )
+ max_pages = max_mfn_offset;
+
if ( pages > max_pages )
{
printk(XENLOG_INFO "xentrace: requested number of %u pages "

View File

@ -1,52 +0,0 @@
changeset: 23405:3057b531d905
user: Olaf Hering <olaf@aepfle.de>
date: Thu May 26 12:35:30 2011 +0100
files: xen/common/trace.c
description:
xentrace: fix type of offset to avoid ouf-of-bounds access
Update the type of the local offset variable to match the type where
this variable is stored. Also update the type of t_info_first_offset
because it has also a limited range.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Acked-by: George Dunlap <george.dunlap@eu.citrix.com>
---
xen/common/trace.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
Index: xen-4.1.2-testing/xen/common/trace.c
===================================================================
--- xen-4.1.2-testing.orig/xen/common/trace.c
+++ xen-4.1.2-testing/xen/common/trace.c
@@ -106,7 +106,7 @@ static uint32_t calc_tinfo_first_offset(
* The t_info layout is fixed and cant be changed without breaking xentrace.
* Initialize t_info_pages based on number of trace pages.
*/
-static int calculate_tbuf_size(unsigned int pages, uint32_t t_info_first_offset)
+static int calculate_tbuf_size(unsigned int pages, uint16_t t_info_first_offset)
{
struct t_buf dummy_size;
typeof(dummy_size.prod) max_size;
@@ -170,8 +170,8 @@ static int alloc_trace_bufs(unsigned int
int i, cpu, order;
/* Start after a fixed-size array of NR_CPUS */
uint32_t *t_info_mfn_list;
- uint32_t t_info_first_offset;
- int offset;
+ uint16_t t_info_first_offset;
+ uint16_t offset;
if ( t_info )
return -EBUSY;
@@ -179,7 +179,7 @@ static int alloc_trace_bufs(unsigned int
if ( pages == 0 )
return -EINVAL;
- /* Calculate offset in u32 of first mfn */
+ /* Calculate offset in units of u32 of first mfn */
t_info_first_offset = calc_tinfo_first_offset();
pages = calculate_tbuf_size(pages, t_info_first_offset);

View File

@ -1,153 +0,0 @@
changeset: 23406:956438803307
user: Olaf Hering <olaf@aepfle.de>
date: Thu May 26 12:36:03 2011 +0100
files: xen/common/trace.c
description:
xentrace: update __insert_record() to copy the trace record to individual mfns
Update __insert_record() to copy the trace record to individual mfns.
This is a prereq before changing the per-cpu allocation from
contiguous to non-contiguous allocation.
v2:
update offset calculation to use shift and mask
update type of mfn_offset to match type of data source
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Acked-by: George Dunlap <george.dunlap@eu.citrix.com>
---
xen/common/trace.c | 71 +++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 55 insertions(+), 16 deletions(-)
Index: xen-4.1.2-testing/xen/common/trace.c
===================================================================
--- xen-4.1.2-testing.orig/xen/common/trace.c
+++ xen-4.1.2-testing/xen/common/trace.c
@@ -52,7 +52,6 @@ static struct t_info *t_info;
static unsigned int t_info_pages;
static DEFINE_PER_CPU_READ_MOSTLY(struct t_buf *, t_bufs);
-static DEFINE_PER_CPU_READ_MOSTLY(unsigned char *, t_data);
static DEFINE_PER_CPU_READ_MOSTLY(spinlock_t, t_lock);
static u32 data_size __read_mostly;
@@ -208,7 +207,6 @@ static int alloc_trace_bufs(unsigned int
per_cpu(t_bufs, cpu) = buf = rawbuf;
buf->cons = buf->prod = 0;
- per_cpu(t_data, cpu) = (unsigned char *)(buf + 1);
}
offset = t_info_first_offset;
@@ -472,10 +470,16 @@ static inline u32 calc_bytes_avail(const
return data_size - calc_unconsumed_bytes(buf);
}
-static inline struct t_rec *next_record(const struct t_buf *buf,
- uint32_t *next)
+static unsigned char *next_record(const struct t_buf *buf, uint32_t *next,
+ unsigned char **next_page,
+ uint32_t *offset_in_page)
{
u32 x = buf->prod, cons = buf->cons;
+ uint16_t per_cpu_mfn_offset;
+ uint32_t per_cpu_mfn_nr;
+ uint32_t *mfn_list;
+ uint32_t mfn;
+ unsigned char *this_page;
barrier(); /* must read buf->prod and buf->cons only once */
*next = x;
@@ -487,7 +491,27 @@ static inline struct t_rec *next_record(
ASSERT(x < data_size);
- return (struct t_rec *)&this_cpu(t_data)[x];
+ /* add leading header to get total offset of next record */
+ x += sizeof(struct t_buf);
+ *offset_in_page = x & ~PAGE_MASK;
+
+ /* offset into array of mfns */
+ per_cpu_mfn_nr = x >> PAGE_SHIFT;
+ per_cpu_mfn_offset = t_info->mfn_offset[smp_processor_id()];
+ mfn_list = (uint32_t *)t_info;
+ mfn = mfn_list[per_cpu_mfn_offset + per_cpu_mfn_nr];
+ this_page = mfn_to_virt(mfn);
+ if (per_cpu_mfn_nr + 1 >= opt_tbuf_size)
+ {
+ /* reached end of buffer? */
+ *next_page = NULL;
+ }
+ else
+ {
+ mfn = mfn_list[per_cpu_mfn_offset + per_cpu_mfn_nr + 1];
+ *next_page = mfn_to_virt(mfn);
+ }
+ return this_page;
}
static inline void __insert_record(struct t_buf *buf,
@@ -497,28 +521,37 @@ static inline void __insert_record(struc
unsigned int rec_size,
const void *extra_data)
{
- struct t_rec *rec;
+ struct t_rec split_rec, *rec;
uint32_t *dst;
+ unsigned char *this_page, *next_page;
unsigned int extra_word = extra / sizeof(u32);
unsigned int local_rec_size = calc_rec_size(cycles, extra);
uint32_t next;
+ uint32_t offset;
+ uint32_t remaining;
BUG_ON(local_rec_size != rec_size);
BUG_ON(extra & 3);
- rec = next_record(buf, &next);
- if ( !rec )
+ this_page = next_record(buf, &next, &next_page, &offset);
+ if ( !this_page )
return;
- /* Double-check once more that we have enough space.
- * Don't bugcheck here, in case the userland tool is doing
- * something stupid. */
- if ( (unsigned char *)rec + rec_size > this_cpu(t_data) + data_size )
+
+ remaining = PAGE_SIZE - offset;
+
+ if ( unlikely(rec_size > remaining) )
{
- if ( printk_ratelimit() )
+ if ( next_page == NULL )
+ {
+ /* access beyond end of buffer */
printk(XENLOG_WARNING
- "%s: size=%08x prod=%08x cons=%08x rec=%u\n",
- __func__, data_size, next, buf->cons, rec_size);
- return;
+ "%s: size=%08x prod=%08x cons=%08x rec=%u remaining=%u\n",
+ __func__, data_size, next, buf->cons, rec_size, remaining);
+ return;
+ }
+ rec = &split_rec;
+ } else {
+ rec = (struct t_rec*)(this_page + offset);
}
rec->event = event;
@@ -535,6 +568,12 @@ static inline void __insert_record(struc
if ( extra_data && extra )
memcpy(dst, extra_data, extra);
+ if ( unlikely(rec_size > remaining) )
+ {
+ memcpy(this_page + offset, rec, remaining);
+ memcpy(next_page, (char *)rec + remaining, rec_size - remaining);
+ }
+
wmb();
next += rec_size;

View File

@ -1,155 +0,0 @@
changeset: 23407:b19898ac3e32
user: Olaf Hering <olaf@aepfle.de>
date: Thu May 26 12:36:27 2011 +0100
files: xen/common/trace.c
description:
xentrace: allocate non-contiguous per-cpu trace buffers
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Acked-by: George Dunlap <george.dunlap@eu.citrix.com>
---
xen/common/trace.c | 92 ++++++++++++++++++++++++++++-------------------------
1 file changed, 50 insertions(+), 42 deletions(-)
Index: xen-4.1.2-testing/xen/common/trace.c
===================================================================
--- xen-4.1.2-testing.orig/xen/common/trace.c
+++ xen-4.1.2-testing/xen/common/trace.c
@@ -166,7 +166,7 @@ static int calculate_tbuf_size(unsigned
*/
static int alloc_trace_bufs(unsigned int pages)
{
- int i, cpu, order;
+ int i, cpu;
/* Start after a fixed-size array of NR_CPUS */
uint32_t *t_info_mfn_list;
uint16_t t_info_first_offset;
@@ -182,34 +182,11 @@ static int alloc_trace_bufs(unsigned int
t_info_first_offset = calc_tinfo_first_offset();
pages = calculate_tbuf_size(pages, t_info_first_offset);
- order = get_order_from_pages(pages);
t_info = alloc_xenheap_pages(get_order_from_pages(t_info_pages), 0);
if ( t_info == NULL )
- goto out_dealloc;
+ goto out_dealloc_t_info;
- /*
- * First, allocate buffers for all of the cpus. If any
- * fails, deallocate what you have so far and exit.
- */
- for_each_online_cpu(cpu)
- {
- void *rawbuf;
- struct t_buf *buf;
-
- if ( (rawbuf = alloc_xenheap_pages(
- order, MEMF_bits(32 + PAGE_SHIFT))) == NULL )
- {
- printk(XENLOG_INFO "xentrace: memory allocation failed "
- "on cpu %d\n", cpu);
- goto out_dealloc;
- }
-
- per_cpu(t_bufs, cpu) = buf = rawbuf;
- buf->cons = buf->prod = 0;
- }
-
- offset = t_info_first_offset;
t_info_mfn_list = (uint32_t *)t_info;
for(i = 0; i < t_info_pages; i++)
@@ -219,27 +196,53 @@ static int alloc_trace_bufs(unsigned int
t_info->tbuf_size = pages;
/*
- * Now share the pages so xentrace can map them, and write them in
- * the global t_info structure.
+ * Allocate buffers for all of the cpus.
+ * If any fails, deallocate what you have so far and exit.
*/
for_each_online_cpu(cpu)
{
- void *rawbuf = per_cpu(t_bufs, cpu);
- struct page_info *p = virt_to_page(rawbuf);
- uint32_t mfn = virt_to_mfn(rawbuf);
+ offset = t_info_first_offset + (cpu * pages);
+ t_info->mfn_offset[cpu] = offset;
for ( i = 0; i < pages; i++ )
{
- share_xen_page_with_privileged_guests(p + i, XENSHARE_writable);
-
- t_info_mfn_list[offset + i]=mfn + i;
+ void *p = alloc_xenheap_pages(0, MEMF_bits(32 + PAGE_SHIFT));
+ if ( !p )
+ {
+ printk(XENLOG_INFO "xentrace: memory allocation failed "
+ "on cpu %d after %d pages\n", cpu, i);
+ t_info_mfn_list[offset + i] = 0;
+ goto out_dealloc;
+ }
+ t_info_mfn_list[offset + i] = virt_to_mfn(p);
}
- t_info->mfn_offset[cpu]=offset;
- printk(XENLOG_INFO "xentrace: p%d mfn %"PRIx32" offset %d\n",
- cpu, mfn, offset);
- offset+=i;
+ }
+
+ /*
+ * Initialize buffers for all of the cpus.
+ */
+ for_each_online_cpu(cpu)
+ {
+ struct t_buf *buf;
+ struct page_info *pg;
spin_lock_init(&per_cpu(t_lock, cpu));
+
+ offset = t_info->mfn_offset[cpu];
+
+ /* Initialize the buffer metadata */
+ per_cpu(t_bufs, cpu) = buf = mfn_to_virt(t_info_mfn_list[offset]);
+ buf->cons = buf->prod = 0;
+
+ printk(XENLOG_INFO "xentrace: p%d mfn %x offset %u\n",
+ cpu, t_info_mfn_list[offset], offset);
+
+ /* Now share the trace pages */
+ for ( i = 0; i < pages; i++ )
+ {
+ pg = mfn_to_page(t_info_mfn_list[offset + i]);
+ share_xen_page_with_privileged_guests(pg, XENSHARE_writable);
+ }
}
data_size = (pages * PAGE_SIZE - sizeof(struct t_buf));
@@ -255,14 +258,19 @@ static int alloc_trace_bufs(unsigned int
out_dealloc:
for_each_online_cpu(cpu)
{
- void *rawbuf = per_cpu(t_bufs, cpu);
- per_cpu(t_bufs, cpu) = NULL;
- if ( rawbuf )
+ offset = t_info->mfn_offset[cpu];
+ if ( !offset )
+ continue;
+ for ( i = 0; i < pages; i++ )
{
- ASSERT(!(virt_to_page(rawbuf)->count_info & PGC_allocated));
- free_xenheap_pages(rawbuf, order);
+ uint32_t mfn = t_info_mfn_list[offset + i];
+ if ( !mfn )
+ break;
+ ASSERT(!(mfn_to_page(mfn)->count_info & PGC_allocated));
+ free_xenheap_pages(mfn_to_virt(mfn), 0);
}
}
+out_dealloc_t_info:
free_xenheap_pages(t_info, get_order_from_pages(t_info_pages));
t_info = NULL;
printk(XENLOG_WARNING "xentrace: allocation failed! Tracing disabled.\n");

View File

@ -1,288 +0,0 @@
References: FATE#311951
# HG changeset patch
# User Keir Fraser <keir@xen.org>
# Date 1307023264 -3600
# Node ID 4804af7048cafecfc014c30cfea374eb0a0360e8
# Parent 5839e797a1307fceffcd0b9ad35ed31644378b47
libxc: Simplify and clean up xc_cpufeature.h
* Remove Linux-private defns with no direct relation to CPUID
* Remove word offsets into Linux-defined cpu_caps array
* Hard tabs -> soft tabs
Signed-off-by: Keir Fraser <keir@xen.org>
# HG changeset patch
# User Keir Fraser <keir@xen.org>
# Date 1307118421 -3600
# Node ID bcd2476c2e2d00dc6371e52fbff66fe3178b7944
# Parent 55c5eff9bf84d4c5f3463c01f038edc1c46f30bc
libxc: Don't refer to meaningless 'word offsets' in xc_cpufeature.h
Signed-off-by: Keir Fraser <keir@xen.org>
Index: xen-4.1.2-testing/tools/libxc/xc_cpufeature.h
===================================================================
--- xen-4.1.2-testing.orig/tools/libxc/xc_cpufeature.h
+++ xen-4.1.2-testing/tools/libxc/xc_cpufeature.h
@@ -17,134 +17,115 @@
#ifndef __LIBXC_CPUFEATURE_H
#define __LIBXC_CPUFEATURE_H
-/* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */
-#define X86_FEATURE_FPU (0*32+ 0) /* Onboard FPU */
-#define X86_FEATURE_VME (0*32+ 1) /* Virtual Mode Extensions */
-#define X86_FEATURE_DE (0*32+ 2) /* Debugging Extensions */
-#define X86_FEATURE_PSE (0*32+ 3) /* Page Size Extensions */
-#define X86_FEATURE_TSC (0*32+ 4) /* Time Stamp Counter */
-#define X86_FEATURE_MSR (0*32+ 5) /* Model-Specific Registers, RDMSR, WRMSR */
-#define X86_FEATURE_PAE (0*32+ 6) /* Physical Address Extensions */
-#define X86_FEATURE_MCE (0*32+ 7) /* Machine Check Architecture */
-#define X86_FEATURE_CX8 (0*32+ 8) /* CMPXCHG8 instruction */
-#define X86_FEATURE_APIC (0*32+ 9) /* Onboard APIC */
-#define X86_FEATURE_SEP (0*32+11) /* SYSENTER/SYSEXIT */
-#define X86_FEATURE_MTRR (0*32+12) /* Memory Type Range Registers */
-#define X86_FEATURE_PGE (0*32+13) /* Page Global Enable */
-#define X86_FEATURE_MCA (0*32+14) /* Machine Check Architecture */
-#define X86_FEATURE_CMOV (0*32+15) /* CMOV instruction (FCMOVCC and FCOMI too if FPU present) */
-#define X86_FEATURE_PAT (0*32+16) /* Page Attribute Table */
-#define X86_FEATURE_PSE36 (0*32+17) /* 36-bit PSEs */
-#define X86_FEATURE_PN (0*32+18) /* Processor serial number */
-#define X86_FEATURE_CLFLSH (0*32+19) /* Supports the CLFLUSH instruction */
-#define X86_FEATURE_DS (0*32+21) /* Debug Store */
-#define X86_FEATURE_ACPI (0*32+22) /* ACPI via MSR */
-#define X86_FEATURE_MMX (0*32+23) /* Multimedia Extensions */
-#define X86_FEATURE_FXSR (0*32+24) /* FXSAVE and FXRSTOR instructions (fast save and restore */
- /* of FPU context), and CR4.OSFXSR available */
-#define X86_FEATURE_XMM (0*32+25) /* Streaming SIMD Extensions */
-#define X86_FEATURE_XMM2 (0*32+26) /* Streaming SIMD Extensions-2 */
-#define X86_FEATURE_SELFSNOOP (0*32+27) /* CPU self snoop */
-#define X86_FEATURE_HT (0*32+28) /* Hyper-Threading */
-#define X86_FEATURE_ACC (0*32+29) /* Automatic clock control */
-#define X86_FEATURE_IA64 (0*32+30) /* IA-64 processor */
-#define X86_FEATURE_PBE (0*32+31) /* Pending Break Enable */
+/* Intel-defined CPU features, CPUID level 0x00000001 (edx) */
+#define X86_FEATURE_FPU 0 /* Onboard FPU */
+#define X86_FEATURE_VME 1 /* Virtual Mode Extensions */
+#define X86_FEATURE_DE 2 /* Debugging Extensions */
+#define X86_FEATURE_PSE 3 /* Page Size Extensions */
+#define X86_FEATURE_TSC 4 /* Time Stamp Counter */
+#define X86_FEATURE_MSR 5 /* Model-Specific Registers, RDMSR, WRMSR */
+#define X86_FEATURE_PAE 6 /* Physical Address Extensions */
+#define X86_FEATURE_MCE 7 /* Machine Check Architecture */
+#define X86_FEATURE_CX8 8 /* CMPXCHG8 instruction */
+#define X86_FEATURE_APIC 9 /* Onboard APIC */
+#define X86_FEATURE_SEP 11 /* SYSENTER/SYSEXIT */
+#define X86_FEATURE_MTRR 12 /* Memory Type Range Registers */
+#define X86_FEATURE_PGE 13 /* Page Global Enable */
+#define X86_FEATURE_MCA 14 /* Machine Check Architecture */
+#define X86_FEATURE_CMOV 15 /* CMOV instruction */
+#define X86_FEATURE_PAT 16 /* Page Attribute Table */
+#define X86_FEATURE_PSE36 17 /* 36-bit PSEs */
+#define X86_FEATURE_PN 18 /* Processor serial number */
+#define X86_FEATURE_CLFLSH 19 /* Supports the CLFLUSH instruction */
+#define X86_FEATURE_DS 21 /* Debug Store */
+#define X86_FEATURE_ACPI 22 /* ACPI via MSR */
+#define X86_FEATURE_MMX 23 /* Multimedia Extensions */
+#define X86_FEATURE_FXSR 24 /* FXSAVE and FXRSTOR instructions */
+#define X86_FEATURE_XMM 25 /* Streaming SIMD Extensions */
+#define X86_FEATURE_XMM2 26 /* Streaming SIMD Extensions-2 */
+#define X86_FEATURE_SELFSNOOP 27 /* CPU self snoop */
+#define X86_FEATURE_HT 28 /* Hyper-Threading */
+#define X86_FEATURE_ACC 29 /* Automatic clock control */
+#define X86_FEATURE_IA64 30 /* IA-64 processor */
+#define X86_FEATURE_PBE 31 /* Pending Break Enable */
-/* AMD-defined CPU features, CPUID level 0x80000001, word 1 */
+/* AMD-defined CPU features, CPUID level 0x80000001 */
/* Don't duplicate feature flags which are redundant with Intel! */
-#define X86_FEATURE_SYSCALL (1*32+11) /* SYSCALL/SYSRET */
-#define X86_FEATURE_MP (1*32+19) /* MP Capable. */
-#define X86_FEATURE_NX (1*32+20) /* Execute Disable */
-#define X86_FEATURE_MMXEXT (1*32+22) /* AMD MMX extensions */
-#define X86_FEATURE_FFXSR (1*32+25) /* FFXSR instruction optimizations */
-#define X86_FEATURE_PAGE1GB (1*32+26) /* 1Gb large page support */
-#define X86_FEATURE_RDTSCP (1*32+27) /* RDTSCP */
-#define X86_FEATURE_LM (1*32+29) /* Long Mode (x86-64) */
-#define X86_FEATURE_3DNOWEXT (1*32+30) /* AMD 3DNow! extensions */
-#define X86_FEATURE_3DNOW (1*32+31) /* 3DNow! */
-
-/* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */
-#define X86_FEATURE_RECOVERY (2*32+ 0) /* CPU in recovery mode */
-#define X86_FEATURE_LONGRUN (2*32+ 1) /* Longrun power control */
-#define X86_FEATURE_LRTI (2*32+ 3) /* LongRun table interface */
-
-/* Other features, Linux-defined mapping, word 3 */
-/* This range is used for feature bits which conflict or are synthesized */
-#define X86_FEATURE_CXMMX (3*32+ 0) /* Cyrix MMX extensions */
-#define X86_FEATURE_K6_MTRR (3*32+ 1) /* AMD K6 nonstandard MTRRs */
-#define X86_FEATURE_CYRIX_ARR (3*32+ 2) /* Cyrix ARRs (= MTRRs) */
-#define X86_FEATURE_CENTAUR_MCR (3*32+ 3) /* Centaur MCRs (= MTRRs) */
-/* cpu types for specific tunings: */
-#define X86_FEATURE_K8 (3*32+ 4) /* Opteron, Athlon64 */
-#define X86_FEATURE_K7 (3*32+ 5) /* Athlon */
-#define X86_FEATURE_P3 (3*32+ 6) /* P3 */
-#define X86_FEATURE_P4 (3*32+ 7) /* P4 */
-#define X86_FEATURE_CONSTANT_TSC (3*32+ 8) /* TSC ticks at a constant rate */
-
-/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
-#define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */
-#define X86_FEATURE_PCLMULQDQ (4*32+ 1) /* Carry-less multiplication */
-#define X86_FEATURE_DTES64 (4*32+ 2) /* 64-bit Debug Store */
-#define X86_FEATURE_MWAIT (4*32+ 3) /* Monitor/Mwait support */
-#define X86_FEATURE_DSCPL (4*32+ 4) /* CPL Qualified Debug Store */
-#define X86_FEATURE_VMXE (4*32+ 5) /* Virtual Machine Extensions */
-#define X86_FEATURE_SMXE (4*32+ 6) /* Safer Mode Extensions */
-#define X86_FEATURE_EST (4*32+ 7) /* Enhanced SpeedStep */
-#define X86_FEATURE_TM2 (4*32+ 8) /* Thermal Monitor 2 */
-#define X86_FEATURE_SSSE3 (4*32+ 9) /* Supplemental Streaming SIMD Extensions-3 */
-#define X86_FEATURE_CID (4*32+10) /* Context ID */
-#define X86_FEATURE_CX16 (4*32+13) /* CMPXCHG16B */
-#define X86_FEATURE_XTPR (4*32+14) /* Send Task Priority Messages */
-#define X86_FEATURE_PDCM (4*32+15) /* Perf/Debug Capability MSR */
-#define X86_FEATURE_DCA (4*32+18) /* Direct Cache Access */
-#define X86_FEATURE_SSE4_1 (4*32+19) /* Streaming SIMD Extensions 4.1 */
-#define X86_FEATURE_SSE4_2 (4*32+20) /* Streaming SIMD Extensions 4.2 */
-#define X86_FEATURE_X2APIC (4*32+21) /* x2APIC */
-#define X86_FEATURE_POPCNT (4*32+23) /* POPCNT instruction */
-#define X86_FEATURE_TSC_DEADLINE (4*32+24) /* "tdt" TSC Deadline Timer */
-#define X86_FEATURE_AES (4*32+25) /* AES acceleration instructions */
-#define X86_FEATURE_XSAVE (4*32+26) /* XSAVE/XRSTOR/XSETBV/XGETBV */
-#define X86_FEATURE_AVX (4*32+28) /* Advanced Vector Extensions */
-#define X86_FEATURE_F16C (4*32+29) /* Half-precision convert instruction */
-#define X86_FEATURE_RDRAND (4*32+30) /* Digital Random Number Generator */
-#define X86_FEATURE_HYPERVISOR (4*32+31) /* Running under some hypervisor */
-
-/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
-#define X86_FEATURE_XSTORE (5*32+ 2) /* on-CPU RNG present (xstore insn) */
-#define X86_FEATURE_XSTORE_EN (5*32+ 3) /* on-CPU RNG enabled */
-#define X86_FEATURE_XCRYPT (5*32+ 6) /* on-CPU crypto (xcrypt insn) */
-#define X86_FEATURE_XCRYPT_EN (5*32+ 7) /* on-CPU crypto enabled */
-#define X86_FEATURE_ACE2 (5*32+ 8) /* Advanced Cryptography Engine v2 */
-#define X86_FEATURE_ACE2_EN (5*32+ 9) /* ACE v2 enabled */
-#define X86_FEATURE_PHE (5*32+ 10) /* PadLock Hash Engine */
-#define X86_FEATURE_PHE_EN (5*32+ 11) /* PHE enabled */
-#define X86_FEATURE_PMM (5*32+ 12) /* PadLock Montgomery Multiplier */
-#define X86_FEATURE_PMM_EN (5*32+ 13) /* PMM enabled */
-
-/* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */
-#define X86_FEATURE_LAHF_LM (6*32+ 0) /* LAHF/SAHF in long mode */
-#define X86_FEATURE_CMP_LEGACY (6*32+ 1) /* If yes HyperThreading not valid */
-#define X86_FEATURE_SVM (6*32+ 2) /* Secure virtual machine */
-#define X86_FEATURE_EXTAPIC (6*32+ 3) /* Extended APIC space */
-#define X86_FEATURE_CR8_LEGACY (6*32+ 4) /* CR8 in 32-bit mode */
-#define X86_FEATURE_ABM (6*32+ 5) /* Advanced bit manipulation */
-#define X86_FEATURE_SSE4A (6*32+ 6) /* SSE-4A */
-#define X86_FEATURE_MISALIGNSSE (6*32+ 7) /* Misaligned SSE mode */
-#define X86_FEATURE_3DNOWPREFETCH (6*32+ 8) /* 3DNow prefetch instructions */
-#define X86_FEATURE_OSVW (6*32+ 9) /* OS Visible Workaround */
-#define X86_FEATURE_IBS (6*32+10) /* Instruction Based Sampling */
-#define X86_FEATURE_XOP (6*32+11) /* extended AVX instructions */
-#define X86_FEATURE_SKINIT (6*32+12) /* SKINIT/STGI instructions */
-#define X86_FEATURE_WDT (6*32+13) /* Watchdog timer */
-#define X86_FEATURE_LWP (6*32+15) /* Light Weight Profiling */
-#define X86_FEATURE_FMA4 (6*32+16) /* 4 operands MAC instructions */
-#define X86_FEATURE_NODEID_MSR (6*32+19) /* NodeId MSR */
-#define X86_FEATURE_TBM (6*32+21) /* trailing bit manipulations */
-#define X86_FEATURE_TOPOEXT (6*32+22) /* topology extensions CPUID leafs */
-
-/* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */
-#define X86_FEATURE_FSGSBASE (7*32+ 0) /* {RD,WR}{FS,GS}BASE instructions */
-#define X86_FEATURE_SMEP (7*32+ 7) /* Supervisor Mode Execution Protection */
-#define X86_FEATURE_ERMS (7*32+ 9) /* Enhanced REP MOVSB/STOSB */
+#define X86_FEATURE_SYSCALL 11 /* SYSCALL/SYSRET */
+#define X86_FEATURE_MP 19 /* MP Capable. */
+#define X86_FEATURE_NX 20 /* Execute Disable */
+#define X86_FEATURE_MMXEXT 22 /* AMD MMX extensions */
+#define X86_FEATURE_FFXSR 25 /* FFXSR instruction optimizations */
+#define X86_FEATURE_PAGE1GB 26 /* 1Gb large page support */
+#define X86_FEATURE_RDTSCP 27 /* RDTSCP */
+#define X86_FEATURE_LM 29 /* Long Mode (x86-64) */
+#define X86_FEATURE_3DNOWEXT 30 /* AMD 3DNow! extensions */
+#define X86_FEATURE_3DNOW 31 /* 3DNow! */
+
+/* Intel-defined CPU features, CPUID level 0x00000001 (ecx) */
+#define X86_FEATURE_XMM3 0 /* Streaming SIMD Extensions-3 */
+#define X86_FEATURE_PCLMULQDQ 1 /* Carry-less multiplication */
+#define X86_FEATURE_DTES64 2 /* 64-bit Debug Store */
+#define X86_FEATURE_MWAIT 3 /* Monitor/Mwait support */
+#define X86_FEATURE_DSCPL 4 /* CPL Qualified Debug Store */
+#define X86_FEATURE_VMXE 5 /* Virtual Machine Extensions */
+#define X86_FEATURE_SMXE 6 /* Safer Mode Extensions */
+#define X86_FEATURE_EST 7 /* Enhanced SpeedStep */
+#define X86_FEATURE_TM2 8 /* Thermal Monitor 2 */
+#define X86_FEATURE_SSSE3 9 /* Supplemental Streaming SIMD Exts-3 */
+#define X86_FEATURE_CID 10 /* Context ID */
+#define X86_FEATURE_CX16 13 /* CMPXCHG16B */
+#define X86_FEATURE_XTPR 14 /* Send Task Priority Messages */
+#define X86_FEATURE_PDCM 15 /* Perf/Debug Capability MSR */
+#define X86_FEATURE_DCA 18 /* Direct Cache Access */
+#define X86_FEATURE_SSE4_1 19 /* Streaming SIMD Extensions 4.1 */
+#define X86_FEATURE_SSE4_2 20 /* Streaming SIMD Extensions 4.2 */
+#define X86_FEATURE_X2APIC 21 /* x2APIC */
+#define X86_FEATURE_POPCNT 23 /* POPCNT instruction */
+#define X86_FEATURE_TSC_DEADLINE 24 /* "tdt" TSC Deadline Timer */
+#define X86_FEATURE_AES 25 /* AES acceleration instructions */
+#define X86_FEATURE_XSAVE 26 /* XSAVE/XRSTOR/XSETBV/XGETBV */
+#define X86_FEATURE_AVX 28 /* Advanced Vector Extensions */
+#define X86_FEATURE_F16C 29 /* Half-precision convert instruction */
+#define X86_FEATURE_RDRAND 30 /* Digital Random Number Generator */
+#define X86_FEATURE_HYPERVISOR 31 /* Running under some hypervisor */
+
+/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001 */
+#define X86_FEATURE_XSTORE 2 /* on-CPU RNG present (xstore insn) */
+#define X86_FEATURE_XSTORE_EN 3 /* on-CPU RNG enabled */
+#define X86_FEATURE_XCRYPT 6 /* on-CPU crypto (xcrypt insn) */
+#define X86_FEATURE_XCRYPT_EN 7 /* on-CPU crypto enabled */
+#define X86_FEATURE_ACE2 8 /* Advanced Cryptography Engine v2 */
+#define X86_FEATURE_ACE2_EN 9 /* ACE v2 enabled */
+#define X86_FEATURE_PHE 10 /* PadLock Hash Engine */
+#define X86_FEATURE_PHE_EN 11 /* PHE enabled */
+#define X86_FEATURE_PMM 12 /* PadLock Montgomery Multiplier */
+#define X86_FEATURE_PMM_EN 13 /* PMM enabled */
+
+/* More extended AMD flags: CPUID level 0x80000001, ecx */
+#define X86_FEATURE_LAHF_LM 0 /* LAHF/SAHF in long mode */
+#define X86_FEATURE_CMP_LEGACY 1 /* If yes HyperThreading not valid */
+#define X86_FEATURE_SVM 2 /* Secure virtual machine */
+#define X86_FEATURE_EXTAPIC 3 /* Extended APIC space */
+#define X86_FEATURE_CR8_LEGACY 4 /* CR8 in 32-bit mode */
+#define X86_FEATURE_ABM 5 /* Advanced bit manipulation */
+#define X86_FEATURE_SSE4A 6 /* SSE-4A */
+#define X86_FEATURE_MISALIGNSSE 7 /* Misaligned SSE mode */
+#define X86_FEATURE_3DNOWPREFETCH 8 /* 3DNow prefetch instructions */
+#define X86_FEATURE_OSVW 9 /* OS Visible Workaround */
+#define X86_FEATURE_IBS 10 /* Instruction Based Sampling */
+#define X86_FEATURE_XOP 11 /* extended AVX instructions */
+#define X86_FEATURE_SKINIT 12 /* SKINIT/STGI instructions */
+#define X86_FEATURE_WDT 13 /* Watchdog timer */
+#define X86_FEATURE_LWP 15 /* Light Weight Profiling */
+#define X86_FEATURE_FMA4 16 /* 4 operands MAC instructions */
+#define X86_FEATURE_NODEID_MSR 19 /* NodeId MSR */
+#define X86_FEATURE_TBM 21 /* trailing bit manipulations */
+#define X86_FEATURE_TOPOEXT 22 /* topology extensions CPUID leafs */
+
+/* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx) */
+#define X86_FEATURE_FSGSBASE 0 /* {RD,WR}{FS,GS}BASE instructions */
+#define X86_FEATURE_SMEP 7 /* Supervisor Mode Execution Protection */
+#define X86_FEATURE_ERMS 9 /* Enhanced REP MOVSB/STOSB */
#endif /* __LIBXC_CPUFEATURE_H */
Index: xen-4.1.2-testing/tools/libxc/xc_cpuid_x86.c
===================================================================
--- xen-4.1.2-testing.orig/tools/libxc/xc_cpuid_x86.c
+++ xen-4.1.2-testing/tools/libxc/xc_cpuid_x86.c
@@ -25,9 +25,9 @@
#include "xc_cpufeature.h"
#include <xen/hvm/params.h>
-#define bitmaskof(idx) (1u << ((idx) & 31))
-#define clear_bit(idx, dst) ((dst) &= ~(1u << ((idx) & 31)))
-#define set_bit(idx, dst) ((dst) |= (1u << ((idx) & 31)))
+#define bitmaskof(idx) (1u << (idx))
+#define clear_bit(idx, dst) ((dst) &= ~(1u << (idx)))
+#define set_bit(idx, dst) ((dst) |= (1u << (idx)))
#define DEF_MAX_BASE 0x0000000du
#define DEF_MAX_EXT 0x80000008u

View File

@ -1,80 +0,0 @@
changeset: 23506:d1309a79bde8
user: Keir Fraser <keir@xen.org>
date: Fri Jun 10 08:18:33 2011 +0100
files: xen/arch/x86/x86_64/mm.c xen/include/asm-x86/mm.h
description:
x86: Disable set_gpfn_from_mfn until m2p table is allocated.
This is a prerequisite for calling set_gpfn_from_mfn() unconditionally
from free_heap_pages().
Signed-off-by: Keir Fraser <keir@xen.org>
---
xen/arch/x86/x86_64/mm.c | 4 ++++
xen/include/asm-x86/mm.h | 15 +++++++++++++--
2 files changed, 17 insertions(+), 2 deletions(-)
Index: xen-4.1.2-testing/xen/arch/x86/x86_64/mm.c
===================================================================
--- xen-4.1.2-testing.orig/xen/arch/x86/x86_64/mm.c
+++ xen-4.1.2-testing/xen/arch/x86/x86_64/mm.c
@@ -47,6 +47,8 @@ unsigned int __read_mostly pfn_pdx_hole_
unsigned int __read_mostly m2p_compat_vstart = __HYPERVISOR_COMPAT_VIRT_START;
+bool_t __read_mostly machine_to_phys_mapping_valid = 0;
+
/* Top-level master (and idle-domain) page directory. */
l4_pgentry_t __attribute__ ((__section__ (".bss.page_aligned")))
idle_pg_table[L4_PAGETABLE_ENTRIES];
@@ -800,6 +802,8 @@ void __init paging_init(void)
#undef CNT
#undef MFN
+ machine_to_phys_mapping_valid = 1;
+
/* Set up linear page table mapping. */
l4e_write(&idle_pg_table[l4_table_offset(LINEAR_PT_VIRT_START)],
l4e_from_paddr(__pa(idle_pg_table), __PAGE_HYPERVISOR));
Index: xen-4.1.2-testing/xen/include/asm-x86/mm.h
===================================================================
--- xen-4.1.2-testing.orig/xen/include/asm-x86/mm.h
+++ xen-4.1.2-testing/xen/include/asm-x86/mm.h
@@ -469,7 +469,7 @@ TYPE_SAFE(unsigned long,mfn);
#ifdef CONFIG_COMPAT
#define compat_machine_to_phys_mapping ((unsigned int *)RDWR_COMPAT_MPT_VIRT_START)
-#define set_gpfn_from_mfn(mfn, pfn) ({ \
+#define _set_gpfn_from_mfn(mfn, pfn) ({ \
struct domain *d = page_get_owner(__mfn_to_page(mfn)); \
unsigned long entry = (d && (d == dom_cow)) ? \
SHARED_M2P_ENTRY : (pfn); \
@@ -478,7 +478,7 @@ TYPE_SAFE(unsigned long,mfn);
machine_to_phys_mapping[(mfn)] = (entry)); \
})
#else
-#define set_gpfn_from_mfn(mfn, pfn) ({ \
+#define _set_gpfn_from_mfn(mfn, pfn) ({ \
struct domain *d = page_get_owner(__mfn_to_page(mfn)); \
if(d && (d == dom_cow)) \
machine_to_phys_mapping[(mfn)] = SHARED_M2P_ENTRY; \
@@ -486,6 +486,17 @@ TYPE_SAFE(unsigned long,mfn);
machine_to_phys_mapping[(mfn)] = (pfn); \
})
#endif
+
+/*
+ * Disable some users of set_gpfn_from_mfn() (e.g., free_heap_pages()) until
+ * the machine_to_phys_mapping is actually set up.
+ */
+extern bool_t machine_to_phys_mapping_valid;
+#define set_gpfn_from_mfn(mfn, pfn) do { \
+ if ( machine_to_phys_mapping_valid ) \
+ _set_gpfn_from_mfn(mfn, pfn); \
+} while (0)
+
#define get_gpfn_from_mfn(mfn) (machine_to_phys_mapping[(mfn)])
#define mfn_to_gmfn(_d, mfn) \

View File

@ -1,62 +0,0 @@
changeset: 23507:0a29c8c3ddf7
user: Keir Fraser <keir@xen.org>
date: Fri Jun 10 08:19:07 2011 +0100
files: xen/common/page_alloc.c
description:
xenpaging: update machine_to_phys_mapping[] during page deallocation
The machine_to_phys_mapping[] array needs updating during page
deallocation. If that page is allocated again, a call to
get_gpfn_from_mfn() will still return an old gfn from another guest.
This will cause trouble because this gfn number has no or different
meaning in the context of the current guest.
This happens when the entire guest ram is paged-out before
xen_vga_populate_vram() runs. Then XENMEM_populate_physmap is called
with gfn 0xff000. A new page is allocated with alloc_domheap_pages.
This new page does not have a gfn yet. However, in
guest_physmap_add_entry() the passed mfn maps still to an old gfn
(perhaps from another old guest). This old gfn is in paged-out state
in this guests context and has no mfn anymore. As a result, the
ASSERT() triggers because p2m_is_ram() is true for p2m_ram_paging*
types. If the machine_to_phys_mapping[] array is updated properly,
both loops in guest_physmap_add_entry() turn into no-ops for the new
page and the mfn/gfn mapping will be done at the end of the function.
If XENMEM_add_to_physmap is used with XENMAPSPACE_gmfn,
get_gpfn_from_mfn() will return an appearently valid gfn. As a
result, guest_physmap_remove_page() is called. The ASSERT in
p2m_remove_page triggers because the passed mfn does not match the old
mfn for the passed gfn.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
xen/common/page_alloc.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
Index: xen-4.1.2-testing/xen/common/page_alloc.c
===================================================================
--- xen-4.1.2-testing.orig/xen/common/page_alloc.c
+++ xen-4.1.2-testing/xen/common/page_alloc.c
@@ -528,7 +528,7 @@ static int reserve_offlined_page(struct
static void free_heap_pages(
struct page_info *pg, unsigned int order)
{
- unsigned long mask;
+ unsigned long mask, mfn = page_to_mfn(pg);
unsigned int i, node = phys_to_nid(page_to_maddr(pg)), tainted = 0;
unsigned int zone = page_to_zone(pg);
@@ -539,6 +539,10 @@ static void free_heap_pages(
for ( i = 0; i < (1 << order); i++ )
{
+ /* This page is not a guest frame any more. */
+ page_set_owner(&pg[i], NULL); /* set_gpfn_from_mfn snoops pg owner */
+ set_gpfn_from_mfn(mfn + i, INVALID_M2P_ENTRY);
+
/*
* Cannot assume that count_info == 0, as there are some corner cases
* where it isn't the case and yet it isn't a bug:

View File

@ -1,47 +0,0 @@
# HG changeset patch
# User Keir Fraser <keir@xen.org>
# Date 1307691167 -3600
# Node ID 2ef6bbee50371e1135236035ed1a9a7b8748e09f
# Parent 0a29c8c3ddf7395ea8e68c5f4cd8633023490022
x86/vmx: Small fixes to MSR_IA32_VMX_PROCBASED_CTLS feature probing.
Should check for VIRTUAL_INTR_PENDING as we unconditionally make use
of it. Also check for CR8 exiting unconditionally on x86/64, as this
is of use to nestedvmx, and every 64-bit cpu should support it.
Signed-off-by: Eddie Dong <eddie.dong@intel.com>
Signed-off-by: Keir Fraser <keir@xen.org>
Index: xen-4.1.3-testing/xen/arch/x86/hvm/vmx/vmcs.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/hvm/vmx/vmcs.c
+++ xen-4.1.3-testing/xen/arch/x86/hvm/vmx/vmcs.c
@@ -143,6 +143,11 @@ static int vmx_init_vmcs_config(void)
MSR_IA32_VMX_PINBASED_CTLS, &mismatch);
min = (CPU_BASED_HLT_EXITING |
+ CPU_BASED_VIRTUAL_INTR_PENDING |
+#ifdef __x86_64__
+ CPU_BASED_CR8_LOAD_EXITING |
+ CPU_BASED_CR8_STORE_EXITING |
+#endif
CPU_BASED_INVLPG_EXITING |
CPU_BASED_CR3_LOAD_EXITING |
CPU_BASED_CR3_STORE_EXITING |
@@ -161,13 +166,9 @@ static int vmx_init_vmcs_config(void)
MSR_IA32_VMX_PROCBASED_CTLS, &mismatch);
_vmx_cpu_based_exec_control &= ~CPU_BASED_RDTSC_EXITING;
#ifdef __x86_64__
- if ( !(_vmx_cpu_based_exec_control & CPU_BASED_TPR_SHADOW) )
- {
- min |= CPU_BASED_CR8_LOAD_EXITING | CPU_BASED_CR8_STORE_EXITING;
- _vmx_cpu_based_exec_control = adjust_vmx_controls(
- "CPU-Based Exec Control", min, opt,
- MSR_IA32_VMX_PROCBASED_CTLS, &mismatch);
- }
+ if ( _vmx_cpu_based_exec_control & CPU_BASED_TPR_SHADOW )
+ _vmx_cpu_based_exec_control &=
+ ~(CPU_BASED_CR8_LOAD_EXITING | CPU_BASED_CR8_STORE_EXITING);
#endif
if ( _vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS )

View File

@ -1,36 +0,0 @@
changeset: 23509:782bc7b2661a
user: Keir Fraser <keir@xen.org>
date: Fri Jun 10 13:51:39 2011 +0100
files: xen/arch/x86/x86_32/mm.c
description:
x86_32: Fix build: Define machine_to_phys_mapping_valid
Signed-off-by: Keir Fraser <keir@xen.org>
---
xen/arch/x86/x86_32/mm.c | 4 ++++
1 file changed, 4 insertions(+)
Index: xen-4.1.2-testing/xen/arch/x86/x86_32/mm.c
===================================================================
--- xen-4.1.2-testing.orig/xen/arch/x86/x86_32/mm.c
+++ xen-4.1.2-testing/xen/arch/x86/x86_32/mm.c
@@ -39,6 +39,8 @@ extern l1_pgentry_t l1_identmap[L1_PAGET
unsigned int __read_mostly PAGE_HYPERVISOR = __PAGE_HYPERVISOR;
unsigned int __read_mostly PAGE_HYPERVISOR_NOCACHE = __PAGE_HYPERVISOR_NOCACHE;
+bool_t __read_mostly machine_to_phys_mapping_valid = 0;
+
static unsigned long __read_mostly mpt_size;
void *alloc_xen_pagetable(void)
@@ -123,6 +125,8 @@ void __init paging_init(void)
#undef CNT
#undef MFN
+ machine_to_phys_mapping_valid = 1;
+
/* Create page tables for ioremap()/map_domain_page_global(). */
for ( i = 0; i < (IOREMAP_MBYTES >> (L2_PAGETABLE_SHIFT - 20)); i++ )
{

View File

@ -1,199 +0,0 @@
changeset: 23562:8a7f52c59d64
user: Olaf Hering <olaf@aepfle.de>
date: Fri Jun 10 10:47:02 2011 +0200
files: tools/xenpaging/mem_event.h tools/xenpaging/spinlock.h tools/xenpaging/xenpaging.c tools/xenpaging/xenpaging.h
description:
xenpaging: remove unused spinlock in pager
The spinlock code in the pager is a no-op because xenpaging is a single
threaded application. There is no locking when put_response() places a
response into the ringbuffer.
The only locking is inside the hypervisor, where mem_event_put_request() and
mem_event_get_response() lock the ringbuffer to protect multiple vcpus from
each other.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Committed-by: Ian Jackson <ian.jackson.citrix.com>
---
tools/xenpaging/mem_event.h | 5 ---
tools/xenpaging/spinlock.h | 69 --------------------------------------------
tools/xenpaging/xenpaging.c | 12 -------
tools/xenpaging/xenpaging.h | 1
4 files changed, 87 deletions(-)
Index: xen-4.1.2-testing/tools/xenpaging/mem_event.h
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/mem_event.h
+++ xen-4.1.2-testing/tools/xenpaging/mem_event.h
@@ -25,7 +25,6 @@
#define __XEN_MEM_EVENT_H__
-#include "spinlock.h"
#include "xc.h"
#include <xc_private.h>
@@ -33,9 +32,6 @@
#include <xen/mem_event.h>
-#define mem_event_ring_lock_init(_m) spin_lock_init(&(_m)->ring_lock)
-#define mem_event_ring_lock(_m) spin_lock(&(_m)->ring_lock)
-#define mem_event_ring_unlock(_m) spin_unlock(&(_m)->ring_lock)
typedef struct mem_event {
@@ -45,7 +41,6 @@ typedef struct mem_event {
mem_event_back_ring_t back_ring;
mem_event_shared_page_t *shared_page;
void *ring_page;
- spinlock_t ring_lock;
} mem_event_t;
Index: xen-4.1.2-testing/tools/xenpaging/spinlock.h
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/spinlock.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/******************************************************************************
- * tools/xenpaging/spinlock.h
- *
- * Spinlock implementation.
- *
- * Copyright (c) 2009 Citrix Systems, Inc. (Patrick Colp)
- *
- * 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 __SPINLOCK_H__
-#define __SPINLOCK_H__
-
-
-#include "bitops.h"
-
-
-#define SPIN_LOCK_UNLOCKED 0
-
-
-typedef int spinlock_t;
-
-
-static inline void spin_lock(spinlock_t *lock)
-{
- while ( test_and_set_bit(1, lock) );
-}
-
-static inline void spin_lock_init(spinlock_t *lock)
-{
- *lock = SPIN_LOCK_UNLOCKED;
-}
-
-static inline void spin_unlock(spinlock_t *lock)
-{
- *lock = SPIN_LOCK_UNLOCKED;
-}
-
-static inline int spin_trylock(spinlock_t *lock)
-{
- return !test_and_set_bit(1, lock);
-}
-
-
-#endif // __SPINLOCK_H__
-
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
@@ -32,7 +32,6 @@
#include <xen/mem_event.h>
#include "bitops.h"
-#include "spinlock.h"
#include "file_ops.h"
#include "xc.h"
@@ -127,9 +126,6 @@ static xenpaging_t *xenpaging_init(domid
BACK_RING_INIT(&paging->mem_event.back_ring,
(mem_event_sring_t *)paging->mem_event.ring_page,
PAGE_SIZE);
-
- /* Initialise lock */
- mem_event_ring_lock_init(&paging->mem_event);
/* Initialise Xen */
rc = xc_mem_event_enable(xch, paging->mem_event.domain_id,
@@ -302,8 +298,6 @@ static int get_request(mem_event_t *mem_
mem_event_back_ring_t *back_ring;
RING_IDX req_cons;
- mem_event_ring_lock(mem_event);
-
back_ring = &mem_event->back_ring;
req_cons = back_ring->req_cons;
@@ -315,8 +309,6 @@ static int get_request(mem_event_t *mem_
back_ring->req_cons = req_cons;
back_ring->sring->req_event = req_cons + 1;
- mem_event_ring_unlock(mem_event);
-
return 0;
}
@@ -325,8 +317,6 @@ static int put_response(mem_event_t *mem
mem_event_back_ring_t *back_ring;
RING_IDX rsp_prod;
- mem_event_ring_lock(mem_event);
-
back_ring = &mem_event->back_ring;
rsp_prod = back_ring->rsp_prod_pvt;
@@ -338,8 +328,6 @@ static int put_response(mem_event_t *mem
back_ring->rsp_prod_pvt = rsp_prod;
RING_PUSH_RESPONSES(back_ring);
- mem_event_ring_unlock(mem_event);
-
return 0;
}
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.h
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.h
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.h
@@ -25,7 +25,6 @@
#define __XEN_PAGING2_H__
-#include "spinlock.h"
#include "xc.h"
#include <xc_private.h>

View File

@ -1,154 +0,0 @@
# HG changeset patch
# User Allen Kay <allen.m.kay@intel.com>
# Date 1308823884 -3600
# Node ID d3ac71f22e8621d9a7604f82f3976337e6c97a9a
# Parent 065ca14be963fe4da55d629ed0b3692a14253a86
[VTD] print out debug message in vt-d fault handler only when iommu=debug is set
Print out debug messages in vtd_page_fault() handler only when
iommu=debug is set xen boot parameter.
Signed-off-by: Allen Kay <allen.m.kay@intel.com>
Index: xen-4.1.3-testing/xen/drivers/passthrough/amd/iommu_acpi.c
===================================================================
--- xen-4.1.3-testing.orig/xen/drivers/passthrough/amd/iommu_acpi.c
+++ xen-4.1.3-testing/xen/drivers/passthrough/amd/iommu_acpi.c
@@ -822,7 +822,7 @@ static int __init parse_ivrs_table(struc
BUG_ON(!table);
- if ( amd_iommu_debug )
+ if ( iommu_debug )
dump_acpi_table_header(table);
/* parse IVRS blocks */
Index: xen-4.1.3-testing/xen/drivers/passthrough/iommu.c
===================================================================
--- xen-4.1.3-testing.orig/xen/drivers/passthrough/iommu.c
+++ xen-4.1.3-testing/xen/drivers/passthrough/iommu.c
@@ -48,7 +48,7 @@ bool_t __read_mostly iommu_snoop = 1;
bool_t __read_mostly iommu_qinval = 1;
bool_t __read_mostly iommu_intremap = 1;
bool_t __read_mostly iommu_hap_pt_share;
-bool_t __read_mostly amd_iommu_debug;
+bool_t __read_mostly iommu_debug;
bool_t __read_mostly amd_iommu_perdev_intremap;
static void __init parse_iommu_param(char *s)
@@ -74,8 +74,8 @@ static void __init parse_iommu_param(cha
iommu_qinval = 0;
else if ( !strcmp(s, "no-intremap") )
iommu_intremap = 0;
- else if ( !strcmp(s, "amd-iommu-debug") )
- amd_iommu_debug = 1;
+ else if ( !strcmp(s, "debug") )
+ iommu_debug = 1;
else if ( !strcmp(s, "amd-iommu-perdev-intremap") )
amd_iommu_perdev_intremap = 1;
else if ( !strcmp(s, "dom0-passthrough") )
Index: xen-4.1.3-testing/xen/drivers/passthrough/vtd/iommu.c
===================================================================
--- xen-4.1.3-testing.orig/xen/drivers/passthrough/vtd/iommu.c
+++ xen-4.1.3-testing/xen/drivers/passthrough/vtd/iommu.c
@@ -844,7 +844,7 @@ static int iommu_page_fault_do_one(struc
if ( fault_type == DMA_REMAP )
{
- dprintk(XENLOG_WARNING VTDPREFIX,
+ INTEL_IOMMU_DEBUG(
"DMAR:[%s] Request device [%02x:%02x.%d] "
"fault addr %"PRIx64", iommu reg = %p\n"
"DMAR:[fault reason %02xh] %s\n",
@@ -853,12 +853,13 @@ static int iommu_page_fault_do_one(struc
PCI_FUNC(source_id & 0xFF), addr, iommu->reg,
fault_reason, reason);
#ifndef __i386__ /* map_domain_page() cannot be used in this context */
- print_vtd_entries(iommu, (source_id >> 8),
+ if (iommu_debug)
+ print_vtd_entries(iommu, (source_id >> 8),
(source_id & 0xff), (addr >> PAGE_SHIFT));
#endif
}
else
- dprintk(XENLOG_WARNING VTDPREFIX,
+ INTEL_IOMMU_DEBUG(
"INTR-REMAP: Request device [%02x:%02x.%d] "
"fault index %"PRIx64", iommu reg = %p\n"
"INTR-REMAP:[fault reason %02xh] %s\n",
@@ -872,26 +873,19 @@ static int iommu_page_fault_do_one(struc
static void iommu_fault_status(u32 fault_status)
{
if ( fault_status & DMA_FSTS_PFO )
- dprintk(XENLOG_ERR VTDPREFIX,
- "iommu_fault_status: Fault Overflow\n");
+ INTEL_IOMMU_DEBUG("iommu_fault_status: Fault Overflow\n");
if ( fault_status & DMA_FSTS_PPF )
- dprintk(XENLOG_ERR VTDPREFIX,
- "iommu_fault_status: Primary Pending Fault\n");
+ INTEL_IOMMU_DEBUG("iommu_fault_status: Primary Pending Fault\n");
if ( fault_status & DMA_FSTS_AFO )
- dprintk(XENLOG_ERR VTDPREFIX,
- "iommu_fault_status: Advanced Fault Overflow\n");
+ INTEL_IOMMU_DEBUG("iommu_fault_status: Advanced Fault Overflow\n");
if ( fault_status & DMA_FSTS_APF )
- dprintk(XENLOG_ERR VTDPREFIX,
- "iommu_fault_status: Advanced Pending Fault\n");
+ INTEL_IOMMU_DEBUG("iommu_fault_status: Advanced Pending Fault\n");
if ( fault_status & DMA_FSTS_IQE )
- dprintk(XENLOG_ERR VTDPREFIX,
- "iommu_fault_status: Invalidation Queue Error\n");
+ INTEL_IOMMU_DEBUG("iommu_fault_status: Invalidation Queue Error\n");
if ( fault_status & DMA_FSTS_ICE )
- dprintk(XENLOG_ERR VTDPREFIX,
- "iommu_fault_status: Invalidation Completion Error\n");
+ INTEL_IOMMU_DEBUG("iommu_fault_status: Invalidation Completion Error\n");
if ( fault_status & DMA_FSTS_ITE )
- dprintk(XENLOG_ERR VTDPREFIX,
- "iommu_fault_status: Invalidation Time-out Error\n");
+ INTEL_IOMMU_DEBUG("iommu_fault_status: Invalidation Time-out Error\n");
}
#define PRIMARY_FAULT_REG_LEN (16)
Index: xen-4.1.3-testing/xen/drivers/passthrough/vtd/iommu.h
===================================================================
--- xen-4.1.3-testing.orig/xen/drivers/passthrough/vtd/iommu.h
+++ xen-4.1.3-testing/xen/drivers/passthrough/vtd/iommu.h
@@ -512,4 +512,11 @@ struct intel_iommu {
struct acpi_drhd_unit *drhd;
};
+#define INTEL_IOMMU_DEBUG(fmt, args...) \
+ do \
+ { \
+ if ( iommu_debug ) \
+ dprintk(XENLOG_WARNING VTDPREFIX, fmt, ## args); \
+ } while(0)
+
#endif
Index: xen-4.1.3-testing/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
===================================================================
--- xen-4.1.3-testing.orig/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
+++ xen-4.1.3-testing/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
@@ -34,7 +34,7 @@
#define AMD_IOMMU_DEBUG(fmt, args...) \
do \
{ \
- if ( amd_iommu_debug ) \
+ if ( iommu_debug ) \
printk(XENLOG_INFO "AMD-Vi: " fmt, ## args); \
} while(0)
Index: xen-4.1.3-testing/xen/include/xen/iommu.h
===================================================================
--- xen-4.1.3-testing.orig/xen/include/xen/iommu.h
+++ xen-4.1.3-testing/xen/include/xen/iommu.h
@@ -31,7 +31,7 @@ extern bool_t force_iommu, iommu_verbose
extern bool_t iommu_workaround_bios_bug, iommu_passthrough;
extern bool_t iommu_snoop, iommu_qinval, iommu_intremap;
extern bool_t iommu_hap_pt_share;
-extern bool_t amd_iommu_debug;
+extern bool_t iommu_debug;
extern bool_t amd_iommu_perdev_intremap;
/* Does this domain have a P2M table we can use as its IOMMU pagetable? */

View File

@ -1,127 +0,0 @@
References: fate#311376, fate#311529, bnc#578927, bnc#628554
# HG changeset patch
# User Jan Beulich <jbeulich@novell.com>
# Date 1308825237 -3600
# Node ID d7644abc218d3232b9d957ce94fc4b4bcc1f456e
# Parent 584c2e5e03d96f912cdfe90f8e9f910d5d661706
x86: allow Dom0 image to be compressed ELF
Rather than being able to decompress only the payloads of bzImage
containers, extend the logic to also decompress simple compressed ELF
images. At once, allow uncompressed bzImage payloads.
This is a prerequisite for native EFI booting support (where, in the
absence of a capable secondary boot loader, the image will always be
in compressed form).
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Index: xen-4.1.2-testing/xen/arch/x86/bzimage.c
===================================================================
--- xen-4.1.2-testing.orig/xen/arch/x86/bzimage.c
+++ xen-4.1.2-testing/xen/arch/x86/bzimage.c
@@ -5,6 +5,7 @@
#include <xen/string.h>
#include <xen/types.h>
#include <xen/decompress.h>
+#include <xen/libelf.h>
#include <asm/bzimage.h>
#define HEAPORDER 3
@@ -199,25 +200,36 @@ static __init int bzimage_check(struct s
return 1;
}
-int __init bzimage_headroom(char *image_start, unsigned long image_length)
+static unsigned long __initdata orig_image_len;
+
+unsigned long __init bzimage_headroom(char *image_start,
+ unsigned long image_length)
{
struct setup_header *hdr = (struct setup_header *)image_start;
- char *img;
- int err, headroom;
+ int err;
+ unsigned long headroom;
err = bzimage_check(hdr, image_length);
- if (err < 1)
+ if ( err < 0 )
return 0;
- img = image_start + (hdr->setup_sects+1) * 512;
- img += hdr->payload_offset;
+ if ( err > 0 )
+ {
+ image_start += (hdr->setup_sects + 1) * 512 + hdr->payload_offset;
+ image_length = hdr->payload_length;
+ }
+
+ if ( elf_is_elfbinary(image_start) )
+ return 0;
- headroom = output_length(img, hdr->payload_length);
- if (gzip_check(img, hdr->payload_length)) {
+ orig_image_len = image_length;
+ headroom = output_length(image_start, image_length);
+ if (gzip_check(image_start, image_length))
+ {
headroom += headroom >> 12; /* Add 8 bytes for every 32K input block */
headroom += (32768 + 18); /* Add 32K + 18 bytes of extra headroom */
} else
- headroom += hdr->payload_length;
+ headroom += image_length;
headroom = (headroom + 4095) & ~4095;
return headroom;
@@ -229,18 +241,24 @@ int __init bzimage_parse(char *image_bas
int err = bzimage_check(hdr, *image_len);
unsigned long output_len;
- if (err < 1)
+ if ( err < 0 )
return err;
+ if ( err > 0 )
+ {
+ *image_start += (hdr->setup_sects + 1) * 512 + hdr->payload_offset;
+ *image_len = hdr->payload_length;
+ }
+
+ if ( elf_is_elfbinary(*image_start) )
+ return 0;
+
BUG_ON(!(image_base < *image_start));
- *image_start += (hdr->setup_sects+1) * 512;
- *image_start += hdr->payload_offset;
- *image_len = hdr->payload_length;
- output_len = output_length(*image_start, *image_len);
+ output_len = output_length(*image_start, orig_image_len);
- if ( (err = perform_gunzip(image_base, *image_start, *image_len)) > 0 )
- err = decompress(*image_start, *image_len, image_base);
+ if ( (err = perform_gunzip(image_base, *image_start, orig_image_len)) > 0 )
+ err = decompress(*image_start, orig_image_len, image_base);
if ( !err )
{
Index: xen-4.1.2-testing/xen/include/asm-x86/bzimage.h
===================================================================
--- xen-4.1.2-testing.orig/xen/include/asm-x86/bzimage.h
+++ xen-4.1.2-testing/xen/include/asm-x86/bzimage.h
@@ -4,10 +4,9 @@
#include <xen/config.h>
#include <xen/init.h>
-int __init bzimage_headroom(char *image_start, unsigned long image_length);
+unsigned long bzimage_headroom(char *image_start, unsigned long image_length);
-int __init bzimage_parse(char *image_base,
- char **image_start,
- unsigned long *image_len);
+int bzimage_parse(char *image_base, char **image_start,
+ unsigned long *image_len);
#endif /* __X86_BZIMAGE_H__ */

View File

@ -1,156 +0,0 @@
References: fate#311376, fate#311529, bnc#578927, bnc#628554
# HG changeset patch
# User Jan Beulich <jbeulich@novell.com>
# Date 1308825280 -3600
# Node ID 4d9598a6a7777c50e109d7e2eb6d1cb28bcb4509
# Parent d7644abc218d3232b9d957ce94fc4b4bcc1f456e
x86/DMI: use proper structures instead of byte offsets
Besides being (in my eyes) desirable cleanup, this at once represents
another prerequisite for native EFI booting support.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Index: xen-4.1.3-testing/xen/arch/x86/dmi_scan.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/dmi_scan.c
+++ xen-4.1.3-testing/xen/arch/x86/dmi_scan.c
@@ -12,11 +12,31 @@
#include <xen/pci.h>
#include <xen/pci_regs.h>
-#define bt_ioremap(b,l) ((u8 *)__acpi_map_table(b,l))
+#define bt_ioremap(b,l) ((void *)__acpi_map_table(b,l))
#define bt_iounmap(b,l) ((void)0)
#define memcpy_fromio memcpy
#define alloc_bootmem(l) xmalloc_bytes(l)
+struct dmi_eps {
+ char anchor[5]; /* "_DMI_" */
+ u8 checksum;
+ u16 size;
+ u32 address;
+ u16 num_structures;
+ u8 revision;
+} __attribute__((packed));
+
+struct smbios_eps {
+ char anchor[4]; /* "_SM_" */
+ u8 checksum;
+ u8 length;
+ u8 major, minor;
+ u16 max_size;
+ u8 revision;
+ u8 _rsrvd_[5];
+ struct dmi_eps dmi;
+} __attribute__((packed));
+
struct dmi_header
{
u8 type;
@@ -92,62 +112,70 @@ static int __init dmi_table(u32 base, in
}
-inline static int __init dmi_checksum(u8 *buf)
+static inline bool_t __init dmi_checksum(const void __iomem *buf,
+ unsigned int len)
{
- u8 sum=0;
- int a;
+ u8 sum = 0;
+ const u8 *p = buf;
+ unsigned int a;
- for(a=0; a<15; a++)
- sum+=buf[a];
- return (sum==0);
+ for (a = 0; a < len; a++)
+ sum += p[a];
+ return sum == 0;
}
int __init dmi_get_table(u32 *base, u32 *len)
{
- u8 buf[15];
+ struct dmi_eps eps;
char __iomem *p, *q;
p = maddr_to_virt(0xF0000);
for (q = p; q < p + 0x10000; q += 16) {
- memcpy_fromio(buf, q, 15);
- if (memcmp(buf, "_DMI_", 5)==0 && dmi_checksum(buf)) {
- *base=buf[11]<<24|buf[10]<<16|buf[9]<<8|buf[8];
- *len=buf[7]<<8|buf[6];
+ memcpy_fromio(&eps, q, 15);
+ if (memcmp(eps.anchor, "_DMI_", 5) == 0 &&
+ dmi_checksum(&eps, sizeof(eps))) {
+ *base = eps.address;
+ *len = eps.size;
return 0;
}
}
return -1;
}
+static int __init _dmi_iterate(const struct dmi_eps *dmi,
+ const struct smbios_eps __iomem *smbios,
+ void (*decode)(struct dmi_header *))
+{
+ u16 num = dmi->num_structures;
+ u16 len = dmi->size;
+ u32 base = dmi->address;
+
+ /*
+ * DMI version 0.0 means that the real version is taken from
+ * the SMBIOS version, which we may not know at this point.
+ */
+ if (dmi->revision)
+ printk(KERN_INFO "DMI %d.%d present.\n",
+ dmi->revision >> 4, dmi->revision & 0x0f);
+ else if (!smbios)
+ printk(KERN_INFO "DMI present.\n");
+ dmi_printk((KERN_INFO "%d structures occupying %d bytes.\n",
+ num, len));
+ dmi_printk((KERN_INFO "DMI table at 0x%08X.\n", base));
+ return dmi_table(base, len, num, decode);
+}
+
static int __init dmi_iterate(void (*decode)(struct dmi_header *))
{
- u8 buf[15];
+ struct dmi_eps eps;
char __iomem *p, *q;
p = maddr_to_virt(0xF0000);
for (q = p; q < p + 0x10000; q += 16) {
- memcpy_fromio(buf, q, 15);
- if (memcmp(buf, "_DMI_", 5)==0 && dmi_checksum(buf)) {
- u16 num=buf[13]<<8|buf[12];
- u16 len=buf[7]<<8|buf[6];
- u32 base=buf[11]<<24|buf[10]<<16|buf[9]<<8|buf[8];
-
- /*
- * DMI version 0.0 means that the real version is taken from
- * the SMBIOS version, which we don't know at this point.
- */
- if(buf[14]!=0)
- printk(KERN_INFO "DMI %d.%d present.\n",
- buf[14]>>4, buf[14]&0x0F);
- else
- printk(KERN_INFO "DMI present.\n");
- dmi_printk((KERN_INFO "%d structures occupying %d bytes.\n",
- num, len));
- dmi_printk((KERN_INFO "DMI table at 0x%08X.\n",
- base));
- if(dmi_table(base,len, num, decode)==0)
- return 0;
- }
+ memcpy_fromio(&eps, q, sizeof(eps));
+ if (memcmp(eps.anchor, "_DMI_", 5) == 0 &&
+ dmi_checksum(&eps, sizeof(eps)))
+ return _dmi_iterate(&eps, NULL, decode);
}
return -1;
}

View File

@ -1,151 +0,0 @@
changeset: 23576:e2235fe267eb
user: Jan Beulich <jbeulich@novell.com>
date: Thu Jun 23 11:35:55 2011 +0100
files: xen/arch/x86/mm.c xen/arch/x86/traps.c xen/arch/x86/x86_32/mm.c xen/arch/x86/x86_32/traps.c xen/arch/x86/x86_64/mm.c xen/arch/x86/x86_64/traps.c
description:
x86: show page walk also for early page faults
At once, move the common (between 32- and 64-bit) definition of
machine_to_phys_mapping_valid to a common location.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
---
xen/arch/x86/mm.c | 2 ++
xen/arch/x86/traps.c | 1 +
xen/arch/x86/x86_32/mm.c | 2 --
xen/arch/x86/x86_32/traps.c | 9 ++++++---
xen/arch/x86/x86_64/mm.c | 2 --
xen/arch/x86/x86_64/traps.c | 12 ++++++++----
6 files changed, 17 insertions(+), 11 deletions(-)
Index: xen-4.1.3-testing/xen/arch/x86/mm.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/mm.c
+++ xen-4.1.3-testing/xen/arch/x86/mm.c
@@ -152,6 +152,8 @@ unsigned long __read_mostly pdx_group_va
(FRAMETABLE_SIZE / sizeof(*frame_table) + PDX_GROUP_COUNT - 1)
/ PDX_GROUP_COUNT)] = { [0] = 1 };
+bool_t __read_mostly machine_to_phys_mapping_valid = 0;
+
#define PAGE_CACHE_ATTRS (_PAGE_PAT|_PAGE_PCD|_PAGE_PWT)
bool_t __read_mostly opt_allow_superpage;
Index: xen-4.1.3-testing/xen/arch/x86/traps.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/traps.c
+++ xen-4.1.3-testing/xen/arch/x86/traps.c
@@ -1454,6 +1454,7 @@ asmlinkage void __init do_early_page_fau
unsigned long *stk = (unsigned long *)regs;
printk("Early fatal page fault at %04x:%p (cr2=%p, ec=%04x)\n",
regs->cs, _p(regs->eip), _p(cr2), regs->error_code);
+ show_page_walk(cr2);
printk("Stack dump: ");
while ( ((long)stk & ((PAGE_SIZE - 1) & ~(BYTES_PER_LONG - 1))) != 0 )
printk("%p ", _p(*stk++));
Index: xen-4.1.3-testing/xen/arch/x86/x86_32/mm.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/x86_32/mm.c
+++ xen-4.1.3-testing/xen/arch/x86/x86_32/mm.c
@@ -39,8 +39,6 @@ extern l1_pgentry_t l1_identmap[L1_PAGET
unsigned int __read_mostly PAGE_HYPERVISOR = __PAGE_HYPERVISOR;
unsigned int __read_mostly PAGE_HYPERVISOR_NOCACHE = __PAGE_HYPERVISOR_NOCACHE;
-bool_t __read_mostly machine_to_phys_mapping_valid = 0;
-
static unsigned long __read_mostly mpt_size;
void *alloc_xen_pagetable(void)
Index: xen-4.1.3-testing/xen/arch/x86/x86_32/traps.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/x86_32/traps.c
+++ xen-4.1.3-testing/xen/arch/x86/x86_32/traps.c
@@ -164,7 +164,8 @@ void show_page_walk(unsigned long addr)
l3t += (cr3 & 0xFE0UL) >> 3;
l3e = l3t[l3_table_offset(addr)];
mfn = l3e_get_pfn(l3e);
- pfn = mfn_valid(mfn) ? get_gpfn_from_mfn(mfn) : INVALID_M2P_ENTRY;
+ pfn = mfn_valid(mfn) && machine_to_phys_mapping_valid ?
+ get_gpfn_from_mfn(mfn) : INVALID_M2P_ENTRY;
printk(" L3[0x%03lx] = %"PRIpte" %08lx\n",
l3_table_offset(addr), l3e_get_intpte(l3e), pfn);
unmap_domain_page(l3t);
@@ -175,7 +176,8 @@ void show_page_walk(unsigned long addr)
l2t = map_domain_page(mfn);
l2e = l2t[l2_table_offset(addr)];
mfn = l2e_get_pfn(l2e);
- pfn = mfn_valid(mfn) ? get_gpfn_from_mfn(mfn) : INVALID_M2P_ENTRY;
+ pfn = mfn_valid(mfn) && machine_to_phys_mapping_valid ?
+ get_gpfn_from_mfn(mfn) : INVALID_M2P_ENTRY;
printk(" L2[0x%03lx] = %"PRIpte" %08lx %s\n",
l2_table_offset(addr), l2e_get_intpte(l2e), pfn,
(l2e_get_flags(l2e) & _PAGE_PSE) ? "(PSE)" : "");
@@ -188,7 +190,8 @@ void show_page_walk(unsigned long addr)
l1t = map_domain_page(mfn);
l1e = l1t[l1_table_offset(addr)];
mfn = l1e_get_pfn(l1e);
- pfn = mfn_valid(mfn) ? get_gpfn_from_mfn(mfn) : INVALID_M2P_ENTRY;
+ pfn = mfn_valid(mfn) && machine_to_phys_mapping_valid ?
+ get_gpfn_from_mfn(mfn) : INVALID_M2P_ENTRY;
printk(" L1[0x%03lx] = %"PRIpte" %08lx\n",
l1_table_offset(addr), l1e_get_intpte(l1e), pfn);
unmap_domain_page(l1t);
Index: xen-4.1.3-testing/xen/arch/x86/x86_64/mm.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/x86_64/mm.c
+++ xen-4.1.3-testing/xen/arch/x86/x86_64/mm.c
@@ -47,8 +47,6 @@ unsigned int __read_mostly pfn_pdx_hole_
unsigned int __read_mostly m2p_compat_vstart = __HYPERVISOR_COMPAT_VIRT_START;
-bool_t __read_mostly machine_to_phys_mapping_valid = 0;
-
/* Top-level master (and idle-domain) page directory. */
l4_pgentry_t __attribute__ ((__section__ (".bss.page_aligned")))
idle_pg_table[L4_PAGETABLE_ENTRIES];
Index: xen-4.1.3-testing/xen/arch/x86/x86_64/traps.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/x86_64/traps.c
+++ xen-4.1.3-testing/xen/arch/x86/x86_64/traps.c
@@ -176,7 +176,8 @@ void show_page_walk(unsigned long addr)
l4t = mfn_to_virt(mfn);
l4e = l4t[l4_table_offset(addr)];
mfn = l4e_get_pfn(l4e);
- pfn = mfn_valid(mfn) ? get_gpfn_from_mfn(mfn) : INVALID_M2P_ENTRY;
+ pfn = mfn_valid(mfn) && machine_to_phys_mapping_valid ?
+ get_gpfn_from_mfn(mfn) : INVALID_M2P_ENTRY;
printk(" L4[0x%03lx] = %"PRIpte" %016lx\n",
l4_table_offset(addr), l4e_get_intpte(l4e), pfn);
if ( !(l4e_get_flags(l4e) & _PAGE_PRESENT) ||
@@ -186,7 +187,8 @@ void show_page_walk(unsigned long addr)
l3t = mfn_to_virt(mfn);
l3e = l3t[l3_table_offset(addr)];
mfn = l3e_get_pfn(l3e);
- pfn = mfn_valid(mfn) ? get_gpfn_from_mfn(mfn) : INVALID_M2P_ENTRY;
+ pfn = mfn_valid(mfn) && machine_to_phys_mapping_valid ?
+ get_gpfn_from_mfn(mfn) : INVALID_M2P_ENTRY;
printk(" L3[0x%03lx] = %"PRIpte" %016lx%s\n",
l3_table_offset(addr), l3e_get_intpte(l3e), pfn,
(l3e_get_flags(l3e) & _PAGE_PSE) ? " (PSE)" : "");
@@ -198,7 +200,8 @@ void show_page_walk(unsigned long addr)
l2t = mfn_to_virt(mfn);
l2e = l2t[l2_table_offset(addr)];
mfn = l2e_get_pfn(l2e);
- pfn = mfn_valid(mfn) ? get_gpfn_from_mfn(mfn) : INVALID_M2P_ENTRY;
+ pfn = mfn_valid(mfn) && machine_to_phys_mapping_valid ?
+ get_gpfn_from_mfn(mfn) : INVALID_M2P_ENTRY;
printk(" L2[0x%03lx] = %"PRIpte" %016lx %s\n",
l2_table_offset(addr), l2e_get_intpte(l2e), pfn,
(l2e_get_flags(l2e) & _PAGE_PSE) ? "(PSE)" : "");
@@ -210,7 +213,8 @@ void show_page_walk(unsigned long addr)
l1t = mfn_to_virt(mfn);
l1e = l1t[l1_table_offset(addr)];
mfn = l1e_get_pfn(l1e);
- pfn = mfn_valid(mfn) ? get_gpfn_from_mfn(mfn) : INVALID_M2P_ENTRY;
+ pfn = mfn_valid(mfn) && machine_to_phys_mapping_valid ?
+ get_gpfn_from_mfn(mfn) : INVALID_M2P_ENTRY;
printk(" L1[0x%03lx] = %"PRIpte" %016lx\n",
l1_table_offset(addr), l1e_get_intpte(l1e), pfn);
}

View File

@ -1,79 +0,0 @@
changeset: 23578:7299a9a44b35
user: Olaf Hering <olaf@aepfle.de>
date: Wed Jun 22 14:47:09 2011 +0100
files: tools/xenpaging/xenpaging.c tools/xenpaging/xenpaging.h
description:
xenpaging: add xs_handle to struct xenpaging
A xs_handle is currently used in the xc_mem_paging_flush_ioemu_cache()
function and will be used by a subsequent patch.
Add it to struct xenpaging.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Committed-by: Ian Jackson <ian.jackson.citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
tools/xenpaging/xenpaging.c | 14 ++++++++++++++
tools/xenpaging/xenpaging.h | 1 +
2 files changed, 15 insertions(+)
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
@@ -28,6 +28,7 @@
#include <signal.h>
#include <unistd.h>
#include <xc_private.h>
+#include <xs.h>
#include <xen/mem_event.h>
@@ -92,6 +93,14 @@ static xenpaging_t *xenpaging_init(domid
paging = malloc(sizeof(xenpaging_t));
memset(paging, 0, sizeof(xenpaging_t));
+ /* Open connection to xenstore */
+ paging->xs_handle = xs_open(0);
+ if ( paging->xs_handle == NULL )
+ {
+ ERROR("Error initialising xenstore connection");
+ goto err;
+ }
+
p = getenv("XENPAGING_POLICY_MRU_SIZE");
if ( p && *p )
{
@@ -221,6 +230,8 @@ static xenpaging_t *xenpaging_init(domid
err:
if ( paging )
{
+ if ( paging->xs_handle )
+ xs_close(paging->xs_handle);
xc_interface_close(xch);
if ( paging->mem_event.shared_page )
{
@@ -277,6 +288,9 @@ static int xenpaging_teardown(xenpaging_
}
paging->mem_event.xce_handle = NULL;
+ /* Close connection to xenstore */
+ xs_close(paging->xs_handle);
+
/* Close connection to Xen */
rc = xc_interface_close(xch);
if ( rc != 0 )
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.h
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.h
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.h
@@ -36,6 +36,7 @@
typedef struct xenpaging {
xc_interface *xc_handle;
+ struct xs_handle *xs_handle;
xc_platform_info_t *platform_info;
xc_domaininfo_t *domain_info;

View File

@ -1,48 +0,0 @@
changeset: 23579:868c8c898f73
user: Olaf Hering <olaf@aepfle.de>
date: Fri Jun 10 10:47:06 2011 +0200
files: tools/xenpaging/policy_default.c tools/xenpaging/xc.h
description:
xenpaging: drop xc.c, remove ASSERT
The ASSERT is not needed, victim is never NULL.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Committed-by: Ian Jackson <ian.jackson.citrix.com>
---
tools/xenpaging/policy_default.c | 1 -
tools/xenpaging/xc.h | 7 -------
2 files changed, 8 deletions(-)
Index: xen-4.1.2-testing/tools/xenpaging/policy_default.c
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/policy_default.c
+++ xen-4.1.2-testing/tools/xenpaging/policy_default.c
@@ -78,7 +78,6 @@ int policy_choose_victim(xenpaging_t *pa
{
xc_interface *xch = paging->xc_handle;
unsigned long wrap = current_gfn;
- ASSERT(victim != NULL);
do
{
Index: xen-4.1.2-testing/tools/xenpaging/xc.h
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xc.h
+++ xen-4.1.2-testing/tools/xenpaging/xc.h
@@ -30,13 +30,6 @@
#include <xen/mem_event.h>
-#if 1
-#define ASSERT(_p) \
- if ( !(_p) ) { DPRINTF("Assertion '%s' failed, line %d, file %s", #_p , \
- __LINE__, __FILE__); *(int*)0=0; }
-#else
-#define ASSERT(_p) ((void)0)
-#endif

View File

@ -1,121 +0,0 @@
changeset: 23580:771b6984aa2a
user: Olaf Hering <olaf@aepfle.de>
date: Fri Jun 10 10:47:07 2011 +0200
files: tools/xenpaging/xc.c tools/xenpaging/xc.h tools/xenpaging/xenpaging.c tools/xenpaging/xenpaging.h
description:
xenpaging: drop xc.c, remove xc_platform_info_t
xc_platform_info_t is not used in xenpaging.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Committed-by: Ian Jackson <ian.jackson.citrix.com>
---
tools/xenpaging/xc.c | 10 ----------
tools/xenpaging/xc.h | 8 --------
tools/xenpaging/xenpaging.c | 17 -----------------
tools/xenpaging/xenpaging.h | 1 -
4 files changed, 36 deletions(-)
Index: xen-4.1.2-testing/tools/xenpaging/xc.c
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xc.c
+++ xen-4.1.2-testing/tools/xenpaging/xc.c
@@ -26,7 +26,6 @@
#include <stdarg.h>
#include <sys/poll.h>
#include <xc_private.h>
-#include <xg_save_restore.h>
#include <xs.h>
#include "xc.h"
@@ -97,15 +96,6 @@ int xc_wait_for_event(xc_interface *xch,
return xc_wait_for_event_or_timeout(xch, xce, -1);
}
-int xc_get_platform_info(xc_interface *xc_handle, domid_t domain_id,
- xc_platform_info_t *platform_info)
-{
- return get_platform_info(xc_handle, domain_id,
- &platform_info->max_mfn,
- &platform_info->hvirt_start,
- &platform_info->pt_levels,
- &platform_info->guest_width);
-}
/*
Index: xen-4.1.2-testing/tools/xenpaging/xc.h
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xc.h
+++ xen-4.1.2-testing/tools/xenpaging/xc.h
@@ -34,12 +34,6 @@
-typedef struct xc_platform_info {
- unsigned long max_mfn;
- unsigned long hvirt_start;
- unsigned int pt_levels;
- unsigned int guest_width;
-} xc_platform_info_t;
@@ -47,8 +41,6 @@ int xc_mem_paging_flush_ioemu_cache(domi
int xc_wait_for_event(xc_interface *xch, xc_evtchn *xce);
int xc_wait_for_event_or_timeout(xc_interface *xch, xc_evtchn *xce, unsigned long ms);
-int xc_get_platform_info(xc_interface *xc_handle, domid_t domain_id,
- xc_platform_info_t *platform_info);
#endif // __XC_H__
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
@@ -176,22 +176,6 @@ static xenpaging_t *xenpaging_init(domid
paging->mem_event.port = rc;
- /* Get platform info */
- paging->platform_info = malloc(sizeof(xc_platform_info_t));
- if ( paging->platform_info == NULL )
- {
- ERROR("Error allocating memory for platform info");
- goto err;
- }
-
- rc = xc_get_platform_info(xch, paging->mem_event.domain_id,
- paging->platform_info);
- if ( rc != 1 )
- {
- ERROR("Error getting platform info");
- goto err;
- }
-
/* Get domaininfo */
paging->domain_info = malloc(sizeof(xc_domaininfo_t));
if ( paging->domain_info == NULL )
@@ -246,7 +230,6 @@ static xenpaging_t *xenpaging_init(domid
}
free(paging->bitmap);
- free(paging->platform_info);
free(paging->domain_info);
free(paging);
}
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.h
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.h
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.h
@@ -38,7 +38,6 @@ typedef struct xenpaging {
xc_interface *xc_handle;
struct xs_handle *xs_handle;
- xc_platform_info_t *platform_info;
xc_domaininfo_t *domain_info;
unsigned long *bitmap;

View File

@ -1,45 +0,0 @@
changeset: 23581:9ce56626a5ab
user: Olaf Hering <olaf@aepfle.de>
date: Fri Jun 10 10:47:08 2011 +0200
files: tools/xenpaging/xc.c tools/xenpaging/xc.h
description:
xenpaging: drop xc.c, remove xc_wait_for_event
xc_wait_for_event is not used in xenpaging.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Committed-by: Ian Jackson <ian.jackson.citrix.com>
---
tools/xenpaging/xc.c | 4 ----
tools/xenpaging/xc.h | 1 -
2 files changed, 5 deletions(-)
Index: xen-4.1.2-testing/tools/xenpaging/xc.c
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xc.c
+++ xen-4.1.2-testing/tools/xenpaging/xc.c
@@ -91,10 +91,6 @@ int xc_wait_for_event_or_timeout(xc_inte
return -errno;
}
-int xc_wait_for_event(xc_interface *xch, xc_evtchn *xce)
-{
- return xc_wait_for_event_or_timeout(xch, xce, -1);
-}
Index: xen-4.1.2-testing/tools/xenpaging/xc.h
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xc.h
+++ xen-4.1.2-testing/tools/xenpaging/xc.h
@@ -38,7 +38,6 @@
int xc_mem_paging_flush_ioemu_cache(domid_t domain_id);
-int xc_wait_for_event(xc_interface *xch, xc_evtchn *xce);
int xc_wait_for_event_or_timeout(xc_interface *xch, xc_evtchn *xce, unsigned long ms);

View File

@ -1,96 +0,0 @@
changeset: 23582:480e548fe76b
user: Olaf Hering <olaf@aepfle.de>
date: Fri Jun 10 10:47:10 2011 +0200
files: tools/xenpaging/xc.c tools/xenpaging/xc.h tools/xenpaging/xenpaging.c
description:
xenpaging: drop xc.c, move xc_mem_paging_flush_ioemu_cache
Move xc_mem_paging_flush_ioemu_cache() into xenpaging and massage it a bit to
use the required members from xenpaging_t.
Also update type of rc to match xs_write() return value.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Committed-by: Ian Jackson <ian.jackson.citrix.com>
---
tools/xenpaging/xc.c | 18 ------------------
tools/xenpaging/xc.h | 1 -
tools/xenpaging/xenpaging.c | 16 +++++++++++++++-
3 files changed, 15 insertions(+), 20 deletions(-)
Index: xen-4.1.2-testing/tools/xenpaging/xc.c
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xc.c
+++ xen-4.1.2-testing/tools/xenpaging/xc.c
@@ -31,24 +31,6 @@
-int xc_mem_paging_flush_ioemu_cache(domid_t domain_id)
-{
- struct xs_handle *xsh = NULL;
- char path[80];
- int rc;
-
- sprintf(path, "/local/domain/0/device-model/%u/command", domain_id);
-
- xsh = xs_daemon_open();
- if ( xsh == NULL )
- return -EIO;
-
- rc = xs_write(xsh, XBT_NULL, path, "flush-cache", strlen("flush-cache"));
-
- xs_daemon_close(xsh);
-
- return rc ? 0 : -1;
-}
int xc_wait_for_event_or_timeout(xc_interface *xch, xc_evtchn *xce, unsigned long ms)
{
Index: xen-4.1.2-testing/tools/xenpaging/xc.h
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xc.h
+++ xen-4.1.2-testing/tools/xenpaging/xc.h
@@ -37,7 +37,6 @@
-int xc_mem_paging_flush_ioemu_cache(domid_t domain_id);
int xc_wait_for_event_or_timeout(xc_interface *xch, xc_evtchn *xce, unsigned long ms);
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
@@ -48,6 +48,20 @@ static void close_handler(int sig)
unlink(filename);
}
+static int xenpaging_mem_paging_flush_ioemu_cache(xenpaging_t *paging)
+{
+ struct xs_handle *xsh = paging->xs_handle;
+ domid_t domain_id = paging->mem_event.domain_id;
+ char path[80];
+ bool rc;
+
+ sprintf(path, "/local/domain/0/device-model/%u/command", domain_id);
+
+ rc = xs_write(xsh, XBT_NULL, path, "flush-cache", strlen("flush-cache"));
+
+ return rc == true ? 0 : -1;
+}
+
static void *init_page(void)
{
void *buffer;
@@ -484,7 +498,7 @@ static int evict_victim(xenpaging_t *pag
else
{
if ( j++ % 1000 == 0 )
- if ( xc_mem_paging_flush_ioemu_cache(paging->mem_event.domain_id) )
+ if ( xenpaging_mem_paging_flush_ioemu_cache(paging) )
ERROR("Error flushing ioemu cache");
}
}

View File

@ -1,161 +0,0 @@
changeset: 23583:235d8fdcb3a9
user: Olaf Hering <olaf@aepfle.de>
date: Fri Jun 10 10:47:11 2011 +0200
files: tools/xenpaging/xc.c tools/xenpaging/xc.h tools/xenpaging/xenpaging.c
description:
xenpaging: drop xc.c, move xc_wait_for_event_or_timeout
Move xc_wait_for_event_or_timeout() into xenpaging and massage it a bit for
further changes in subsequent patches.
Include poll.h instead of sys/poll.h.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Committed-by: Ian Jackson <ian.jackson.citrix.com>
---
tools/xenpaging/xc.c | 40 ------------------------------------
tools/xenpaging/xc.h | 1
tools/xenpaging/xenpaging.c | 48 +++++++++++++++++++++++++++++++++++++++++---
3 files changed, 45 insertions(+), 44 deletions(-)
Index: xen-4.1.2-testing/tools/xenpaging/xc.c
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xc.c
+++ xen-4.1.2-testing/tools/xenpaging/xc.c
@@ -32,46 +32,6 @@
-int xc_wait_for_event_or_timeout(xc_interface *xch, xc_evtchn *xce, unsigned long ms)
-{
- struct pollfd fd = { .fd = xc_evtchn_fd(xce), .events = POLLIN | POLLERR };
- int port;
- int rc;
-
- rc = poll(&fd, 1, ms);
- if ( rc == -1 )
- {
- if (errno == EINTR)
- return 0;
-
- ERROR("Poll exited with an error");
- goto err;
- }
-
- if ( rc == 1 )
- {
- port = xc_evtchn_pending(xce);
- if ( port == -1 )
- {
- ERROR("Failed to read port from event channel");
- goto err;
- }
-
- rc = xc_evtchn_unmask(xce, port);
- if ( rc != 0 )
- {
- ERROR("Failed to unmask event channel port");
- goto err;
- }
- }
- else
- port = -1;
-
- return port;
-
- err:
- return -errno;
-}
Index: xen-4.1.2-testing/tools/xenpaging/xc.h
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xc.h
+++ xen-4.1.2-testing/tools/xenpaging/xc.h
@@ -37,7 +37,6 @@
-int xc_wait_for_event_or_timeout(xc_interface *xch, xc_evtchn *xce, unsigned long ms);
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
@@ -27,6 +27,7 @@
#include <time.h>
#include <signal.h>
#include <unistd.h>
+#include <poll.h>
#include <xc_private.h>
#include <xs.h>
@@ -62,6 +63,47 @@ static int xenpaging_mem_paging_flush_io
return rc == true ? 0 : -1;
}
+static int xenpaging_wait_for_event_or_timeout(xenpaging_t *paging)
+{
+ xc_interface *xch = paging->xc_handle;
+ xc_evtchn *xce = paging->mem_event.xce_handle;
+ struct pollfd fd[1];
+ int port;
+ int rc;
+
+ fd[0].fd = xc_evtchn_fd(xce);
+ fd[0].events = POLLIN | POLLERR;
+ rc = poll(fd, 1, 100);
+ if ( rc < 0 )
+ {
+ if (errno == EINTR)
+ return 0;
+
+ ERROR("Poll exited with an error");
+ return -errno;
+ }
+
+ if ( rc && fd[0].revents & POLLIN )
+ {
+ DPRINTF("Got event from evtchn\n");
+ port = xc_evtchn_pending(xce);
+ if ( port == -1 )
+ {
+ ERROR("Failed to read port from event channel");
+ rc = -1;
+ goto err;
+ }
+
+ rc = xc_evtchn_unmask(xce, port);
+ if ( rc < 0 )
+ {
+ ERROR("Failed to unmask event channel port");
+ }
+ }
+err:
+ return rc;
+}
+
static void *init_page(void)
{
void *buffer;
@@ -598,13 +640,13 @@ int main(int argc, char *argv[])
while ( !interrupted )
{
/* Wait for Xen to signal that a page needs paged in */
- rc = xc_wait_for_event_or_timeout(xch, paging->mem_event.xce_handle, 100);
- if ( rc < -1 )
+ rc = xenpaging_wait_for_event_or_timeout(paging);
+ if ( rc < 0 )
{
ERROR("Error getting event");
goto out;
}
- else if ( rc != -1 )
+ else if ( rc != 0 )
{
DPRINTF("Got event from Xen\n");
}

View File

@ -1,182 +0,0 @@
changeset: 23584:e30cff57b146
user: Olaf Hering <olaf@aepfle.de>
date: Fri Jun 10 10:47:12 2011 +0200
files: tools/xenpaging/Makefile tools/xenpaging/mem_event.h tools/xenpaging/xc.c tools/xenpaging/xc.h tools/xenpaging/xenpaging.c tools/xenpaging/xenpaging.h
description:
xenpaging: drop xc.c, remove xc files
Finally remove xc.c/xc.h and its references since both are empty now.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Committed-by: Ian Jackson <ian.jackson.citrix.com>
---
tools/xenpaging/Makefile | 2 -
tools/xenpaging/mem_event.h | 1
tools/xenpaging/xc.c | 47 --------------------------------------
tools/xenpaging/xc.h | 54 --------------------------------------------
tools/xenpaging/xenpaging.c | 1
tools/xenpaging/xenpaging.h | 1
6 files changed, 1 insertion(+), 105 deletions(-)
Index: xen-4.1.2-testing/tools/xenpaging/Makefile
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/Makefile
+++ xen-4.1.2-testing/tools/xenpaging/Makefile
@@ -9,7 +9,7 @@ LDLIBS += $(LDLIBS_libxenctrl) $(LDLIBS
POLICY = default
SRC :=
-SRCS += file_ops.c xc.c xenpaging.c policy_$(POLICY).c
+SRCS += file_ops.c xenpaging.c policy_$(POLICY).c
CFLAGS += -Werror
CFLAGS += -Wno-unused
Index: xen-4.1.2-testing/tools/xenpaging/mem_event.h
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/mem_event.h
+++ xen-4.1.2-testing/tools/xenpaging/mem_event.h
@@ -25,7 +25,6 @@
#define __XEN_MEM_EVENT_H__
-#include "xc.h"
#include <xc_private.h>
#include <xen/event_channel.h>
Index: xen-4.1.2-testing/tools/xenpaging/xc.c
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xc.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/******************************************************************************
- * tools/xenpaging/lib/xc.c
- *
- * libxc-type add-ons for paging support.
- *
- * Copyright (c) 2009 Citrix Systems, Inc. (Patrick Colp)
- *
- * 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
- */
-
-
-#include <errno.h>
-#include <string.h>
-#include <stdarg.h>
-#include <sys/poll.h>
-#include <xc_private.h>
-#include <xs.h>
-#include "xc.h"
-
-
-
-
-
-
-
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
Index: xen-4.1.2-testing/tools/xenpaging/xc.h
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xc.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/******************************************************************************
- * tools/xenpaging/lib/xc.h
- *
- * libxc add-ons.
- *
- * Copyright (c) 2009 Citrix Systems, Inc. (Patrick Colp)
- *
- * 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 __XC_H__
-#define __XC_H__
-
-
-#include <stdarg.h>
-#include <xc_private.h>
-#include <xen/mem_event.h>
-
-
-
-
-
-
-
-
-
-
-
-
-#endif // __XC_H__
-
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
@@ -35,7 +35,6 @@
#include "xc_bitops.h"
#include "file_ops.h"
-#include "xc.h"
#include "policy.h"
#include "xenpaging.h"
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.h
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.h
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.h
@@ -25,7 +25,6 @@
#define __XEN_PAGING2_H__
-#include "xc.h"
#include <xc_private.h>
#include <xen/event_channel.h>

View File

@ -1,59 +0,0 @@
changeset: 23585:b4d18ac00a46
user: Olaf Hering <olaf@aepfle.de>
date: Fri Jun 10 10:47:14 2011 +0200
files: tools/xenpaging/xenpaging.c
description:
xenpaging: correct dropping of pages to avoid full ring buffer
Doing a one-way channel from Xen to xenpaging is not possible with the
current ring buffer implementation. xenpaging uses the mem_event ring
buffer, which expects request/response pairs to make progress. The
previous patch, which tried to establish a one-way communication from
Xen to xenpaging, stalled the guest once the buffer was filled up with
requests. Correct page-dropping by taking the slow path and let
p2m_mem_paging_resume() consume the response from xenpaging. This makes
room for yet another request/response pair and avoids hanging guests.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Committed-by: Ian Jackson <ian.jackson.citrix.com>
---
tools/xenpaging/xenpaging.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
@@ -690,19 +690,19 @@ int main(int argc, char *argv[])
ERROR("Error populating page");
goto out;
}
+ }
- /* Prepare the response */
- rsp.gfn = req.gfn;
- rsp.p2mt = req.p2mt;
- rsp.vcpu_id = req.vcpu_id;
- rsp.flags = req.flags;
+ /* Prepare the response */
+ rsp.gfn = req.gfn;
+ rsp.p2mt = req.p2mt;
+ rsp.vcpu_id = req.vcpu_id;
+ rsp.flags = req.flags;
- rc = xenpaging_resume_page(paging, &rsp, 1);
- if ( rc != 0 )
- {
- ERROR("Error resuming page");
- goto out;
- }
+ rc = xenpaging_resume_page(paging, &rsp, 1);
+ if ( rc != 0 )
+ {
+ ERROR("Error resuming page");
+ goto out;
}
/* Evict a new page to replace the one we just paged in */

View File

@ -1,49 +0,0 @@
changeset: 23586:bbdd7413a50a
user: Olaf Hering <olaf@aepfle.de>
date: Wed Jun 22 14:47:13 2011 +0100
files: tools/xenpaging/xenpaging.c
description:
xenpaging: do not bounce p2mt back to the hypervisor
do not bounce p2mt back to the hypervisor because p2m_mem_paging_populate()
and p2m_mem_paging_resume() dont make use of p2mt.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Committed-by: Ian Jackson <ian.jackson.citrix.com>
---
tools/xenpaging/xenpaging.c | 4 ----
1 file changed, 4 deletions(-)
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
@@ -694,7 +694,6 @@ int main(int argc, char *argv[])
/* Prepare the response */
rsp.gfn = req.gfn;
- rsp.p2mt = req.p2mt;
rsp.vcpu_id = req.vcpu_id;
rsp.flags = req.flags;
@@ -711,10 +710,8 @@ int main(int argc, char *argv[])
else
{
DPRINTF("page already populated (domain = %d; vcpu = %d;"
- " p2mt = %x;"
" gfn = %"PRIx64"; paused = %d)\n",
paging->mem_event.domain_id, req.vcpu_id,
- req.p2mt,
req.gfn, req.flags & MEM_EVENT_FLAG_VCPU_PAUSED);
/* Tell Xen to resume the vcpu */
@@ -723,7 +720,6 @@ int main(int argc, char *argv[])
{
/* Prepare the response */
rsp.gfn = req.gfn;
- rsp.p2mt = req.p2mt;
rsp.vcpu_id = req.vcpu_id;
rsp.flags = req.flags;

View File

@ -1,32 +0,0 @@
changeset: 23587:926febc8bd98
user: Olaf Hering <olaf@aepfle.de>
date: Fri Jun 10 10:47:16 2011 +0200
files: tools/xenpaging/xenpaging.c
description:
xenpaging: remove srand call
The policy uses now a linear algorithm instead of a random one.
Remove the call to srand().
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Committed-by: Ian Jackson <ian.jackson.citrix.com>
---
tools/xenpaging/xenpaging.c | 3 ---
1 file changed, 3 deletions(-)
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
@@ -581,9 +581,6 @@ int main(int argc, char *argv[])
domain_id = atoi(argv[1]);
num_pages = atoi(argv[2]);
- /* Seed random-number generator */
- srand(time(NULL));
-
/* Initialise domain paging */
paging = xenpaging_init(domain_id);
if ( paging == NULL )

View File

@ -1,78 +0,0 @@
changeset: 23588:e48535e70145
user: Olaf Hering <olaf@aepfle.de>
date: Fri Jun 10 10:47:18 2011 +0200
files: tools/xenpaging/xenpaging.c
description:
xenpaging: remove return values from functions that can not fail
get_request() and put_response() can not fail, remove return value
and update calling functions.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Committed-by: Ian Jackson <ian.jackson.citrix.com>
---
tools/xenpaging/xenpaging.c | 19 ++++---------------
1 file changed, 4 insertions(+), 15 deletions(-)
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
@@ -342,7 +342,7 @@ static int xenpaging_teardown(xenpaging_
return -1;
}
-static int get_request(mem_event_t *mem_event, mem_event_request_t *req)
+static void get_request(mem_event_t *mem_event, mem_event_request_t *req)
{
mem_event_back_ring_t *back_ring;
RING_IDX req_cons;
@@ -357,11 +357,9 @@ static int get_request(mem_event_t *mem_
/* Update ring */
back_ring->req_cons = req_cons;
back_ring->sring->req_event = req_cons + 1;
-
- return 0;
}
-static int put_response(mem_event_t *mem_event, mem_event_response_t *rsp)
+static void put_response(mem_event_t *mem_event, mem_event_response_t *rsp)
{
mem_event_back_ring_t *back_ring;
RING_IDX rsp_prod;
@@ -376,8 +374,6 @@ static int put_response(mem_event_t *mem
/* Update ring */
back_ring->rsp_prod_pvt = rsp_prod;
RING_PUSH_RESPONSES(back_ring);
-
- return 0;
}
static int xenpaging_evict_page(xenpaging_t *paging,
@@ -437,9 +433,7 @@ static int xenpaging_resume_page(xenpagi
int ret;
/* Put the page info on the ring */
- ret = put_response(&paging->mem_event, rsp);
- if ( ret != 0 )
- goto out;
+ put_response(&paging->mem_event, rsp);
/* Notify policy of page being paged in */
if ( notify_policy )
@@ -649,12 +643,7 @@ int main(int argc, char *argv[])
while ( RING_HAS_UNCONSUMED_REQUESTS(&paging->mem_event.back_ring) )
{
- rc = get_request(&paging->mem_event, &req);
- if ( rc != 0 )
- {
- ERROR("Error getting request");
- goto out;
- }
+ get_request(&paging->mem_event, &req);
/* Check if the page has already been paged in */
if ( test_and_clear_bit(req.gfn, paging->bitmap) )

View File

@ -1,34 +0,0 @@
changeset: 23589:49cb290ede16
user: Olaf Hering <olaf@aepfle.de>
date: Fri Jun 10 10:47:19 2011 +0200
files: tools/xenpaging/xenpaging.c
description:
xenpaging: catch xc_mem_paging_resume errors
In the unlikely event that xc_mem_paging_resume() fails, do not overwrite the
error with the return value from xc_evtchn_notify()
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Committed-by: Ian Jackson <ian.jackson.citrix.com>
---
tools/xenpaging/xenpaging.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
@@ -442,8 +442,9 @@ static int xenpaging_resume_page(xenpagi
/* Tell Xen page is ready */
ret = xc_mem_paging_resume(paging->xc_handle, paging->mem_event.domain_id,
rsp->gfn);
- ret = xc_evtchn_notify(paging->mem_event.xce_handle,
- paging->mem_event.port);
+ if ( ret == 0 )
+ ret = xc_evtchn_notify(paging->mem_event.xce_handle,
+ paging->mem_event.port);
out:
return ret;

View File

@ -1,57 +0,0 @@
changeset: 23590:d957acb8bee6
user: Olaf Hering <olaf@aepfle.de>
date: Fri Jun 10 10:47:20 2011 +0200
files: tools/xenpaging/xenpaging.c
description:
xenpaging: remove local domain_id variable
Remove the local domain_id variable, it is already fetched from
paging->mem_event in other places.
Update the sprintf format string to use unsigned argument.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Committed-by: Ian Jackson <ian.jackson.citrix.com>
---
tools/xenpaging/xenpaging.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
@@ -552,7 +552,6 @@ static int evict_victim(xenpaging_t *pag
int main(int argc, char *argv[])
{
struct sigaction act;
- domid_t domain_id;
int num_pages;
xenpaging_t *paging;
xenpaging_victim_t *victims;
@@ -573,11 +572,10 @@ int main(int argc, char *argv[])
return -1;
}
- domain_id = atoi(argv[1]);
num_pages = atoi(argv[2]);
/* Initialise domain paging */
- paging = xenpaging_init(domain_id);
+ paging = xenpaging_init(atoi(argv[1]));
if ( paging == NULL )
{
fprintf(stderr, "Error initialising paging");
@@ -585,10 +583,10 @@ int main(int argc, char *argv[])
}
xch = paging->xc_handle;
- DPRINTF("starting %s %u %d\n", argv[0], domain_id, num_pages);
+ DPRINTF("starting %s %u %d\n", argv[0], paging->mem_event.domain_id, num_pages);
/* Open file */
- sprintf(filename, "page_cache_%d", domain_id);
+ sprintf(filename, "page_cache_%u", paging->mem_event.domain_id);
fd = open(filename, open_flags, open_mode);
if ( fd < 0 )
{

View File

@ -1,129 +0,0 @@
changeset: 23591:4aaa90c1db42
user: Olaf Hering <olaf@aepfle.de>
date: Fri Jun 10 10:47:22 2011 +0200
files: tools/xenpaging/xenpaging.c tools/xenpaging/xenpaging.h
description:
xenpaging: move num_pages into xenpaging struct
Move num_pages into struct xenpaging.
num_pages will be used by the policy in a subsequent patch.
Also remove a memset, the victims array is allocated with calloc.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Committed-by: Ian Jackson <ian.jackson.citrix.com>
---
tools/xenpaging/xenpaging.c | 30 ++++++++++++++----------------
tools/xenpaging/xenpaging.h | 1 +
2 files changed, 15 insertions(+), 16 deletions(-)
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
@@ -128,7 +128,7 @@ static void *init_page(void)
return NULL;
}
-static xenpaging_t *xenpaging_init(domid_t domain_id)
+static xenpaging_t *xenpaging_init(domid_t domain_id, int num_pages)
{
xenpaging_t *paging;
xc_interface *xch;
@@ -256,6 +256,13 @@ static xenpaging_t *xenpaging_init(domid
}
DPRINTF("max_pages = %"PRIx64"\n", paging->domain_info->max_pages);
+ if ( num_pages < 0 || num_pages > paging->domain_info->max_pages )
+ {
+ num_pages = paging->domain_info->max_pages;
+ DPRINTF("setting num_pages to %d\n", num_pages);
+ }
+ paging->num_pages = num_pages;
+
/* Initialise policy */
rc = policy_init(paging);
if ( rc != 0 )
@@ -552,7 +559,6 @@ static int evict_victim(xenpaging_t *pag
int main(int argc, char *argv[])
{
struct sigaction act;
- int num_pages;
xenpaging_t *paging;
xenpaging_victim_t *victims;
mem_event_request_t req;
@@ -572,10 +578,8 @@ int main(int argc, char *argv[])
return -1;
}
- num_pages = atoi(argv[2]);
-
/* Initialise domain paging */
- paging = xenpaging_init(atoi(argv[1]));
+ paging = xenpaging_init(atoi(argv[1]), atoi(argv[2]));
if ( paging == NULL )
{
fprintf(stderr, "Error initialising paging");
@@ -583,7 +587,7 @@ int main(int argc, char *argv[])
}
xch = paging->xc_handle;
- DPRINTF("starting %s %u %d\n", argv[0], paging->mem_event.domain_id, num_pages);
+ DPRINTF("starting %s %u %d\n", argv[0], paging->mem_event.domain_id, paging->num_pages);
/* Open file */
sprintf(filename, "page_cache_%u", paging->mem_event.domain_id);
@@ -594,12 +598,7 @@ int main(int argc, char *argv[])
return 2;
}
- if ( num_pages < 0 || num_pages > paging->domain_info->max_pages )
- {
- num_pages = paging->domain_info->max_pages;
- DPRINTF("setting num_pages to %d\n", num_pages);
- }
- victims = calloc(num_pages, sizeof(xenpaging_victim_t));
+ victims = calloc(paging->num_pages, sizeof(xenpaging_victim_t));
/* ensure that if we get a signal, we'll do cleanup, then exit */
act.sa_handler = close_handler;
@@ -611,8 +610,7 @@ int main(int argc, char *argv[])
sigaction(SIGALRM, &act, NULL);
/* Evict pages */
- memset(victims, 0, sizeof(xenpaging_victim_t) * num_pages);
- for ( i = 0; i < num_pages; i++ )
+ for ( i = 0; i < paging->num_pages; i++ )
{
rc = evict_victim(paging, &victims[i], fd, i);
if ( rc == -ENOSPC )
@@ -648,13 +646,13 @@ int main(int argc, char *argv[])
if ( test_and_clear_bit(req.gfn, paging->bitmap) )
{
/* Find where in the paging file to read from */
- for ( i = 0; i < num_pages; i++ )
+ for ( i = 0; i < paging->num_pages; i++ )
{
if ( victims[i].gfn == req.gfn )
break;
}
- if ( i >= num_pages )
+ if ( i >= paging->num_pages )
{
DPRINTF("Couldn't find page %"PRIx64"\n", req.gfn);
goto out;
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.h
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.h
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.h
@@ -42,6 +42,7 @@ typedef struct xenpaging {
unsigned long *bitmap;
mem_event_t mem_event;
+ int num_pages;
int policy_mru_size;
} xenpaging_t;

View File

@ -1,33 +0,0 @@
changeset: 23592:1e44e75d889c
user: Olaf Hering <olaf@aepfle.de>
date: Fri Jun 10 10:47:23 2011 +0200
files: tools/xenpaging/policy_default.c
description:
xenpaging: start paging in the middle of gfn range
Set the starting gfn to somewhere in the middle of the gfn range to
avoid paging during BIOS startup. This can speedup booting of a guest.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Committed-by: Ian Jackson <ian.jackson.citrix.com>
---
tools/xenpaging/policy_default.c | 4 ++++
1 file changed, 4 insertions(+)
Index: xen-4.1.2-testing/tools/xenpaging/policy_default.c
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/policy_default.c
+++ xen-4.1.2-testing/tools/xenpaging/policy_default.c
@@ -69,6 +69,10 @@ int policy_init(xenpaging_t *paging)
/* Don't page out page 0 */
set_bit(0, bitmap);
+ /* Start in the middle to avoid paging during BIOS startup */
+ current_gfn = max_pages / 2;
+ current_gfn -= paging->num_pages / 2;
+
rc = 0;
out:
return rc;

View File

@ -1,74 +0,0 @@
changeset: 23593:7d72475641fa
user: Olaf Hering <olaf@aepfle.de>
date: Fri Jun 10 10:47:24 2011 +0200
files: tools/xenpaging/xenpaging.c
description:
xenpaging: pass integer to xenpaging_populate_page
Pass gfn as integer to xenpaging_populate_page(). xc_map_foreign_pages()
takes a pointer to a list of gfns, but its a const pointer. So writing
the value back to the caller is not needed.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Committed-by: Ian Jackson <ian.jackson.citrix.com>
---
tools/xenpaging/xenpaging.c | 16 ++++++----------
1 file changed, 6 insertions(+), 10 deletions(-)
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
@@ -458,27 +458,24 @@ static int xenpaging_resume_page(xenpagi
}
static int xenpaging_populate_page(xenpaging_t *paging,
- uint64_t *gfn, int fd, int i)
+ xen_pfn_t gfn, int fd, int i)
{
xc_interface *xch = paging->xc_handle;
- unsigned long _gfn;
void *page;
int ret;
unsigned char oom = 0;
- _gfn = *gfn;
- DPRINTF("populate_page < gfn %lx pageslot %d\n", _gfn, i);
+ DPRINTF("populate_page < gfn %"PRI_xen_pfn" pageslot %d\n", gfn, i);
do
{
/* Tell Xen to allocate a page for the domain */
- ret = xc_mem_paging_prep(xch, paging->mem_event.domain_id,
- _gfn);
+ ret = xc_mem_paging_prep(xch, paging->mem_event.domain_id, gfn);
if ( ret != 0 )
{
if ( errno == ENOMEM )
{
if ( oom++ == 0 )
- DPRINTF("ENOMEM while preparing gfn %lx\n", _gfn);
+ DPRINTF("ENOMEM while preparing gfn %"PRI_xen_pfn"\n", gfn);
sleep(1);
continue;
}
@@ -491,8 +488,7 @@ static int xenpaging_populate_page(xenpa
/* Map page */
ret = -EFAULT;
page = xc_map_foreign_pages(xch, paging->mem_event.domain_id,
- PROT_READ | PROT_WRITE, &_gfn, 1);
- *gfn = _gfn;
+ PROT_READ | PROT_WRITE, &gfn, 1);
if ( page == NULL )
{
ERROR("Error mapping page: page is null");
@@ -667,7 +663,7 @@ int main(int argc, char *argv[])
else
{
/* Populate the page */
- rc = xenpaging_populate_page(paging, &req.gfn, fd, i);
+ rc = xenpaging_populate_page(paging, req.gfn, fd, i);
if ( rc != 0 )
{
ERROR("Error populating page");

View File

@ -1,53 +0,0 @@
changeset: 23594:2fe46305a00d
user: Olaf Hering <olaf@aepfle.de>
date: Fri Jun 10 10:47:25 2011 +0200
files: tools/xenpaging/xenpaging.c
description:
xenpaging: add helper function for unlinking pagefile
Unlink pagefile in the signal handler and also in the exit path.
This does not leave a stale pagefile if an error occoured.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Committed-by: Ian Jackson <ian.jackson.citrix.com>
---
tools/xenpaging/xenpaging.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
@@ -41,11 +41,20 @@
static char filename[80];
static int interrupted;
-static void close_handler(int sig)
+
+static void unlink_pagefile(void)
{
- interrupted = sig;
if ( filename[0] )
+ {
unlink(filename);
+ filename[0] = '\0';
+ }
+}
+
+static void close_handler(int sig)
+{
+ interrupted = sig;
+ unlink_pagefile();
}
static int xenpaging_mem_paging_flush_ioemu_cache(xenpaging_t *paging)
@@ -716,6 +725,7 @@ int main(int argc, char *argv[])
out:
close(fd);
+ unlink_pagefile();
free(victims);
/* Tear down domain paging */

View File

@ -1,96 +0,0 @@
changeset: 23595:389c8bf31688
user: Olaf Hering <olaf@aepfle.de>
date: Fri Jun 10 10:47:27 2011 +0200
files: tools/xenpaging/xenpaging.c
description:
xenpaging: add watch thread to catch guest shutdown
If xenpaging is started manually then no event is sent to xenpaging when
the guest is shutdown or rebooted. Add a watch on the @releaseDomain
node to leave the loop and gracefully shutdown the pager.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Committed-by: Ian Jackson <ian.jackson.citrix.com>
---
tools/xenpaging/xenpaging.c | 40 ++++++++++++++++++++++++++++++++++++++--
1 file changed, 38 insertions(+), 2 deletions(-)
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
@@ -39,6 +39,7 @@
#include "policy.h"
#include "xenpaging.h"
+static char watch_token[16];
static char filename[80];
static int interrupted;
@@ -75,13 +76,19 @@ static int xenpaging_wait_for_event_or_t
{
xc_interface *xch = paging->xc_handle;
xc_evtchn *xce = paging->mem_event.xce_handle;
- struct pollfd fd[1];
+ char **vec;
+ unsigned int num;
+ struct pollfd fd[2];
int port;
int rc;
+ /* Wait for event channel and xenstore */
fd[0].fd = xc_evtchn_fd(xce);
fd[0].events = POLLIN | POLLERR;
- rc = poll(fd, 1, 100);
+ fd[1].fd = xs_fileno(paging->xs_handle);
+ fd[1].events = POLLIN | POLLERR;
+
+ rc = poll(fd, 2, 100);
if ( rc < 0 )
{
if (errno == EINTR)
@@ -91,6 +98,27 @@ static int xenpaging_wait_for_event_or_t
return -errno;
}
+ /* First check for guest shutdown */
+ if ( rc && fd[1].revents & POLLIN )
+ {
+ DPRINTF("Got event from xenstore\n");
+ vec = xs_read_watch(paging->xs_handle, &num);
+ if ( vec )
+ {
+ if ( strcmp(vec[XS_WATCH_TOKEN], watch_token) == 0 )
+ {
+ /* If our guest disappeared, set interrupt flag and fall through */
+ if ( xs_is_domain_introduced(paging->xs_handle, paging->mem_event.domain_id) == false )
+ {
+ xs_unwatch(paging->xs_handle, "@releaseDomain", watch_token);
+ interrupted = SIGQUIT;
+ rc = 0;
+ }
+ }
+ free(vec);
+ }
+ }
+
if ( rc && fd[0].revents & POLLIN )
{
DPRINTF("Got event from evtchn\n");
@@ -165,6 +193,14 @@ static xenpaging_t *xenpaging_init(domid
goto err;
}
+ /* write domain ID to watch so we can ignore other domain shutdowns */
+ snprintf(watch_token, sizeof(watch_token), "%u", domain_id);
+ if ( xs_watch(paging->xs_handle, "@releaseDomain", watch_token) == false )
+ {
+ ERROR("Could not bind to shutdown watch\n");
+ goto err;
+ }
+
p = getenv("XENPAGING_POLICY_MRU_SIZE");
if ( p && *p )
{

View File

@ -1,187 +0,0 @@
changeset: 23596:c49e22648d0e
user: Olaf Hering <olaf@aepfle.de>
date: Fri Jun 10 10:47:28 2011 +0200
files: tools/xenpaging/Makefile tools/xenpaging/pagein.c tools/xenpaging/xenpaging.c tools/xenpaging/xenpaging.h
description:
xenpaging: implement stopping of pager by sending SIGTERM/SIGINT
Write all paged-out pages back into the guest if the pager is
interrupted by ctrl-c or if it receives SIGTERM.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Committed-by: Ian Jackson <ian.jackson.citrix.com>
---
tools/xenpaging/Makefile | 1
tools/xenpaging/pagein.c | 68 ++++++++++++++++++++++++++++++++++++++++++++
tools/xenpaging/xenpaging.c | 35 ++++++++++++++++++++--
tools/xenpaging/xenpaging.h | 3 +
4 files changed, 104 insertions(+), 3 deletions(-)
Index: xen-4.1.2-testing/tools/xenpaging/Makefile
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/Makefile
+++ xen-4.1.2-testing/tools/xenpaging/Makefile
@@ -10,6 +10,7 @@ POLICY = default
SRC :=
SRCS += file_ops.c xenpaging.c policy_$(POLICY).c
+SRCS += pagein.c
CFLAGS += -Werror
CFLAGS += -Wno-unused
Index: xen-4.1.2-testing/tools/xenpaging/pagein.c
===================================================================
--- /dev/null
+++ xen-4.1.2-testing/tools/xenpaging/pagein.c
@@ -0,0 +1,68 @@
+/* Trigger a page-in in a separate thread-of-execution to avoid deadlock */
+#include <pthread.h>
+#include "xc_private.h"
+
+struct page_in_args {
+ domid_t dom;
+ xc_interface *xch;
+};
+
+static struct page_in_args page_in_args;
+static unsigned long page_in_gfn;
+static unsigned int page_in_possible;
+
+static pthread_t page_in_thread;
+static pthread_cond_t page_in_cond = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t page_in_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static void *page_in(void *arg)
+{
+ struct page_in_args *pia = arg;
+ void *page;
+ xen_pfn_t gfn;
+
+ while (1)
+ {
+ pthread_mutex_lock(&page_in_mutex);
+ while (!page_in_gfn)
+ pthread_cond_wait(&page_in_cond, &page_in_mutex);
+ gfn = page_in_gfn;
+ page_in_gfn = 0;
+ pthread_mutex_unlock(&page_in_mutex);
+
+ /* Ignore errors */
+ page = xc_map_foreign_pages(pia->xch, pia->dom, PROT_READ, &gfn, 1);
+ if (page)
+ munmap(page, PAGE_SIZE);
+ }
+ page_in_possible = 0;
+ pthread_exit(NULL);
+}
+
+void page_in_trigger(unsigned long gfn)
+{
+ if (!page_in_possible)
+ return;
+
+ pthread_mutex_lock(&page_in_mutex);
+ page_in_gfn = gfn;
+ pthread_mutex_unlock(&page_in_mutex);
+ pthread_cond_signal(&page_in_cond);
+}
+
+void create_page_in_thread(domid_t domain_id, xc_interface *xch)
+{
+ page_in_args.dom = domain_id;
+ page_in_args.xch = xch;
+ if (pthread_create(&page_in_thread, NULL, page_in, &page_in_args) == 0)
+ page_in_possible = 1;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
@@ -650,6 +650,9 @@ int main(int argc, char *argv[])
sigaction(SIGINT, &act, NULL);
sigaction(SIGALRM, &act, NULL);
+ /* listen for page-in events to stop pager */
+ create_page_in_thread(paging->mem_event.domain_id, xch);
+
/* Evict pages */
for ( i = 0; i < paging->num_pages; i++ )
{
@@ -665,7 +668,7 @@ int main(int argc, char *argv[])
DPRINTF("%d pages evicted. Done.\n", i);
/* Swap pages in and out */
- while ( !interrupted )
+ while ( 1 )
{
/* Wait for Xen to signal that a page needs paged in */
rc = xenpaging_wait_for_event_or_timeout(paging);
@@ -728,8 +731,12 @@ int main(int argc, char *argv[])
goto out;
}
- /* Evict a new page to replace the one we just paged in */
- evict_victim(paging, &victims[i], fd, i);
+ /* Evict a new page to replace the one we just paged in,
+ * or clear this pagefile slot on exit */
+ if ( interrupted )
+ victims[i].gfn = INVALID_MFN;
+ else
+ evict_victim(paging, &victims[i], fd, i);
}
else
{
@@ -756,6 +763,28 @@ int main(int argc, char *argv[])
}
}
}
+
+ /* Write all pages back into the guest */
+ if ( interrupted == SIGTERM || interrupted == SIGINT )
+ {
+ for ( i = 0; i < paging->domain_info->max_pages; i++ )
+ {
+ if ( test_bit(i, paging->bitmap) )
+ {
+ page_in_trigger(i);
+ break;
+ }
+ }
+ /* If no more pages to process, exit loop */
+ if ( i == paging->domain_info->max_pages )
+ break;
+ }
+ else
+ {
+ /* Exit on any other signal */
+ if ( interrupted )
+ break;
+ }
}
DPRINTF("xenpaging got signal %d\n", interrupted);
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.h
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.h
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.h
@@ -53,6 +53,9 @@ typedef struct xenpaging_victim {
} xenpaging_victim_t;
+extern void create_page_in_thread(domid_t domain_id, xc_interface *xch);
+extern void page_in_trigger(unsigned long gfn);
+
#endif // __XEN_PAGING_H__

View File

@ -1,123 +0,0 @@
changeset: 23597:3dcb553f3ba9
user: Olaf Hering <olaf@aepfle.de>
date: Fri Jun 10 10:47:29 2011 +0200
files: tools/xenpaging/mem_event.h tools/xenpaging/xenpaging.c tools/xenpaging/xenpaging.h
description:
xenpaging: remove private mem_event.h
tools/xenpaging/mem_event.h is only included in xenpaging.h.
Add the contents into that file and remove mem_event.h.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Committed-by: Ian Jackson <ian.jackson.citrix.com>
---
tools/xenpaging/mem_event.h | 57 --------------------------------------------
tools/xenpaging/xenpaging.c | 3 --
tools/xenpaging/xenpaging.h | 11 ++++++--
3 files changed, 8 insertions(+), 63 deletions(-)
Index: xen-4.1.2-testing/tools/xenpaging/mem_event.h
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/mem_event.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/******************************************************************************
- * tools/xenpaging/mem_event.h
- *
- * Memory event structures.
- *
- * Copyright (c) 2009 Citrix Systems, Inc. (Patrick Colp)
- *
- * 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_MEM_EVENT_H__
-#define __XEN_MEM_EVENT_H__
-
-
-#include <xc_private.h>
-
-#include <xen/event_channel.h>
-#include <xen/mem_event.h>
-
-
-
-
-typedef struct mem_event {
- domid_t domain_id;
- xc_evtchn *xce_handle;
- int port;
- mem_event_back_ring_t back_ring;
- mem_event_shared_page_t *shared_page;
- void *ring_page;
-} mem_event_t;
-
-
-#endif // __XEN_MEM_EVENT_H__
-
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
@@ -31,11 +31,8 @@
#include <xc_private.h>
#include <xs.h>
-#include <xen/mem_event.h>
-
#include "xc_bitops.h"
#include "file_ops.h"
-
#include "policy.h"
#include "xenpaging.h"
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.h
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.h
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.h
@@ -26,12 +26,17 @@
#include <xc_private.h>
-
#include <xen/event_channel.h>
#include <xen/mem_event.h>
-#include "mem_event.h"
-
+typedef struct mem_event {
+ domid_t domain_id;
+ xc_evtchn *xce_handle;
+ int port;
+ mem_event_back_ring_t back_ring;
+ mem_event_shared_page_t *shared_page;
+ void *ring_page;
+} mem_event_t;
typedef struct xenpaging {
xc_interface *xc_handle;

View File

@ -1,30 +0,0 @@
changeset: 23599:d3027374a8c0
user: Tim Deegan <Tim.Deegan@citrix.com>
date: Mon Jun 27 14:48:57 2011 +0100
files: tools/xenpaging/Makefile
description:
tools: fix build after recent xenpaging changes
xenpaging now uses pthreads, so must link appropriately.
Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com>
Committed-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
tools/xenpaging/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: xen-4.1.2-testing/tools/xenpaging/Makefile
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/Makefile
+++ xen-4.1.2-testing/tools/xenpaging/Makefile
@@ -4,7 +4,7 @@ include $(XEN_ROOT)/tools/Rules.mk
CFLAGS += -I $(XEN_XC)
CFLAGS += -I ./
CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenstore)
-LDLIBS += $(LDLIBS_libxenctrl) $(LDLIBS_libxenstore)
+LDLIBS += $(LDLIBS_libxenctrl) $(LDLIBS_libxenstore) -pthread
POLICY = default

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,850 +0,0 @@
References: fate#311376, fate#311529, bnc#578927, bnc#628554
# HG changeset patch
# User Jan Beulich <jbeulich@novell.com>
# Date 1309249249 -3600
# Node ID d19e778442673050bba8ea8cf61585902ff81162
# Parent 8b7d00f2abb21b504f6f8e1a6cc235cee8eb0858
x86-64: EFI runtime code
This allows Dom0 access to all suitable EFI runtime services. The
actual calls into EFI are done in "physical" mode, as entering virtual
mode has been determined to be incompatible with kexec (EFI's
SetVirtualAddressMap() can be called only once, and hence the
secondary kernel can't establish its mappings). ("Physical" mode here
being quoted because this is a mode with paging enabled [otherwise
64-bit mode wouldn't work] but all mappings being 1:1.)
Signed-off-by: Jan Beulich <jbeulich@novell.com>
# HG changeset patch
# User Jan Beulich <jbeulich@novell.com>
# Date 1309549303 -3600
# Node ID 7631c461132000979f05759705c055eb3c975c0b
# Parent 335e96664589dd14dfce7ef72e3fee71ad9c39e3
x86/EFI: fix interrupt and fault handling during runtime services calls
The missing piece was the setting up of an accessible GDT prior to
switching page tables (and reverting to the original setting after
having established the normal page tables again afterwards).
Signed-off-by: Jan Beulich <jbeulich@novell.com>
# HG changeset patch
# User Jan Beulich <jbeulich@novell.com>
# Date 1311081015 -3600
# Node ID 7bc5825e471db5a3a989f47d21334ef63a6b5610
# Parent 0ccb94d533d6feaece5d48eb1bbfb9ae1b6174c1
x86-64/EFI: don't call EfiResetSystem() from machine_halt()
c/s 23615:d19e77844267 was a little too eager in adding calls to EFI
runtime services: machine_halt() doesn't really want to power off the
machine, but that's what EfiResetSystem(EfiResetShutdown, ...) (called
through efi_halt_system()) does.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Index: xen-4.1.2-testing/xen/arch/x86/efi/boot.c
===================================================================
--- xen-4.1.2-testing.orig/xen/arch/x86/efi/boot.c
+++ xen-4.1.2-testing/xen/arch/x86/efi/boot.c
@@ -16,6 +16,7 @@
#include <xen/stringify.h>
#include <xen/vga.h>
#include <asm/e820.h>
+#include <asm/mm.h>
#include <asm/msr.h>
#include <asm/processor.h>
@@ -1149,6 +1150,53 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SY
for( ; ; ); /* not reached */
}
+static __init void copy_mapping(unsigned long mfn, unsigned long end,
+ bool_t (*is_valid)(unsigned long smfn,
+ unsigned long emfn))
+{
+ unsigned long next;
+
+ for ( ; mfn < end; mfn = next )
+ {
+ l4_pgentry_t l4e = efi_l4_pgtable[l4_table_offset(mfn << PAGE_SHIFT)];
+ l3_pgentry_t *l3src, *l3dst;
+ unsigned long va = (unsigned long)mfn_to_virt(mfn);
+
+ next = mfn + (1UL << (L3_PAGETABLE_SHIFT - PAGE_SHIFT));
+ if ( !is_valid(mfn, min(next, end)) )
+ continue;
+ if ( !(l4e_get_flags(l4e) & _PAGE_PRESENT) )
+ {
+ l3dst = alloc_xen_pagetable();
+ BUG_ON(!l3dst);
+ clear_page(l3dst);
+ efi_l4_pgtable[l4_table_offset(mfn << PAGE_SHIFT)] =
+ l4e_from_paddr(virt_to_maddr(l3dst), __PAGE_HYPERVISOR);
+ }
+ else
+ l3dst = l4e_to_l3e(l4e);
+ l3src = l4e_to_l3e(idle_pg_table[l4_table_offset(va)]);
+ l3dst[l3_table_offset(mfn << PAGE_SHIFT)] = l3src[l3_table_offset(va)];
+ }
+}
+
+static bool_t __init ram_range_valid(unsigned long smfn, unsigned long emfn)
+{
+ unsigned long sz = pfn_to_pdx(emfn - 1) / PDX_GROUP_COUNT + 1;
+
+ return !(smfn & pfn_hole_mask) &&
+ find_next_bit(pdx_group_valid, sz,
+ pfn_to_pdx(smfn) / PDX_GROUP_COUNT) < sz;
+}
+
+static bool_t __init rt_range_valid(unsigned long smfn, unsigned long emfn)
+{
+ return 1;
+}
+
+#define INVALID_VIRTUAL_ADDRESS (0xBAAADUL << \
+ (EFI_PAGE_SHIFT + BITS_PER_LONG - 32))
+
void __init efi_init_memory(void)
{
unsigned int i;
@@ -1169,11 +1217,11 @@ void __init efi_init_memory(void)
if ( !(desc->Attribute & EFI_MEMORY_RUNTIME) )
continue;
+ desc->VirtualStart = INVALID_VIRTUAL_ADDRESS;
+
smfn = PFN_DOWN(desc->PhysicalStart);
emfn = PFN_UP(desc->PhysicalStart + len);
- desc->VirtualStart = 0xBAAADUL << (EFI_PAGE_SHIFT + BITS_PER_LONG - 32);
-
if ( desc->Attribute & EFI_MEMORY_WB )
/* nothing */;
else if ( desc->Attribute & EFI_MEMORY_WT )
@@ -1217,5 +1265,34 @@ void __init efi_init_memory(void)
#if 0 /* Incompatible with kexec. */
efi_rs->SetVirtualAddressMap(efi_memmap_size, efi_mdesc_size,
mdesc_ver, efi_memmap);
+#else
+ /* Set up 1:1 page tables to do runtime calls in "physical" mode. */
+ efi_l4_pgtable = alloc_xen_pagetable();
+ BUG_ON(!efi_l4_pgtable);
+ clear_page(efi_l4_pgtable);
+
+ copy_mapping(0, max_page, ram_range_valid);
+
+ /* Insert non-RAM runtime mappings. */
+ for ( i = 0; i < efi_memmap_size; i += efi_mdesc_size )
+ {
+ const EFI_MEMORY_DESCRIPTOR *desc = efi_memmap + i;
+
+ if ( desc->Attribute & EFI_MEMORY_RUNTIME )
+ {
+ if ( desc->VirtualStart != INVALID_VIRTUAL_ADDRESS )
+ copy_mapping(PFN_DOWN(desc->PhysicalStart),
+ PFN_UP(desc->PhysicalStart +
+ (desc->NumberOfPages << EFI_PAGE_SHIFT)),
+ rt_range_valid);
+ else
+ /* XXX */;
+ }
+ }
+
+ /* Insert Xen mappings. */
+ for ( i = l4_table_offset(HYPERVISOR_VIRT_START);
+ i < l4_table_offset(HYPERVISOR_VIRT_END); ++i )
+ efi_l4_pgtable[i] = idle_pg_table[i];
#endif
}
Index: xen-4.1.2-testing/xen/arch/x86/efi/compat.c
===================================================================
--- xen-4.1.2-testing.orig/xen/arch/x86/efi/compat.c
+++ xen-4.1.2-testing/xen/arch/x86/efi/compat.c
@@ -4,13 +4,27 @@
#define efi_get_info efi_compat_get_info
#define xenpf_efi_info compat_pf_efi_info
+#define efi_runtime_call efi_compat_runtime_call
+#define xenpf_efi_runtime_call compat_pf_efi_runtime_call
+
+#define xenpf_efi_guid compat_pf_efi_guid
+#define xenpf_efi_time compat_pf_efi_time
+
#define COMPAT
#undef DEFINE_XEN_GUEST_HANDLE
#define DEFINE_XEN_GUEST_HANDLE DEFINE_COMPAT_HANDLE
+#undef XEN_GUEST_HANDLE
+#define XEN_GUEST_HANDLE COMPAT_HANDLE
#undef guest_handle_okay
#define guest_handle_okay compat_handle_okay
#undef guest_handle_cast
#define guest_handle_cast compat_handle_cast
+#undef __copy_from_guest
+#define __copy_from_guest __copy_from_compat
+#undef copy_from_guest_offset
+#define copy_from_guest_offset copy_from_compat_offset
+#undef copy_to_guest
+#define copy_to_guest copy_to_compat
#undef __copy_to_guest_offset
#define __copy_to_guest_offset __copy_to_compat_offset
#include "runtime.c"
Index: xen-4.1.2-testing/xen/arch/x86/efi/efi.h
===================================================================
--- xen-4.1.2-testing.orig/xen/arch/x86/efi/efi.h
+++ xen-4.1.2-testing/xen/arch/x86/efi/efi.h
@@ -5,6 +5,8 @@
#include <efi/efidevp.h>
#include <efi/efiapi.h>
#include <xen/efi.h>
+#include <xen/spinlock.h>
+#include <asm/page.h>
extern unsigned int efi_num_ct;
extern EFI_CONFIGURATION_TABLE *efi_ct;
@@ -16,3 +18,8 @@ extern EFI_RUNTIME_SERVICES *efi_rs;
extern UINTN efi_memmap_size, efi_mdesc_size;
extern void *efi_memmap;
+
+extern l4_pgentry_t *efi_l4_pgtable;
+
+unsigned long efi_rs_enter(void);
+void efi_rs_leave(unsigned long);
Index: xen-4.1.2-testing/xen/arch/x86/efi/runtime.c
===================================================================
--- xen-4.1.2-testing.orig/xen/arch/x86/efi/runtime.c
+++ xen-4.1.2-testing/xen/arch/x86/efi/runtime.c
@@ -2,6 +2,7 @@
#include <xen/cache.h>
#include <xen/errno.h>
#include <xen/guest_access.h>
+#include <xen/time.h>
DEFINE_XEN_GUEST_HANDLE(CHAR16);
@@ -19,6 +20,7 @@ unsigned int __read_mostly efi_fw_revisi
const CHAR16 *__read_mostly efi_fw_vendor;
EFI_RUNTIME_SERVICES *__read_mostly efi_rs;
+static DEFINE_SPINLOCK(efi_rs_lock);
UINTN __read_mostly efi_memmap_size;
UINTN __read_mostly efi_mdesc_size;
@@ -30,6 +32,88 @@ struct efi __read_mostly efi = {
.smbios = EFI_INVALID_TABLE_ADDR,
};
+l4_pgentry_t *__read_mostly efi_l4_pgtable;
+
+unsigned long efi_rs_enter(void)
+{
+ unsigned long cr3 = read_cr3();
+
+ spin_lock(&efi_rs_lock);
+
+ /* prevent fixup_page_fault() from doing anything */
+ irq_enter();
+
+ if ( !is_hvm_vcpu(current) && !is_idle_vcpu(current) )
+ {
+ struct desc_ptr gdt_desc = {
+ .limit = LAST_RESERVED_GDT_BYTE,
+ .base = (unsigned long)(per_cpu(gdt_table, smp_processor_id()) -
+ FIRST_RESERVED_GDT_ENTRY)
+ };
+
+ asm volatile ( "lgdt %0" : : "m" (gdt_desc) );
+ }
+
+ write_cr3(virt_to_maddr(efi_l4_pgtable));
+
+ return cr3;
+}
+
+void efi_rs_leave(unsigned long cr3)
+{
+ write_cr3(cr3);
+ if ( !is_hvm_vcpu(current) && !is_idle_vcpu(current) )
+ {
+ struct desc_ptr gdt_desc = {
+ .limit = LAST_RESERVED_GDT_BYTE,
+ .base = GDT_VIRT_START(current)
+ };
+
+ asm volatile ( "lgdt %0" : : "m" (gdt_desc) );
+ }
+ irq_exit();
+ spin_unlock(&efi_rs_lock);
+}
+
+unsigned long efi_get_time(void)
+{
+ EFI_TIME time;
+ EFI_STATUS status;
+ unsigned long cr3 = efi_rs_enter();
+
+ status = efi_rs->GetTime(&time, NULL);
+ efi_rs_leave(cr3);
+
+ if ( EFI_ERROR(status) )
+ return 0;
+
+ return mktime(time.Year, time.Month, time.Day,
+ time.Hour, time.Minute, time.Second);
+}
+
+void efi_halt_system(void)
+{
+ EFI_STATUS status;
+ unsigned long cr3 = efi_rs_enter();
+
+ status = efi_rs->ResetSystem(EfiResetShutdown, EFI_SUCCESS, 0, NULL);
+ efi_rs_leave(cr3);
+
+ printk(XENLOG_WARNING "EFI: could not halt system (%#lx)\n", status);
+}
+
+void efi_reset_system(bool_t warm)
+{
+ EFI_STATUS status;
+ unsigned long cr3 = efi_rs_enter();
+
+ status = efi_rs->ResetSystem(warm ? EfiResetWarm : EfiResetCold,
+ EFI_SUCCESS, 0, NULL);
+ efi_rs_leave(cr3);
+
+ printk(XENLOG_WARNING "EFI: could not reset system (%#lx)\n", status);
+}
+
#endif
int efi_get_info(uint32_t idx, union xenpf_efi_info *info)
@@ -86,3 +170,267 @@ int efi_get_info(uint32_t idx, union xen
return 0;
}
+
+static long gwstrlen(XEN_GUEST_HANDLE(CHAR16) str)
+{
+ unsigned long len;
+
+ for ( len = 0; ; ++len )
+ {
+ CHAR16 c;
+
+ if ( copy_from_guest_offset(&c, str, len, 1) )
+ return -EFAULT;
+ if ( !c )
+ break;
+ }
+
+ return len;
+}
+
+static inline EFI_TIME *cast_time(struct xenpf_efi_time *time)
+{
+#define chk_fld(F, f) \
+ BUILD_BUG_ON(sizeof(cast_time(NULL)->F) != sizeof(time->f) || \
+ offsetof(EFI_TIME, F) != offsetof(struct xenpf_efi_time, f))
+ chk_fld(Year, year);
+ chk_fld(Month, month);
+ chk_fld(Day, day);
+ chk_fld(Hour, hour);
+ chk_fld(Minute, min);
+ chk_fld(Second, sec);
+ chk_fld(Nanosecond, ns);
+ chk_fld(TimeZone, tz);
+ chk_fld(Daylight, daylight);
+#undef chk_fld
+ return (void *)time;
+}
+
+static inline EFI_GUID *cast_guid(struct xenpf_efi_guid *guid)
+{
+#define chk_fld(n) \
+ BUILD_BUG_ON(sizeof(cast_guid(NULL)->Data##n) != sizeof(guid->data##n) || \
+ offsetof(EFI_GUID, Data##n) != \
+ offsetof(struct xenpf_efi_guid, data##n))
+ chk_fld(1);
+ chk_fld(2);
+ chk_fld(3);
+ chk_fld(4);
+#undef chk_fld
+ return (void *)guid;
+}
+
+int efi_runtime_call(struct xenpf_efi_runtime_call *op)
+{
+ unsigned long cr3;
+ EFI_STATUS status = EFI_NOT_STARTED;
+ int rc = 0;
+
+ switch ( op->function )
+ {
+ case XEN_EFI_get_time:
+ {
+ EFI_TIME_CAPABILITIES caps;
+
+ if ( op->misc )
+ return -EINVAL;
+
+ cr3 = efi_rs_enter();
+ status = efi_rs->GetTime(cast_time(&op->u.get_time.time), &caps);
+ efi_rs_leave(cr3);
+
+ if ( !EFI_ERROR(status) )
+ {
+ op->u.get_time.resolution = caps.Resolution;
+ op->u.get_time.accuracy = caps.Accuracy;
+ if ( caps.SetsToZero )
+ op->misc = XEN_EFI_GET_TIME_SET_CLEARS_NS;
+ }
+ }
+ break;
+
+ case XEN_EFI_set_time:
+ if ( op->misc )
+ return -EINVAL;
+
+ cr3 = efi_rs_enter();
+ status = efi_rs->SetTime(cast_time(&op->u.set_time));
+ efi_rs_leave(cr3);
+ break;
+
+ case XEN_EFI_get_wakeup_time:
+ {
+ BOOLEAN enabled, pending;
+
+ if ( op->misc )
+ return -EINVAL;
+
+ cr3 = efi_rs_enter();
+ status = efi_rs->GetWakeupTime(&enabled, &pending,
+ cast_time(&op->u.get_wakeup_time));
+ efi_rs_leave(cr3);
+
+ if ( !EFI_ERROR(status) )
+ {
+ if ( enabled )
+ op->misc |= XEN_EFI_GET_WAKEUP_TIME_ENABLED;
+ if ( pending )
+ op->misc |= XEN_EFI_GET_WAKEUP_TIME_PENDING;
+ }
+ }
+ break;
+
+ case XEN_EFI_set_wakeup_time:
+ if ( op->misc & ~(XEN_EFI_SET_WAKEUP_TIME_ENABLE |
+ XEN_EFI_SET_WAKEUP_TIME_ENABLE_ONLY) )
+ return -EINVAL;
+
+ cr3 = efi_rs_enter();
+ status = efi_rs->SetWakeupTime(!!(op->misc &
+ XEN_EFI_SET_WAKEUP_TIME_ENABLE),
+ (op->misc &
+ XEN_EFI_SET_WAKEUP_TIME_ENABLE_ONLY) ?
+ NULL :
+ cast_time(&op->u.set_wakeup_time));
+ efi_rs_leave(cr3);
+
+ op->misc = 0;
+ break;
+
+ case XEN_EFI_get_next_high_monotonic_count:
+ if ( op->misc )
+ return -EINVAL;
+
+ cr3 = efi_rs_enter();
+ status = efi_rs->GetNextHighMonotonicCount(&op->misc);
+ efi_rs_leave(cr3);
+ break;
+
+ case XEN_EFI_get_variable:
+ {
+ CHAR16 *name;
+ long len;
+ unsigned char *data;
+ UINTN size;
+
+ if ( op->misc )
+ return -EINVAL;
+
+ len = gwstrlen(guest_handle_cast(op->u.get_variable.name, CHAR16));
+ if ( len < 0 )
+ return len;
+ name = xmalloc_array(CHAR16, ++len);
+ if ( !name )
+ return -ENOMEM;
+ __copy_from_guest(name, op->u.get_variable.name, len);
+
+ size = op->u.get_variable.size;
+ if ( size )
+ {
+ data = xmalloc_bytes(size);
+ if ( !data )
+ {
+ xfree(name);
+ return -ENOMEM;
+ }
+ }
+ else
+ data = NULL;
+
+ cr3 = efi_rs_enter();
+ status = efi_rs->GetVariable(
+ name, cast_guid(&op->u.get_variable.vendor_guid),
+ &op->misc, &size, data);
+ efi_rs_leave(cr3);
+
+ if ( !EFI_ERROR(status) &&
+ copy_to_guest(op->u.get_variable.data, data, size) )
+ rc = -EFAULT;
+ op->u.get_variable.size = size;
+
+ xfree(data);
+ xfree(name);
+ }
+ break;
+
+ case XEN_EFI_set_variable:
+ {
+ CHAR16 *name;
+ long len;
+ unsigned char *data;
+
+ if ( op->misc )
+ return -EINVAL;
+
+ len = gwstrlen(guest_handle_cast(op->u.set_variable.name, CHAR16));
+ if ( len < 0 )
+ return len;
+ name = xmalloc_array(CHAR16, ++len);
+ if ( !name )
+ return -ENOMEM;
+ __copy_from_guest(name, op->u.set_variable.name, len);
+
+ data = xmalloc_bytes(op->u.set_variable.size);
+ if ( !data )
+ rc = -ENOMEM;
+ else if ( copy_from_guest(data, op->u.set_variable.data,
+ op->u.set_variable.size) )
+ rc = -EFAULT;
+ else
+ {
+ cr3 = efi_rs_enter();
+ status = efi_rs->SetVariable(
+ name, cast_guid(&op->u.set_variable.vendor_guid),
+ op->misc, op->u.set_variable.size, data);
+ efi_rs_leave(cr3);
+ }
+
+ xfree(data);
+ xfree(name);
+ }
+ break;
+
+ case XEN_EFI_get_next_variable_name:
+ {
+ union {
+ CHAR16 *str;
+ unsigned char *raw;
+ } name;
+ UINTN size;
+
+ if ( op->misc )
+ return -EINVAL;
+
+ size = op->u.get_next_variable_name.size;
+ name.raw = xmalloc_bytes(size);
+ if ( !name.raw )
+ return -ENOMEM;
+ copy_from_guest(name.raw, op->u.get_next_variable_name.name, size);
+
+ cr3 = efi_rs_enter();
+ status = efi_rs->GetNextVariableName(
+ &size, name.str,
+ cast_guid(&op->u.get_next_variable_name.vendor_guid));
+ efi_rs_leave(cr3);
+
+ if ( !EFI_ERROR(status) &&
+ copy_to_guest(op->u.get_next_variable_name.name, name.raw, size) )
+ rc = -EFAULT;
+ op->u.get_next_variable_name.size = size;
+
+ xfree(name.raw);
+ }
+ break;
+
+ default:
+ return -ENOSYS;
+ }
+
+#ifndef COMPAT
+ op->status = status;
+#else
+ op->status = (status & 0x3fffffff) | (status >> 62);
+#endif
+
+ return rc;
+}
Index: xen-4.1.2-testing/xen/arch/x86/efi/stub.c
===================================================================
--- xen-4.1.2-testing.orig/xen/arch/x86/efi/stub.c
+++ xen-4.1.2-testing/xen/arch/x86/efi/stub.c
@@ -1,6 +1,7 @@
#include <xen/efi.h>
#include <xen/errno.h>
#include <xen/init.h>
+#include <asm/bug.h>
#ifndef efi_enabled
const bool_t efi_enabled = 0;
@@ -8,6 +9,15 @@ const bool_t efi_enabled = 0;
void __init efi_init_memory(void) { }
+unsigned long efi_get_time(void)
+{
+ BUG();
+ return 0;
+}
+
+void efi_halt_system(void) { }
+void efi_reset_system(bool_t warm) { }
+
int efi_get_info(uint32_t idx, union xenpf_efi_info *info)
{
return -ENOSYS;
@@ -15,3 +25,11 @@ int efi_get_info(uint32_t idx, union xen
int efi_compat_get_info(uint32_t idx, union compat_pf_efi_info *)
__attribute__((__alias__("efi_get_info")));
+
+int efi_runtime_call(struct xenpf_efi_runtime_call *op)
+{
+ return -ENOSYS;
+}
+
+int efi_compat_runtime_call(struct compat_pf_efi_runtime_call *)
+ __attribute__((__alias__("efi_runtime_call")));
Index: xen-4.1.2-testing/xen/arch/x86/platform_hypercall.c
===================================================================
--- xen-4.1.2-testing.orig/xen/arch/x86/platform_hypercall.c
+++ xen-4.1.2-testing/xen/arch/x86/platform_hypercall.c
@@ -309,6 +309,17 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
}
break;
+ case XENPF_efi_runtime_call:
+ ret = xsm_efi_runtime_call();
+ if ( ret )
+ break;
+
+ ret = efi_runtime_call(&op->u.efi_runtime_call);
+ if ( ret == 0 &&
+ copy_field_to_guest(u_xenpf_op, op, u.efi_runtime_call) )
+ ret = -EFAULT;
+ break;
+
case XENPF_enter_acpi_sleep:
ret = xsm_acpi_sleep();
if ( ret )
Index: xen-4.1.2-testing/xen/arch/x86/shutdown.c
===================================================================
--- xen-4.1.2-testing.orig/xen/arch/x86/shutdown.c
+++ xen-4.1.2-testing/xen/arch/x86/shutdown.c
@@ -15,6 +15,7 @@
#include <xen/console.h>
#include <xen/shutdown.h>
#include <xen/acpi.h>
+#include <xen/efi.h>
#include <asm/msr.h>
#include <asm/regs.h>
#include <asm/mc146818rtc.h>
@@ -337,6 +338,8 @@ void machine_restart(unsigned int delay_
if ( tboot_in_measured_env() )
tboot_shutdown(TB_SHUTDOWN_REBOOT);
+ efi_reset_system(reboot_mode != 0);
+
/* Rebooting needs to touch the page at absolute address 0. */
*((unsigned short *)__va(0x472)) = reboot_mode;
Index: xen-4.1.2-testing/xen/arch/x86/time.c
===================================================================
--- xen-4.1.2-testing.orig/xen/arch/x86/time.c
+++ xen-4.1.2-testing/xen/arch/x86/time.c
@@ -21,6 +21,7 @@
#include <xen/smp.h>
#include <xen/irq.h>
#include <xen/softirq.h>
+#include <xen/efi.h>
#include <xen/cpuidle.h>
#include <xen/keyhandler.h>
#include <xen/guest_access.h>
@@ -756,6 +757,13 @@ static unsigned long get_cmos_time(void)
unsigned long res, flags;
int i;
+ if ( efi_enabled )
+ {
+ res = efi_get_time();
+ if ( res )
+ return res;
+ }
+
spin_lock_irqsave(&rtc_lock, flags);
/* read RTC exactly on falling edge of update flag */
Index: xen-4.1.2-testing/xen/arch/x86/x86_64/platform_hypercall.c
===================================================================
--- xen-4.1.2-testing.orig/xen/arch/x86/x86_64/platform_hypercall.c
+++ xen-4.1.2-testing/xen/arch/x86/x86_64/platform_hypercall.c
@@ -12,6 +12,7 @@ DEFINE_XEN_GUEST_HANDLE(compat_platform_
#define do_platform_op(x) compat_platform_op(_##x)
#define efi_get_info efi_compat_get_info
+#define efi_runtime_call(x) efi_compat_runtime_call(x)
#define xen_processor_px compat_processor_px
#define xen_processor_px_t compat_processor_px_t
Index: xen-4.1.2-testing/xen/include/public/platform.h
===================================================================
--- xen-4.1.2-testing.orig/xen/include/public/platform.h
+++ xen-4.1.2-testing/xen/include/public/platform.h
@@ -114,6 +114,77 @@ struct xenpf_platform_quirk {
typedef struct xenpf_platform_quirk xenpf_platform_quirk_t;
DEFINE_XEN_GUEST_HANDLE(xenpf_platform_quirk_t);
+#define XENPF_efi_runtime_call 49
+#define XEN_EFI_get_time 1
+#define XEN_EFI_set_time 2
+#define XEN_EFI_get_wakeup_time 3
+#define XEN_EFI_set_wakeup_time 4
+#define XEN_EFI_get_next_high_monotonic_count 5
+#define XEN_EFI_get_variable 6
+#define XEN_EFI_set_variable 7
+#define XEN_EFI_get_next_variable_name 8
+struct xenpf_efi_runtime_call {
+ uint32_t function;
+ /*
+ * This field is generally used for per sub-function flags (defined
+ * below), except for the XEN_EFI_get_next_high_monotonic_count case,
+ * where it holds the single returned value.
+ */
+ uint32_t misc;
+ unsigned long status;
+ union {
+#define XEN_EFI_GET_TIME_SET_CLEARS_NS 0x00000001
+ struct {
+ struct xenpf_efi_time {
+ uint16_t year;
+ uint8_t month;
+ uint8_t day;
+ uint8_t hour;
+ uint8_t min;
+ uint8_t sec;
+ uint32_t ns;
+ int16_t tz;
+ uint8_t daylight;
+ } time;
+ uint32_t resolution;
+ uint32_t accuracy;
+ } get_time;
+
+ struct xenpf_efi_time set_time;
+
+#define XEN_EFI_GET_WAKEUP_TIME_ENABLED 0x00000001
+#define XEN_EFI_GET_WAKEUP_TIME_PENDING 0x00000002
+ struct xenpf_efi_time get_wakeup_time;
+
+#define XEN_EFI_SET_WAKEUP_TIME_ENABLE 0x00000001
+#define XEN_EFI_SET_WAKEUP_TIME_ENABLE_ONLY 0x00000002
+ struct xenpf_efi_time set_wakeup_time;
+
+#define XEN_EFI_VARIABLE_NON_VOLATILE 0x00000001
+#define XEN_EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002
+#define XEN_EFI_VARIABLE_RUNTIME_ACCESS 0x00000004
+ struct {
+ XEN_GUEST_HANDLE(void) name; /* UCS-2/UTF-16 string */
+ unsigned long size;
+ XEN_GUEST_HANDLE(void) data;
+ struct xenpf_efi_guid {
+ uint32_t data1;
+ uint16_t data2;
+ uint16_t data3;
+ uint8_t data4[8];
+ } vendor_guid;
+ } get_variable, set_variable;
+
+ struct {
+ unsigned long size;
+ XEN_GUEST_HANDLE(void) name; /* UCS-2/UTF-16 string */
+ struct xenpf_efi_guid vendor_guid;
+ } get_next_variable_name;
+ } u;
+};
+typedef struct xenpf_efi_runtime_call xenpf_efi_runtime_call_t;
+DEFINE_XEN_GUEST_HANDLE(xenpf_efi_runtime_call_t);
+
#define XENPF_firmware_info 50
#define XEN_FW_DISK_INFO 1 /* from int 13 AH=08/41/48 */
#define XEN_FW_DISK_MBR_SIGNATURE 2 /* from MBR offset 0x1b8 */
@@ -388,6 +459,7 @@ struct xen_platform_op {
struct xenpf_read_memtype read_memtype;
struct xenpf_microcode_update microcode;
struct xenpf_platform_quirk platform_quirk;
+ struct xenpf_efi_runtime_call efi_runtime_call;
struct xenpf_firmware_info firmware_info;
struct xenpf_enter_acpi_sleep enter_acpi_sleep;
struct xenpf_change_freq change_freq;
Index: xen-4.1.2-testing/xen/include/xen/efi.h
===================================================================
--- xen-4.1.2-testing.orig/xen/include/xen/efi.h
+++ xen-4.1.2-testing/xen/include/xen/efi.h
@@ -29,10 +29,18 @@ extern struct efi efi;
union xenpf_efi_info;
union compat_pf_efi_info;
+struct xenpf_efi_runtime_call;
+struct compat_pf_efi_runtime_call;
+
void efi_init_memory(void);
+unsigned long efi_get_time(void);
+void efi_halt_system(void);
+void efi_reset_system(bool_t warm);
#ifndef COMPAT
int efi_get_info(uint32_t idx, union xenpf_efi_info *);
+int efi_runtime_call(struct xenpf_efi_runtime_call *);
#endif
int efi_compat_get_info(uint32_t idx, union compat_pf_efi_info *);
+int efi_compat_runtime_call(struct compat_pf_efi_runtime_call *);
#endif /* __XEN_EFI_H__ */
Index: xen-4.1.2-testing/xen/include/xsm/xsm.h
===================================================================
--- xen-4.1.2-testing.orig/xen/include/xsm/xsm.h
+++ xen-4.1.2-testing/xen/include/xsm/xsm.h
@@ -131,6 +131,7 @@ struct xsm_operations {
int (*physinfo) (void);
int (*platform_quirk) (uint32_t);
int (*firmware_info) (void);
+ int (*efi_runtime_call) (void);
int (*acpi_sleep) (void);
int (*change_freq) (void);
int (*getidletime) (void);
@@ -546,6 +547,11 @@ static inline int xsm_firmware_info (voi
return xsm_call(firmware_info());
}
+static inline int xsm_efi_runtime_call (void)
+{
+ return xsm_call(efi_runtime_call());
+}
+
static inline int xsm_acpi_sleep (void)
{
return xsm_call(acpi_sleep());

View File

@ -1,158 +0,0 @@
References: fate#311376, fate#311529, bnc#578927, bnc#628554
# HG changeset patch
# User Jan Beulich <jbeulich@novell.com>
# Date 1309249288 -3600
# Node ID dffcd8b4c197b58d2acb914d0e07a100e340f7ae
# Parent d19e778442673050bba8ea8cf61585902ff81162
x86-64: EFI MPS support
It's not clear this is needed - Linux doesn't use the MPS table even
if available, and no system having one was seen so far.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
# HG changeset patch
# User Keir Fraser <keir@xen.org>
# Date 1309268736 -3600
# Node ID d22b64ccf088db8bfce1d6c4830f08e3e834ec84
# Parent 6d404796a8e587eb648a66f2859991d385b65eb6
x86_32: Fix build after EFI MPS patch.
Signed-off-by: Keir Fraser <keir@xen.org>
Index: xen-4.1.2-testing/xen/arch/x86/efi/boot.c
===================================================================
--- xen-4.1.2-testing.orig/xen/arch/x86/efi/boot.c
+++ xen-4.1.2-testing/xen/arch/x86/efi/boot.c
@@ -897,12 +897,15 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SY
{
static EFI_GUID __initdata acpi2_guid = ACPI_20_TABLE_GUID;
static EFI_GUID __initdata acpi_guid = ACPI_TABLE_GUID;
+ static EFI_GUID __initdata mps_guid = MPS_TABLE_GUID;
static EFI_GUID __initdata smbios_guid = SMBIOS_TABLE_GUID;
if ( match_guid(&acpi2_guid, &efi_ct[i].VendorGuid) )
efi.acpi20 = (long)efi_ct[i].VendorTable;
if ( match_guid(&acpi_guid, &efi_ct[i].VendorGuid) )
efi.acpi = (long)efi_ct[i].VendorTable;
+ if ( match_guid(&mps_guid, &efi_ct[i].VendorGuid) )
+ efi.mps = (long)efi_ct[i].VendorTable;
if ( match_guid(&smbios_guid, &efi_ct[i].VendorGuid) )
efi.smbios = (long)efi_ct[i].VendorTable;
}
Index: xen-4.1.2-testing/xen/arch/x86/efi/runtime.c
===================================================================
--- xen-4.1.2-testing.orig/xen/arch/x86/efi/runtime.c
+++ xen-4.1.2-testing/xen/arch/x86/efi/runtime.c
@@ -29,6 +29,7 @@ void *__read_mostly efi_memmap;
struct efi __read_mostly efi = {
.acpi = EFI_INVALID_TABLE_ADDR,
.acpi20 = EFI_INVALID_TABLE_ADDR,
+ .mps = EFI_INVALID_TABLE_ADDR,
.smbios = EFI_INVALID_TABLE_ADDR,
};
Index: xen-4.1.2-testing/xen/arch/x86/mpparse.c
===================================================================
--- xen-4.1.2-testing.orig/xen/arch/x86/mpparse.c
+++ xen-4.1.2-testing/xen/arch/x86/mpparse.c
@@ -19,6 +19,8 @@
#include <xen/init.h>
#include <xen/acpi.h>
#include <xen/delay.h>
+#include <xen/efi.h>
+#include <xen/pfn.h>
#include <xen/sched.h>
#include <asm/mc146818rtc.h>
@@ -655,6 +657,14 @@ static inline void __init construct_defa
}
}
+#define FIX_EFI_MPF FIX_KEXEC_BASE_0
+
+static __init void efi_unmap_mpf(void)
+{
+ if (efi_enabled)
+ __set_fixmap(FIX_EFI_MPF, 0, 0);
+}
+
static struct intel_mp_floating *mpf_found;
/*
@@ -669,6 +679,7 @@ void __init get_smp_config (void)
* processors, where MPS only supports physical.
*/
if (acpi_lapic && acpi_ioapic) {
+ efi_unmap_mpf();
printk(KERN_INFO "Using ACPI (MADT) for SMP configuration information\n");
return;
}
@@ -699,6 +710,7 @@ void __init get_smp_config (void)
* override the defaults.
*/
if (!smp_read_mpc((void *)(unsigned long)mpf->mpf_physptr)) {
+ efi_unmap_mpf();
smp_found_config = 0;
printk(KERN_ERR "BIOS bug, MP table errors detected!...\n");
printk(KERN_ERR "... disabling SMP support. (tell your hw vendor)\n");
@@ -725,6 +737,8 @@ void __init get_smp_config (void)
} else
BUG();
+ efi_unmap_mpf();
+
printk(KERN_INFO "Processors: %d\n", num_processors);
/*
* Only use the first configuration found.
@@ -779,10 +793,37 @@ static int __init smp_scan_config (unsig
return 0;
}
+static void __init efi_check_config(void)
+{
+ struct intel_mp_floating *mpf;
+
+ if (efi.mps == EFI_INVALID_TABLE_ADDR)
+ return;
+
+ __set_fixmap(FIX_EFI_MPF, PFN_DOWN(efi.mps), __PAGE_HYPERVISOR);
+ mpf = (void *)fix_to_virt(FIX_EFI_MPF) + ((long)efi.mps & (PAGE_SIZE-1));
+
+ if (memcmp(mpf->mpf_signature, "_MP_", 4) == 0 &&
+ mpf->mpf_length == 1 &&
+ mpf_checksum((void *)mpf, 16) &&
+ (mpf->mpf_specification == 1 || mpf->mpf_specification == 4)) {
+ smp_found_config = 1;
+ printk(KERN_INFO "SMP MP-table at %08lx\n", efi.mps);
+ mpf_found = mpf;
+ }
+ else
+ efi_unmap_mpf();
+}
+
void __init find_smp_config (void)
{
unsigned int address;
+ if (efi_enabled) {
+ efi_check_config();
+ return;
+ }
+
/*
* FIXME: Linux assumes you have 640K of base ram..
* this continues the error...
Index: xen-4.1.2-testing/xen/include/xen/efi.h
===================================================================
--- xen-4.1.2-testing.orig/xen/include/xen/efi.h
+++ xen-4.1.2-testing/xen/include/xen/efi.h
@@ -17,6 +17,7 @@ extern const bool_t efi_enabled;
/* Add fields here only if they need to be referenced from non-EFI code. */
struct efi {
+ unsigned long mps; /* MPS table */
unsigned long acpi; /* ACPI table (IA64 ext 0.71) */
unsigned long acpi20; /* ACPI table (ACPI 2.0) */
unsigned long smbios; /* SM BIOS table */

View File

@ -1,58 +0,0 @@
changeset: 23643:335e96664589
user: George Dunlap <george.dunlap@eu.citrix.com>
date: Fri Jul 01 20:31:18 2011 +0100
files: xen/common/trace.c
description:
xentrace: Allow tracing to be enabled at boot
Add a "tevt_mask" parameter to the xen command-line, allowing
trace records to be gathered early in boot. They will be placed
into the trace buffers, and read when the user runs "xentrace".
Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
---
xen/common/trace.c | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
Index: xen-4.1.2-testing/xen/common/trace.c
===================================================================
--- xen-4.1.2-testing.orig/xen/common/trace.c
+++ xen-4.1.2-testing/xen/common/trace.c
@@ -45,7 +45,9 @@ CHECK_t_buf;
/* opt_tbuf_size: trace buffer size (in pages) for each cpu */
static unsigned int opt_tbuf_size;
+static unsigned int opt_tevt_mask;
integer_param("tbuf_size", opt_tbuf_size);
+integer_param("tevt_mask", opt_tevt_mask);
/* Pointers to the meta-data objects for all system trace buffers */
static struct t_info *t_info;
@@ -338,11 +340,21 @@ void __init init_trace_bufs(void)
{
register_cpu_notifier(&cpu_nfb);
- if ( opt_tbuf_size && alloc_trace_bufs(opt_tbuf_size) )
+ if ( opt_tbuf_size )
{
- printk(XENLOG_INFO "xentrace: allocation size %d failed, disabling\n",
- opt_tbuf_size);
- opt_tbuf_size = 0;
+ if ( alloc_trace_bufs(opt_tbuf_size) )
+ {
+ printk("xentrace: allocation size %d failed, disabling\n",
+ opt_tbuf_size);
+ opt_tbuf_size = 0;
+ }
+ else if ( opt_tevt_mask )
+ {
+ printk("xentrace: Starting tracing, enabling mask %x\n",
+ opt_tevt_mask);
+ tb_event_mask = opt_tevt_mask;
+ tb_init_done=1;
+ }
}
}

View File

@ -1,65 +0,0 @@
# HG changeset patch
# User Jan Beulich <jbeulich@novell.com>
# Date 1310631973 -3600
# Node ID 80c9db90bba96e443a22d268c06948fdef9c6a75
# Parent 88823213a4780ebced6d7adcb1ffd2dda6a339ca
x86-64: properly handle alias mappings beyond _end
Changeset 19632:b0966b6f5180 wasn't really complete: The Xen image
mapping doesn't end at _end, but a full 16Mb gets mapped during boot
(and never got unmapped so far), hence all of this space was subject
to alias mappings when it comes to cache attribute changes. Unmap all
full large pages between _end and the 16Mb boundary, and include all
other pages beyond _end when checking for aliases.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Index: xen-4.1.3-testing/xen/arch/x86/mm.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/mm.c
+++ xen-4.1.3-testing/xen/arch/x86/mm.c
@@ -779,7 +779,7 @@ static int update_xen_mappings(unsigned
int err = 0;
#ifdef __x86_64__
bool_t alias = mfn >= PFN_DOWN(xen_phys_start) &&
- mfn < PFN_UP(xen_phys_start + (unsigned long)_end - XEN_VIRT_START);
+ mfn < PFN_UP(xen_phys_start + xen_virt_end - XEN_VIRT_START);
unsigned long xen_va =
XEN_VIRT_START + ((mfn - PFN_DOWN(xen_phys_start)) << PAGE_SHIFT);
Index: xen-4.1.3-testing/xen/arch/x86/setup.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/setup.c
+++ xen-4.1.3-testing/xen/arch/x86/setup.c
@@ -97,6 +97,8 @@ unsigned long __read_mostly xen_phys_sta
/* Limits of Xen heap, used to initialise the allocator. */
unsigned long __initdata xenheap_initial_phys_start;
unsigned long __read_mostly xenheap_phys_end;
+#else
+unsigned long __read_mostly xen_virt_end;
#endif
DEFINE_PER_CPU(struct tss_struct, init_tss);
@@ -1096,6 +1098,9 @@ void __init __start_xen(unsigned long mb
map_pages_to_xen((unsigned long)__va(kexec_crash_area.start),
kexec_crash_area.start >> PAGE_SHIFT,
PFN_UP(kexec_crash_area.size), PAGE_HYPERVISOR);
+ xen_virt_end = ((unsigned long)_end + (1UL << L2_PAGETABLE_SHIFT) - 1) &
+ ~((1UL << L2_PAGETABLE_SHIFT) - 1);
+ destroy_xen_mappings(xen_virt_end, XEN_VIRT_START + BOOTSTRAP_MAP_BASE);
#endif
memguard_init();
Index: xen-4.1.3-testing/xen/include/asm-x86/x86_64/page.h
===================================================================
--- xen-4.1.3-testing.orig/xen/include/asm-x86/x86_64/page.h
+++ xen-4.1.3-testing/xen/include/asm-x86/x86_64/page.h
@@ -34,6 +34,8 @@
#include <xen/config.h>
#include <asm/types.h>
+extern unsigned long xen_virt_end;
+
extern unsigned long max_pdx;
extern unsigned long pfn_pdx_bottom_mask, ma_va_bottom_mask;
extern unsigned int pfn_pdx_hole_shift;

View File

@ -1,39 +0,0 @@
# HG changeset patch
# User Ian Campbell <ian.campbell@citrix.com>
# Date 1310749975 -3600
# Node ID 5e1032229546c2d5640dc05205303d91d78a92c3
# Parent c1d7fa123dae73708da7306c0ec611d6fa6a6140
pygrub: prefer Grub2 to Grub1
If a VM image has grub2 installed it is likely the one we need to be using.
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
Committed-by: Ian Jackson <ian.jackson@eu.citrix.com>
Index: xen-4.1.3-testing/tools/pygrub/src/pygrub
===================================================================
--- xen-4.1.3-testing.orig/tools/pygrub/src/pygrub
+++ xen-4.1.3-testing/tools/pygrub/src/pygrub
@@ -394,15 +394,14 @@ class Grub:
# fallbacks
["/efi/boot/elilo.conf", "/elilo.conf",])
else:
- cfg_list = map(lambda x: (x,grub.GrubConf.GrubConfigFile),
- ["/boot/grub/menu.lst", "/boot/grub/grub.conf",
- "/grub/menu.lst", "/grub/grub.conf"]) + \
- map(lambda x: (x,grub.GrubConf.Grub2ConfigFile),
- ["/boot/grub/grub.cfg", "/grub/grub.cfg",
- "/boot/grub2/grub.cfg", "/grub2/grub.cfg"]) + \
+ cfg_list = map(lambda x: (x,grub.GrubConf.Grub2ConfigFile),
+ ["/boot/grub/grub.cfg", "/grub/grub.cfg"]) + \
map(lambda x: (x,grub.ExtLinuxConf.ExtLinuxConfigFile),
["/boot/isolinux/isolinux.cfg",
- "/boot/extlinux.conf"])
+ "/boot/extlinux.conf"]) + \
+ map(lambda x: (x,grub.GrubConf.GrubConfigFile),
+ ["/boot/grub/menu.lst", "/boot/grub/grub.conf",
+ "/grub/menu.lst", "/grub/grub.conf"])
if not fs:
# set the config file and parse it

View File

@ -1,37 +0,0 @@
changeset: 23719:c2888876abd3
user: Olaf Hering <olaf@aepfle.de>
date: Tue Jul 19 08:22:19 2011 +0100
files: xen/common/trace.c
description:
xentrace: update __trace_var comment
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
xen/common/trace.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
Index: xen-4.1.2-testing/xen/common/trace.c
===================================================================
--- xen-4.1.2-testing.orig/xen/common/trace.c
+++ xen-4.1.2-testing/xen/common/trace.c
@@ -657,13 +657,13 @@ static DECLARE_SOFTIRQ_TASKLET(trace_not
trace_notify_dom0, 0);
/**
- * trace - Enters a trace tuple into the trace buffer for the current CPU.
+ * __trace_var - Enters a trace tuple into the trace buffer for the current CPU.
* @event: the event type being logged
- * @d1...d5: the data items for the event being logged
+ * @cycles: include tsc timestamp into trace record
+ * @extra: size of additional trace data in bytes
+ * @extra_data: pointer to additional trace data
*
- * Logs a trace record into the appropriate buffer. Returns nonzero on
- * failure, otherwise 0. Failure occurs only if the trace buffers are not yet
- * initialised.
+ * Logs a trace record into the appropriate buffer.
*/
void __trace_var(u32 event, bool_t cycles, unsigned int extra,
const void *extra_data)

View File

@ -1,283 +0,0 @@
# HG changeset patch
# User Jan Beulich <jbeulich@novell.com>
# Date 1311081053 -3600
# Node ID 18653a163b1e8e10b4353272bcb9e8302bfd2e19
# Parent 7bc5825e471db5a3a989f47d21334ef63a6b5610
x86: consistently serialize CMOS/RTC accesses on rtc_lock
Since RTC/CMOS accesses aren't atomic, there are possible races
between code paths setting the index register and subsequently
reading/writing the data register. This is supposed to be dealt with
by acquiring rtc_lock, but two places up to now lacked respective
synchronization: Accesses to the EFI time functions and
smpboot_{setup,restore}_warm_reset_vector().
This in turn requires no longer directly passing through guest writes
to the index register, but instead using a machanism similar to that
for PCI config space method 1 accesses.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Index: xen-4.1.3-testing/xen/arch/x86/efi/runtime.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/efi/runtime.c
+++ xen-4.1.3-testing/xen/arch/x86/efi/runtime.c
@@ -3,6 +3,7 @@
#include <xen/errno.h>
#include <xen/guest_access.h>
#include <xen/time.h>
+#include <asm/mc146818rtc.h>
DEFINE_XEN_GUEST_HANDLE(CHAR16);
@@ -80,9 +81,11 @@ unsigned long efi_get_time(void)
{
EFI_TIME time;
EFI_STATUS status;
- unsigned long cr3 = efi_rs_enter();
+ unsigned long cr3 = efi_rs_enter(), flags;
+ spin_lock_irqsave(&rtc_lock, flags);
status = efi_rs->GetTime(&time, NULL);
+ spin_unlock_irqrestore(&rtc_lock, flags);
efi_rs_leave(cr3);
if ( EFI_ERROR(status) )
@@ -223,7 +226,7 @@ static inline EFI_GUID *cast_guid(struct
int efi_runtime_call(struct xenpf_efi_runtime_call *op)
{
- unsigned long cr3;
+ unsigned long cr3, flags;
EFI_STATUS status = EFI_NOT_STARTED;
int rc = 0;
@@ -237,7 +240,9 @@ int efi_runtime_call(struct xenpf_efi_ru
return -EINVAL;
cr3 = efi_rs_enter();
+ spin_lock_irqsave(&rtc_lock, flags);
status = efi_rs->GetTime(cast_time(&op->u.get_time.time), &caps);
+ spin_unlock_irqrestore(&rtc_lock, flags);
efi_rs_leave(cr3);
if ( !EFI_ERROR(status) )
@@ -255,7 +260,9 @@ int efi_runtime_call(struct xenpf_efi_ru
return -EINVAL;
cr3 = efi_rs_enter();
+ spin_lock_irqsave(&rtc_lock, flags);
status = efi_rs->SetTime(cast_time(&op->u.set_time));
+ spin_unlock_irqrestore(&rtc_lock, flags);
efi_rs_leave(cr3);
break;
@@ -267,8 +274,10 @@ int efi_runtime_call(struct xenpf_efi_ru
return -EINVAL;
cr3 = efi_rs_enter();
+ spin_lock_irqsave(&rtc_lock, flags);
status = efi_rs->GetWakeupTime(&enabled, &pending,
cast_time(&op->u.get_wakeup_time));
+ spin_unlock_irqrestore(&rtc_lock, flags);
efi_rs_leave(cr3);
if ( !EFI_ERROR(status) )
@@ -287,12 +296,14 @@ int efi_runtime_call(struct xenpf_efi_ru
return -EINVAL;
cr3 = efi_rs_enter();
+ spin_lock_irqsave(&rtc_lock, flags);
status = efi_rs->SetWakeupTime(!!(op->misc &
XEN_EFI_SET_WAKEUP_TIME_ENABLE),
(op->misc &
XEN_EFI_SET_WAKEUP_TIME_ENABLE_ONLY) ?
NULL :
cast_time(&op->u.set_wakeup_time));
+ spin_unlock_irqrestore(&rtc_lock, flags);
efi_rs_leave(cr3);
op->misc = 0;
Index: xen-4.1.3-testing/xen/arch/x86/hpet.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/hpet.c
+++ xen-4.1.3-testing/xen/arch/x86/hpet.c
@@ -525,18 +525,10 @@ static void hpet_detach_channel(int cpu,
#include <asm/mc146818rtc.h>
-void (*pv_rtc_handler)(unsigned int port, uint8_t value);
+void (*__read_mostly pv_rtc_handler)(uint8_t index, uint8_t value);
-static void handle_rtc_once(unsigned int port, uint8_t value)
+static void handle_rtc_once(uint8_t index, uint8_t value)
{
- static int index;
-
- if ( port == 0x70 )
- {
- index = value;
- return;
- }
-
if ( index != RTC_REG_B )
return;
Index: xen-4.1.3-testing/xen/arch/x86/traps.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/traps.c
+++ xen-4.1.3-testing/xen/arch/x86/traps.c
@@ -67,6 +67,8 @@
#include <asm/hypercall.h>
#include <asm/mce.h>
#include <asm/apic.h>
+#include <asm/mc146818rtc.h>
+#include <asm/hpet.h>
#include <public/arch-x86/cpuid.h>
/*
@@ -1656,6 +1658,10 @@ static int admin_io_okay(
if ( (port == 0xcf8) && (bytes == 4) )
return 0;
+ /* We also never permit direct access to the RTC/CMOS registers. */
+ if ( ((port & ~1) == RTC_PORT(0)) )
+ return 0;
+
return ioports_access_permitted(v->domain, port, port + bytes - 1);
}
@@ -1685,6 +1691,21 @@ static uint32_t guest_io_read(
{
sub_data = pv_pit_handler(port, 0, 0);
}
+ else if ( (port == RTC_PORT(0)) )
+ {
+ sub_data = v->domain->arch.cmos_idx;
+ }
+ else if ( (port == RTC_PORT(1)) &&
+ ioports_access_permitted(v->domain, RTC_PORT(0),
+ RTC_PORT(1)) )
+ {
+ unsigned long flags;
+
+ spin_lock_irqsave(&rtc_lock, flags);
+ outb(v->domain->arch.cmos_idx & 0x7f, RTC_PORT(0));
+ sub_data = inb(RTC_PORT(1));
+ spin_unlock_irqrestore(&rtc_lock, flags);
+ }
else if ( (port == 0xcf8) && (bytes == 4) )
{
size = 4;
@@ -1710,8 +1731,6 @@ static uint32_t guest_io_read(
return data;
}
-extern void (*pv_rtc_handler)(unsigned int port, uint8_t value);
-
static void guest_io_write(
unsigned int port, unsigned int bytes, uint32_t data,
struct vcpu *v, struct cpu_user_regs *regs)
@@ -1720,8 +1739,6 @@ static void guest_io_write(
{
switch ( bytes ) {
case 1:
- if ( ((port == 0x70) || (port == 0x71)) && pv_rtc_handler )
- pv_rtc_handler(port, (uint8_t)data);
outb((uint8_t)data, port);
if ( pv_post_outb_hook )
pv_post_outb_hook(port, (uint8_t)data);
@@ -1744,6 +1761,23 @@ static void guest_io_write(
{
pv_pit_handler(port, (uint8_t)data, 1);
}
+ else if ( (port == RTC_PORT(0)) )
+ {
+ v->domain->arch.cmos_idx = data;
+ }
+ else if ( (port == RTC_PORT(1)) &&
+ ioports_access_permitted(v->domain, RTC_PORT(0),
+ RTC_PORT(1)) )
+ {
+ unsigned long flags;
+
+ if ( pv_rtc_handler )
+ pv_rtc_handler(v->domain->arch.cmos_idx & 0x7f, data);
+ spin_lock_irqsave(&rtc_lock, flags);
+ outb(v->domain->arch.cmos_idx & 0x7f, RTC_PORT(0));
+ outb(data, RTC_PORT(1));
+ spin_unlock_irqrestore(&rtc_lock, flags);
+ }
else if ( (port == 0xcf8) && (bytes == 4) )
{
size = 4;
@@ -2109,10 +2143,6 @@ static int emulate_privileged_op(struct
goto fail;
if ( admin_io_okay(port, op_bytes, v, regs) )
{
- if ( (op_bytes == 1) &&
- ((port == 0x71) || (port == 0x70)) &&
- pv_rtc_handler )
- pv_rtc_handler(port, regs->eax);
io_emul(regs);
if ( (op_bytes == 1) && pv_post_outb_hook )
pv_post_outb_hook(port, regs->eax);
Index: xen-4.1.3-testing/xen/include/asm-x86/domain.h
===================================================================
--- xen-4.1.3-testing.orig/xen/include/asm-x86/domain.h
+++ xen-4.1.3-testing/xen/include/asm-x86/domain.h
@@ -251,6 +251,7 @@ struct arch_domain
/* I/O-port admin-specified access capabilities. */
struct rangeset *ioport_caps;
uint32_t pci_cf8;
+ uint8_t cmos_idx;
struct list_head pdev_list;
struct hvm_domain hvm_domain;
Index: xen-4.1.3-testing/xen/include/asm-x86/hpet.h
===================================================================
--- xen-4.1.3-testing.orig/xen/include/asm-x86/hpet.h
+++ xen-4.1.3-testing/xen/include/asm-x86/hpet.h
@@ -52,6 +52,7 @@
#define HPET_TN_FSB_CAP 0x8000
#define HPET_TN_ROUTE_SHIFT 9
+extern void (*pv_rtc_handler)(uint8_t reg, uint8_t value);
#define hpet_read32(x) \
(*(volatile u32 *)(fix_to_virt(FIX_HPET_BASE) + (x)))
Index: xen-4.1.3-testing/xen/include/asm-x86/mach-default/smpboot_hooks.h
===================================================================
--- xen-4.1.3-testing.orig/xen/include/asm-x86/mach-default/smpboot_hooks.h
+++ xen-4.1.3-testing/xen/include/asm-x86/mach-default/smpboot_hooks.h
@@ -3,7 +3,11 @@
static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&rtc_lock, flags);
CMOS_WRITE(0xa, 0xf);
+ spin_unlock_irqrestore(&rtc_lock, flags);
flush_tlb_local();
Dprintk("1.\n");
*((volatile unsigned short *) TRAMPOLINE_HIGH) = start_eip >> 4;
@@ -14,6 +18,8 @@ static inline void smpboot_setup_warm_re
static inline void smpboot_restore_warm_reset_vector(void)
{
+ unsigned long flags;
+
/*
* Install writable page 0 entry to set BIOS data area.
*/
@@ -23,7 +29,9 @@ static inline void smpboot_restore_warm_
* Paranoid: Set warm reset code and vector here back
* to default values.
*/
+ spin_lock_irqsave(&rtc_lock, flags);
CMOS_WRITE(0, 0xf);
+ spin_unlock_irqrestore(&rtc_lock, flags);
*((volatile int *) maddr_to_virt(0x467)) = 0;
}

View File

@ -1,252 +0,0 @@
References: bnc#702407
# HG changeset patch
# User Jan Beulich <jbeulich@novell.com>
# Date 1311407355 -3600
# Node ID 537918f518eec3d8e2e2dad403fce40303321523
# Parent 42edf1481c5704c8ce1eb171a713b5411df0551a
add privileged (dom0) kernel feature indication
With our switching away from supporting 32-bit Dom0 operation, users
complained that attempts (perhaps due to lack of knowledge of that
change) to boot the no longer privileged kernel in Dom0 resulted in
apparently silent failure. To make the mismatch explicit and visible,
add dom0 feature flag that the kernel can set to indicate operation as
dom0 is supported.
Due to the way elf_xen_parse_features() worked up to now (getting
fixed here), adding features indications to the old, string based ELF
note would make the respective kernel unusable on older hypervisors.
For that reason, a new ELF Note is being introduced that allows
specifying supported features as a bit array instead (with features
unknown to the hypervisor simply ignored, as now also done by
elf_xen_parse_features(), whereas here unknown kernel-required
features still keep the kernel [and hence VM] from booting).
Introduce and use elf_note_numeric_array() to be forward
compatible (or else an old hypervisor wouldn't be able to parse kernel
specified features occupying more than 64 bits - thanks, Ian!).
Signed-off-by: Jan Beulich <jbeulich@novell.com>
# HG changeset patch
# User Jan Beulich <jbeulich@novell.com>
# Date 1311598088 -3600
# Node ID 50ddc200a60cad3929a79a992f09145fd39af49d
# Parent d8725d9fb8657874011d2f2772f5e970b24dfe9b
fix regression from c/s 23735:537918f518ee
This was checking presence of the wrong (old) ELF note. I don't really
understand how this failed consistently only for one of the xen-boot
tests...
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Index: xen-4.1.3-testing/tools/libxc/xc_dom_elfloader.c
===================================================================
--- xen-4.1.3-testing.orig/tools/libxc/xc_dom_elfloader.c
+++ xen-4.1.3-testing/tools/libxc/xc_dom_elfloader.c
@@ -286,6 +286,13 @@ static int xc_dom_parse_elf_kernel(struc
if ( (rc = elf_xen_parse(elf, &dom->parms)) != 0 )
return rc;
+ if ( elf_xen_feature_get(XENFEAT_dom0, dom->parms.f_required) )
+ {
+ xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: Kernel does not"
+ " support unprivileged (DomU) operation", __FUNCTION__);
+ return -EINVAL;
+ }
+
/* find kernel segment */
dom->kernel_seg.vstart = dom->parms.virt_kstart;
dom->kernel_seg.vend = dom->parms.virt_kend;
Index: xen-4.1.3-testing/xen/arch/ia64/xen/domain.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/ia64/xen/domain.c
+++ xen-4.1.3-testing/xen/arch/ia64/xen/domain.c
@@ -2165,6 +2165,13 @@ int __init construct_dom0(struct domain
return -1;
}
+ if (parms.elf_notes[XEN_ELFNOTE_SUPPORTED_FEATURES].type != XEN_ENT_NONE &&
+ !test_bit(XENFEAT_dom0, parms.f_supported))
+ {
+ printk("Kernel does not support Dom0 operation\n");
+ return -1;
+ }
+
p_start = parms.virt_base;
pkern_start = parms.virt_kstart;
pkern_end = parms.virt_kend;
Index: xen-4.1.3-testing/xen/arch/x86/domain_build.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/domain_build.c
+++ xen-4.1.3-testing/xen/arch/x86/domain_build.c
@@ -417,6 +417,13 @@ int __init construct_dom0(
return -EINVAL;
}
+ if ( parms.elf_notes[XEN_ELFNOTE_SUPPORTED_FEATURES].type != XEN_ENT_NONE &&
+ !test_bit(XENFEAT_dom0, parms.f_supported) )
+ {
+ printk("Kernel does not support Dom0 operation\n");
+ return -EINVAL;
+ }
+
#if defined(__x86_64__)
if ( compat32 )
{
Index: xen-4.1.3-testing/xen/common/kernel.c
===================================================================
--- xen-4.1.3-testing.orig/xen/common/kernel.c
+++ xen-4.1.3-testing/xen/common/kernel.c
@@ -289,6 +289,8 @@ DO(xen_version)(int cmd, XEN_GUEST_HANDL
(1U << XENFEAT_auto_translated_physmap);
if ( supervisor_mode_kernel )
fi.submap |= 1U << XENFEAT_supervisor_mode_kernel;
+ if ( current->domain == dom0 )
+ fi.submap |= 1U << XENFEAT_dom0;
#ifdef CONFIG_X86
if ( !is_hvm_vcpu(current) )
fi.submap |= (1U << XENFEAT_mmu_pt_update_preserve_ad) |
Index: xen-4.1.3-testing/xen/common/libelf/libelf-dominfo.c
===================================================================
--- xen-4.1.3-testing.orig/xen/common/libelf/libelf-dominfo.c
+++ xen-4.1.3-testing/xen/common/libelf/libelf-dominfo.c
@@ -26,7 +26,8 @@ static const char *const elf_xen_feature
[XENFEAT_writable_descriptor_tables] = "writable_descriptor_tables",
[XENFEAT_auto_translated_physmap] = "auto_translated_physmap",
[XENFEAT_supervisor_mode_kernel] = "supervisor_mode_kernel",
- [XENFEAT_pae_pgdir_above_4gb] = "pae_pgdir_above_4gb"
+ [XENFEAT_pae_pgdir_above_4gb] = "pae_pgdir_above_4gb",
+ [XENFEAT_dom0] = "dom0"
};
static const int elf_xen_features =
sizeof(elf_xen_feature_names) / sizeof(elf_xen_feature_names[0]);
@@ -82,7 +83,7 @@ int elf_xen_parse_features(const char *f
}
}
}
- if ( i == elf_xen_features )
+ if ( i == elf_xen_features && required && feature[0] == '!' )
return -1;
}
@@ -113,6 +114,7 @@ int elf_xen_parse_note(struct elf_binary
[XEN_ELFNOTE_LOADER] = { "LOADER", 1},
[XEN_ELFNOTE_PAE_MODE] = { "PAE_MODE", 1},
[XEN_ELFNOTE_FEATURES] = { "FEATURES", 1},
+ [XEN_ELFNOTE_SUPPORTED_FEATURES] = { "SUPPORTED_FEATURES", 0},
[XEN_ELFNOTE_BSD_SYMTAB] = { "BSD_SYMTAB", 1},
[XEN_ELFNOTE_SUSPEND_CANCEL] = { "SUSPEND_CANCEL", 0 },
[XEN_ELFNOTE_MOD_START_PFN] = { "MOD_START_PFN", 0 },
@@ -121,6 +123,7 @@ int elf_xen_parse_note(struct elf_binary
const char *str = NULL;
uint64_t val = 0;
+ unsigned int i;
int type = elf_uval(elf, note, type);
if ( (type >= sizeof(note_desc) / sizeof(note_desc[0])) ||
@@ -199,6 +202,12 @@ int elf_xen_parse_note(struct elf_binary
return -1;
break;
+ case XEN_ELFNOTE_SUPPORTED_FEATURES:
+ for ( i = 0; i < XENFEAT_NR_SUBMAPS; ++i )
+ parms->f_supported[i] |= elf_note_numeric_array(
+ elf, note, sizeof(*parms->f_supported), i);
+ break;
+
}
return 0;
}
Index: xen-4.1.3-testing/xen/common/libelf/libelf-tools.c
===================================================================
--- xen-4.1.3-testing.orig/xen/common/libelf/libelf-tools.c
+++ xen-4.1.3-testing/xen/common/libelf/libelf-tools.c
@@ -227,6 +227,27 @@ uint64_t elf_note_numeric(struct elf_bin
return 0;
}
}
+
+uint64_t elf_note_numeric_array(struct elf_binary *elf, const elf_note *note,
+ unsigned int unitsz, unsigned int idx)
+{
+ const void *desc = elf_note_desc(elf, note);
+ int descsz = elf_uval(elf, note, descsz);
+
+ if ( descsz % unitsz || idx >= descsz / unitsz )
+ return 0;
+ switch (unitsz)
+ {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ return elf_access_unsigned(elf, desc, idx * unitsz, unitsz);
+ default:
+ return 0;
+ }
+}
+
const elf_note *elf_note_next(struct elf_binary *elf, const elf_note * note)
{
int namesz = (elf_uval(elf, note, namesz) + 3) & ~3;
Index: xen-4.1.3-testing/xen/include/public/elfnote.h
===================================================================
--- xen-4.1.3-testing.orig/xen/include/public/elfnote.h
+++ xen-4.1.3-testing/xen/include/public/elfnote.h
@@ -179,9 +179,22 @@
#define XEN_ELFNOTE_MOD_START_PFN 16
/*
+ * The features supported by this kernel (numeric).
+ *
+ * Other than XEN_ELFNOTE_FEATURES on pre-4.2 Xen, this note allows a
+ * kernel to specify support for features that older hypervisors don't
+ * know about. The set of features 4.2 and newer hypervisors will
+ * consider supported by the kernel is the combination of the sets
+ * specified through this and the string note.
+ *
+ * LEGACY: FEATURES
+ */
+#define XEN_ELFNOTE_SUPPORTED_FEATURES 17
+
+/*
* The number of the highest elfnote defined.
*/
-#define XEN_ELFNOTE_MAX XEN_ELFNOTE_MOD_START_PFN
+#define XEN_ELFNOTE_MAX XEN_ELFNOTE_SUPPORTED_FEATURES
/*
* System information exported through crash notes.
Index: xen-4.1.3-testing/xen/include/public/features.h
===================================================================
--- xen-4.1.3-testing.orig/xen/include/public/features.h
+++ xen-4.1.3-testing/xen/include/public/features.h
@@ -75,7 +75,10 @@
#define XENFEAT_hvm_safe_pvclock 9
/* x86: pirq can be used by HVM guests */
-#define XENFEAT_hvm_pirqs 10
+#define XENFEAT_hvm_pirqs 10
+
+/* operation as Dom0 is supported */
+#define XENFEAT_dom0 11
#define XENFEAT_NR_SUBMAPS 1
Index: xen-4.1.3-testing/xen/include/xen/libelf.h
===================================================================
--- xen-4.1.3-testing.orig/xen/include/xen/libelf.h
+++ xen-4.1.3-testing/xen/include/xen/libelf.h
@@ -179,6 +179,8 @@ const elf_sym *elf_sym_by_index(struct e
const char *elf_note_name(struct elf_binary *elf, const elf_note * note);
const void *elf_note_desc(struct elf_binary *elf, const elf_note * note);
uint64_t elf_note_numeric(struct elf_binary *elf, const elf_note * note);
+uint64_t elf_note_numeric_array(struct elf_binary *, const elf_note *,
+ unsigned int unitsz, unsigned int idx);
const elf_note *elf_note_next(struct elf_binary *elf, const elf_note * note);
int elf_is_elfbinary(const void *image);

View File

@ -1,66 +0,0 @@
# HG changeset patch
# User Jan Beulich <jbeulich@novell.com>
# Date 1311608539 -3600
# Node ID b07b6fa766562c990b1d1e59af032feda15c2edb
# Parent aa54b8175954bd6ffeb3bcf72e782e133896b388
x86-64/MMCFG: correct base address computation for regions not starting at bus 0
As per the specification, the base address reported by ACPI is the one
that would be used if the region started at bus 0. Hence the
start_bus_number offset needs to be added not only to the virtual
address, but also the physical one when establishing the mapping, and
it then needs to be subtracted when obtaining the virtual address for
doing accesses.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Index: xen-4.1.2-testing/xen/arch/x86/x86_64/mmconfig_64.c
===================================================================
--- xen-4.1.2-testing.orig/xen/arch/x86/x86_64/mmconfig_64.c
+++ xen-4.1.2-testing/xen/arch/x86/x86_64/mmconfig_64.c
@@ -25,7 +25,7 @@ struct mmcfg_virt {
static struct mmcfg_virt *pci_mmcfg_virt;
static int __initdata mmcfg_pci_segment_shift;
-static char __iomem *get_virt(unsigned int seg, unsigned bus)
+static char __iomem *get_virt(unsigned int seg, unsigned int *bus)
{
struct acpi_mcfg_allocation *cfg;
int cfg_num;
@@ -33,9 +33,11 @@ static char __iomem *get_virt(unsigned i
for (cfg_num = 0; cfg_num < pci_mmcfg_config_num; cfg_num++) {
cfg = pci_mmcfg_virt[cfg_num].cfg;
if (cfg->pci_segment == seg &&
- (cfg->start_bus_number <= bus) &&
- (cfg->end_bus_number >= bus))
+ (cfg->start_bus_number <= *bus) &&
+ (cfg->end_bus_number >= *bus)) {
+ *bus -= cfg->start_bus_number;
return pci_mmcfg_virt[cfg_num].virt;
+ }
}
/* Fall back to type 0 */
@@ -46,7 +48,7 @@ static char __iomem *pci_dev_base(unsign
{
char __iomem *addr;
- addr = get_virt(seg, bus);
+ addr = get_virt(seg, &bus);
if (!addr)
return NULL;
return addr + ((bus << 20) | (devfn << 12));
@@ -121,8 +123,11 @@ static void __iomem * __init mcfg_iorema
if (virt + size < virt || virt + size > PCI_MCFG_VIRT_END)
return NULL;
- map_pages_to_xen(virt, cfg->address >> PAGE_SHIFT,
- size >> PAGE_SHIFT, PAGE_HYPERVISOR_NOCACHE);
+ if (map_pages_to_xen(virt,
+ (cfg->address >> PAGE_SHIFT) +
+ (cfg->start_bus_number << (20 - PAGE_SHIFT)),
+ size >> PAGE_SHIFT, PAGE_HYPERVISOR_NOCACHE))
+ return NULL;
return (void __iomem *) virt;
}

View File

@ -1,421 +0,0 @@
# HG changeset patch
# User Jan Beulich <jbeulich@novell.com>
# Date 1311608606 -3600
# Node ID e8d1c8f074babcb0e4511393106e80a918a38204
# Parent e1717d180897e6e7a04d83a41d86b35ac16912b9
x86-64/MMCFG: pass down firmware (ACPI) reservation status of used memory space
Reserving the MMCFG address range(s) in E820 is specified to only be
optional for the firmware to do. The requirement is to have them
reserved in ACPI resources. Those, however, aren't directly visible to
Xen as they require the ACPI interpreter to be active. Thus, if a
range isn't reserved in E820, we should not completely disable use of
MMCFG on the respective bus range, but rather keep it disabled until
Dom0 can pass down information on the ACPI reservation status (though
a new physdevop hypercall).
Signed-off-by: Jan Beulich <jbeulich@novell.com>
# HG changeset patch
# User Jan Beulich <jbeulich@suse.com>
# Date 1322813126 -3600
# Node ID 60d4e257d04ba0bd663bbef5e93a97b6d8b66e54
# Parent 3f815406feb25a9348d8be9bc49fdc8c93ccb7c2
x86-64/mmcfg: remove __initdata annotation overlooked in 23749:e8d1c8f074ba
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Index: xen-4.1.3-testing/xen/arch/x86/physdev.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/physdev.c
+++ xen-4.1.3-testing/xen/arch/x86/physdev.c
@@ -16,6 +16,10 @@
#include <xsm/xsm.h>
#include <asm/p2m.h>
+#ifdef CONFIG_X86_64
+#include "x86_64/mmconfig.h"
+#endif
+
#ifndef COMPAT
typedef long ret_t;
#endif
@@ -540,6 +544,24 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
break;
}
+#ifdef __x86_64__
+ case PHYSDEVOP_pci_mmcfg_reserved: {
+ struct physdev_pci_mmcfg_reserved info;
+
+ ret = -EPERM;
+ if ( !IS_PRIV(current->domain) )
+ break;
+
+ ret = -EFAULT;
+ if ( copy_from_guest(&info, arg, 1) )
+ break;
+
+ ret = pci_mmcfg_reserved(info.address, info.segment,
+ info.start_bus, info.end_bus, info.flags);
+ break;
+ }
+#endif
+
case PHYSDEVOP_restore_msi: {
struct physdev_restore_msi restore_msi;
struct pci_dev *pdev;
Index: xen-4.1.3-testing/xen/arch/x86/x86_64/mmconfig.h
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/x86_64/mmconfig.h
+++ xen-4.1.3-testing/xen/arch/x86/x86_64/mmconfig.h
@@ -84,6 +84,11 @@ extern int pci_mmcfg_config_num;
extern struct acpi_mcfg_allocation *pci_mmcfg_config;
/* function prototypes */
+struct acpi_table_header;
int acpi_parse_mcfg(struct acpi_table_header *header);
+int pci_mmcfg_reserved(uint64_t address, unsigned int segment,
+ unsigned int start_bus, unsigned int end_bus,
+ unsigned int flags);
int pci_mmcfg_arch_init(void);
-void pci_mmcfg_arch_free(void);
+int pci_mmcfg_arch_enable(unsigned int);
+void pci_mmcfg_arch_disable(unsigned int);
Index: xen-4.1.3-testing/xen/arch/x86/x86_64/mmconfig-shared.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/x86_64/mmconfig-shared.c
+++ xen-4.1.3-testing/xen/arch/x86/x86_64/mmconfig-shared.c
@@ -22,10 +22,10 @@
#include <asm/e820.h>
#include <asm/msr.h>
#include <asm/msr-index.h>
+#include <public/physdev.h>
#include "mmconfig.h"
-static int __initdata known_bridge;
unsigned int pci_probe = PCI_PROBE_CONF1 | PCI_PROBE_MMCONF;
static void __init parse_mmcfg(char *s)
@@ -316,26 +316,21 @@ static int __init pci_mmcfg_check_hostbr
return name != NULL;
}
-typedef int (*check_reserved_t)(u64 start, u64 end, unsigned type);
-
static int __init is_mmconf_reserved(
- check_reserved_t is_reserved,
u64 addr, u64 size, int i,
- typeof(pci_mmcfg_config[0]) *cfg, int with_e820)
+ typeof(pci_mmcfg_config[0]) *cfg)
{
u64 old_size = size;
int valid = 0;
- while (!is_reserved(addr, addr + size - 1, E820_RESERVED)) {
+ while (!e820_all_mapped(addr, addr + size - 1, E820_RESERVED)) {
size >>= 1;
if (size < (16UL<<20))
break;
}
if (size >= (16UL<<20) || size == old_size) {
- printk(KERN_NOTICE
- "PCI: MCFG area at %lx reserved in %s\n",
- addr, with_e820?"E820":"ACPI motherboard resources");
+ printk(KERN_NOTICE "PCI: MCFG area at %lx reserved in E820\n", addr);
valid = 1;
if (old_size != size) {
@@ -352,15 +347,16 @@ static int __init is_mmconf_reserved(
return valid;
}
-static void __init pci_mmcfg_reject_broken(void)
+static bool_t __init pci_mmcfg_reject_broken(void)
{
typeof(pci_mmcfg_config[0]) *cfg;
int i;
+ bool_t valid = 1;
if ((pci_mmcfg_config_num == 0) ||
(pci_mmcfg_config == NULL) ||
(pci_mmcfg_config[0].address == 0))
- return;
+ return 0;
cfg = &pci_mmcfg_config[0];
@@ -374,27 +370,25 @@ static void __init pci_mmcfg_reject_brok
size = cfg->end_bus_number + 1 - cfg->start_bus_number;
size <<= 20;
printk(KERN_NOTICE "PCI: MCFG configuration %d: base %lx "
- "segment %hu buses %u - %u\n",
+ "segment %04x buses %02x - %02x\n",
i, (unsigned long)cfg->address, cfg->pci_segment,
(unsigned int)cfg->start_bus_number,
(unsigned int)cfg->end_bus_number);
- if (!is_mmconf_reserved(e820_all_mapped, addr, size, i, cfg, 1))
- goto reject;
+ if (!is_mmconf_reserved(addr, size, i, cfg) ||
+ pci_mmcfg_arch_enable(i)) {
+ pci_mmcfg_arch_disable(i);
+ valid = 0;
+ }
}
- return;
-
-reject:
- printk(KERN_INFO "PCI: Not using MMCONFIG.\n");
- pci_mmcfg_arch_free();
- xfree(pci_mmcfg_config);
- pci_mmcfg_config = NULL;
- pci_mmcfg_config_num = 0;
+ return valid;
}
void __init acpi_mmcfg_init(void)
{
+ bool_t valid = 1;
+
/* MMCONFIG disabled */
if ((pci_probe & PCI_PROBE_MMCONF) == 0)
return;
@@ -403,16 +397,17 @@ void __init acpi_mmcfg_init(void)
if (!(pci_probe & PCI_PROBE_MASK & ~PCI_PROBE_MMCONF))
return;
- /* for late to exit */
- if (known_bridge)
- return;
+ if (pci_mmcfg_check_hostbridge()) {
+ unsigned int i;
- if (pci_mmcfg_check_hostbridge())
- known_bridge = 1;
-
- if (!known_bridge) {
+ pci_mmcfg_arch_init();
+ for (i = 0; i < pci_mmcfg_config_num; ++i)
+ if (pci_mmcfg_arch_enable(i))
+ valid = 0;
+ } else {
acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
- pci_mmcfg_reject_broken();
+ pci_mmcfg_arch_init();
+ valid = pci_mmcfg_reject_broken();
}
if ((pci_mmcfg_config_num == 0) ||
@@ -420,9 +415,41 @@ void __init acpi_mmcfg_init(void)
(pci_mmcfg_config[0].address == 0))
return;
- if (pci_mmcfg_arch_init()) {
+ if (valid)
pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
+}
+
+int pci_mmcfg_reserved(uint64_t address, unsigned int segment,
+ unsigned int start_bus, unsigned int end_bus,
+ unsigned int flags)
+{
+ unsigned int i;
+
+ if (flags & ~XEN_PCI_MMCFG_RESERVED)
+ return -EINVAL;
+
+ for (i = 0; i < pci_mmcfg_config_num; ++i) {
+ const typeof(pci_mmcfg_config[0]) *cfg = &pci_mmcfg_config[i];
+
+ if (cfg->pci_segment == segment &&
+ cfg->start_bus_number == start_bus &&
+ cfg->end_bus_number == end_bus) {
+ if (cfg->address != address) {
+ printk(KERN_WARNING
+ "Base address presented for segment %04x bus %02x-%02x"
+ " (%08" PRIx64 ") does not match previously obtained"
+ " one (%08" PRIx64 ")\n",
+ segment, start_bus, end_bus, address, cfg->address);
+ return -EIO;
+ }
+ if (flags & XEN_PCI_MMCFG_RESERVED)
+ return pci_mmcfg_arch_enable(i);
+ pci_mmcfg_arch_disable(i);
+ return 0;
+ }
}
+
+ return -ENODEV;
}
/**
Index: xen-4.1.3-testing/xen/arch/x86/x86_64/mmconfig_64.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/x86_64/mmconfig_64.c
+++ xen-4.1.3-testing/xen/arch/x86/x86_64/mmconfig_64.c
@@ -23,7 +23,7 @@ struct mmcfg_virt {
char __iomem *virt;
};
static struct mmcfg_virt *pci_mmcfg_virt;
-static int __initdata mmcfg_pci_segment_shift;
+static unsigned int mmcfg_pci_segment_shift;
static char __iomem *get_virt(unsigned int seg, unsigned int *bus)
{
@@ -112,7 +112,8 @@ int pci_mmcfg_write(unsigned int seg, un
return 0;
}
-static void __iomem * __init mcfg_ioremap(struct acpi_mcfg_allocation *cfg)
+static void __iomem *mcfg_ioremap(const struct acpi_mcfg_allocation *cfg,
+ unsigned int prot)
{
unsigned long virt, size;
@@ -126,19 +127,55 @@ static void __iomem * __init mcfg_iorema
if (map_pages_to_xen(virt,
(cfg->address >> PAGE_SHIFT) +
(cfg->start_bus_number << (20 - PAGE_SHIFT)),
- size >> PAGE_SHIFT, PAGE_HYPERVISOR_NOCACHE))
+ size >> PAGE_SHIFT, prot))
return NULL;
return (void __iomem *) virt;
}
+int pci_mmcfg_arch_enable(unsigned int idx)
+{
+ const typeof(pci_mmcfg_config[0]) *cfg = pci_mmcfg_virt[idx].cfg;
+
+ if (pci_mmcfg_virt[idx].virt)
+ return 0;
+ pci_mmcfg_virt[idx].virt = mcfg_ioremap(cfg, PAGE_HYPERVISOR_NOCACHE);
+ if (!pci_mmcfg_virt[idx].virt) {
+ printk(KERN_ERR "PCI: Cannot map MCFG aperture for segment %04x\n",
+ cfg->pci_segment);
+ return -ENOMEM;
+ }
+ printk(KERN_INFO "PCI: Using MCFG for segment %04x bus %02x-%02x\n",
+ cfg->pci_segment, cfg->start_bus_number, cfg->end_bus_number);
+ return 0;
+}
+
+void pci_mmcfg_arch_disable(unsigned int idx)
+{
+ const typeof(pci_mmcfg_config[0]) *cfg = pci_mmcfg_virt[idx].cfg;
+
+ pci_mmcfg_virt[idx].virt = NULL;
+ /*
+ * Don't use destroy_xen_mappings() here, or make sure that at least
+ * the necessary L4 entries get populated (so that they get properly
+ * propagated to guest domains' page tables).
+ */
+ mcfg_ioremap(cfg, 0);
+ printk(KERN_WARNING "PCI: Not using MCFG for segment %04x bus %02x-%02x\n",
+ cfg->pci_segment, cfg->start_bus_number, cfg->end_bus_number);
+}
+
int __init pci_mmcfg_arch_init(void)
{
int i;
+ if (pci_mmcfg_virt)
+ return 0;
+
pci_mmcfg_virt = xmalloc_array(struct mmcfg_virt, pci_mmcfg_config_num);
if (pci_mmcfg_virt == NULL) {
printk(KERN_ERR "PCI: Can not allocate memory for mmconfig structures\n");
+ pci_mmcfg_config_num = 0;
return 0;
}
memset(pci_mmcfg_virt, 0, sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num);
@@ -149,34 +186,5 @@ int __init pci_mmcfg_arch_init(void)
++mmcfg_pci_segment_shift;
}
mmcfg_pci_segment_shift += 20;
- for (i = 0; i < pci_mmcfg_config_num; ++i) {
- pci_mmcfg_virt[i].virt = mcfg_ioremap(&pci_mmcfg_config[i]);
- if (!pci_mmcfg_virt[i].virt) {
- printk(KERN_ERR "PCI: Cannot map mmconfig aperture for "
- "segment %d\n",
- pci_mmcfg_config[i].pci_segment);
- pci_mmcfg_arch_free();
- return 0;
- }
- }
return 1;
}
-
-void __init pci_mmcfg_arch_free(void)
-{
- int i;
-
- if (pci_mmcfg_virt == NULL)
- return;
-
- for (i = 0; i < pci_mmcfg_config_num; ++i) {
- if (pci_mmcfg_virt[i].virt) {
- iounmap(pci_mmcfg_virt[i].virt);
- pci_mmcfg_virt[i].virt = NULL;
- pci_mmcfg_virt[i].cfg = NULL;
- }
- }
-
- xfree(pci_mmcfg_virt);
- pci_mmcfg_virt = NULL;
-}
Index: xen-4.1.3-testing/xen/arch/x86/x86_64/physdev.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/x86_64/physdev.c
+++ xen-4.1.3-testing/xen/arch/x86/x86_64/physdev.c
@@ -54,6 +54,10 @@
#define physdev_get_free_pirq compat_physdev_get_free_pirq
#define physdev_get_free_pirq_t physdev_get_free_pirq_compat_t
+#define xen_physdev_pci_mmcfg_reserved physdev_pci_mmcfg_reserved
+CHECK_physdev_pci_mmcfg_reserved;
+#undef xen_physdev_pci_mmcfg_reserved
+
#define COMPAT
#undef guest_handle_okay
#define guest_handle_okay compat_handle_okay
Index: xen-4.1.3-testing/xen/include/public/physdev.h
===================================================================
--- xen-4.1.3-testing.orig/xen/include/public/physdev.h
+++ xen-4.1.3-testing/xen/include/public/physdev.h
@@ -263,6 +263,19 @@ struct physdev_get_free_pirq {
typedef struct physdev_get_free_pirq physdev_get_free_pirq_t;
DEFINE_XEN_GUEST_HANDLE(physdev_get_free_pirq_t);
+#define XEN_PCI_MMCFG_RESERVED 0x1
+
+#define PHYSDEVOP_pci_mmcfg_reserved 24
+struct physdev_pci_mmcfg_reserved {
+ uint64_t address;
+ uint16_t segment;
+ uint8_t start_bus;
+ uint8_t end_bus;
+ uint32_t flags;
+};
+typedef struct physdev_pci_mmcfg_reserved physdev_pci_mmcfg_reserved_t;
+DEFINE_XEN_GUEST_HANDLE(physdev_pci_mmcfg_reserved_t);
+
/*
* Notify that some PIRQ-bound event channels have been unmasked.
* ** This command is obsolete since interface version 0x00030202 and is **
Index: xen-4.1.3-testing/xen/include/xlat.lst
===================================================================
--- xen-4.1.3-testing.orig/xen/include/xlat.lst
+++ xen-4.1.3-testing/xen/include/xlat.lst
@@ -60,6 +60,7 @@
! memory_map memory.h
! memory_reservation memory.h
! pod_target memory.h
+? physdev_pci_mmcfg_reserved physdev.h
! sched_poll sched.h
? sched_remote_shutdown sched.h
? sched_shutdown sched.h

View File

@ -1,63 +0,0 @@
References: bnc#701686
# HG changeset patch
# User Jan Beulich <jbeulich@novell.com>
# Date 1313503555 -3600
# Node ID fc2be6cb89ad49efd90fe1b650f7efaab72f61b2
# Parent 5c1ebc117f9901bc155d2b92ae902a4144767dfb
x86: simplify (and fix) clear_IO_APIC{,_pin}()
These are used during bootup and (emergency) shutdown only, and their
only purpose is to get the actual IO-APIC's RTE(s) cleared.
Consequently, only the "raw" accessors should be used (and the ones
going through interrupt remapping code can be skipped), with the
exception of determining the delivery mode: This one must always go
through the interrupt remapping path, as in the VT-d case the actual
IO-APIC's RTE will have the delivery mode always set to zero (which
before possibly could have resulted in such an entry getting cleared
in the "raw" pass, though I haven't observed this case in practice).
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Index: xen-4.1.3-testing/xen/arch/x86/io_apic.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/io_apic.c
+++ xen-4.1.3-testing/xen/arch/x86/io_apic.c
@@ -458,14 +458,12 @@ static void eoi_IO_APIC_irq(unsigned int
spin_unlock_irqrestore(&ioapic_lock, flags);
}
-#define clear_IO_APIC_pin(a,p) __clear_IO_APIC_pin(a,p,0)
-#define clear_IO_APIC_pin_raw(a,p) __clear_IO_APIC_pin(a,p,1)
-static void __clear_IO_APIC_pin(unsigned int apic, unsigned int pin, int raw)
+static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin)
{
struct IO_APIC_route_entry entry;
/* Check delivery_mode to be sure we're not clearing an SMI pin */
- entry = ioapic_read_entry(apic, pin, raw);
+ entry = __ioapic_read_entry(apic, pin, FALSE);
if (entry.delivery_mode == dest_SMI)
return;
@@ -474,7 +472,7 @@ static void __clear_IO_APIC_pin(unsigned
*/
memset(&entry, 0, sizeof(entry));
entry.mask = 1;
- ioapic_write_entry(apic, pin, raw, entry);
+ __ioapic_write_entry(apic, pin, TRUE, entry);
}
static void clear_IO_APIC (void)
@@ -482,10 +480,8 @@ static void clear_IO_APIC (void)
int apic, pin;
for (apic = 0; apic < nr_ioapics; apic++) {
- for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
+ for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
clear_IO_APIC_pin(apic, pin);
- clear_IO_APIC_pin_raw(apic, pin);
- }
}
}

View File

@ -1,383 +0,0 @@
# HG changeset patch
# User Jan Beulich <jbeulich@novell.com>
# Date 1313744066 -3600
# Node ID 29aeed4979a78f26519f5fde8a405f8438297ab9
# Parent fc2be6cb89ad49efd90fe1b650f7efaab72f61b2
x86: make run-time part of trampoline relocatable
In order to eliminate an initial hack in the EFI boot code (where
memory for the trampoline was just "claimed" instead of properly
allocated), the trampoline code must no longer make assumption on the
address at which it would be located. For the time being, the fixed
address is being retained for the traditional multiboot path.
As an additional benefit (at least from my pov) it allows confining
the visibility of the BOOT_TRAMPOLINE definition to just the boot
code.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Index: xen-4.1.3-testing/xen/arch/x86/boot/Makefile
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/boot/Makefile
+++ xen-4.1.3-testing/xen/arch/x86/boot/Makefile
@@ -2,8 +2,8 @@ obj-y += head.o
head.o: reloc.S
-BOOT_TRAMPOLINE := $(shell sed -n 's,^\#define[[:space:]]\{1\,\}BOOT_TRAMPOLINE[[:space:]]\{1\,\},,p' $(BASEDIR)/include/asm-x86/config.h)
+BOOT_TRAMPOLINE := $(shell sed -n 's,^\#define[[:space:]]\{1\,\}BOOT_TRAMPOLINE[[:space:]]\{1\,\},,p' head.S)
%.S: %.c
RELOC=$(BOOT_TRAMPOLINE) $(MAKE) -f build32.mk $@
-reloc.S: $(BASEDIR)/include/asm-x86/config.h
+reloc.S: head.S
Index: xen-4.1.3-testing/xen/arch/x86/boot/head.S
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/boot/head.S
+++ xen-4.1.3-testing/xen/arch/x86/boot/head.S
@@ -9,7 +9,7 @@
.text
.code32
-#undef bootsym_phys
+#define BOOT_TRAMPOLINE 0x7c000
#define sym_phys(sym) ((sym) - __XEN_VIRT_START)
#define bootsym_phys(sym) ((sym) - trampoline_start + BOOT_TRAMPOLINE)
@@ -189,6 +189,17 @@ __start:
mov %edi,sym_phys(idle_pg_table_l2) + (__PAGE_OFFSET>>18)
#endif
+ /* Apply relocations to bootstrap trampoline. */
+ mov $BOOT_TRAMPOLINE,%edx
+ mov $sym_phys(__trampoline_rel_start),%edi
+ mov %edx,sym_phys(trampoline_phys)
+1:
+ mov (%edi),%eax
+ add %edx,(%edi,%eax)
+ add $4,%edi
+ cmp $sym_phys(__trampoline_rel_stop),%edi
+ jb 1b
+
/* Copy bootstrap trampoline to low memory, below 1MB. */
mov $sym_phys(trampoline_start),%esi
mov $bootsym_phys(trampoline_start),%edi
Index: xen-4.1.3-testing/xen/arch/x86/boot/trampoline.S
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/boot/trampoline.S
+++ xen-4.1.3-testing/xen/arch/x86/boot/trampoline.S
@@ -4,6 +4,13 @@
#undef bootsym
#define bootsym(s) ((s)-trampoline_start)
+#define bootsym_rel(sym, off, opnd...) \
+ bootsym(sym),##opnd; \
+111:; \
+ .pushsection .trampoline_rel, "a"; \
+ .long 111b - (off) - .; \
+ .popsection
+
.globl trampoline_realmode_entry
trampoline_realmode_entry:
mov %cs,%ax
@@ -17,11 +24,11 @@ trampoline_realmode_entry:
xor %ax, %ax
inc %ax
lmsw %ax # CR0.PE = 1 (enter protected mode)
- ljmpl $BOOT_CS32,$bootsym_phys(trampoline_protmode_entry)
+ ljmpl $BOOT_CS32,$bootsym_rel(trampoline_protmode_entry,6)
idt_48: .word 0, 0, 0 # base = limit = 0
gdt_48: .word 6*8-1
- .long bootsym_phys(trampoline_gdt)
+ .long bootsym_rel(trampoline_gdt,4)
trampoline_gdt:
/* 0x0000: unused */
.quad 0x0000000000000000
@@ -32,11 +39,16 @@ trampoline_gdt:
/* 0x0018: ring 0 data */
.quad 0x00cf92000000ffff
/* 0x0020: real-mode code @ BOOT_TRAMPOLINE */
- .long 0x0000ffff | ((BOOT_TRAMPOLINE & 0x00ffff) << 16)
- .long 0x00009a00 | ((BOOT_TRAMPOLINE & 0xff0000) >> 16)
+ .long 0x0000ffff
+ .long 0x00009a00
/* 0x0028: real-mode data @ BOOT_TRAMPOLINE */
- .long 0x0000ffff | ((BOOT_TRAMPOLINE & 0x00ffff) << 16)
- .long 0x00009200 | ((BOOT_TRAMPOLINE & 0xff0000) >> 16)
+ .long 0x0000ffff
+ .long 0x00009200
+
+ .pushsection .trampoline_rel, "a"
+ .long trampoline_gdt + BOOT_PSEUDORM_CS + 2 - .
+ .long trampoline_gdt + BOOT_PSEUDORM_DS + 2 - .
+ .popsection
.globl cpuid_ext_features
cpuid_ext_features:
@@ -66,11 +78,11 @@ trampoline_protmode_entry:
/* Load pagetable base register. */
mov $sym_phys(idle_pg_table),%eax
- add bootsym_phys(trampoline_xen_phys_start),%eax
+ add bootsym_rel(trampoline_xen_phys_start,4,%eax)
mov %eax,%cr3
/* Set up EFER (Extended Feature Enable Register). */
- mov bootsym_phys(cpuid_ext_features),%edi
+ mov bootsym_rel(cpuid_ext_features,4,%edi)
test $0x20100800,%edi /* SYSCALL/SYSRET, No Execute, Long Mode? */
jz .Lskip_efer
movl $MSR_EFER,%ecx
@@ -93,7 +105,7 @@ trampoline_protmode_entry:
#if defined(__x86_64__)
/* Now in compatibility mode. Long-jump into 64-bit mode. */
- ljmp $BOOT_CS64,$bootsym_phys(start64)
+ ljmp $BOOT_CS64,$bootsym_rel(start64,6)
.code64
start64:
Index: xen-4.1.3-testing/xen/arch/x86/boot/wakeup.S
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/boot/wakeup.S
+++ xen-4.1.3-testing/xen/arch/x86/boot/wakeup.S
@@ -42,15 +42,13 @@ ENTRY(wakeup_start)
# boot trampoline is under 1M, and shift its start into
# %fs to reference symbols in that area
- movl $BOOT_TRAMPOLINE, %eax
- shrl $4, %eax
- movl %eax, %fs
+ mov wakesym(trampoline_seg), %fs
lidt %fs:bootsym(idt_48)
lgdt %fs:bootsym(gdt_48)
movw $1, %ax
lmsw %ax # Turn on CR0.PE
- ljmpl $BOOT_CS32, $bootsym_phys(wakeup_32)
+ ljmpl $BOOT_CS32, $bootsym_rel(wakeup_32, 6)
/* This code uses an extended set of video mode numbers. These include:
* Aliases for standard modes
@@ -103,6 +101,10 @@ real_magic: .long 0x12345678
.globl video_mode, video_flags
video_mode: .long 0
video_flags: .long 0
+trampoline_seg: .word BOOT_TRAMPOLINE >> 4
+ .pushsection .trampoline_seg, "a"
+ .long trampoline_seg - .
+ .popsection
.code32
@@ -114,11 +116,11 @@ wakeup_32:
mov $BOOT_DS, %eax
mov %eax, %ds
mov %eax, %ss
- mov $bootsym_phys(early_stack), %esp
+ mov $bootsym_rel(early_stack, 4, %esp)
# check saved magic again
mov $sym_phys(saved_magic), %eax
- add bootsym_phys(trampoline_xen_phys_start), %eax
+ add bootsym_rel(trampoline_xen_phys_start, 4, %eax)
mov (%eax), %eax
cmp $0x9abcdef0, %eax
jne bogus_saved_magic
@@ -131,12 +133,12 @@ wakeup_32:
/* Load pagetable base register */
mov $sym_phys(idle_pg_table),%eax
- add bootsym_phys(trampoline_xen_phys_start),%eax
+ add bootsym_rel(trampoline_xen_phys_start,4,%eax)
mov %eax,%cr3
/* Will cpuid feature change after resume? */
/* Set up EFER (Extended Feature Enable Register). */
- mov bootsym_phys(cpuid_ext_features),%edi
+ mov bootsym_rel(cpuid_ext_features,4,%edi)
test $0x20100800,%edi /* SYSCALL/SYSRET, No Execute, Long Mode? */
jz .Lskip_eferw
movl $MSR_EFER,%ecx
@@ -162,7 +164,7 @@ wakeup_32:
#if defined(__x86_64__)
/* Now in compatibility mode. Long-jump to 64-bit mode */
- ljmp $BOOT_CS64, $bootsym_phys(wakeup_64)
+ ljmp $BOOT_CS64, $bootsym_rel(wakeup_64,6)
.code64
wakeup_64:
Index: xen-4.1.3-testing/xen/arch/x86/efi/boot.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/efi/boot.c
+++ xen-4.1.3-testing/xen/arch/x86/efi/boot.c
@@ -599,6 +599,9 @@ static void __init relocate_image(unsign
}
}
+extern const s32 __trampoline_rel_start[], __trampoline_rel_stop[];
+extern const s32 __trampoline_seg_start[], __trampoline_seg_stop[];
+
void EFIAPI __init __attribute__((__noreturn__))
efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
@@ -614,9 +617,10 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SY
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *mode_info;
EFI_FILE_HANDLE dir_handle;
union string section = { NULL }, name;
+ const s32 *trampoline_ptr;
struct e820entry *e;
u64 efer;
- bool_t base_video = 0, trampoline_okay = 0;
+ bool_t base_video = 0;
efi_ih = ImageHandle;
efi_bs = SystemTable->BootServices;
@@ -914,15 +918,27 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SY
dmi_efi_get_table((void *)(long)efi.smbios);
/* Allocate space for trampoline (in first Mb). */
- cfg.addr = BOOT_TRAMPOLINE;
+ cfg.addr = 0x100000;
cfg.size = trampoline_end - trampoline_start;
- status = efi_bs->AllocatePages(AllocateAddress, EfiLoaderData,
+ status = efi_bs->AllocatePages(AllocateMaxAddress, EfiLoaderData,
PFN_UP(cfg.size), &cfg.addr);
if ( EFI_ERROR(status) )
{
cfg.addr = 0;
- PrintErr(L"Note: Trampoline area is in use\r\n");
+ blexit(L"No memory for trampoline\r\n");
}
+ trampoline_phys = cfg.addr;
+ /* Apply relocations to trampoline. */
+ for ( trampoline_ptr = __trampoline_rel_start;
+ trampoline_ptr < __trampoline_rel_stop;
+ ++trampoline_ptr )
+ *(u32 *)(*trampoline_ptr + (long)trampoline_ptr) +=
+ trampoline_phys;
+ for ( trampoline_ptr = __trampoline_seg_start;
+ trampoline_ptr < __trampoline_seg_stop;
+ ++trampoline_ptr )
+ *(u16 *)(*trampoline_ptr + (long)trampoline_ptr) =
+ trampoline_phys >> 4;
/* Initialise L2 identity-map and xen page table entries (16MB). */
for ( i = 0; i < 8; ++i )
@@ -1096,14 +1112,8 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SY
e->type = type;
++e820nr;
}
- if ( type == E820_RAM && e->addr <= BOOT_TRAMPOLINE &&
- e->addr + e->size >= BOOT_TRAMPOLINE + cfg.size )
- trampoline_okay = 1;
}
- if ( !trampoline_okay )
- blexit(L"Trampoline area unavailable\r\n");
-
status = efi_bs->ExitBootServices(ImageHandle, map_key);
if ( EFI_ERROR(status) )
PrintErrMesg(L"Cannot exit boot services", status);
@@ -1117,7 +1127,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SY
efi_fw_vendor = (void *)efi_fw_vendor + DIRECTMAP_VIRT_START;
relocate_image(__XEN_VIRT_START - xen_phys_start);
- memcpy((void *)(long)BOOT_TRAMPOLINE, trampoline_start, cfg.size);
+ memcpy((void *)trampoline_phys, trampoline_start, cfg.size);
/* Set system registers and transfer control. */
asm volatile("pushq $0\n\tpopfq");
Index: xen-4.1.3-testing/xen/arch/x86/smpboot.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/smpboot.c
+++ xen-4.1.3-testing/xen/arch/x86/smpboot.c
@@ -49,6 +49,8 @@
#define setup_trampoline() (bootsym_phys(trampoline_realmode_entry))
+unsigned long __read_mostly trampoline_phys;
+
/* Set if we find a B stepping CPU */
static int smp_b_stepping;
Index: xen-4.1.3-testing/xen/arch/x86/x86_32/mm.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/x86_32/mm.c
+++ xen-4.1.3-testing/xen/arch/x86/x86_32/mm.c
@@ -22,6 +22,7 @@
#include <xen/lib.h>
#include <xen/init.h>
#include <xen/mm.h>
+#include <xen/pfn.h>
#include <xen/sched.h>
#include <xen/guest_access.h>
#include <asm/current.h>
@@ -166,8 +167,9 @@ void __init zap_low_mappings(l2_pgentry_
flush_all(FLUSH_TLB_GLOBAL);
/* Replace with mapping of the boot trampoline only. */
- map_pages_to_xen(BOOT_TRAMPOLINE, BOOT_TRAMPOLINE >> PAGE_SHIFT,
- 0x10, __PAGE_HYPERVISOR);
+ map_pages_to_xen(trampoline_phys, trampoline_phys >> PAGE_SHIFT,
+ PFN_UP(trampoline_end - trampoline_start),
+ __PAGE_HYPERVISOR);
}
void __init subarch_init_memory(void)
Index: xen-4.1.3-testing/xen/arch/x86/x86_64/mm.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/x86_64/mm.c
+++ xen-4.1.3-testing/xen/arch/x86/x86_64/mm.c
@@ -830,7 +830,7 @@ void __init zap_low_mappings(void)
flush_local(FLUSH_TLB_GLOBAL);
/* Replace with mapping of the boot trampoline only. */
- map_pages_to_xen(BOOT_TRAMPOLINE, BOOT_TRAMPOLINE >> PAGE_SHIFT,
+ map_pages_to_xen(trampoline_phys, trampoline_phys >> PAGE_SHIFT,
PFN_UP(trampoline_end - trampoline_start),
__PAGE_HYPERVISOR);
}
Index: xen-4.1.3-testing/xen/arch/x86/xen.lds.S
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/xen.lds.S
+++ xen-4.1.3-testing/xen/arch/x86/xen.lds.S
@@ -103,6 +103,13 @@ SECTIONS
*(.init.data)
*(.init.data.rel)
*(.init.data.rel.*)
+ . = ALIGN(4);
+ __trampoline_rel_start = .;
+ *(.trampoline_rel)
+ __trampoline_rel_stop = .;
+ __trampoline_seg_start = .;
+ *(.trampoline_seg)
+ __trampoline_seg_stop = .;
} :text
. = ALIGN(32);
.init.setup : {
Index: xen-4.1.3-testing/xen/include/asm-x86/config.h
===================================================================
--- xen-4.1.3-testing.orig/xen/include/asm-x86/config.h
+++ xen-4.1.3-testing/xen/include/asm-x86/config.h
@@ -95,13 +95,13 @@
/* Primary stack is restricted to 8kB by guard pages. */
#define PRIMARY_STACK_SIZE 8192
-#define BOOT_TRAMPOLINE 0x7c000
+#ifndef __ASSEMBLY__
+extern unsigned long trampoline_phys;
#define bootsym_phys(sym) \
- (((unsigned long)&(sym)-(unsigned long)&trampoline_start)+BOOT_TRAMPOLINE)
+ (((unsigned long)&(sym)-(unsigned long)&trampoline_start)+trampoline_phys)
#define bootsym(sym) \
(*RELOC_HIDE((typeof(&(sym)))__va(__pa(&(sym))), \
- BOOT_TRAMPOLINE-__pa(trampoline_start)))
-#ifndef __ASSEMBLY__
+ trampoline_phys-__pa(trampoline_start)))
extern char trampoline_start[], trampoline_end[];
extern char trampoline_realmode_entry[];
extern unsigned int trampoline_xen_phys_start;

View File

@ -1,370 +0,0 @@
# HG changeset patch
# User Jan Beulich <jbeulich@novell.com>
# Date 1313744120 -3600
# Node ID e35c5202625ef5534561f84352833ad9467d986c
# Parent dd90b59cb11c60c48e174c899190e2967341fe32
x86-64/EFI: construct EDD data from device path protocol information
In the absence of a BIOS to handle INT13 requests, this information
must be constructed artificially instead when booted from EFI.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Index: xen-4.1.2-testing/xen/arch/x86/boot/edd.S
===================================================================
--- xen-4.1.2-testing.orig/xen/arch/x86/boot/edd.S
+++ xen-4.1.2-testing/xen/arch/x86/boot/edd.S
@@ -16,21 +16,13 @@
* Updated and ported for Xen by Keir Fraser <keir@xensource.com> June 2007
*/
+#include <asm/edd.h>
+
.code16
/* Offset of disc signature in the MBR. */
#define EDD_MBR_SIG_OFFSET 0x1B8
-/* Maximum number of EDD information structures at boot_edd_info. */
-#define EDD_INFO_MAX 6
-
-/* Maximum number of MBR signatures at boot_mbr_signature. */
-#define EDD_MBR_SIG_MAX 16
-
-/* Size of components of EDD information structure. */
-#define EDDEXTSIZE 8
-#define EDDPARMSIZE 74
-
get_edd:
cmpb $2, bootsym(opt_edd) # edd=off ?
je edd_done
Index: xen-4.1.2-testing/xen/arch/x86/efi/boot.c
===================================================================
--- xen-4.1.2-testing.orig/xen/arch/x86/efi/boot.c
+++ xen-4.1.2-testing/xen/arch/x86/efi/boot.c
@@ -16,6 +16,7 @@
#include <xen/stringify.h>
#include <xen/vga.h>
#include <asm/e820.h>
+#include <asm/edd.h>
#include <asm/mm.h>
#include <asm/msr.h>
#include <asm/processor.h>
@@ -539,6 +540,18 @@ static void __init split_value(char *s)
*s = 0;
}
+static void __init edd_put_string(u8 *dst, size_t n, const char *src)
+{
+ while ( n-- && *src )
+ *dst++ = *src++;
+ if ( *src )
+ PrintErrMesg(L"Internal error populating EDD info",
+ EFI_BUFFER_TOO_SMALL);
+ while ( n-- )
+ *dst++ = ' ';
+}
+#define edd_put_string(d, s) edd_put_string(d, ARRAY_SIZE(d), s)
+
static int __init set_color(u32 mask, int bpp, u8 *pos, u8 *sz)
{
if ( bpp < 0 )
@@ -607,6 +620,8 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SY
{
static EFI_GUID __initdata loaded_image_guid = LOADED_IMAGE_PROTOCOL;
static EFI_GUID __initdata gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
+ static EFI_GUID __initdata bio_guid = BLOCK_IO_PROTOCOL;
+ static EFI_GUID __initdata devp_guid = DEVICE_PATH_PROTOCOL;
EFI_LOADED_IMAGE *loaded_image;
EFI_STATUS status;
unsigned int i, argc;
@@ -887,7 +902,148 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SY
place_string(&mbi.mem_upper, NULL);
- /* XXX Collect EDD info. */
+ /* Collect EDD info. */
+ BUILD_BUG_ON(offsetof(struct edd_info, edd_device_params) != EDDEXTSIZE);
+ BUILD_BUG_ON(sizeof(struct edd_device_params) != EDDPARMSIZE);
+ size = 0;
+ status = efi_bs->LocateHandle(ByProtocol, &bio_guid, NULL, &size, NULL);
+ if ( status == EFI_BUFFER_TOO_SMALL )
+ status = efi_bs->AllocatePool(EfiLoaderData, size, (void **)&handles);
+ if ( !EFI_ERROR(status) )
+ status = efi_bs->LocateHandle(ByProtocol, &bio_guid, NULL, &size,
+ handles);
+ if ( EFI_ERROR(status) )
+ size = 0;
+ for ( i = 0; i < size / sizeof(*handles); ++i )
+ {
+ EFI_BLOCK_IO *bio;
+ EFI_DEV_PATH_PTR devp;
+ struct edd_info *info = boot_edd_info + boot_edd_info_nr;
+ struct edd_device_params *params = &info->edd_device_params;
+ enum { root, acpi, pci, ctrlr } state = root;
+
+ status = efi_bs->HandleProtocol(handles[i], &bio_guid, (void **)&bio);
+ if ( EFI_ERROR(status) ||
+ bio->Media->RemovableMedia ||
+ bio->Media->LogicalPartition )
+ continue;
+ if ( boot_edd_info_nr < EDD_INFO_MAX )
+ {
+ info->device = 0x80 + boot_edd_info_nr; /* fake */
+ info->version = 0x11;
+ params->length = offsetof(struct edd_device_params, dpte_ptr);
+ params->number_of_sectors = bio->Media->LastBlock + 1;
+ params->bytes_per_sector = bio->Media->BlockSize;
+ params->dpte_ptr = ~0;
+ }
+ ++boot_edd_info_nr;
+ status = efi_bs->HandleProtocol(handles[i], &devp_guid,
+ (void **)&devp);
+ if ( EFI_ERROR(status) )
+ continue;
+ for ( ; !IsDevicePathEnd(devp.DevPath);
+ devp.DevPath = NextDevicePathNode(devp.DevPath) )
+ {
+ switch ( DevicePathType(devp.DevPath) )
+ {
+ const u8 *p;
+
+ case ACPI_DEVICE_PATH:
+ if ( state != root || boot_edd_info_nr > EDD_INFO_MAX )
+ break;
+ switch ( DevicePathSubType(devp.DevPath) )
+ {
+ case ACPI_DP:
+ if ( devp.Acpi->HID != EISA_PNP_ID(0xA03) &&
+ devp.Acpi->HID != EISA_PNP_ID(0xA08) )
+ break;
+ params->interface_path.pci.bus = devp.Acpi->UID;
+ state = acpi;
+ break;
+ case EXPANDED_ACPI_DP:
+ /* XXX */
+ break;
+ }
+ break;
+ case HARDWARE_DEVICE_PATH:
+ if ( state != acpi ||
+ DevicePathSubType(devp.DevPath) != HW_PCI_DP ||
+ boot_edd_info_nr > EDD_INFO_MAX )
+ break;
+ state = pci;
+ edd_put_string(params->host_bus_type, "PCI");
+ params->interface_path.pci.slot = devp.Pci->Device;
+ params->interface_path.pci.function = devp.Pci->Function;
+ break;
+ case MESSAGING_DEVICE_PATH:
+ if ( state != pci || boot_edd_info_nr > EDD_INFO_MAX )
+ break;
+ state = ctrlr;
+ switch ( DevicePathSubType(devp.DevPath) )
+ {
+ case MSG_ATAPI_DP:
+ edd_put_string(params->interface_type, "ATAPI");
+ params->interface_path.pci.channel =
+ devp.Atapi->PrimarySecondary;
+ params->device_path.atapi.device = devp.Atapi->SlaveMaster;
+ params->device_path.atapi.lun = devp.Atapi->Lun;
+ break;
+ case MSG_SCSI_DP:
+ edd_put_string(params->interface_type, "SCSI");
+ params->device_path.scsi.id = devp.Scsi->Pun;
+ params->device_path.scsi.lun = devp.Scsi->Lun;
+ break;
+ case MSG_FIBRECHANNEL_DP:
+ edd_put_string(params->interface_type, "FIBRE");
+ params->device_path.fibre.wwid = devp.FibreChannel->WWN;
+ params->device_path.fibre.lun = devp.FibreChannel->Lun;
+ break;
+ case MSG_1394_DP:
+ edd_put_string(params->interface_type, "1394");
+ params->device_path.i1394.eui = devp.F1394->Guid;
+ break;
+ case MSG_USB_DP:
+ case MSG_USB_CLASS_DP:
+ edd_put_string(params->interface_type, "USB");
+ break;
+ case MSG_I2O_DP:
+ edd_put_string(params->interface_type, "I2O");
+ params->device_path.i2o.identity_tag = devp.I2O->Tid;
+ break;
+ default:
+ continue;
+ }
+ info->version = 0x30;
+ params->length = sizeof(struct edd_device_params);
+ params->key = 0xbedd;
+ params->device_path_info_length =
+ sizeof(struct edd_device_params) -
+ offsetof(struct edd_device_params, key);
+ for ( p = (const u8 *)&params->key; p < &params->checksum; ++p )
+ params->checksum -= *p;
+ break;
+ case MEDIA_DEVICE_PATH:
+ if ( DevicePathSubType(devp.DevPath) == MEDIA_HARDDRIVE_DP &&
+ devp.HardDrive->MBRType == MBR_TYPE_PCAT &&
+ boot_mbr_signature_nr < EDD_MBR_SIG_MAX )
+ {
+ struct mbr_signature *sig = boot_mbr_signature +
+ boot_mbr_signature_nr;
+
+ sig->device = 0x80 + boot_edd_info_nr; /* fake */
+ memcpy(&sig->signature, devp.HardDrive->Signature,
+ sizeof(sig->signature));
+ ++boot_mbr_signature_nr;
+ }
+ break;
+ }
+ }
+ }
+ if ( handles )
+ efi_bs->FreePool(handles);
+ if ( boot_edd_info_nr > EDD_INFO_MAX )
+ boot_edd_info_nr = EDD_INFO_MAX;
+
/* XXX Collect EDID info. */
if ( cpuid_eax(0x80000000) > 0x80000000 )
Index: xen-4.1.2-testing/xen/include/asm-x86/edd.h
===================================================================
--- xen-4.1.2-testing.orig/xen/include/asm-x86/edd.h
+++ xen-4.1.2-testing/xen/include/asm-x86/edd.h
@@ -23,6 +23,8 @@
#ifndef __XEN_EDD_H__
#define __XEN_EDD_H__
+#ifndef __ASSEMBLY__
+
struct edd_info {
/* Int13, Fn48: Check Extensions Present. */
u8 device; /* %dl: device */
@@ -33,10 +35,106 @@ struct edd_info {
u8 legacy_max_head; /* %dh: maximum head number */
u8 legacy_sectors_per_track; /* %cl[5:0]: maximum sector number */
/* Int13, Fn41: Get Device Parameters (as filled into %ds:%esi). */
- struct {
+ struct edd_device_params {
u16 length;
- u8 data[72];
- } edd_device_params;
+ u16 info_flags;
+ u32 num_default_cylinders;
+ u32 num_default_heads;
+ u32 sectors_per_track;
+ u64 number_of_sectors;
+ u16 bytes_per_sector;
+ u32 dpte_ptr; /* 0xFFFFFFFF for our purposes */
+ u16 key; /* = 0xBEDD */
+ u8 device_path_info_length;
+ u8 reserved2;
+ u16 reserved3;
+ u8 host_bus_type[4];
+ u8 interface_type[8];
+ union {
+ struct {
+ u16 base_address;
+ u16 reserved1;
+ u32 reserved2;
+ } __attribute__ ((packed)) isa;
+ struct {
+ u8 bus;
+ u8 slot;
+ u8 function;
+ u8 channel;
+ u32 reserved;
+ } __attribute__ ((packed)) pci;
+ /* pcix is same as pci */
+ struct {
+ u64 reserved;
+ } __attribute__ ((packed)) ibnd;
+ struct {
+ u64 reserved;
+ } __attribute__ ((packed)) xprs;
+ struct {
+ u64 reserved;
+ } __attribute__ ((packed)) htpt;
+ struct {
+ u64 reserved;
+ } __attribute__ ((packed)) unknown;
+ } interface_path;
+ union {
+ struct {
+ u8 device;
+ u8 reserved1;
+ u16 reserved2;
+ u32 reserved3;
+ u64 reserved4;
+ } __attribute__ ((packed)) ata;
+ struct {
+ u8 device;
+ u8 lun;
+ u8 reserved1;
+ u8 reserved2;
+ u32 reserved3;
+ u64 reserved4;
+ } __attribute__ ((packed)) atapi;
+ struct {
+ u16 id;
+ u64 lun;
+ u16 reserved1;
+ u32 reserved2;
+ } __attribute__ ((packed)) scsi;
+ struct {
+ u64 serial_number;
+ u64 reserved;
+ } __attribute__ ((packed)) usb;
+ struct {
+ u64 eui;
+ u64 reserved;
+ } __attribute__ ((packed)) i1394;
+ struct {
+ u64 wwid;
+ u64 lun;
+ } __attribute__ ((packed)) fibre;
+ struct {
+ u64 identity_tag;
+ u64 reserved;
+ } __attribute__ ((packed)) i2o;
+ struct {
+ u32 array_number;
+ u32 reserved1;
+ u64 reserved2;
+ } __attribute__ ((packed)) raid;
+ struct {
+ u8 device;
+ u8 reserved1;
+ u16 reserved2;
+ u32 reserved3;
+ u64 reserved4;
+ } __attribute__ ((packed)) sata;
+ struct {
+ u64 reserved1;
+ u64 reserved2;
+ } __attribute__ ((packed)) unknown;
+ } device_path;
+ u8 reserved4;
+ u8 checksum;
+ } __attribute__ ((packed)) edd_device_params;
} __attribute__ ((packed));
struct mbr_signature {
@@ -51,4 +149,16 @@ extern u8 boot_mbr_signature_nr;
extern struct edd_info boot_edd_info[];
extern u8 boot_edd_info_nr;
+#endif /* __ASSEMBLY__ */
+
+/* Maximum number of EDD information structures at boot_edd_info. */
+#define EDD_INFO_MAX 6
+
+/* Maximum number of MBR signatures at boot_mbr_signature. */
+#define EDD_MBR_SIG_MAX 16
+
+/* Size of components of EDD information structure. */
+#define EDDEXTSIZE 8
+#define EDDPARMSIZE 74
+
#endif /* __XEN_EDD_H__ */

View File

@ -1,62 +0,0 @@
References: bnc#701686
# HG changeset patch
# User Jan Beulich <jbeulich@novell.com>
# Date 1314004270 -3600
# Node ID 25dfe53bb1898b3967ceb71a7eb60a8b760c25fb
# Parent 0849b0e59e2418e8215616df147f955b01b07577
x86/IO-APIC: clear remoteIRR in clear_IO_APIC_pin()
It was found that in a crash scenario, the remoteIRR bit in an IO-APIC
RTE could be left set, causing problems when bringing up a kdump
kernel. While this generally is most important to be taken care of in
the new kernel (which usually would be a native one), it still seems
desirable to also address this problem in Xen so that (a) the problem
doesn't bite Xen when used as a secondary emergency kernel and (b) an
attempt is being made to save un-fixed secondary kernels from running
into said problem.
Based on a Linux patch from suresh.b.siddha@intel.com.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Index: xen-4.1.3-testing/xen/arch/x86/io_apic.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/io_apic.c
+++ xen-4.1.3-testing/xen/arch/x86/io_apic.c
@@ -468,11 +468,35 @@ static void clear_IO_APIC_pin(unsigned i
return;
/*
+ * Make sure the entry is masked and re-read the contents to check
+ * if it is a level triggered pin and if the remoteIRR is set.
+ */
+ if (!entry.mask) {
+ entry.mask = 1;
+ __ioapic_write_entry(apic, pin, FALSE, entry);
+ }
+ entry = __ioapic_read_entry(apic, pin, TRUE);
+
+ if (entry.irr) {
+ /* Make sure the trigger mode is set to level. */
+ if (!entry.trigger) {
+ entry.trigger = 1;
+ __ioapic_write_entry(apic, pin, TRUE, entry);
+ }
+ __io_apic_eoi(apic, entry.vector, pin);
+ }
+
+ /*
* Disable it in the IO-APIC irq-routing table:
*/
memset(&entry, 0, sizeof(entry));
entry.mask = 1;
__ioapic_write_entry(apic, pin, TRUE, entry);
+
+ entry = __ioapic_read_entry(apic, pin, TRUE);
+ if (entry.irr)
+ printk(KERN_ERR "IO-APIC%02x-%u: Unable to reset IRR\n",
+ IO_APIC_ID(apic), pin);
}
static void clear_IO_APIC (void)

View File

@ -1,286 +0,0 @@
# HG changeset patch
# User Jan Beulich <jbeulich@novell.com>
# Date 1314004356 -3600
# Node ID 2029263c501c315fa4d94845e5cfa6a9b0b395d5
# Parent 25dfe53bb1898b3967ceb71a7eb60a8b760c25fb
ACPI: add _PDC input override mechanism
In order to have Dom0 call _PDC with input fully representing Xen's
capabilities, and in order to avoid building knowledge of Xen
implementation details into Dom0, this provides a mechanism by which
the Dom0 kernel can, once it filled the _PDC input buffer according to
its own knowledge, present the buffer to Xen to apply overrides for
the parts of the C-, P-, and T-state management that it controls. This
is particularly to address the dependency of Xen using MWAIT to enter
certain C-states on the availability of the break-on-interrupt
extension (which the Dom0 kernel should have no need to know about).
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Index: xen-4.1.3-testing/xen/arch/ia64/linux-xen/acpi.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/ia64/linux-xen/acpi.c
+++ xen-4.1.3-testing/xen/arch/ia64/linux-xen/acpi.c
@@ -243,6 +243,13 @@ int get_cpu_id(u32 acpi_id)
return -1;
}
+
+int arch_acpi_set_pdc_bits(u32 acpi_id, u32 *pdc, u32 mask)
+{
+ pdc[2] |= ACPI_PDC_EST_CAPABILITY_SMP & mask;
+ return 0;
+}
+
#endif
static int __init
Index: xen-4.1.3-testing/xen/arch/x86/acpi/cpu_idle.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/acpi/cpu_idle.c
+++ xen-4.1.3-testing/xen/arch/x86/acpi/cpu_idle.c
@@ -644,12 +644,6 @@ static int cpuidle_init_cpu(int cpu)
return 0;
}
-#define CPUID_MWAIT_LEAF (5)
-#define CPUID5_ECX_EXTENSIONS_SUPPORTED (0x1)
-#define CPUID5_ECX_INTERRUPT_BREAK (0x2)
-
-#define MWAIT_ECX_INTERRUPT_BREAK (0x1)
-
#define MWAIT_SUBSTATE_MASK (0xf)
#define MWAIT_SUBSTATE_SIZE (4)
Index: xen-4.1.3-testing/xen/arch/x86/acpi/boot.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/acpi/boot.c
+++ xen-4.1.3-testing/xen/arch/x86/acpi/boot.c
@@ -1006,3 +1006,47 @@ unsigned int acpi_get_processor_id(unsig
return INVALID_ACPIID;
}
+
+static void get_mwait_ecx(void *info)
+{
+ *(u32 *)info = cpuid_ecx(CPUID_MWAIT_LEAF);
+}
+
+int arch_acpi_set_pdc_bits(u32 acpi_id, u32 *pdc, u32 mask)
+{
+ unsigned int cpu = get_cpu_id(acpi_id);
+ struct cpuinfo_x86 *c;
+ u32 ecx;
+
+ if (!(acpi_id + 1))
+ c = &boot_cpu_data;
+ else if (cpu >= NR_CPUS || !cpu_online(cpu))
+ return -EINVAL;
+ else
+ c = cpu_data + cpu;
+
+ pdc[2] |= ACPI_PDC_C_CAPABILITY_SMP & mask;
+
+ if (cpu_has(c, X86_FEATURE_EST))
+ pdc[2] |= ACPI_PDC_EST_CAPABILITY_SWSMP & mask;
+
+ if (cpu_has(c, X86_FEATURE_ACPI))
+ pdc[2] |= ACPI_PDC_T_FFH & mask;
+
+ /*
+ * If mwait/monitor or its break-on-interrupt extension are
+ * unsupported, Cx_FFH will be disabled.
+ */
+ if (!cpu_has(c, X86_FEATURE_MWAIT) ||
+ c->cpuid_level < CPUID_MWAIT_LEAF)
+ ecx = 0;
+ else if (c == &boot_cpu_data || cpu == smp_processor_id())
+ ecx = cpuid_ecx(CPUID_MWAIT_LEAF);
+ else
+ on_selected_cpus(cpumask_of(cpu), get_mwait_ecx, &ecx, 1);
+ if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) ||
+ !(ecx & CPUID5_ECX_INTERRUPT_BREAK))
+ pdc[2] &= ~(ACPI_PDC_C_C1_FFH | ACPI_PDC_C_C2C3_FFH);
+
+ return 0;
+}
Index: xen-4.1.3-testing/xen/arch/x86/platform_hypercall.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/platform_hypercall.c
+++ xen-4.1.3-testing/xen/arch/x86/platform_hypercall.c
@@ -419,6 +419,15 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
ret = -EINVAL;
break;
+ case XEN_PM_PDC:
+ {
+ XEN_GUEST_HANDLE(uint32) pdc;
+
+ guest_from_compat_handle(pdc, op->u.set_pminfo.u.pdc);
+ ret = acpi_set_pdc_bits(op->u.set_pminfo.id, pdc);
+ }
+ break;
+
default:
ret = -EINVAL;
break;
Index: xen-4.1.3-testing/xen/drivers/acpi/pmstat.c
===================================================================
--- xen-4.1.3-testing.orig/xen/drivers/acpi/pmstat.c
+++ xen-4.1.3-testing/xen/drivers/acpi/pmstat.c
@@ -521,3 +521,34 @@ int do_pm_op(struct xen_sysctl_pm_op *op
return ret;
}
+
+int acpi_set_pdc_bits(u32 acpi_id, XEN_GUEST_HANDLE(uint32) pdc)
+{
+ u32 bits[3];
+ int ret;
+
+ if ( copy_from_guest(bits, pdc, 2) )
+ ret = -EFAULT;
+ else if ( bits[0] != ACPI_PDC_REVISION_ID || !bits[1] )
+ ret = -EINVAL;
+ else if ( copy_from_guest_offset(bits + 2, pdc, 2, 1) )
+ ret = -EFAULT;
+ else
+ {
+ u32 mask = 0;
+
+ if ( xen_processor_pmbits & XEN_PROCESSOR_PM_CX )
+ mask |= ACPI_PDC_C_MASK | ACPI_PDC_SMP_C1PT;
+ if ( xen_processor_pmbits & XEN_PROCESSOR_PM_PX )
+ mask |= ACPI_PDC_P_MASK | ACPI_PDC_SMP_C1PT;
+ if ( xen_processor_pmbits & XEN_PROCESSOR_PM_TX )
+ mask |= ACPI_PDC_T_MASK | ACPI_PDC_SMP_C1PT;
+ bits[2] &= (ACPI_PDC_C_MASK | ACPI_PDC_P_MASK | ACPI_PDC_T_MASK |
+ ACPI_PDC_SMP_C1PT) & ~mask;
+ ret = arch_acpi_set_pdc_bits(acpi_id, bits, mask);
+ }
+ if ( !ret )
+ ret = copy_to_guest_offset(pdc, 2, bits + 2, 1);
+
+ return ret;
+}
Index: xen-4.1.3-testing/xen/include/acpi/cpufreq/processor_perf.h
===================================================================
--- xen-4.1.3-testing.orig/xen/include/acpi/cpufreq/processor_perf.h
+++ xen-4.1.3-testing/xen/include/acpi/cpufreq/processor_perf.h
@@ -3,10 +3,10 @@
#include <public/platform.h>
#include <public/sysctl.h>
+#include <xen/acpi.h>
#define XEN_PX_INIT 0x80000000
-int get_cpu_id(u32);
int powernow_cpufreq_init(void);
unsigned int powernow_register_driver(void);
unsigned int get_measured_perf(unsigned int cpu, unsigned int flag);
Index: xen-4.1.3-testing/xen/include/acpi/pdc_intel.h
===================================================================
--- xen-4.1.3-testing.orig/xen/include/acpi/pdc_intel.h
+++ xen-4.1.3-testing/xen/include/acpi/pdc_intel.h
@@ -4,6 +4,8 @@
#ifndef __PDC_INTEL_H__
#define __PDC_INTEL_H__
+#define ACPI_PDC_REVISION_ID 1
+
#define ACPI_PDC_P_FFH (0x0001)
#define ACPI_PDC_C_C1_HALT (0x0002)
#define ACPI_PDC_T_FFH (0x0004)
@@ -14,6 +16,7 @@
#define ACPI_PDC_SMP_T_SWCOORD (0x0080)
#define ACPI_PDC_C_C1_FFH (0x0100)
#define ACPI_PDC_C_C2C3_FFH (0x0200)
+#define ACPI_PDC_SMP_P_HWCOORD (0x0800)
#define ACPI_PDC_EST_CAPABILITY_SMP (ACPI_PDC_SMP_C1PT | \
ACPI_PDC_C_C1_HALT | \
@@ -22,6 +25,7 @@
#define ACPI_PDC_EST_CAPABILITY_SWSMP (ACPI_PDC_SMP_C1PT | \
ACPI_PDC_C_C1_HALT | \
ACPI_PDC_SMP_P_SWCOORD | \
+ ACPI_PDC_SMP_P_HWCOORD | \
ACPI_PDC_P_FFH)
#define ACPI_PDC_C_CAPABILITY_SMP (ACPI_PDC_SMP_C2C3 | \
@@ -30,4 +34,17 @@
ACPI_PDC_C_C1_FFH | \
ACPI_PDC_C_C2C3_FFH)
+#define ACPI_PDC_C_MASK (ACPI_PDC_C_C1_HALT | \
+ ACPI_PDC_C_C1_FFH | \
+ ACPI_PDC_SMP_C2C3 | \
+ ACPI_PDC_SMP_C_SWCOORD | \
+ ACPI_PDC_C_C2C3_FFH)
+
+#define ACPI_PDC_P_MASK (ACPI_PDC_P_FFH | \
+ ACPI_PDC_SMP_P_SWCOORD | \
+ ACPI_PDC_SMP_P_HWCOORD)
+
+#define ACPI_PDC_T_MASK (ACPI_PDC_T_FFH | \
+ ACPI_PDC_SMP_T_SWCOORD)
+
#endif /* __PDC_INTEL_H__ */
Index: xen-4.1.3-testing/xen/include/asm-x86/cpufeature.h
===================================================================
--- xen-4.1.3-testing.orig/xen/include/asm-x86/cpufeature.h
+++ xen-4.1.3-testing/xen/include/asm-x86/cpufeature.h
@@ -151,6 +151,10 @@
#define boot_cpu_has(bit) test_bit(bit, boot_cpu_data.x86_capability)
#define cpufeat_mask(idx) (1u << ((idx) & 31))
+#define CPUID_MWAIT_LEAF 5
+#define CPUID5_ECX_EXTENSIONS_SUPPORTED 0x1
+#define CPUID5_ECX_INTERRUPT_BREAK 0x2
+
#ifdef __i386__
#define cpu_has_vme boot_cpu_has(X86_FEATURE_VME)
#define cpu_has_de boot_cpu_has(X86_FEATURE_DE)
Index: xen-4.1.3-testing/xen/include/public/platform.h
===================================================================
--- xen-4.1.3-testing.orig/xen/include/public/platform.h
+++ xen-4.1.3-testing/xen/include/public/platform.h
@@ -304,6 +304,7 @@ DEFINE_XEN_GUEST_HANDLE(xenpf_getidletim
#define XEN_PM_CX 0
#define XEN_PM_PX 1
#define XEN_PM_TX 2
+#define XEN_PM_PDC 3
/* Px sub info type */
#define XEN_PX_PCT 1
@@ -401,6 +402,7 @@ struct xenpf_set_processor_pminfo {
union {
struct xen_processor_power power;/* Cx: _CST/_CSD */
struct xen_processor_performance perf; /* Px: _PPC/_PCT/_PSS/_PSD */
+ XEN_GUEST_HANDLE(uint32) pdc; /* _PDC */
} u;
};
typedef struct xenpf_set_processor_pminfo xenpf_set_processor_pminfo_t;
Index: xen-4.1.3-testing/xen/include/xen/acpi.h
===================================================================
--- xen-4.1.3-testing.orig/xen/include/xen/acpi.h
+++ xen-4.1.3-testing/xen/include/xen/acpi.h
@@ -334,6 +334,8 @@ static inline int acpi_boot_table_init(v
#endif /*!CONFIG_ACPI_BOOT*/
+int get_cpu_id(u32 acpi_id);
+
unsigned int acpi_register_gsi (u32 gsi, int edge_level, int active_high_low);
int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
@@ -431,6 +433,9 @@ static inline unsigned int acpi_get_csta
static inline void acpi_set_cstate_limit(unsigned int new_limit) { return; }
#endif
+int acpi_set_pdc_bits(u32 acpi_id, XEN_GUEST_HANDLE(uint32));
+int arch_acpi_set_pdc_bits(u32 acpi_id, u32 *, u32 mask);
+
#ifdef CONFIG_ACPI_NUMA
int acpi_get_pxm(acpi_handle handle);
#else

View File

@ -1,23 +0,0 @@
# HG changeset patch
# User Keir Fraser <keir@xen.org>
# Date 1314800089 -3600
# Node ID 72edc40e2942a3cf0ee8e0d3a330d2e5c2bdfb53
# Parent ac9aa65050e9abc8f1c12c8603acf3b99e22cddc
x86-64: Fix off-by-one error in __addr_ok() macro
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Keir Fraser <keir@xen.org>
Index: xen-4.1.2-testing/xen/include/asm-x86/x86_64/uaccess.h
===================================================================
--- xen-4.1.2-testing.orig/xen/include/asm-x86/x86_64/uaccess.h
+++ xen-4.1.2-testing/xen/include/asm-x86/x86_64/uaccess.h
@@ -21,7 +21,7 @@ void free_compat_arg_xlat(struct vcpu *v
* non-canonical address (and thus fault) before ever reaching VIRT_START.
*/
#define __addr_ok(addr) \
- (((unsigned long)(addr) < (1UL<<48)) || \
+ (((unsigned long)(addr) < (1UL<<47)) || \
((unsigned long)(addr) >= HYPERVISOR_VIRT_END))
#define access_ok(addr, size) \

View File

@ -1,109 +0,0 @@
# HG changeset patch
# User Kevin Tian <kevin.tian@intel.com>
# Date 1314800303 -3600
# Node ID 42d76c68b2bfbedee3e5f79d32344e14bce48b0f
# Parent 51983821efa4db4040ae1c5063a4404791597699
x86: add irq count for IPIs
such count is useful to assist decision make in cpuidle governor,
while w/o this patch only device interrupts through do_IRQ is
currently counted.
Signed-off-by: Kevin Tian <kevin.tian@intel.com>
Index: xen-4.1.3-testing/xen/arch/x86/apic.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/apic.c
+++ xen-4.1.3-testing/xen/arch/x86/apic.c
@@ -1378,6 +1378,7 @@ fastcall void smp_apic_timer_interrupt(s
struct cpu_user_regs *old_regs = set_irq_regs(regs);
ack_APIC_irq();
perfc_incr(apic_timer);
+ this_cpu(irq_count)++;
raise_softirq(TIMER_SOFTIRQ);
set_irq_regs(old_regs);
}
@@ -1399,6 +1400,7 @@ fastcall void smp_spurious_interrupt(str
unsigned long v;
struct cpu_user_regs *old_regs = set_irq_regs(regs);
+ this_cpu(irq_count)++;
irq_enter();
/*
@@ -1434,6 +1436,7 @@ fastcall void smp_error_interrupt(struct
unsigned long v, v1;
struct cpu_user_regs *old_regs = set_irq_regs(regs);
+ this_cpu(irq_count)++;
irq_enter();
/* First tickle the hardware, only then report what went on. -- REW */
v = apic_read(APIC_ESR);
@@ -1465,6 +1468,7 @@ fastcall void smp_pmu_apic_interrupt(str
{
struct cpu_user_regs *old_regs = set_irq_regs(regs);
ack_APIC_irq();
+ this_cpu(irq_count)++;
hvm_do_pmu_interrupt(regs);
set_irq_regs(old_regs);
}
Index: xen-4.1.3-testing/xen/arch/x86/cpu/mcheck/mce_intel.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/cpu/mcheck/mce_intel.c
+++ xen-4.1.3-testing/xen/arch/x86/cpu/mcheck/mce_intel.c
@@ -66,6 +66,7 @@ static void (*vendor_thermal_interrupt)(
fastcall void smp_thermal_interrupt(struct cpu_user_regs *regs)
{
struct cpu_user_regs *old_regs = set_irq_regs(regs);
+ this_cpu(irq_count)++;
irq_enter();
vendor_thermal_interrupt(regs);
irq_exit();
@@ -1094,6 +1095,7 @@ fastcall void smp_cmci_interrupt(struct
struct cpu_user_regs *old_regs = set_irq_regs(regs);
ack_APIC_irq();
+ this_cpu(irq_count)++;
irq_enter();
mctc = mcheck_mca_logout(
Index: xen-4.1.3-testing/xen/arch/x86/io_apic.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/io_apic.c
+++ xen-4.1.3-testing/xen/arch/x86/io_apic.c
@@ -516,6 +516,7 @@ fastcall void smp_irq_move_cleanup_inter
struct cpu_user_regs *old_regs = set_irq_regs(regs);
ack_APIC_irq();
+ this_cpu(irq_count)++;
irq_enter();
me = smp_processor_id();
Index: xen-4.1.3-testing/xen/arch/x86/smp.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/smp.c
+++ xen-4.1.3-testing/xen/arch/x86/smp.c
@@ -222,6 +222,7 @@ fastcall void smp_invalidate_interrupt(v
{
ack_APIC_irq();
perfc_incr(ipis);
+ this_cpu(irq_count)++;
irq_enter();
if ( !__sync_local_execstate() ||
(flush_flags & (FLUSH_TLB_GLOBAL | FLUSH_CACHE)) )
@@ -387,6 +388,7 @@ fastcall void smp_event_check_interrupt(
struct cpu_user_regs *old_regs = set_irq_regs(regs);
ack_APIC_irq();
perfc_incr(ipis);
+ this_cpu(irq_count)++;
set_irq_regs(old_regs);
}
@@ -423,6 +425,7 @@ fastcall void smp_call_function_interrup
ack_APIC_irq();
perfc_incr(ipis);
+ this_cpu(irq_count)++;
__smp_call_function_interrupt();
set_irq_regs(old_regs);
}

View File

@ -1,144 +0,0 @@
changeset: 23817:083f10851dd8
user: Olaf Hering <olaf@aepfle.de>
date: Mon Sep 05 15:10:09 2011 +0100
files: xen/arch/x86/mm/mem_event.c xen/arch/x86/mm/mem_sharing.c xen/arch/x86/mm/p2m.c xen/include/asm-x86/mem_event.h xen/include/xen/sched.h
description:
mem_event: add ref counting for free requestslots
If mem_event_check_ring() is called by many vcpus at the same time
before any of them called also mem_event_put_request(), all of the
callers must assume there are enough free slots available in the ring.
Record the number of request producers in mem_event_check_ring() to
keep track of available free slots.
Add a new mem_event_put_req_producers() function to release a request
attempt made in mem_event_check_ring(). Its required for
p2m_mem_paging_populate() because that function can only modify the
p2m type if there are free request slots. But in some cases
p2m_mem_paging_populate() does not actually have to produce another
request when it is known that the same request was already made
earlier by a different vcpu.
mem_event_check_ring() can not return a reference to a free request
slot because there could be multiple references for different vcpus
and the order of mem_event_put_request() calls is not known. As a
result, incomplete requests could be consumed by the ring user.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
xen/arch/x86/mm/mem_event.c | 19 ++++++++++++-------
xen/arch/x86/mm/mem_sharing.c | 1 -
xen/arch/x86/mm/p2m.c | 1 +
xen/include/asm-x86/mem_event.h | 1 +
xen/include/xen/sched.h | 1 +
5 files changed, 15 insertions(+), 8 deletions(-)
Index: xen-4.1.3-testing/xen/arch/x86/mm/mem_event.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/mm/mem_event.c
+++ xen-4.1.3-testing/xen/arch/x86/mm/mem_event.c
@@ -37,8 +37,6 @@
#define mem_event_ring_lock(_d) spin_lock(&(_d)->mem_event.ring_lock)
#define mem_event_ring_unlock(_d) spin_unlock(&(_d)->mem_event.ring_lock)
-#define MEM_EVENT_RING_THRESHOLD 4
-
static int mem_event_enable(struct domain *d, mfn_t ring_mfn, mfn_t shared_mfn)
{
int rc;
@@ -109,6 +107,7 @@ void mem_event_put_request(struct domain
req_prod++;
/* Update ring */
+ d->mem_event.req_producers--;
front_ring->req_prod_pvt = req_prod;
RING_PUSH_REQUESTS(front_ring);
@@ -153,11 +152,18 @@ void mem_event_mark_and_pause(struct vcp
vcpu_sleep_nosync(v);
}
+void mem_event_put_req_producers(struct domain *d)
+{
+ mem_event_ring_lock(d);
+ d->mem_event.req_producers--;
+ mem_event_ring_unlock(d);
+}
+
int mem_event_check_ring(struct domain *d)
{
struct vcpu *curr = current;
int free_requests;
- int ring_full;
+ int ring_full = 1;
if ( !d->mem_event.ring_page )
return -1;
@@ -165,12 +171,11 @@ int mem_event_check_ring(struct domain *
mem_event_ring_lock(d);
free_requests = RING_FREE_REQUESTS(&d->mem_event.front_ring);
- if ( unlikely(free_requests < 2) )
+ if ( d->mem_event.req_producers < free_requests )
{
- gdprintk(XENLOG_INFO, "free request slots: %d\n", free_requests);
- WARN_ON(free_requests == 0);
+ d->mem_event.req_producers++;
+ ring_full = 0;
}
- ring_full = free_requests < MEM_EVENT_RING_THRESHOLD ? 1 : 0;
if ( (curr->domain->domain_id == d->domain_id) && ring_full )
{
Index: xen-4.1.3-testing/xen/arch/x86/mm/mem_sharing.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/mm/mem_sharing.c
+++ xen-4.1.3-testing/xen/arch/x86/mm/mem_sharing.c
@@ -322,7 +322,6 @@ static struct page_info* mem_sharing_all
req.flags |= MEM_EVENT_FLAG_VCPU_PAUSED;
}
- /* XXX: Need to reserve a request, not just check the ring! */
if(mem_event_check_ring(d)) return page;
req.gfn = gfn;
Index: xen-4.1.3-testing/xen/arch/x86/mm/p2m.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/mm/p2m.c
+++ xen-4.1.3-testing/xen/arch/x86/mm/p2m.c
@@ -2976,6 +2976,7 @@ void p2m_mem_paging_populate(struct p2m_
else if ( p2mt != p2m_ram_paging_out && p2mt != p2m_ram_paged )
{
/* gfn is already on its way back and vcpu is not paused */
+ mem_event_put_req_producers(d);
return;
}
Index: xen-4.1.3-testing/xen/include/asm-x86/mem_event.h
===================================================================
--- xen-4.1.3-testing.orig/xen/include/asm-x86/mem_event.h
+++ xen-4.1.3-testing/xen/include/asm-x86/mem_event.h
@@ -27,6 +27,7 @@
/* Pauses VCPU while marking pause flag for mem event */
void mem_event_mark_and_pause(struct vcpu *v);
int mem_event_check_ring(struct domain *d);
+void mem_event_put_req_producers(struct domain *d);
void mem_event_put_request(struct domain *d, mem_event_request_t *req);
void mem_event_get_response(struct domain *d, mem_event_response_t *rsp);
void mem_event_unpause_vcpus(struct domain *d);
Index: xen-4.1.3-testing/xen/include/xen/sched.h
===================================================================
--- xen-4.1.3-testing.orig/xen/include/xen/sched.h
+++ xen-4.1.3-testing/xen/include/xen/sched.h
@@ -190,6 +190,7 @@ struct mem_event_domain
{
/* ring lock */
spinlock_t ring_lock;
+ unsigned int req_producers;
/* shared page */
mem_event_shared_page_t *shared_page;
/* shared ring page */

View File

@ -1,30 +0,0 @@
changeset: 23818:0268e7380953
user: Olaf Hering <olaf@aepfle.de>
date: Mon Sep 05 15:10:28 2011 +0100
files: xen/arch/x86/mm/mem_event.c
description:
mem_event: use mem_event_mark_and_pause() in mem_event_check_ring()
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
xen/arch/x86/mm/mem_event.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
Index: xen-4.1.2-testing/xen/arch/x86/mm/mem_event.c
===================================================================
--- xen-4.1.2-testing.orig/xen/arch/x86/mm/mem_event.c
+++ xen-4.1.2-testing/xen/arch/x86/mm/mem_event.c
@@ -178,10 +178,7 @@ int mem_event_check_ring(struct domain *
}
if ( (curr->domain->domain_id == d->domain_id) && ring_full )
- {
- set_bit(_VPF_mem_event, &curr->pause_flags);
- vcpu_sleep_nosync(curr);
- }
+ mem_event_mark_and_pause(curr);
mem_event_ring_unlock(d);

View File

@ -1,178 +0,0 @@
changeset: 23827:d1d6abc1db20
user: Olaf Hering <olaf@aepfle.de>
date: Tue Sep 13 10:25:32 2011 +0100
files: tools/xenpaging/pagein.c tools/xenpaging/xenpaging.c tools/xenpaging/xenpaging.h
description:
xenpaging: use batch of pages during final page-in
Map up to RING_SIZE pages in exit path to fill the ring instead of
populating one page at a time.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
tools/xenpaging/pagein.c | 36 ++++++++++++++++++++++++------------
tools/xenpaging/xenpaging.c | 18 +++++++++++++-----
tools/xenpaging/xenpaging.h | 7 +++++--
3 files changed, 42 insertions(+), 19 deletions(-)
Index: xen-4.1.2-testing/tools/xenpaging/pagein.c
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/pagein.c
+++ xen-4.1.2-testing/tools/xenpaging/pagein.c
@@ -1,14 +1,16 @@
/* Trigger a page-in in a separate thread-of-execution to avoid deadlock */
#include <pthread.h>
-#include "xc_private.h"
+#include <xc_private.h>
+#include "xenpaging.h"
struct page_in_args {
domid_t dom;
+ unsigned long *pagein_queue;
xc_interface *xch;
};
static struct page_in_args page_in_args;
-static unsigned long page_in_gfn;
+static unsigned long page_in_request;
static unsigned int page_in_possible;
static pthread_t page_in_thread;
@@ -19,19 +21,28 @@ static void *page_in(void *arg)
{
struct page_in_args *pia = arg;
void *page;
- xen_pfn_t gfn;
+ int i, num;
+ xen_pfn_t gfns[XENPAGING_PAGEIN_QUEUE_SIZE];
while (1)
{
pthread_mutex_lock(&page_in_mutex);
- while (!page_in_gfn)
+ while (!page_in_request)
pthread_cond_wait(&page_in_cond, &page_in_mutex);
- gfn = page_in_gfn;
- page_in_gfn = 0;
+ num = 0;
+ for (i = 0; i < XENPAGING_PAGEIN_QUEUE_SIZE; i++)
+ {
+ if (!pia->pagein_queue[i])
+ continue;
+ gfns[num] = pia->pagein_queue[i];
+ pia->pagein_queue[i] = 0;
+ num++;
+ }
+ page_in_request = 0;
pthread_mutex_unlock(&page_in_mutex);
/* Ignore errors */
- page = xc_map_foreign_pages(pia->xch, pia->dom, PROT_READ, &gfn, 1);
+ page = xc_map_foreign_pages(pia->xch, pia->dom, PROT_READ, gfns, num);
if (page)
munmap(page, PAGE_SIZE);
}
@@ -39,21 +50,22 @@ static void *page_in(void *arg)
pthread_exit(NULL);
}
-void page_in_trigger(unsigned long gfn)
+void page_in_trigger(void)
{
if (!page_in_possible)
return;
pthread_mutex_lock(&page_in_mutex);
- page_in_gfn = gfn;
+ page_in_request = 1;
pthread_mutex_unlock(&page_in_mutex);
pthread_cond_signal(&page_in_cond);
}
-void create_page_in_thread(domid_t domain_id, xc_interface *xch)
+void create_page_in_thread(xenpaging_t *paging)
{
- page_in_args.dom = domain_id;
- page_in_args.xch = xch;
+ page_in_args.dom = paging->mem_event.domain_id;
+ page_in_args.pagein_queue = paging->pagein_queue;
+ page_in_args.xch = paging->xc_handle;
if (pthread_create(&page_in_thread, NULL, page_in, &page_in_args) == 0)
page_in_possible = 1;
}
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
@@ -648,7 +648,7 @@ int main(int argc, char *argv[])
sigaction(SIGALRM, &act, NULL);
/* listen for page-in events to stop pager */
- create_page_in_thread(paging->mem_event.domain_id, xch);
+ create_page_in_thread(paging);
/* Evict pages */
for ( i = 0; i < paging->num_pages; i++ )
@@ -764,16 +764,24 @@ int main(int argc, char *argv[])
/* Write all pages back into the guest */
if ( interrupted == SIGTERM || interrupted == SIGINT )
{
+ int num = 0;
for ( i = 0; i < paging->domain_info->max_pages; i++ )
{
if ( test_bit(i, paging->bitmap) )
{
- page_in_trigger(i);
- break;
+ paging->pagein_queue[num] = i;
+ num++;
+ if ( num == XENPAGING_PAGEIN_QUEUE_SIZE )
+ break;
}
}
- /* If no more pages to process, exit loop */
- if ( i == paging->domain_info->max_pages )
+ /*
+ * One more round if there are still pages to process.
+ * If no more pages to process, exit loop.
+ */
+ if ( num )
+ page_in_trigger();
+ else if ( i == paging->domain_info->max_pages )
break;
}
else
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.h
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.h
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.h
@@ -29,6 +29,8 @@
#include <xen/event_channel.h>
#include <xen/mem_event.h>
+#define XENPAGING_PAGEIN_QUEUE_SIZE 64
+
typedef struct mem_event {
domid_t domain_id;
xc_evtchn *xce_handle;
@@ -49,6 +51,7 @@ typedef struct xenpaging {
mem_event_t mem_event;
int num_pages;
int policy_mru_size;
+ unsigned long pagein_queue[XENPAGING_PAGEIN_QUEUE_SIZE];
} xenpaging_t;
@@ -58,8 +61,8 @@ typedef struct xenpaging_victim {
} xenpaging_victim_t;
-extern void create_page_in_thread(domid_t domain_id, xc_interface *xch);
-extern void page_in_trigger(unsigned long gfn);
+extern void create_page_in_thread(xenpaging_t *paging);
+extern void page_in_trigger(void);
#endif // __XEN_PAGING_H__

View File

@ -1,405 +0,0 @@
changeset: 23841:ed7586b1d515
user: Olaf Hering <olaf@aepfle.de>
date: Fri Sep 16 12:13:31 2011 +0100
files: xen/arch/x86/hvm/hvm.c xen/arch/x86/mm/mem_event.c xen/arch/x86/mm/mem_sharing.c xen/arch/x86/mm/p2m.c xen/include/asm-x86/mem_event.h
description:
mem_event: pass mem_event_domain pointer to mem_event functions
Pass a struct mem_event_domain pointer to the various mem_event
functions. This will be used in a subsequent patch which creates
different ring buffers for the memshare, xenpaging and memaccess
functionality.
Remove the struct domain argument from some functions.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Acked-by: Tim Deegan <tim@xen.org>
Committed-by: Tim Deegan <tim@xen.org>
---
xen/arch/x86/hvm/hvm.c | 4 -
xen/arch/x86/mm/mem_event.c | 95 ++++++++++++++++++++--------------------
xen/arch/x86/mm/mem_sharing.c | 6 +-
xen/arch/x86/mm/p2m.c | 18 +++----
xen/include/asm-x86/mem_event.h | 8 +--
5 files changed, 66 insertions(+), 65 deletions(-)
Index: xen-4.1.3-testing/xen/arch/x86/hvm/hvm.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/hvm/hvm.c
+++ xen-4.1.3-testing/xen/arch/x86/hvm/hvm.c
@@ -3920,7 +3920,7 @@ static int hvm_memory_event_traps(long p
if ( (p & HVMPME_onchangeonly) && (value == old) )
return 1;
- rc = mem_event_check_ring(d);
+ rc = mem_event_check_ring(d, &d->mem_event);
if ( rc )
return rc;
@@ -3943,7 +3943,7 @@ static int hvm_memory_event_traps(long p
req.gla_valid = 1;
}
- mem_event_put_request(d, &req);
+ mem_event_put_request(d, &d->mem_event, &req);
return 1;
}
Index: xen-4.1.3-testing/xen/arch/x86/mm/mem_event.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/mm/mem_event.c
+++ xen-4.1.3-testing/xen/arch/x86/mm/mem_event.c
@@ -33,21 +33,21 @@
#define xen_rmb() rmb()
#define xen_wmb() wmb()
-#define mem_event_ring_lock_init(_d) spin_lock_init(&(_d)->mem_event.ring_lock)
-#define mem_event_ring_lock(_d) spin_lock(&(_d)->mem_event.ring_lock)
-#define mem_event_ring_unlock(_d) spin_unlock(&(_d)->mem_event.ring_lock)
+#define mem_event_ring_lock_init(_med) spin_lock_init(&(_med)->ring_lock)
+#define mem_event_ring_lock(_med) spin_lock(&(_med)->ring_lock)
+#define mem_event_ring_unlock(_med) spin_unlock(&(_med)->ring_lock)
-static int mem_event_enable(struct domain *d, mfn_t ring_mfn, mfn_t shared_mfn)
+static int mem_event_enable(struct domain *d, struct mem_event_domain *med, mfn_t ring_mfn, mfn_t shared_mfn)
{
int rc;
/* Map ring and shared pages */
- d->mem_event.ring_page = map_domain_page(mfn_x(ring_mfn));
- if ( d->mem_event.ring_page == NULL )
+ med->ring_page = map_domain_page(mfn_x(ring_mfn));
+ if ( med->ring_page == NULL )
goto err;
- d->mem_event.shared_page = map_domain_page(mfn_x(shared_mfn));
- if ( d->mem_event.shared_page == NULL )
+ med->shared_page = map_domain_page(mfn_x(shared_mfn));
+ if ( med->shared_page == NULL )
goto err_ring;
/* Allocate event channel */
@@ -56,15 +56,15 @@ static int mem_event_enable(struct domai
if ( rc < 0 )
goto err_shared;
- ((mem_event_shared_page_t *)d->mem_event.shared_page)->port = rc;
- d->mem_event.xen_port = rc;
+ ((mem_event_shared_page_t *)med->shared_page)->port = rc;
+ med->xen_port = rc;
/* Prepare ring buffer */
- FRONT_RING_INIT(&d->mem_event.front_ring,
- (mem_event_sring_t *)d->mem_event.ring_page,
+ FRONT_RING_INIT(&med->front_ring,
+ (mem_event_sring_t *)med->ring_page,
PAGE_SIZE);
- mem_event_ring_lock_init(d);
+ mem_event_ring_lock_init(med);
/* Wake any VCPUs paused for memory events */
mem_event_unpause_vcpus(d);
@@ -72,34 +72,34 @@ static int mem_event_enable(struct domai
return 0;
err_shared:
- unmap_domain_page(d->mem_event.shared_page);
- d->mem_event.shared_page = NULL;
+ unmap_domain_page(med->shared_page);
+ med->shared_page = NULL;
err_ring:
- unmap_domain_page(d->mem_event.ring_page);
- d->mem_event.ring_page = NULL;
+ unmap_domain_page(med->ring_page);
+ med->ring_page = NULL;
err:
return 1;
}
-static int mem_event_disable(struct domain *d)
+static int mem_event_disable(struct mem_event_domain *med)
{
- unmap_domain_page(d->mem_event.ring_page);
- d->mem_event.ring_page = NULL;
+ unmap_domain_page(med->ring_page);
+ med->ring_page = NULL;
- unmap_domain_page(d->mem_event.shared_page);
- d->mem_event.shared_page = NULL;
+ unmap_domain_page(med->shared_page);
+ med->shared_page = NULL;
return 0;
}
-void mem_event_put_request(struct domain *d, mem_event_request_t *req)
+void mem_event_put_request(struct domain *d, struct mem_event_domain *med, mem_event_request_t *req)
{
mem_event_front_ring_t *front_ring;
RING_IDX req_prod;
- mem_event_ring_lock(d);
+ mem_event_ring_lock(med);
- front_ring = &d->mem_event.front_ring;
+ front_ring = &med->front_ring;
req_prod = front_ring->req_prod_pvt;
/* Copy request */
@@ -107,23 +107,23 @@ void mem_event_put_request(struct domain
req_prod++;
/* Update ring */
- d->mem_event.req_producers--;
+ med->req_producers--;
front_ring->req_prod_pvt = req_prod;
RING_PUSH_REQUESTS(front_ring);
- mem_event_ring_unlock(d);
+ mem_event_ring_unlock(med);
- notify_via_xen_event_channel(d, d->mem_event.xen_port);
+ notify_via_xen_event_channel(d, med->xen_port);
}
-void mem_event_get_response(struct domain *d, mem_event_response_t *rsp)
+void mem_event_get_response(struct mem_event_domain *med, mem_event_response_t *rsp)
{
mem_event_front_ring_t *front_ring;
RING_IDX rsp_cons;
- mem_event_ring_lock(d);
+ mem_event_ring_lock(med);
- front_ring = &d->mem_event.front_ring;
+ front_ring = &med->front_ring;
rsp_cons = front_ring->rsp_cons;
/* Copy response */
@@ -134,7 +134,7 @@ void mem_event_get_response(struct domai
front_ring->rsp_cons = rsp_cons;
front_ring->sring->rsp_event = rsp_cons + 1;
- mem_event_ring_unlock(d);
+ mem_event_ring_unlock(med);
}
void mem_event_unpause_vcpus(struct domain *d)
@@ -152,35 +152,35 @@ void mem_event_mark_and_pause(struct vcp
vcpu_sleep_nosync(v);
}
-void mem_event_put_req_producers(struct domain *d)
+void mem_event_put_req_producers(struct mem_event_domain *med)
{
- mem_event_ring_lock(d);
- d->mem_event.req_producers--;
- mem_event_ring_unlock(d);
+ mem_event_ring_lock(med);
+ med->req_producers--;
+ mem_event_ring_unlock(med);
}
-int mem_event_check_ring(struct domain *d)
+int mem_event_check_ring(struct domain *d, struct mem_event_domain *med)
{
struct vcpu *curr = current;
int free_requests;
int ring_full = 1;
- if ( !d->mem_event.ring_page )
+ if ( !med->ring_page )
return -1;
- mem_event_ring_lock(d);
+ mem_event_ring_lock(med);
- free_requests = RING_FREE_REQUESTS(&d->mem_event.front_ring);
- if ( d->mem_event.req_producers < free_requests )
+ free_requests = RING_FREE_REQUESTS(&med->front_ring);
+ if ( med->req_producers < free_requests )
{
- d->mem_event.req_producers++;
+ med->req_producers++;
ring_full = 0;
}
- if ( (curr->domain->domain_id == d->domain_id) && ring_full )
+ if ( ring_full && (curr->domain == d) )
mem_event_mark_and_pause(curr);
- mem_event_ring_unlock(d);
+ mem_event_ring_unlock(med);
return ring_full;
}
@@ -230,6 +230,7 @@ int mem_event_domctl(struct domain *d, x
{
struct domain *dom_mem_event = current->domain;
struct vcpu *v = current;
+ struct mem_event_domain *med = &d->mem_event;
unsigned long ring_addr = mec->ring_addr;
unsigned long shared_addr = mec->shared_addr;
l1_pgentry_t l1e;
@@ -242,7 +243,7 @@ int mem_event_domctl(struct domain *d, x
* the cache is in an undefined state and so is the guest
*/
rc = -EBUSY;
- if ( d->mem_event.ring_page )
+ if ( med->ring_page )
break;
/* Currently only EPT is supported */
@@ -270,7 +271,7 @@ int mem_event_domctl(struct domain *d, x
break;
rc = -EINVAL;
- if ( mem_event_enable(d, ring_mfn, shared_mfn) != 0 )
+ if ( mem_event_enable(d, med, ring_mfn, shared_mfn) != 0 )
break;
rc = 0;
@@ -279,7 +280,7 @@ int mem_event_domctl(struct domain *d, x
case XEN_DOMCTL_MEM_EVENT_OP_DISABLE:
{
- rc = mem_event_disable(d);
+ rc = mem_event_disable(&d->mem_event);
}
break;
Index: xen-4.1.3-testing/xen/arch/x86/mm/mem_sharing.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/mm/mem_sharing.c
+++ xen-4.1.3-testing/xen/arch/x86/mm/mem_sharing.c
@@ -322,12 +322,12 @@ static struct page_info* mem_sharing_all
req.flags |= MEM_EVENT_FLAG_VCPU_PAUSED;
}
- if(mem_event_check_ring(d)) return page;
+ if(mem_event_check_ring(d, &d->mem_event)) return page;
req.gfn = gfn;
req.p2mt = p2m_ram_shared;
req.vcpu_id = v->vcpu_id;
- mem_event_put_request(d, &req);
+ mem_event_put_request(d, &d->mem_event, &req);
return page;
}
@@ -342,7 +342,7 @@ int mem_sharing_sharing_resume(struct do
mem_event_response_t rsp;
/* Get request off the ring */
- mem_event_get_response(d, &rsp);
+ mem_event_get_response(&d->mem_event, &rsp);
/* Unpause domain/vcpu */
if( rsp.flags & MEM_EVENT_FLAG_VCPU_PAUSED )
Index: xen-4.1.3-testing/xen/arch/x86/mm/p2m.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/mm/p2m.c
+++ xen-4.1.3-testing/xen/arch/x86/mm/p2m.c
@@ -2929,7 +2929,7 @@ void p2m_mem_paging_drop_page(struct p2m
struct domain *d = p2m->domain;
/* Check that there's space on the ring for this request */
- if ( mem_event_check_ring(d) == 0)
+ if ( mem_event_check_ring(d, &d->mem_event) == 0)
{
/* Send release notification to pager */
memset(&req, 0, sizeof(req));
@@ -2937,7 +2937,7 @@ void p2m_mem_paging_drop_page(struct p2m
req.gfn = gfn;
req.vcpu_id = v->vcpu_id;
- mem_event_put_request(d, &req);
+ mem_event_put_request(d, &d->mem_event, &req);
}
}
@@ -2949,7 +2949,7 @@ void p2m_mem_paging_populate(struct p2m_
struct domain *d = p2m->domain;
/* Check that there's space on the ring for this request */
- if ( mem_event_check_ring(d) )
+ if ( mem_event_check_ring(d, &d->mem_event) )
return;
memset(&req, 0, sizeof(req));
@@ -2976,7 +2976,7 @@ void p2m_mem_paging_populate(struct p2m_
else if ( p2mt != p2m_ram_paging_out && p2mt != p2m_ram_paged )
{
/* gfn is already on its way back and vcpu is not paused */
- mem_event_put_req_producers(d);
+ mem_event_put_req_producers(&d->mem_event);
return;
}
@@ -2985,7 +2985,7 @@ void p2m_mem_paging_populate(struct p2m_
req.p2mt = p2mt;
req.vcpu_id = v->vcpu_id;
- mem_event_put_request(d, &req);
+ mem_event_put_request(d, &d->mem_event, &req);
}
int p2m_mem_paging_prep(struct p2m_domain *p2m, unsigned long gfn)
@@ -3014,7 +3014,7 @@ void p2m_mem_paging_resume(struct p2m_do
mfn_t mfn;
/* Pull the response off the ring */
- mem_event_get_response(d, &rsp);
+ mem_event_get_response(&d->mem_event, &rsp);
/* Fix p2m entry if the page was not dropped */
if ( !(rsp.flags & MEM_EVENT_FLAG_DROP_PAGE) )
@@ -3061,7 +3061,7 @@ void p2m_mem_access_check(paddr_t gpa, b
p2m_unlock(p2m);
/* Otherwise, check if there is a memory event listener, and send the message along */
- res = mem_event_check_ring(d);
+ res = mem_event_check_ring(d, &d->mem_event);
if ( res < 0 )
{
/* No listener */
@@ -3105,7 +3105,7 @@ void p2m_mem_access_check(paddr_t gpa, b
req.vcpu_id = v->vcpu_id;
- mem_event_put_request(d, &req);
+ mem_event_put_request(d, &d->mem_event, &req);
/* VCPU paused, mem event request sent */
}
@@ -3115,7 +3115,7 @@ void p2m_mem_access_resume(struct p2m_do
struct domain *d = p2m->domain;
mem_event_response_t rsp;
- mem_event_get_response(d, &rsp);
+ mem_event_get_response(&d->mem_event, &rsp);
/* Unpause domain */
if ( rsp.flags & MEM_EVENT_FLAG_VCPU_PAUSED )
Index: xen-4.1.3-testing/xen/include/asm-x86/mem_event.h
===================================================================
--- xen-4.1.3-testing.orig/xen/include/asm-x86/mem_event.h
+++ xen-4.1.3-testing/xen/include/asm-x86/mem_event.h
@@ -26,10 +26,10 @@
/* Pauses VCPU while marking pause flag for mem event */
void mem_event_mark_and_pause(struct vcpu *v);
-int mem_event_check_ring(struct domain *d);
-void mem_event_put_req_producers(struct domain *d);
-void mem_event_put_request(struct domain *d, mem_event_request_t *req);
-void mem_event_get_response(struct domain *d, mem_event_response_t *rsp);
+int mem_event_check_ring(struct domain *d, struct mem_event_domain *med);
+void mem_event_put_req_producers(struct mem_event_domain *med);
+void mem_event_put_request(struct domain *d, struct mem_event_domain *med, mem_event_request_t *req);
+void mem_event_get_response(struct mem_event_domain *med, mem_event_response_t *rsp);
void mem_event_unpause_vcpus(struct domain *d);
int mem_event_domctl(struct domain *d, xen_domctl_mem_event_op_t *mec,

View File

@ -1,868 +0,0 @@
changeset: 23842:483c5f8319ad
user: Olaf Hering <olaf@aepfle.de>
date: Fri Sep 16 12:19:26 2011 +0100
files: tools/libxc/Makefile tools/libxc/xc_mem_access.c tools/libxc/xc_mem_event.c tools/libxc/xc_mem_paging.c tools/libxc/xc_memshr.c tools/libxc/xenctrl.h tools/tests/xen-access/xen-access.c tools/xenpaging/xenpaging.c xen/arch/ia64/xen/dom0_ops.c xen/arch/x86/hvm/hvm.c xen/arch/x86/mm/mem_event.c xen/arch/x86/mm/mem_paging.c xen/arch/x86/mm/mem_sharing.c xen/arch/x86/mm/p2m.c xen/include/public/domctl.h xen/include/xen/sched.h
description:
mem_event: use different ringbuffers for share, paging and access
Up to now a single ring buffer was used for mem_share, xenpaging and
xen-access. Each helper would have to cooperate and pull only its own
requests from the ring. Unfortunately this was not implemented. And
even if it was, it would make the whole concept fragile because a crash
or early exit of one helper would stall the others.
What happend up to now is that active xenpaging + memory_sharing would
push memsharing requests in the buffer. xenpaging is not prepared for
such requests.
This patch creates an independet ring buffer for mem_share, xenpaging
and xen-access and adds also new functions to enable xenpaging and
xen-access. The xc_mem_event_enable/xc_mem_event_disable functions will
be removed. The various XEN_DOMCTL_MEM_EVENT_* macros were cleaned up.
Due to the removal the API changed, so the SONAME will be changed too.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Acked-by: Tim Deegan <tim@xen.org>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
Committed-by: Tim Deegan <tim@xen.org>
---
tools/libxc/Makefile | 2
tools/libxc/xc_mem_access.c | 21 ++++
tools/libxc/xc_mem_event.c | 15 ---
tools/libxc/xc_mem_paging.c | 33 +++++--
tools/libxc/xc_memshr.c | 16 +--
tools/libxc/xenctrl.h | 9 +
tools/tests/xen-access/xen-access.c | 4
tools/xenpaging/xenpaging.c | 4
xen/arch/ia64/xen/dom0_ops.c | 2
xen/arch/x86/hvm/hvm.c | 4
xen/arch/x86/mm/mem_event.c | 163 ++++++++++++++++++++----------------
xen/arch/x86/mm/mem_sharing.c | 22 ++--
xen/arch/x86/mm/p2m.c | 18 +--
xen/include/public/domctl.h | 43 +++++----
xen/include/xen/sched.h | 6 +
15 files changed, 206 insertions(+), 156 deletions(-)
Index: xen-4.1.3-testing/tools/libxc/Makefile
===================================================================
--- xen-4.1.3-testing.orig/tools/libxc/Makefile
+++ xen-4.1.3-testing/tools/libxc/Makefile
@@ -1,7 +1,7 @@
XEN_ROOT = $(CURDIR)/../..
include $(XEN_ROOT)/tools/Rules.mk
-MAJOR = 4.0
+MAJOR = 4.2
MINOR = 0
CTRL_SRCS-y :=
Index: xen-4.1.3-testing/tools/libxc/xc_mem_access.c
===================================================================
--- xen-4.1.3-testing.orig/tools/libxc/xc_mem_access.c
+++ xen-4.1.3-testing/tools/libxc/xc_mem_access.c
@@ -24,12 +24,29 @@
#include "xc_private.h"
+int xc_mem_access_enable(xc_interface *xch, domid_t domain_id,
+ void *shared_page, void *ring_page)
+{
+ return xc_mem_event_control(xch, domain_id,
+ XEN_DOMCTL_MEM_EVENT_OP_ACCESS_ENABLE,
+ XEN_DOMCTL_MEM_EVENT_OP_ACCESS,
+ shared_page, ring_page, INVALID_MFN);
+}
+
+int xc_mem_access_disable(xc_interface *xch, domid_t domain_id)
+{
+ return xc_mem_event_control(xch, domain_id,
+ XEN_DOMCTL_MEM_EVENT_OP_ACCESS_DISABLE,
+ XEN_DOMCTL_MEM_EVENT_OP_ACCESS,
+ NULL, NULL, INVALID_MFN);
+}
+
int xc_mem_access_resume(xc_interface *xch, domid_t domain_id, unsigned long gfn)
{
return xc_mem_event_control(xch, domain_id,
XEN_DOMCTL_MEM_EVENT_OP_ACCESS_RESUME,
- XEN_DOMCTL_MEM_EVENT_OP_ACCESS, NULL, NULL,
- gfn);
+ XEN_DOMCTL_MEM_EVENT_OP_ACCESS,
+ NULL, NULL, gfn);
}
/*
Index: xen-4.1.3-testing/tools/libxc/xc_mem_event.c
===================================================================
--- xen-4.1.3-testing.orig/tools/libxc/xc_mem_event.c
+++ xen-4.1.3-testing/tools/libxc/xc_mem_event.c
@@ -42,18 +42,3 @@ int xc_mem_event_control(xc_interface *x
return do_domctl(xch, &domctl);
}
-int xc_mem_event_enable(xc_interface *xch, domid_t domain_id,
- void *shared_page, void *ring_page)
-{
- return xc_mem_event_control(xch, domain_id,
- XEN_DOMCTL_MEM_EVENT_OP_ENABLE, 0,
- shared_page, ring_page, INVALID_MFN);
-}
-
-int xc_mem_event_disable(xc_interface *xch, domid_t domain_id)
-{
- return xc_mem_event_control(xch, domain_id,
- XEN_DOMCTL_MEM_EVENT_OP_DISABLE, 0,
- NULL, NULL, INVALID_MFN);
-}
-
Index: xen-4.1.3-testing/tools/libxc/xc_mem_paging.c
===================================================================
--- xen-4.1.3-testing.orig/tools/libxc/xc_mem_paging.c
+++ xen-4.1.3-testing/tools/libxc/xc_mem_paging.c
@@ -24,36 +24,53 @@
#include "xc_private.h"
+int xc_mem_paging_enable(xc_interface *xch, domid_t domain_id,
+ void *shared_page, void *ring_page)
+{
+ return xc_mem_event_control(xch, domain_id,
+ XEN_DOMCTL_MEM_EVENT_OP_PAGING_ENABLE,
+ XEN_DOMCTL_MEM_EVENT_OP_PAGING,
+ shared_page, ring_page, INVALID_MFN);
+}
+
+int xc_mem_paging_disable(xc_interface *xch, domid_t domain_id)
+{
+ return xc_mem_event_control(xch, domain_id,
+ XEN_DOMCTL_MEM_EVENT_OP_PAGING_DISABLE,
+ XEN_DOMCTL_MEM_EVENT_OP_PAGING,
+ NULL, NULL, INVALID_MFN);
+}
+
int xc_mem_paging_nominate(xc_interface *xch, domid_t domain_id, unsigned long gfn)
{
return xc_mem_event_control(xch, domain_id,
XEN_DOMCTL_MEM_EVENT_OP_PAGING_NOMINATE,
- XEN_DOMCTL_MEM_EVENT_OP_PAGING, NULL, NULL,
- gfn);
+ XEN_DOMCTL_MEM_EVENT_OP_PAGING,
+ NULL, NULL, gfn);
}
int xc_mem_paging_evict(xc_interface *xch, domid_t domain_id, unsigned long gfn)
{
return xc_mem_event_control(xch, domain_id,
XEN_DOMCTL_MEM_EVENT_OP_PAGING_EVICT,
- XEN_DOMCTL_MEM_EVENT_OP_PAGING, NULL, NULL,
- gfn);
+ XEN_DOMCTL_MEM_EVENT_OP_PAGING,
+ NULL, NULL, gfn);
}
int xc_mem_paging_prep(xc_interface *xch, domid_t domain_id, unsigned long gfn)
{
return xc_mem_event_control(xch, domain_id,
XEN_DOMCTL_MEM_EVENT_OP_PAGING_PREP,
- XEN_DOMCTL_MEM_EVENT_OP_PAGING, NULL, NULL,
- gfn);
+ XEN_DOMCTL_MEM_EVENT_OP_PAGING,
+ NULL, NULL, gfn);
}
int xc_mem_paging_resume(xc_interface *xch, domid_t domain_id, unsigned long gfn)
{
return xc_mem_event_control(xch, domain_id,
XEN_DOMCTL_MEM_EVENT_OP_PAGING_RESUME,
- XEN_DOMCTL_MEM_EVENT_OP_PAGING, NULL, NULL,
- gfn);
+ XEN_DOMCTL_MEM_EVENT_OP_PAGING,
+ NULL, NULL, gfn);
}
Index: xen-4.1.3-testing/tools/libxc/xc_memshr.c
===================================================================
--- xen-4.1.3-testing.orig/tools/libxc/xc_memshr.c
+++ xen-4.1.3-testing/tools/libxc/xc_memshr.c
@@ -36,7 +36,7 @@ int xc_memshr_control(xc_interface *xch,
domctl.interface_version = XEN_DOMCTL_INTERFACE_VERSION;
domctl.domain = (domid_t)domid;
op = &(domctl.u.mem_sharing_op);
- op->op = XEN_DOMCTL_MEM_SHARING_OP_CONTROL;
+ op->op = XEN_DOMCTL_MEM_EVENT_OP_SHARING_CONTROL;
op->u.enable = enable;
return do_domctl(xch, &domctl);
@@ -55,7 +55,7 @@ int xc_memshr_nominate_gfn(xc_interface
domctl.interface_version = XEN_DOMCTL_INTERFACE_VERSION;
domctl.domain = (domid_t)domid;
op = &(domctl.u.mem_sharing_op);
- op->op = XEN_DOMCTL_MEM_SHARING_OP_NOMINATE_GFN;
+ op->op = XEN_DOMCTL_MEM_EVENT_OP_SHARING_NOMINATE_GFN;
op->u.nominate.u.gfn = gfn;
ret = do_domctl(xch, &domctl);
@@ -77,7 +77,7 @@ int xc_memshr_nominate_gref(xc_interface
domctl.interface_version = XEN_DOMCTL_INTERFACE_VERSION;
domctl.domain = (domid_t)domid;
op = &(domctl.u.mem_sharing_op);
- op->op = XEN_DOMCTL_MEM_SHARING_OP_NOMINATE_GREF;
+ op->op = XEN_DOMCTL_MEM_EVENT_OP_SHARING_NOMINATE_GREF;
op->u.nominate.u.grant_ref = gref;
ret = do_domctl(xch, &domctl);
@@ -97,7 +97,7 @@ int xc_memshr_share(xc_interface *xch,
domctl.interface_version = XEN_DOMCTL_INTERFACE_VERSION;
domctl.domain = 0;
op = &(domctl.u.mem_sharing_op);
- op->op = XEN_DOMCTL_MEM_SHARING_OP_SHARE;
+ op->op = XEN_DOMCTL_MEM_EVENT_OP_SHARING_SHARE;
op->u.share.source_handle = source_handle;
op->u.share.client_handle = client_handle;
@@ -114,7 +114,7 @@ int xc_memshr_domain_resume(xc_interface
domctl.interface_version = XEN_DOMCTL_INTERFACE_VERSION;
domctl.domain = (domid_t)domid;
op = &(domctl.u.mem_sharing_op);
- op->op = XEN_DOMCTL_MEM_SHARING_OP_RESUME;
+ op->op = XEN_DOMCTL_MEM_EVENT_OP_SHARING_RESUME;
return do_domctl(xch, &domctl);
}
@@ -130,7 +130,7 @@ int xc_memshr_debug_gfn(xc_interface *xc
domctl.interface_version = XEN_DOMCTL_INTERFACE_VERSION;
domctl.domain = (domid_t)domid;
op = &(domctl.u.mem_sharing_op);
- op->op = XEN_DOMCTL_MEM_SHARING_OP_DEBUG_GFN;
+ op->op = XEN_DOMCTL_MEM_EVENT_OP_SHARING_DEBUG_GFN;
op->u.debug.u.gfn = gfn;
return do_domctl(xch, &domctl);
@@ -147,7 +147,7 @@ int xc_memshr_debug_mfn(xc_interface *xc
domctl.interface_version = XEN_DOMCTL_INTERFACE_VERSION;
domctl.domain = (domid_t)domid;
op = &(domctl.u.mem_sharing_op);
- op->op = XEN_DOMCTL_MEM_SHARING_OP_DEBUG_MFN;
+ op->op = XEN_DOMCTL_MEM_EVENT_OP_SHARING_DEBUG_MFN;
op->u.debug.u.mfn = mfn;
return do_domctl(xch, &domctl);
@@ -164,7 +164,7 @@ int xc_memshr_debug_gref(xc_interface *x
domctl.interface_version = XEN_DOMCTL_INTERFACE_VERSION;
domctl.domain = (domid_t)domid;
op = &(domctl.u.mem_sharing_op);
- op->op = XEN_DOMCTL_MEM_SHARING_OP_DEBUG_GREF;
+ op->op = XEN_DOMCTL_MEM_EVENT_OP_SHARING_DEBUG_GREF;
op->u.debug.u.gref = gref;
return do_domctl(xch, &domctl);
Index: xen-4.1.3-testing/tools/libxc/xenctrl.h
===================================================================
--- xen-4.1.3-testing.orig/tools/libxc/xenctrl.h
+++ xen-4.1.3-testing/tools/libxc/xenctrl.h
@@ -1734,16 +1734,19 @@ int xc_mem_event_control(xc_interface *x
unsigned int mode, void *shared_page,
void *ring_page, unsigned long gfn);
-int xc_mem_event_enable(xc_interface *xch, domid_t domain_id,
+int xc_mem_paging_enable(xc_interface *xch, domid_t domain_id,
void *shared_page, void *ring_page);
-int xc_mem_event_disable(xc_interface *xch, domid_t domain_id);
-
+int xc_mem_paging_disable(xc_interface *xch, domid_t domain_id);
int xc_mem_paging_nominate(xc_interface *xch, domid_t domain_id,
unsigned long gfn);
int xc_mem_paging_evict(xc_interface *xch, domid_t domain_id, unsigned long gfn);
int xc_mem_paging_prep(xc_interface *xch, domid_t domain_id, unsigned long gfn);
int xc_mem_paging_resume(xc_interface *xch, domid_t domain_id,
unsigned long gfn);
+
+int xc_mem_access_enable(xc_interface *xch, domid_t domain_id,
+ void *shared_page, void *ring_page);
+int xc_mem_access_disable(xc_interface *xch, domid_t domain_id);
int xc_mem_access_resume(xc_interface *xch, domid_t domain_id,
unsigned long gfn);
Index: xen-4.1.3-testing/tools/tests/xen-access/xen-access.c
===================================================================
--- xen-4.1.3-testing.orig/tools/tests/xen-access/xen-access.c
+++ xen-4.1.3-testing/tools/tests/xen-access/xen-access.c
@@ -241,7 +241,7 @@ xenaccess_t *xenaccess_init(xc_interface
mem_event_ring_lock_init(&xenaccess->mem_event);
/* Initialise Xen */
- rc = xc_mem_event_enable(xenaccess->xc_handle, xenaccess->mem_event.domain_id,
+ rc = xc_mem_access_enable(xenaccess->xc_handle, xenaccess->mem_event.domain_id,
xenaccess->mem_event.shared_page,
xenaccess->mem_event.ring_page);
if ( rc != 0 )
@@ -351,7 +351,7 @@ int xenaccess_teardown(xc_interface *xch
return 0;
/* Tear down domain xenaccess in Xen */
- rc = xc_mem_event_disable(xenaccess->xc_handle, xenaccess->mem_event.domain_id);
+ rc = xc_mem_access_disable(xenaccess->xc_handle, xenaccess->mem_event.domain_id);
if ( rc != 0 )
{
ERROR("Error tearing down domain xenaccess in xen");
Index: xen-4.1.3-testing/tools/xenpaging/xenpaging.c
===================================================================
--- xen-4.1.3-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.1.3-testing/tools/xenpaging/xenpaging.c
@@ -234,7 +234,7 @@ static xenpaging_t *xenpaging_init(domid
PAGE_SIZE);
/* Initialise Xen */
- rc = xc_mem_event_enable(xch, paging->mem_event.domain_id,
+ rc = xc_mem_paging_enable(xch, paging->mem_event.domain_id,
paging->mem_event.shared_page,
paging->mem_event.ring_page);
if ( rc != 0 )
@@ -353,7 +353,7 @@ static int xenpaging_teardown(xenpaging_
xch = paging->xc_handle;
paging->xc_handle = NULL;
/* Tear down domain paging in Xen */
- rc = xc_mem_event_disable(xch, paging->mem_event.domain_id);
+ rc = xc_mem_paging_disable(xch, paging->mem_event.domain_id);
if ( rc != 0 )
{
ERROR("Error tearing down domain paging in xen");
Index: xen-4.1.3-testing/xen/arch/ia64/xen/dom0_ops.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/ia64/xen/dom0_ops.c
+++ xen-4.1.3-testing/xen/arch/ia64/xen/dom0_ops.c
@@ -688,7 +688,7 @@ long arch_do_domctl(xen_domctl_t *op, XE
switch(mec->op)
{
- case XEN_DOMCTL_MEM_SHARING_OP_CONTROL:
+ case XEN_DOMCTL_MEM_EVENT_OP_SHARING_CONTROL:
{
if (mec->u.enable) {
ret = -EINVAL; /* not implemented */
Index: xen-4.1.3-testing/xen/arch/x86/hvm/hvm.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/hvm/hvm.c
+++ xen-4.1.3-testing/xen/arch/x86/hvm/hvm.c
@@ -3920,7 +3920,7 @@ static int hvm_memory_event_traps(long p
if ( (p & HVMPME_onchangeonly) && (value == old) )
return 1;
- rc = mem_event_check_ring(d, &d->mem_event);
+ rc = mem_event_check_ring(d, &d->mem_access);
if ( rc )
return rc;
@@ -3943,7 +3943,7 @@ static int hvm_memory_event_traps(long p
req.gla_valid = 1;
}
- mem_event_put_request(d, &d->mem_event, &req);
+ mem_event_put_request(d, &d->mem_access, &req);
return 1;
}
Index: xen-4.1.3-testing/xen/arch/x86/mm/mem_event.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/mm/mem_event.c
+++ xen-4.1.3-testing/xen/arch/x86/mm/mem_event.c
@@ -37,24 +37,52 @@
#define mem_event_ring_lock(_med) spin_lock(&(_med)->ring_lock)
#define mem_event_ring_unlock(_med) spin_unlock(&(_med)->ring_lock)
-static int mem_event_enable(struct domain *d, struct mem_event_domain *med, mfn_t ring_mfn, mfn_t shared_mfn)
+static int mem_event_enable(struct domain *d,
+ xen_domctl_mem_event_op_t *mec,
+ struct mem_event_domain *med)
{
int rc;
+ struct domain *dom_mem_event = current->domain;
+ struct vcpu *v = current;
+ unsigned long ring_addr = mec->ring_addr;
+ unsigned long shared_addr = mec->shared_addr;
+ l1_pgentry_t l1e;
+ unsigned long gfn;
+ p2m_type_t p2mt;
+ mfn_t ring_mfn;
+ mfn_t shared_mfn;
+
+ /* Only one helper at a time. If the helper crashed,
+ * the ring is in an undefined state and so is the guest.
+ */
+ if ( med->ring_page )
+ return -EBUSY;
+
+ /* Get MFN of ring page */
+ guest_get_eff_l1e(v, ring_addr, &l1e);
+ gfn = l1e_get_pfn(l1e);
+ ring_mfn = gfn_to_mfn(p2m_get_hostp2m(dom_mem_event), gfn, &p2mt);
+
+ if ( unlikely(!mfn_valid(mfn_x(ring_mfn))) )
+ return -EINVAL;
+
+ /* Get MFN of shared page */
+ guest_get_eff_l1e(v, shared_addr, &l1e);
+ gfn = l1e_get_pfn(l1e);
+ shared_mfn = gfn_to_mfn(p2m_get_hostp2m(dom_mem_event), gfn, &p2mt);
+
+ if ( unlikely(!mfn_valid(mfn_x(shared_mfn))) )
+ return -EINVAL;
/* Map ring and shared pages */
med->ring_page = map_domain_page(mfn_x(ring_mfn));
- if ( med->ring_page == NULL )
- goto err;
-
med->shared_page = map_domain_page(mfn_x(shared_mfn));
- if ( med->shared_page == NULL )
- goto err_ring;
/* Allocate event channel */
rc = alloc_unbound_xen_event_channel(d->vcpu[0],
current->domain->domain_id);
if ( rc < 0 )
- goto err_shared;
+ goto err;
((mem_event_shared_page_t *)med->shared_page)->port = rc;
med->xen_port = rc;
@@ -71,14 +99,14 @@ static int mem_event_enable(struct domai
return 0;
- err_shared:
+ err:
unmap_domain_page(med->shared_page);
med->shared_page = NULL;
- err_ring:
+
unmap_domain_page(med->ring_page);
med->ring_page = NULL;
- err:
- return 1;
+
+ return rc;
}
static int mem_event_disable(struct mem_event_domain *med)
@@ -220,86 +248,79 @@ int mem_event_domctl(struct domain *d, x
rc = -ENOSYS;
- switch ( mec-> mode )
+ switch ( mec->mode )
{
- case 0:
+ case XEN_DOMCTL_MEM_EVENT_OP_PAGING:
{
+ struct mem_event_domain *med = &d->mem_paging;
+ rc = -ENODEV;
+ /* Only HAP is supported */
+ if ( !hap_enabled(d) )
+ break;
+
+ /* Currently only EPT is supported */
+ if ( boot_cpu_data.x86_vendor != X86_VENDOR_INTEL )
+ break;
+
switch( mec->op )
{
- case XEN_DOMCTL_MEM_EVENT_OP_ENABLE:
+ case XEN_DOMCTL_MEM_EVENT_OP_PAGING_ENABLE:
{
- struct domain *dom_mem_event = current->domain;
- struct vcpu *v = current;
- struct mem_event_domain *med = &d->mem_event;
- unsigned long ring_addr = mec->ring_addr;
- unsigned long shared_addr = mec->shared_addr;
- l1_pgentry_t l1e;
- unsigned long gfn;
- p2m_type_t p2mt;
- mfn_t ring_mfn;
- mfn_t shared_mfn;
-
- /* Only one xenpaging at a time. If xenpaging crashed,
- * the cache is in an undefined state and so is the guest
- */
- rc = -EBUSY;
- if ( med->ring_page )
- break;
-
- /* Currently only EPT is supported */
- rc = -ENODEV;
- if ( !(hap_enabled(d) &&
- (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)) )
- break;
-
- /* Get MFN of ring page */
- guest_get_eff_l1e(v, ring_addr, &l1e);
- gfn = l1e_get_pfn(l1e);
- ring_mfn = gfn_to_mfn(p2m_get_hostp2m(dom_mem_event), gfn, &p2mt);
-
- rc = -EINVAL;
- if ( unlikely(!mfn_valid(mfn_x(ring_mfn))) )
- break;
-
- /* Get MFN of shared page */
- guest_get_eff_l1e(v, shared_addr, &l1e);
- gfn = l1e_get_pfn(l1e);
- shared_mfn = gfn_to_mfn(p2m_get_hostp2m(dom_mem_event), gfn, &p2mt);
-
- rc = -EINVAL;
- if ( unlikely(!mfn_valid(mfn_x(shared_mfn))) )
- break;
-
- rc = -EINVAL;
- if ( mem_event_enable(d, med, ring_mfn, shared_mfn) != 0 )
- break;
-
- rc = 0;
+ rc = mem_event_enable(d, mec, med);
}
break;
- case XEN_DOMCTL_MEM_EVENT_OP_DISABLE:
+ case XEN_DOMCTL_MEM_EVENT_OP_PAGING_DISABLE:
{
- rc = mem_event_disable(&d->mem_event);
+ rc = mem_event_disable(med);
}
break;
default:
- rc = -ENOSYS;
- break;
+ {
+ if ( med->ring_page )
+ rc = mem_paging_domctl(d, mec, u_domctl);
}
break;
+ }
}
- case XEN_DOMCTL_MEM_EVENT_OP_PAGING:
- {
- rc = mem_paging_domctl(d, mec, u_domctl);
- break;
- }
+ break;
+
case XEN_DOMCTL_MEM_EVENT_OP_ACCESS:
{
- rc = mem_access_domctl(d, mec, u_domctl);
+ struct mem_event_domain *med = &d->mem_access;
+ rc = -ENODEV;
+ /* Only HAP is supported */
+ if ( !hap_enabled(d) )
+ break;
+
+ /* Currently only EPT is supported */
+ if ( boot_cpu_data.x86_vendor != X86_VENDOR_INTEL )
+ break;
+
+ switch( mec->op )
+ {
+ case XEN_DOMCTL_MEM_EVENT_OP_ACCESS_ENABLE:
+ {
+ rc = mem_event_enable(d, mec, med);
+ }
+ break;
+
+ case XEN_DOMCTL_MEM_EVENT_OP_ACCESS_DISABLE:
+ {
+ rc = mem_event_disable(&d->mem_access);
+ }
+ break;
+
+ default:
+ {
+ if ( med->ring_page )
+ rc = mem_access_domctl(d, mec, u_domctl);
+ }
break;
+ }
}
+ break;
}
return rc;
Index: xen-4.1.3-testing/xen/arch/x86/mm/mem_sharing.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/mm/mem_sharing.c
+++ xen-4.1.3-testing/xen/arch/x86/mm/mem_sharing.c
@@ -322,12 +322,12 @@ static struct page_info* mem_sharing_all
req.flags |= MEM_EVENT_FLAG_VCPU_PAUSED;
}
- if(mem_event_check_ring(d, &d->mem_event)) return page;
+ if(mem_event_check_ring(d, &d->mem_share)) return page;
req.gfn = gfn;
req.p2mt = p2m_ram_shared;
req.vcpu_id = v->vcpu_id;
- mem_event_put_request(d, &d->mem_event, &req);
+ mem_event_put_request(d, &d->mem_share, &req);
return page;
}
@@ -342,7 +342,7 @@ int mem_sharing_sharing_resume(struct do
mem_event_response_t rsp;
/* Get request off the ring */
- mem_event_get_response(&d->mem_event, &rsp);
+ mem_event_get_response(&d->mem_share, &rsp);
/* Unpause domain/vcpu */
if( rsp.flags & MEM_EVENT_FLAG_VCPU_PAUSED )
@@ -739,7 +739,7 @@ int mem_sharing_domctl(struct domain *d,
switch(mec->op)
{
- case XEN_DOMCTL_MEM_SHARING_OP_CONTROL:
+ case XEN_DOMCTL_MEM_EVENT_OP_SHARING_CONTROL:
{
d->arch.hvm_domain.mem_sharing_enabled = mec->u.enable;
mem_sharing_audit();
@@ -747,7 +747,7 @@ int mem_sharing_domctl(struct domain *d,
}
break;
- case XEN_DOMCTL_MEM_SHARING_OP_NOMINATE_GFN:
+ case XEN_DOMCTL_MEM_EVENT_OP_SHARING_NOMINATE_GFN:
{
unsigned long gfn = mec->u.nominate.u.gfn;
shr_handle_t handle;
@@ -759,7 +759,7 @@ int mem_sharing_domctl(struct domain *d,
}
break;
- case XEN_DOMCTL_MEM_SHARING_OP_NOMINATE_GREF:
+ case XEN_DOMCTL_MEM_EVENT_OP_SHARING_NOMINATE_GREF:
{
grant_ref_t gref = mec->u.nominate.u.grant_ref;
unsigned long gfn;
@@ -776,7 +776,7 @@ int mem_sharing_domctl(struct domain *d,
}
break;
- case XEN_DOMCTL_MEM_SHARING_OP_SHARE:
+ case XEN_DOMCTL_MEM_EVENT_OP_SHARING_SHARE:
{
shr_handle_t sh = mec->u.share.source_handle;
shr_handle_t ch = mec->u.share.client_handle;
@@ -785,7 +785,7 @@ int mem_sharing_domctl(struct domain *d,
}
break;
- case XEN_DOMCTL_MEM_SHARING_OP_RESUME:
+ case XEN_DOMCTL_MEM_EVENT_OP_SHARING_RESUME:
{
if(!mem_sharing_enabled(d))
return -EINVAL;
@@ -794,7 +794,7 @@ int mem_sharing_domctl(struct domain *d,
}
break;
- case XEN_DOMCTL_MEM_SHARING_OP_DEBUG_GFN:
+ case XEN_DOMCTL_MEM_EVENT_OP_SHARING_DEBUG_GFN:
{
unsigned long gfn = mec->u.debug.u.gfn;
rc = mem_sharing_debug_gfn(d, gfn);
@@ -802,7 +802,7 @@ int mem_sharing_domctl(struct domain *d,
}
break;
- case XEN_DOMCTL_MEM_SHARING_OP_DEBUG_MFN:
+ case XEN_DOMCTL_MEM_EVENT_OP_SHARING_DEBUG_MFN:
{
unsigned long mfn = mec->u.debug.u.mfn;
rc = mem_sharing_debug_mfn(mfn);
@@ -810,7 +810,7 @@ int mem_sharing_domctl(struct domain *d,
}
break;
- case XEN_DOMCTL_MEM_SHARING_OP_DEBUG_GREF:
+ case XEN_DOMCTL_MEM_EVENT_OP_SHARING_DEBUG_GREF:
{
grant_ref_t gref = mec->u.debug.u.gref;
rc = mem_sharing_debug_gref(d, gref);
Index: xen-4.1.3-testing/xen/arch/x86/mm/p2m.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/mm/p2m.c
+++ xen-4.1.3-testing/xen/arch/x86/mm/p2m.c
@@ -2929,7 +2929,7 @@ void p2m_mem_paging_drop_page(struct p2m
struct domain *d = p2m->domain;
/* Check that there's space on the ring for this request */
- if ( mem_event_check_ring(d, &d->mem_event) == 0)
+ if ( mem_event_check_ring(d, &d->mem_paging) == 0)
{
/* Send release notification to pager */
memset(&req, 0, sizeof(req));
@@ -2937,7 +2937,7 @@ void p2m_mem_paging_drop_page(struct p2m
req.gfn = gfn;
req.vcpu_id = v->vcpu_id;
- mem_event_put_request(d, &d->mem_event, &req);
+ mem_event_put_request(d, &d->mem_paging, &req);
}
}
@@ -2949,7 +2949,7 @@ void p2m_mem_paging_populate(struct p2m_
struct domain *d = p2m->domain;
/* Check that there's space on the ring for this request */
- if ( mem_event_check_ring(d, &d->mem_event) )
+ if ( mem_event_check_ring(d, &d->mem_paging) )
return;
memset(&req, 0, sizeof(req));
@@ -2976,7 +2976,7 @@ void p2m_mem_paging_populate(struct p2m_
else if ( p2mt != p2m_ram_paging_out && p2mt != p2m_ram_paged )
{
/* gfn is already on its way back and vcpu is not paused */
- mem_event_put_req_producers(&d->mem_event);
+ mem_event_put_req_producers(&d->mem_paging);
return;
}
@@ -2985,7 +2985,7 @@ void p2m_mem_paging_populate(struct p2m_
req.p2mt = p2mt;
req.vcpu_id = v->vcpu_id;
- mem_event_put_request(d, &d->mem_event, &req);
+ mem_event_put_request(d, &d->mem_paging, &req);
}
int p2m_mem_paging_prep(struct p2m_domain *p2m, unsigned long gfn)
@@ -3014,7 +3014,7 @@ void p2m_mem_paging_resume(struct p2m_do
mfn_t mfn;
/* Pull the response off the ring */
- mem_event_get_response(&d->mem_event, &rsp);
+ mem_event_get_response(&d->mem_paging, &rsp);
/* Fix p2m entry if the page was not dropped */
if ( !(rsp.flags & MEM_EVENT_FLAG_DROP_PAGE) )
@@ -3061,7 +3061,7 @@ void p2m_mem_access_check(paddr_t gpa, b
p2m_unlock(p2m);
/* Otherwise, check if there is a memory event listener, and send the message along */
- res = mem_event_check_ring(d, &d->mem_event);
+ res = mem_event_check_ring(d, &d->mem_access);
if ( res < 0 )
{
/* No listener */
@@ -3105,7 +3105,7 @@ void p2m_mem_access_check(paddr_t gpa, b
req.vcpu_id = v->vcpu_id;
- mem_event_put_request(d, &d->mem_event, &req);
+ mem_event_put_request(d, &d->mem_access, &req);
/* VCPU paused, mem event request sent */
}
@@ -3115,7 +3115,7 @@ void p2m_mem_access_resume(struct p2m_do
struct domain *d = p2m->domain;
mem_event_response_t rsp;
- mem_event_get_response(&d->mem_event, &rsp);
+ mem_event_get_response(&d->mem_access, &rsp);
/* Unpause domain */
if ( rsp.flags & MEM_EVENT_FLAG_VCPU_PAUSED )
Index: xen-4.1.3-testing/xen/include/public/domctl.h
===================================================================
--- xen-4.1.3-testing.orig/xen/include/public/domctl.h
+++ xen-4.1.3-testing/xen/include/public/domctl.h
@@ -707,20 +707,18 @@ struct xen_domctl_gdbsx_domstatus {
/* XEN_DOMCTL_mem_event_op */
-/* Add and remove memory handlers */
-#define XEN_DOMCTL_MEM_EVENT_OP_ENABLE 0
-#define XEN_DOMCTL_MEM_EVENT_OP_DISABLE 1
-
/*
+* Domain memory paging
* Page memory in and out.
*/
#define XEN_DOMCTL_MEM_EVENT_OP_PAGING 1
-/* Domain memory paging */
-#define XEN_DOMCTL_MEM_EVENT_OP_PAGING_NOMINATE 0
-#define XEN_DOMCTL_MEM_EVENT_OP_PAGING_EVICT 1
-#define XEN_DOMCTL_MEM_EVENT_OP_PAGING_PREP 2
-#define XEN_DOMCTL_MEM_EVENT_OP_PAGING_RESUME 3
+#define XEN_DOMCTL_MEM_EVENT_OP_PAGING_ENABLE 0
+#define XEN_DOMCTL_MEM_EVENT_OP_PAGING_DISABLE 1
+#define XEN_DOMCTL_MEM_EVENT_OP_PAGING_NOMINATE 2
+#define XEN_DOMCTL_MEM_EVENT_OP_PAGING_EVICT 3
+#define XEN_DOMCTL_MEM_EVENT_OP_PAGING_PREP 4
+#define XEN_DOMCTL_MEM_EVENT_OP_PAGING_RESUME 5
/*
* Access permissions.
@@ -733,11 +731,14 @@ struct xen_domctl_gdbsx_domstatus {
* ACCESS_RESUME mode for the following domctl.
*/
#define XEN_DOMCTL_MEM_EVENT_OP_ACCESS 2
-#define XEN_DOMCTL_MEM_EVENT_OP_ACCESS_RESUME 0
+
+#define XEN_DOMCTL_MEM_EVENT_OP_ACCESS_ENABLE 0
+#define XEN_DOMCTL_MEM_EVENT_OP_ACCESS_DISABLE 1
+#define XEN_DOMCTL_MEM_EVENT_OP_ACCESS_RESUME 2
struct xen_domctl_mem_event_op {
- uint32_t op; /* XEN_DOMCTL_MEM_EVENT_OP_* */
- uint32_t mode; /* XEN_DOMCTL_MEM_EVENT_ENABLE_* */
+ uint32_t op; /* XEN_DOMCTL_MEM_EVENT_OP_*_* */
+ uint32_t mode; /* XEN_DOMCTL_MEM_EVENT_OP_* */
/* OP_ENABLE */
uint64_aligned_t shared_addr; /* IN: Virtual address of shared page */
@@ -754,14 +755,16 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_mem_e
*/
/* XEN_DOMCTL_mem_sharing_op */
-#define XEN_DOMCTL_MEM_SHARING_OP_CONTROL 0
-#define XEN_DOMCTL_MEM_SHARING_OP_NOMINATE_GFN 1
-#define XEN_DOMCTL_MEM_SHARING_OP_NOMINATE_GREF 2
-#define XEN_DOMCTL_MEM_SHARING_OP_SHARE 3
-#define XEN_DOMCTL_MEM_SHARING_OP_RESUME 4
-#define XEN_DOMCTL_MEM_SHARING_OP_DEBUG_GFN 5
-#define XEN_DOMCTL_MEM_SHARING_OP_DEBUG_MFN 6
-#define XEN_DOMCTL_MEM_SHARING_OP_DEBUG_GREF 7
+#define XEN_DOMCTL_MEM_EVENT_OP_SHARING 3
+
+#define XEN_DOMCTL_MEM_EVENT_OP_SHARING_CONTROL 0
+#define XEN_DOMCTL_MEM_EVENT_OP_SHARING_NOMINATE_GFN 1
+#define XEN_DOMCTL_MEM_EVENT_OP_SHARING_NOMINATE_GREF 2
+#define XEN_DOMCTL_MEM_EVENT_OP_SHARING_SHARE 3
+#define XEN_DOMCTL_MEM_EVENT_OP_SHARING_RESUME 4
+#define XEN_DOMCTL_MEM_EVENT_OP_SHARING_DEBUG_GFN 5
+#define XEN_DOMCTL_MEM_EVENT_OP_SHARING_DEBUG_MFN 6
+#define XEN_DOMCTL_MEM_EVENT_OP_SHARING_DEBUG_GREF 7
#define XEN_DOMCTL_MEM_SHARING_S_HANDLE_INVALID (-10)
#define XEN_DOMCTL_MEM_SHARING_C_HANDLE_INVALID (-9)
Index: xen-4.1.3-testing/xen/include/xen/sched.h
===================================================================
--- xen-4.1.3-testing.orig/xen/include/xen/sched.h
+++ xen-4.1.3-testing/xen/include/xen/sched.h
@@ -326,8 +326,12 @@ struct domain
/* Non-migratable and non-restoreable? */
bool_t disable_migrate;
+ /* Memory sharing support */
+ struct mem_event_domain mem_share;
/* Memory paging support */
- struct mem_event_domain mem_event;
+ struct mem_event_domain mem_paging;
+ /* Memory access support */
+ struct mem_event_domain mem_access;
/* Currently computed from union of all vcpu cpu-affinity masks. */
nodemask_t node_affinity;

View File

@ -1,122 +0,0 @@
changeset: 23874:651aed73b39c
user: Olaf Hering <olafiaepfle.de>
date: Mon Sep 26 22:19:42 2011 +0100
files: tools/libxc/xc_domain.c tools/libxc/xenctrl.h xen/arch/x86/mm/p2m.c xen/common/domctl.c xen/include/public/domctl.h xen/include/xen/sched.h
description:
xenpaging: track number of paged pages in struct domain
The toolstack should know how many pages are paged-out at a given point
in time so it could make smarter decisions about how many pages should
be paged or ballooned.
Add a new member to xen_domctl_getdomaininfo and bump interface version.
Use the new member in xc_dominfo_t.
The SONAME of libxc should be changed if this patch gets applied.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Tim Deegan <tim@xen.org>
Committed-by: Tim Deegan <tim@xen.org>
---
tools/libxc/xc_domain.c | 1 +
tools/libxc/xenctrl.h | 1 +
xen/arch/x86/mm/p2m.c | 5 +++++
xen/common/domctl.c | 1 +
xen/include/public/domctl.h | 3 ++-
xen/include/xen/sched.h | 1 +
6 files changed, 11 insertions(+), 1 deletion(-)
Index: xen-4.1.3-testing/tools/libxc/xc_domain.c
===================================================================
--- xen-4.1.3-testing.orig/tools/libxc/xc_domain.c
+++ xen-4.1.3-testing/tools/libxc/xc_domain.c
@@ -235,6 +235,7 @@ int xc_domain_getinfo(xc_interface *xch,
info->ssidref = domctl.u.getdomaininfo.ssidref;
info->nr_pages = domctl.u.getdomaininfo.tot_pages;
info->nr_shared_pages = domctl.u.getdomaininfo.shr_pages;
+ info->nr_paged_pages = domctl.u.getdomaininfo.paged_pages;
info->max_memkb = domctl.u.getdomaininfo.max_pages << (PAGE_SHIFT-10);
info->shared_info_frame = domctl.u.getdomaininfo.shared_info_frame;
info->cpu_time = domctl.u.getdomaininfo.cpu_time;
Index: xen-4.1.3-testing/tools/libxc/xenctrl.h
===================================================================
--- xen-4.1.3-testing.orig/tools/libxc/xenctrl.h
+++ xen-4.1.3-testing/tools/libxc/xenctrl.h
@@ -353,6 +353,7 @@ typedef struct xc_dominfo {
unsigned int shutdown_reason; /* only meaningful if shutdown==1 */
unsigned long nr_pages; /* current number, not maximum */
unsigned long nr_shared_pages;
+ unsigned long nr_paged_pages;
unsigned long shared_info_frame;
uint64_t cpu_time;
unsigned long max_memkb;
Index: xen-4.1.3-testing/xen/arch/x86/mm/p2m.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/mm/p2m.c
+++ xen-4.1.3-testing/xen/arch/x86/mm/p2m.c
@@ -2919,6 +2919,9 @@ int p2m_mem_paging_evict(struct p2m_doma
/* Put the page back so it gets freed */
put_page(page);
+ /* Track number of paged gfns */
+ atomic_inc(&p2m->domain->paged_pages);
+
return 0;
}
@@ -3003,6 +3006,8 @@ int p2m_mem_paging_prep(struct p2m_domai
audit_p2m(p2m, 1);
p2m_unlock(p2m);
+ atomic_dec(&p2m->domain->paged_pages);
+
return 0;
}
Index: xen-4.1.3-testing/xen/common/domctl.c
===================================================================
--- xen-4.1.3-testing.orig/xen/common/domctl.c
+++ xen-4.1.3-testing/xen/common/domctl.c
@@ -139,6 +139,7 @@ void getdomaininfo(struct domain *d, str
info->tot_pages = d->tot_pages;
info->max_pages = d->max_pages;
info->shr_pages = atomic_read(&d->shr_pages);
+ info->paged_pages = atomic_read(&d->paged_pages);
info->shared_info_frame = mfn_to_gmfn(d, __pa(d->shared_info)>>PAGE_SHIFT);
BUG_ON(SHARED_M2P(info->shared_info_frame));
Index: xen-4.1.3-testing/xen/include/public/domctl.h
===================================================================
--- xen-4.1.3-testing.orig/xen/include/public/domctl.h
+++ xen-4.1.3-testing/xen/include/public/domctl.h
@@ -35,7 +35,7 @@
#include "xen.h"
#include "grant_table.h"
-#define XEN_DOMCTL_INTERFACE_VERSION 0x00000007
+#define XEN_DOMCTL_INTERFACE_VERSION 0x00000008
/*
* NB. xen_domctl.domain is an IN/OUT parameter for this operation.
@@ -95,6 +95,7 @@ struct xen_domctl_getdomaininfo {
uint64_aligned_t tot_pages;
uint64_aligned_t max_pages;
uint64_aligned_t shr_pages;
+ uint64_aligned_t paged_pages;
uint64_aligned_t shared_info_frame; /* GMFN of shared_info struct */
uint64_aligned_t cpu_time;
uint32_t nr_online_vcpus; /* Number of VCPUs currently online. */
Index: xen-4.1.3-testing/xen/include/xen/sched.h
===================================================================
--- xen-4.1.3-testing.orig/xen/include/xen/sched.h
+++ xen-4.1.3-testing/xen/include/xen/sched.h
@@ -215,6 +215,7 @@ struct domain
unsigned int tot_pages; /* number of pages currently possesed */
unsigned int max_pages; /* maximum value for tot_pages */
atomic_t shr_pages; /* number of shared pages */
+ atomic_t paged_pages; /* number of paged-out pages */
unsigned int xenheap_pages; /* # pages allocated from Xen heap */
unsigned int max_vcpus;

View File

@ -1,69 +0,0 @@
# HG changeset patch
# User Keir Fraser <keir@xen.org>
# Date 1317413803 -3600
# Node ID 2215d7d7382617adbe97831fe35752a027917d1d
# Parent d568e2313fd6f055b66a6c3cb2bca6372b77692e
X86 MCE: Prevent malicious guest access broken page again
To avoid recursive mce.
Signed-off-by: Liu, Jinsong <jinsong.liu@intel.com>
Committed-by: Keir Fraser <keir@xen.org>
Index: xen-4.1.2-testing/xen/arch/x86/cpu/mcheck/mce_intel.c
===================================================================
--- xen-4.1.2-testing.orig/xen/arch/x86/cpu/mcheck/mce_intel.c
+++ xen-4.1.2-testing/xen/arch/x86/cpu/mcheck/mce_intel.c
@@ -639,6 +639,8 @@ static void intel_memerr_dhandler(int bn
/* This is free page */
if (status & PG_OFFLINE_OFFLINED)
result->result = MCA_RECOVERED;
+ else if (status & PG_OFFLINE_AGAIN)
+ result->result = MCA_NO_ACTION;
else if (status & PG_OFFLINE_PENDING) {
/* This page has owner */
if (status & PG_OFFLINE_OWNED) {
Index: xen-4.1.2-testing/xen/common/page_alloc.c
===================================================================
--- xen-4.1.2-testing.orig/xen/common/page_alloc.c
+++ xen-4.1.2-testing/xen/common/page_alloc.c
@@ -38,6 +38,7 @@
#include <xen/tmem.h>
#include <xen/tmem_xen.h>
#include <public/sysctl.h>
+#include <public/sched.h>
#include <asm/page.h>
#include <asm/numa.h>
#include <asm/flushtlb.h>
@@ -708,6 +709,19 @@ int offline_page(unsigned long mfn, int
return -EINVAL;
}
+ /*
+ * NB. When broken page belong to guest, usually hypervisor will
+ * notify the guest to handle the broken page. However, hypervisor
+ * need to prevent malicious guest access the broken page again.
+ * Under such case, hypervisor shutdown guest, preventing recursive mce.
+ */
+ if ( (pg->count_info & PGC_broken) && (owner = page_get_owner(pg)) )
+ {
+ *status = PG_OFFLINE_AGAIN;
+ domain_shutdown(owner, SHUTDOWN_crash);
+ return 0;
+ }
+
spin_lock(&heap_lock);
old_info = mark_page_offline(pg, broken);
Index: xen-4.1.2-testing/xen/include/public/sysctl.h
===================================================================
--- xen-4.1.2-testing.orig/xen/include/public/sysctl.h
+++ xen-4.1.2-testing/xen/include/public/sysctl.h
@@ -399,6 +399,7 @@ struct xen_sysctl_page_offline_op {
#define PG_OFFLINE_OFFLINED (0x1UL << 1)
#define PG_OFFLINE_PENDING (0x1UL << 2)
#define PG_OFFLINE_FAILED (0x1UL << 3)
+#define PG_OFFLINE_AGAIN (0x1UL << 4)
#define PG_ONLINE_FAILED PG_OFFLINE_FAILED
#define PG_ONLINE_ONLINED PG_OFFLINE_OFFLINED

View File

@ -1,131 +0,0 @@
changeset: 23904:ecab267b85ef
user: Olaf Hering <olaf@aepfle.de>
date: Thu Oct 06 12:33:17 2011 +0100
files: xen/arch/x86/mm/p2m.c
description:
xenpaging: use p2m->get_entry() in p2m_mem_paging functions
Use p2m->get_entry() in the p2m_mem_paging functions. This preserves the
p2m_access type when gfn is updated with set_p2m_entry().
Its also a preparation for locking fixes in a subsequent patch.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Acked-by: Tim Deegan <tim@xen.org>
Committed-by: Tim Deegan <tim@xen.org>
---
xen/arch/x86/mm/p2m.c | 25 ++++++++++++++++---------
1 file changed, 16 insertions(+), 9 deletions(-)
Index: xen-4.1.3-testing/xen/arch/x86/mm/p2m.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/mm/p2m.c
+++ xen-4.1.3-testing/xen/arch/x86/mm/p2m.c
@@ -2845,10 +2845,11 @@ int p2m_mem_paging_nominate(struct p2m_d
{
struct page_info *page;
p2m_type_t p2mt;
+ p2m_access_t a;
mfn_t mfn;
int ret;
- mfn = gfn_to_mfn(p2m, gfn, &p2mt);
+ mfn = p2m->get_entry(p2m, gfn, &p2mt, &a, p2m_query);
/* Check if mfn is valid */
ret = -EINVAL;
@@ -2875,7 +2876,7 @@ int p2m_mem_paging_nominate(struct p2m_d
/* Fix p2m entry */
p2m_lock(p2m);
- set_p2m_entry(p2m, gfn, mfn, 0, p2m_ram_paging_out, p2m->default_access);
+ set_p2m_entry(p2m, gfn, mfn, 0, p2m_ram_paging_out, a);
audit_p2m(p2m, 1);
p2m_unlock(p2m);
@@ -2889,11 +2890,12 @@ int p2m_mem_paging_evict(struct p2m_doma
{
struct page_info *page;
p2m_type_t p2mt;
+ p2m_access_t a;
mfn_t mfn;
struct domain *d = p2m->domain;
/* Get mfn */
- mfn = gfn_to_mfn(p2m, gfn, &p2mt);
+ mfn = p2m->get_entry(p2m, gfn, &p2mt, &a, p2m_query);
if ( unlikely(!mfn_valid(mfn)) )
return -EINVAL;
@@ -2912,7 +2914,7 @@ int p2m_mem_paging_evict(struct p2m_doma
/* Remove mapping from p2m table */
p2m_lock(p2m);
- set_p2m_entry(p2m, gfn, _mfn(PAGING_MFN), 0, p2m_ram_paged, p2m->default_access);
+ set_p2m_entry(p2m, gfn, _mfn(PAGING_MFN), 0, p2m_ram_paged, a);
audit_p2m(p2m, 1);
p2m_unlock(p2m);
@@ -2949,6 +2951,7 @@ void p2m_mem_paging_populate(struct p2m_
struct vcpu *v = current;
mem_event_request_t req;
p2m_type_t p2mt;
+ p2m_access_t a;
struct domain *d = p2m->domain;
/* Check that there's space on the ring for this request */
@@ -2961,11 +2964,11 @@ void p2m_mem_paging_populate(struct p2m_
/* Fix p2m mapping */
/* XXX: It seems inefficient to have this here, as it's only needed
* in one case (ept guest accessing paging out page) */
- gfn_to_mfn(p2m, gfn, &p2mt);
+ p2m->get_entry(p2m, gfn, &p2mt, &a, p2m_query);
if ( p2mt == p2m_ram_paged )
{
p2m_lock(p2m);
- set_p2m_entry(p2m, gfn, _mfn(PAGING_MFN), 0, p2m_ram_paging_in_start, p2m->default_access);
+ set_p2m_entry(p2m, gfn, _mfn(PAGING_MFN), 0, p2m_ram_paging_in_start, a);
audit_p2m(p2m, 1);
p2m_unlock(p2m);
}
@@ -2994,7 +2997,10 @@ void p2m_mem_paging_populate(struct p2m_
int p2m_mem_paging_prep(struct p2m_domain *p2m, unsigned long gfn)
{
struct page_info *page;
+ p2m_type_t p2mt;
+ p2m_access_t a;
+ p2m->get_entry(p2m, gfn, &p2mt, &a, p2m_query);
/* Get a free page */
page = alloc_domheap_page(p2m->domain, 0);
if ( unlikely(page == NULL) )
@@ -3002,7 +3008,7 @@ int p2m_mem_paging_prep(struct p2m_domai
/* Fix p2m mapping */
p2m_lock(p2m);
- set_p2m_entry(p2m, gfn, page_to_mfn(page), 0, p2m_ram_paging_in, p2m->default_access);
+ set_p2m_entry(p2m, gfn, page_to_mfn(page), 0, p2m_ram_paging_in, a);
audit_p2m(p2m, 1);
p2m_unlock(p2m);
@@ -3016,6 +3022,7 @@ void p2m_mem_paging_resume(struct p2m_do
struct domain *d = p2m->domain;
mem_event_response_t rsp;
p2m_type_t p2mt;
+ p2m_access_t a;
mfn_t mfn;
/* Pull the response off the ring */
@@ -3024,9 +3031,9 @@ void p2m_mem_paging_resume(struct p2m_do
/* Fix p2m entry if the page was not dropped */
if ( !(rsp.flags & MEM_EVENT_FLAG_DROP_PAGE) )
{
- mfn = gfn_to_mfn(p2m, rsp.gfn, &p2mt);
+ mfn = p2m->get_entry(p2m, rsp.gfn, &p2mt, &a, p2m_query);
p2m_lock(p2m);
- set_p2m_entry(p2m, rsp.gfn, mfn, 0, p2m_ram_rw, p2m->default_access);
+ set_p2m_entry(p2m, rsp.gfn, mfn, 0, p2m_ram_rw, a);
set_gpfn_from_mfn(mfn_x(mfn), rsp.gfn);
audit_p2m(p2m, 1);
p2m_unlock(p2m);

View File

@ -1,157 +0,0 @@
changeset: 23905:50ee6be56460
user: Olaf Hering <olaf@aepfle.de>
date: Thu Oct 06 12:33:17 2011 +0100
files: xen/arch/x86/mm/p2m.c
description:
xenpaging: fix locking in p2m_mem_paging functions
As suggested by <hongkaixing@huawei.com>, query and adjust the p2mt
under the p2m_lock to prevent races with PoD.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Acked-by: Tim Deegan <tim@xen.org>
Committed-by: Tim Deegan <tim@xen.org>
---
xen/arch/x86/mm/p2m.c | 42 ++++++++++++++++++++++++++----------------
1 file changed, 26 insertions(+), 16 deletions(-)
Index: xen-4.1.3-testing/xen/arch/x86/mm/p2m.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/mm/p2m.c
+++ xen-4.1.3-testing/xen/arch/x86/mm/p2m.c
@@ -2849,6 +2849,8 @@ int p2m_mem_paging_nominate(struct p2m_d
mfn_t mfn;
int ret;
+ p2m_lock(p2m);
+
mfn = p2m->get_entry(p2m, gfn, &p2mt, &a, p2m_query);
/* Check if mfn is valid */
@@ -2875,14 +2877,12 @@ int p2m_mem_paging_nominate(struct p2m_d
goto out;
/* Fix p2m entry */
- p2m_lock(p2m);
set_p2m_entry(p2m, gfn, mfn, 0, p2m_ram_paging_out, a);
audit_p2m(p2m, 1);
- p2m_unlock(p2m);
-
ret = 0;
out:
+ p2m_unlock(p2m);
return ret;
}
@@ -2893,30 +2893,31 @@ int p2m_mem_paging_evict(struct p2m_doma
p2m_access_t a;
mfn_t mfn;
struct domain *d = p2m->domain;
+ int ret = -EINVAL;
+
+ p2m_lock(p2m);
/* Get mfn */
mfn = p2m->get_entry(p2m, gfn, &p2mt, &a, p2m_query);
if ( unlikely(!mfn_valid(mfn)) )
- return -EINVAL;
+ goto out;
if ( (p2mt == p2m_ram_paged) || (p2mt == p2m_ram_paging_in) ||
(p2mt == p2m_ram_paging_in_start) )
- return -EINVAL;
+ goto out;
/* Get the page so it doesn't get modified under Xen's feet */
page = mfn_to_page(mfn);
if ( unlikely(!get_page(page, d)) )
- return -EINVAL;
+ goto out;
/* Decrement guest domain's ref count of the page */
if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
put_page(page);
/* Remove mapping from p2m table */
- p2m_lock(p2m);
set_p2m_entry(p2m, gfn, _mfn(PAGING_MFN), 0, p2m_ram_paged, a);
audit_p2m(p2m, 1);
- p2m_unlock(p2m);
/* Put the page back so it gets freed */
put_page(page);
@@ -2924,7 +2925,11 @@ int p2m_mem_paging_evict(struct p2m_doma
/* Track number of paged gfns */
atomic_inc(&p2m->domain->paged_pages);
- return 0;
+ ret = 0;
+
+ out:
+ p2m_unlock(p2m);
+ return ret;
}
void p2m_mem_paging_drop_page(struct p2m_domain *p2m, unsigned long gfn)
@@ -2964,14 +2969,14 @@ void p2m_mem_paging_populate(struct p2m_
/* Fix p2m mapping */
/* XXX: It seems inefficient to have this here, as it's only needed
* in one case (ept guest accessing paging out page) */
+ p2m_lock(p2m);
p2m->get_entry(p2m, gfn, &p2mt, &a, p2m_query);
if ( p2mt == p2m_ram_paged )
{
- p2m_lock(p2m);
set_p2m_entry(p2m, gfn, _mfn(PAGING_MFN), 0, p2m_ram_paging_in_start, a);
audit_p2m(p2m, 1);
- p2m_unlock(p2m);
}
+ p2m_unlock(p2m);
/* Pause domain */
if ( v->domain->domain_id == d->domain_id )
@@ -2999,22 +3004,27 @@ int p2m_mem_paging_prep(struct p2m_domai
struct page_info *page;
p2m_type_t p2mt;
p2m_access_t a;
+ int ret = -ENOMEM;
+
+ p2m_lock(p2m);
p2m->get_entry(p2m, gfn, &p2mt, &a, p2m_query);
+
/* Get a free page */
page = alloc_domheap_page(p2m->domain, 0);
if ( unlikely(page == NULL) )
- return -ENOMEM;
+ goto out;
/* Fix p2m mapping */
- p2m_lock(p2m);
set_p2m_entry(p2m, gfn, page_to_mfn(page), 0, p2m_ram_paging_in, a);
audit_p2m(p2m, 1);
- p2m_unlock(p2m);
atomic_dec(&p2m->domain->paged_pages);
- return 0;
+ ret = 0;
+ out:
+ p2m_unlock(p2m);
+ return ret;
}
void p2m_mem_paging_resume(struct p2m_domain *p2m)
@@ -3031,8 +3041,8 @@ void p2m_mem_paging_resume(struct p2m_do
/* Fix p2m entry if the page was not dropped */
if ( !(rsp.flags & MEM_EVENT_FLAG_DROP_PAGE) )
{
- mfn = p2m->get_entry(p2m, rsp.gfn, &p2mt, &a, p2m_query);
p2m_lock(p2m);
+ mfn = p2m->get_entry(p2m, rsp.gfn, &p2mt, &a, p2m_query);
set_p2m_entry(p2m, rsp.gfn, mfn, 0, p2m_ram_rw, a);
set_gpfn_from_mfn(mfn_x(mfn), rsp.gfn);
audit_p2m(p2m, 1);

View File

@ -1,35 +0,0 @@
changeset: 23906:7bf85c3fd9f0
user: Olaf Hering <olaf@aepfle.de>
date: Thu Oct 06 12:33:17 2011 +0100
files: xen/arch/x86/mm/p2m.c
description:
xenpaging: remove confusing comment from p2m_mem_paging_populate
Currently there is no way to avoid the double check of the p2mt
because p2m_mem_paging_populate() is called from many places without
the p2m_lock held. Upcoming changes will move the function into
gfn_to_mfn(), so its interface could be changed and the extra
p2m_lock/get_entry can be removed.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Acked-by: Tim Deegan <tim@xen.org>
Committed-by: Tim Deegan <tim@xen.org>
---
xen/arch/x86/mm/p2m.c | 2 --
1 file changed, 2 deletions(-)
Index: xen-4.1.3-testing/xen/arch/x86/mm/p2m.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/mm/p2m.c
+++ xen-4.1.3-testing/xen/arch/x86/mm/p2m.c
@@ -2967,8 +2967,6 @@ void p2m_mem_paging_populate(struct p2m_
req.type = MEM_EVENT_TYPE_PAGING;
/* Fix p2m mapping */
- /* XXX: It seems inefficient to have this here, as it's only needed
- * in one case (ept guest accessing paging out page) */
p2m_lock(p2m);
p2m->get_entry(p2m, gfn, &p2mt, &a, p2m_query);
if ( p2mt == p2m_ram_paged )

View File

@ -1,138 +0,0 @@
# HG changeset patch
# User Jan Beulich <jbeulich@suse.com>
# Date 1318231292 -7200
# Node ID 0b81515b8e982e8012c28e5f8d9e965c63b6503d
# Parent 0c2bfd1f9c6822fbd23af0043f83d93be976323c
passthrough: update bus2bridge mapping as PCI devices get added/removed
This deals with two limitations at once: On device removal, the
mapping did not get updated so far at all, and hotplugged devices as
well as such not discoverable by Xen's initial bus scan (including the
case where a non-zero PCI segment wasn't accessible during Xen boot,
but became accessible after Dom0 validated access information against
ACPI data) wouldn't cause updates to the mapping either.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: "Kay, Allen M" <allen.m.kay@intel.com>
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -63,11 +63,67 @@ static struct pci_dev *alloc_pdev(u8 bus
list_add(&pdev->alldevs_list, &alldevs_list);
spin_lock_init(&pdev->msix_table_lock);
+ /* update bus2bridge */
+ switch ( pdev_type(bus, devfn) )
+ {
+ u8 sec_bus, sub_bus;
+
+ case DEV_TYPE_PCIe_BRIDGE:
+ break;
+
+ case DEV_TYPE_PCIe2PCI_BRIDGE:
+ case DEV_TYPE_LEGACY_PCI_BRIDGE:
+ sec_bus = pci_conf_read8(bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
+ PCI_SECONDARY_BUS);
+ sub_bus = pci_conf_read8(bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
+ PCI_SUBORDINATE_BUS);
+
+ spin_lock(&bus2bridge_lock);
+ for ( ; sec_bus <= sub_bus; sec_bus++ )
+ {
+ bus2bridge[sec_bus].map = 1;
+ bus2bridge[sec_bus].bus = bus;
+ bus2bridge[sec_bus].devfn = devfn;
+ }
+ spin_unlock(&bus2bridge_lock);
+ break;
+
+ case DEV_TYPE_PCIe_ENDPOINT:
+ case DEV_TYPE_PCI:
+ break;
+
+ default:
+ printk(XENLOG_WARNING "%s: unknown type: %02x:%02x.%u\n",
+ __func__, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+ break;
+ }
+
return pdev;
}
static void free_pdev(struct pci_dev *pdev)
{
+ /* update bus2bridge */
+ switch ( pdev_type(pdev->bus, pdev->devfn) )
+ {
+ u8 dev, func, sec_bus, sub_bus;
+
+ case DEV_TYPE_PCIe2PCI_BRIDGE:
+ case DEV_TYPE_LEGACY_PCI_BRIDGE:
+ dev = PCI_SLOT(pdev->devfn);
+ func = PCI_FUNC(pdev->devfn);
+ sec_bus = pci_conf_read8(pdev->bus, dev, func,
+ PCI_SECONDARY_BUS);
+ sub_bus = pci_conf_read8(pdev->bus, dev, func,
+ PCI_SUBORDINATE_BUS);
+
+ spin_lock(&bus2bridge_lock);
+ for ( ; sec_bus <= sub_bus; sec_bus++ )
+ bus2bridge[sec_bus] = bus2bridge[pdev->bus];
+ spin_unlock(&bus2bridge_lock);
+ break;
+ }
+
list_del(&pdev->alldevs_list);
xfree(pdev);
}
@@ -432,8 +488,6 @@ int __init scan_pci_devices(void)
{
struct pci_dev *pdev;
int bus, dev, func;
- u8 sec_bus, sub_bus;
- int type;
spin_lock(&pcidevs_lock);
for ( bus = 0; bus < 256; bus++ )
@@ -453,41 +507,6 @@ int __init scan_pci_devices(void)
return -ENOMEM;
}
- /* build bus2bridge */
- type = pdev_type(bus, PCI_DEVFN(dev, func));
- switch ( type )
- {
- case DEV_TYPE_PCIe_BRIDGE:
- break;
-
- case DEV_TYPE_PCIe2PCI_BRIDGE:
- case DEV_TYPE_LEGACY_PCI_BRIDGE:
- sec_bus = pci_conf_read8(bus, dev, func,
- PCI_SECONDARY_BUS);
- sub_bus = pci_conf_read8(bus, dev, func,
- PCI_SUBORDINATE_BUS);
-
- spin_lock(&bus2bridge_lock);
- for ( sub_bus &= 0xff; sec_bus <= sub_bus; sec_bus++ )
- {
- bus2bridge[sec_bus].map = 1;
- bus2bridge[sec_bus].bus = bus;
- bus2bridge[sec_bus].devfn = PCI_DEVFN(dev, func);
- }
- spin_unlock(&bus2bridge_lock);
- break;
-
- case DEV_TYPE_PCIe_ENDPOINT:
- case DEV_TYPE_PCI:
- break;
-
- default:
- printk("%s: unknown type: bdf = %x:%x.%x\n",
- __func__, bus, dev, func);
- spin_unlock(&pcidevs_lock);
- return -EINVAL;
- }
-
if ( !func && !(pci_conf_read8(bus, dev, func,
PCI_HEADER_TYPE) & 0x80) )
break;

View File

@ -1,53 +0,0 @@
changeset: 23943:1185ae04b5aa
user: Olaf Hering <olaf@aepfle.de>
date: Tue Oct 11 10:46:28 2011 +0100
files: tools/xenpaging/xenpaging.c xen/arch/x86/mm/p2m.c
description:
xenpaging: clear page content after evict
If the guest happens to read from the gfn while xenpaging is in the process of
evicting the page, the guest may read zeros instead of actual data.
Also if eviction fails the page content will be corrupted and xenpaging wont
attempt to restore the page.
Remove page scrubbing from pager and do it after successful eviction.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
Acked-by: Tim Deegan <tim@xen.org>
Committed-by: Tim Deegan <tim@xen.org>
---
tools/xenpaging/xenpaging.c | 3 ---
xen/arch/x86/mm/p2m.c | 3 +++
2 files changed, 3 insertions(+), 3 deletions(-)
Index: xen-4.1.3-testing/tools/xenpaging/xenpaging.c
===================================================================
--- xen-4.1.3-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.1.3-testing/tools/xenpaging/xenpaging.c
@@ -455,9 +455,6 @@ static int xenpaging_evict_page(xenpagin
goto out;
}
- /* Clear page */
- memset(page, 0, PAGE_SIZE);
-
munmap(page, PAGE_SIZE);
/* Tell Xen to evict page */
Index: xen-4.1.3-testing/xen/arch/x86/mm/p2m.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/mm/p2m.c
+++ xen-4.1.3-testing/xen/arch/x86/mm/p2m.c
@@ -2919,6 +2919,9 @@ int p2m_mem_paging_evict(struct p2m_doma
set_p2m_entry(p2m, gfn, _mfn(PAGING_MFN), 0, p2m_ram_paged, a);
audit_p2m(p2m, 1);
+ /* Clear content before returning the page to Xen */
+ scrub_one_page(page);
+
/* Put the page back so it gets freed */
put_page(page);

View File

@ -1,73 +0,0 @@
# HG changeset patch
# User Guido Gunther <agx@sigxcpu.org>
# Date 1318330978 -3600
# Node ID 4b0907c6a08c348962bd976c2976257b412408be
# Parent 1185ae04b5aad429fd68d1872f404791df627965
pygrub: add debug flag
Debugging config file errors is tedious so help a bit by not silently
dropping parsing exceptions when --debug is given. Also intialize the
logging API at debug level in this case.
Signed-off-by: Guido Gunther <agx@sigxcpu.org>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Committed-by: Ian Jackson <ian.jackson@eu.citrix.com>
Index: xen-4.1.3-testing/tools/pygrub/src/pygrub
===================================================================
--- xen-4.1.3-testing.orig/tools/pygrub/src/pygrub
+++ xen-4.1.3-testing/tools/pygrub/src/pygrub
@@ -13,7 +13,7 @@
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
-import os, sys, string, struct, tempfile, re
+import os, sys, string, struct, tempfile, re, traceback
import copy
import logging
import platform
@@ -674,7 +674,7 @@ if __name__ == "__main__":
["quiet", "interactive", "not-really", "help",
"output=", "output-format=", "output-directory=",
"entry=", "kernel=",
- "ramdisk=", "args=", "isconfig"])
+ "ramdisk=", "args=", "isconfig", "debug"])
except getopt.GetoptError:
usage()
sys.exit(1)
@@ -688,6 +688,7 @@ if __name__ == "__main__":
entry = None
interactive = True
isconfig = False
+ debug = False
not_really = False
output_format = "sxp"
output_directory = "/var/run/xend/boot"
@@ -723,6 +724,8 @@ if __name__ == "__main__":
interactive = False
elif o in ("--isconfig",):
isconfig = True
+ elif o in ("--debug",):
+ debug = True
elif o in ("--output-format",):
if a not in ["sxp", "simple", "simple0"]:
print "unkonwn output format %s" % a
@@ -732,6 +735,9 @@ if __name__ == "__main__":
elif o in ("--output-directory",):
output_directory = a
+ if debug:
+ logging.basicConfig(level=logging.DEBUG)
+
if output is None or output == "-":
fd = sys.stdout.fileno()
else:
@@ -778,6 +784,8 @@ if __name__ == "__main__":
except:
# IOErrors raised by fsimage.open
# RuntimeErrors raised by run_grub if no menu.lst present
+ if debug:
+ traceback.print_exc()
fs = None
continue

View File

@ -1,127 +0,0 @@
changeset: 23949:39df16923958
user: Jan Beulich <jbeulich@suse.com>
date: Thu Oct 13 10:00:13 2011 +0200
files: xen/arch/x86/cpu/mcheck/vmce.c xen/arch/x86/traps.c xen/common/schedule.c xen/include/xen/sched.h
description:
constify vcpu_set_affinity()'s second parameter
None of the callers actually make use of the function's returning of
the old affinity through its second parameter, and eliminating this
capability allows some callers to no longer use a local variable here,
reducing their stack footprint significantly when building with large
NR_CPUS.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
---
xen/arch/x86/cpu/mcheck/vmce.c | 5 +----
xen/arch/x86/traps.c | 10 ++--------
xen/common/schedule.c | 6 ++----
xen/include/xen/sched.h | 2 +-
4 files changed, 6 insertions(+), 17 deletions(-)
Index: xen-4.1.3-testing/xen/arch/x86/cpu/mcheck/vmce.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/cpu/mcheck/vmce.c
+++ xen-4.1.3-testing/xen/arch/x86/cpu/mcheck/vmce.c
@@ -304,7 +304,6 @@ int vmce_wrmsr(u32 msr, u64 val)
int inject_vmce(struct domain *d)
{
int cpu = smp_processor_id();
- cpumask_t affinity;
/* PV guest and HVM guest have different vMCE# injection methods. */
if ( !test_and_set_bool(d->vcpu[0]->mce_pending) )
@@ -323,11 +322,9 @@ int inject_vmce(struct domain *d)
{
d->vcpu[0]->cpu_affinity_tmp =
d->vcpu[0]->cpu_affinity;
- cpus_clear(affinity);
- cpu_set(cpu, affinity);
mce_printk(MCE_VERBOSE, "MCE: CPU%d set affinity, old %d\n",
cpu, d->vcpu[0]->processor);
- vcpu_set_affinity(d->vcpu[0], &affinity);
+ vcpu_set_affinity(d->vcpu[0], cpumask_of(cpu));
vcpu_kick(d->vcpu[0]);
}
else
Index: xen-4.1.3-testing/xen/arch/x86/traps.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/traps.c
+++ xen-4.1.3-testing/xen/arch/x86/traps.c
@@ -3106,7 +3106,6 @@ static void nmi_mce_softirq(void)
{
int cpu = smp_processor_id();
struct softirq_trap *st = &per_cpu(softirq_trap, cpu);
- cpumask_t affinity;
BUG_ON(st == NULL);
BUG_ON(st->vcpu == NULL);
@@ -3122,9 +3121,7 @@ static void nmi_mce_softirq(void)
* Make sure to wakeup the vcpu on the
* specified processor.
*/
- cpus_clear(affinity);
- cpu_set(st->processor, affinity);
- vcpu_set_affinity(st->vcpu, &affinity);
+ vcpu_set_affinity(st->vcpu, cpumask_of(st->processor));
/* Affinity is restored in the iret hypercall. */
}
@@ -3199,14 +3196,11 @@ void async_exception_cleanup(struct vcpu
!test_and_set_bool(curr->mce_pending) )
{
int cpu = smp_processor_id();
- cpumask_t affinity;
curr->cpu_affinity_tmp = curr->cpu_affinity;
- cpus_clear(affinity);
- cpu_set(cpu, affinity);
printk(XENLOG_DEBUG "MCE: CPU%d set affinity, old %d\n",
cpu, curr->processor);
- vcpu_set_affinity(curr, &affinity);
+ vcpu_set_affinity(curr, cpumask_of(cpu));
}
}
}
Index: xen-4.1.3-testing/xen/common/schedule.c
===================================================================
--- xen-4.1.3-testing.orig/xen/common/schedule.c
+++ xen-4.1.3-testing/xen/common/schedule.c
@@ -598,9 +598,9 @@ int cpu_disable_scheduler(unsigned int c
return ret;
}
-int vcpu_set_affinity(struct vcpu *v, cpumask_t *affinity)
+int vcpu_set_affinity(struct vcpu *v, const cpumask_t *affinity)
{
- cpumask_t online_affinity, old_affinity;
+ cpumask_t online_affinity;
cpumask_t *online;
if ( v->domain->is_pinned )
@@ -612,9 +612,7 @@ int vcpu_set_affinity(struct vcpu *v, cp
vcpu_schedule_lock_irq(v);
- old_affinity = v->cpu_affinity;
v->cpu_affinity = *affinity;
- *affinity = old_affinity;
if ( !cpu_isset(v->processor, v->cpu_affinity) )
set_bit(_VPF_migrating, &v->pause_flags);
Index: xen-4.1.3-testing/xen/include/xen/sched.h
===================================================================
--- xen-4.1.3-testing.orig/xen/include/xen/sched.h
+++ xen-4.1.3-testing/xen/include/xen/sched.h
@@ -624,7 +624,7 @@ void scheduler_free(struct scheduler *sc
int schedule_cpu_switch(unsigned int cpu, struct cpupool *c);
void vcpu_force_reschedule(struct vcpu *v);
int cpu_disable_scheduler(unsigned int cpu);
-int vcpu_set_affinity(struct vcpu *v, cpumask_t *affinity);
+int vcpu_set_affinity(struct vcpu *v, const cpumask_t *affinity);
void vcpu_runstate_get(struct vcpu *v, struct vcpu_runstate_info *runstate);
uint64_t get_cpu_idle_time(unsigned int cpu);

View File

@ -1,232 +0,0 @@
changeset: 23953:eda18b27de6e
user: Olaf Hering <olaf@aepfle.de>
date: Thu Oct 13 12:21:10 2011 +0100
files: tools/xenpaging/xenpaging.c xen/arch/x86/mm.c xen/arch/x86/mm/p2m.c xen/include/public/mem_event.h
description:
xenpaging: handle evict failures
Evict of a nominated gfn must fail if some other process mapped the
page without checking the p2mt of that gfn first.
Add a check to cancel eviction if the page usage count is not 1.
Handle the possible eviction failure in the page-in paths.
After nominate and before evict, something may check the p2mt and call
populate. Handle this case and let the gfn enter the page-in path. The
gfn may still be connected to a mfn, so there is no need to allocate a
new page in prep.
Adjust do_mmu_update to return -ENOENT only if the gfn has entered the
page-in path and if it is not yet connected to a mfn. Otherwise
linux_privcmd_map_foreign_bulk() may loop forever.
Add MEM_EVENT_FLAG_EVICT_FAIL to inform pager that a page-in request for
a possible not-evicted page was sent. xenpaging does currently not need
that flag because failure to evict a gfn will be caught.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Acked-by: Tim Deegan <tim@xen.org>
Committed-by: Tim Deegan <tim@xen.org>
---
tools/xenpaging/xenpaging.c | 10 ++++---
xen/arch/x86/mm.c | 8 ++---
xen/arch/x86/mm/p2m.c | 55 +++++++++++++++++++++++++++++------------
xen/include/public/mem_event.h | 1
4 files changed, 50 insertions(+), 24 deletions(-)
Index: xen-4.1.3-testing/tools/xenpaging/xenpaging.c
===================================================================
--- xen-4.1.3-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.1.3-testing/tools/xenpaging/xenpaging.c
@@ -734,10 +734,12 @@ int main(int argc, char *argv[])
}
else
{
- DPRINTF("page already populated (domain = %d; vcpu = %d;"
- " gfn = %"PRIx64"; paused = %d)\n",
- paging->mem_event.domain_id, req.vcpu_id,
- req.gfn, req.flags & MEM_EVENT_FLAG_VCPU_PAUSED);
+ DPRINTF("page %s populated (domain = %d; vcpu = %d;"
+ " gfn = %"PRIx64"; paused = %d; evict_fail = %d)\n",
+ req.flags & MEM_EVENT_FLAG_EVICT_FAIL ? "not" : "already",
+ paging->mem_event.domain_id, req.vcpu_id, req.gfn,
+ !!(req.flags & MEM_EVENT_FLAG_VCPU_PAUSED) ,
+ !!(req.flags & MEM_EVENT_FLAG_EVICT_FAIL) );
/* Tell Xen to resume the vcpu */
/* XXX: Maybe just check if the vcpu was paused? */
Index: xen-4.1.3-testing/xen/arch/x86/mm.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/mm.c
+++ xen-4.1.3-testing/xen/arch/x86/mm.c
@@ -3504,7 +3504,7 @@ int do_mmu_update(
rc = -ENOENT;
break;
}
- else if ( p2m_ram_paging_in_start == l1e_p2mt )
+ else if ( p2m_ram_paging_in_start == l1e_p2mt && !mfn_valid(mfn) )
{
rc = -ENOENT;
break;
@@ -3545,7 +3545,7 @@ int do_mmu_update(
rc = -ENOENT;
break;
}
- else if ( p2m_ram_paging_in_start == l2e_p2mt )
+ else if ( p2m_ram_paging_in_start == l2e_p2mt && !mfn_valid(mfn) )
{
rc = -ENOENT;
break;
@@ -3574,7 +3574,7 @@ int do_mmu_update(
rc = -ENOENT;
break;
}
- else if ( p2m_ram_paging_in_start == l3e_p2mt )
+ else if ( p2m_ram_paging_in_start == l3e_p2mt && !mfn_valid(mfn) )
{
rc = -ENOENT;
break;
@@ -3604,7 +3604,7 @@ int do_mmu_update(
rc = -ENOENT;
break;
}
- else if ( p2m_ram_paging_in_start == l4e_p2mt )
+ else if ( p2m_ram_paging_in_start == l4e_p2mt && !mfn_valid(mfn) )
{
rc = -ENOENT;
break;
Index: xen-4.1.3-testing/xen/arch/x86/mm/p2m.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/mm/p2m.c
+++ xen-4.1.3-testing/xen/arch/x86/mm/p2m.c
@@ -2902,15 +2902,24 @@ int p2m_mem_paging_evict(struct p2m_doma
if ( unlikely(!mfn_valid(mfn)) )
goto out;
- if ( (p2mt == p2m_ram_paged) || (p2mt == p2m_ram_paging_in) ||
- (p2mt == p2m_ram_paging_in_start) )
+ /* Allow only nominated pages */
+ if ( p2mt != p2m_ram_paging_out )
goto out;
+ ret = -EBUSY;
/* Get the page so it doesn't get modified under Xen's feet */
page = mfn_to_page(mfn);
if ( unlikely(!get_page(page, d)) )
goto out;
+ /* Check page count and type once more */
+ if ( (page->count_info & (PGC_count_mask | PGC_allocated)) !=
+ (2 | PGC_allocated) )
+ goto out_put;
+
+ if ( (page->u.inuse.type_info & PGT_type_mask) != PGT_none )
+ goto out_put;
+
/* Decrement guest domain's ref count of the page */
if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
put_page(page);
@@ -2922,14 +2931,15 @@ int p2m_mem_paging_evict(struct p2m_doma
/* Clear content before returning the page to Xen */
scrub_one_page(page);
- /* Put the page back so it gets freed */
- put_page(page);
-
/* Track number of paged gfns */
atomic_inc(&p2m->domain->paged_pages);
ret = 0;
+ out_put:
+ /* Put the page back so it gets freed */
+ put_page(page);
+
out:
p2m_unlock(p2m);
return ret;
@@ -2960,6 +2970,7 @@ void p2m_mem_paging_populate(struct p2m_
mem_event_request_t req;
p2m_type_t p2mt;
p2m_access_t a;
+ mfn_t mfn;
struct domain *d = p2m->domain;
/* Check that there's space on the ring for this request */
@@ -2971,20 +2982,26 @@ void p2m_mem_paging_populate(struct p2m_
/* Fix p2m mapping */
p2m_lock(p2m);
- p2m->get_entry(p2m, gfn, &p2mt, &a, p2m_query);
- if ( p2mt == p2m_ram_paged )
+ mfn = p2m->get_entry(p2m, gfn, &p2mt, &a, p2m_query);
+ /* Allow only nominated or evicted pages to enter page-in path */
+ if ( p2mt == p2m_ram_paging_out || p2mt == p2m_ram_paged )
{
- set_p2m_entry(p2m, gfn, _mfn(PAGING_MFN), 0, p2m_ram_paging_in_start, a);
+ /* Evict will fail now, tag this request for pager */
+ if ( p2mt == p2m_ram_paging_out )
+ req.flags |= MEM_EVENT_FLAG_EVICT_FAIL;
+
+ set_p2m_entry(p2m, gfn, mfn, 0, p2m_ram_paging_in_start, a);
audit_p2m(p2m, 1);
}
p2m_unlock(p2m);
- /* Pause domain */
- if ( v->domain->domain_id == d->domain_id )
+ /* Pause domain if request came from guest and gfn has paging type */
+ if ( p2m_is_paging(p2mt) && v->domain->domain_id == d->domain_id )
{
vcpu_pause_nosync(v);
req.flags |= MEM_EVENT_FLAG_VCPU_PAUSED;
}
+ /* No need to inform pager if the gfn is not in the page-out path */
else if ( p2mt != p2m_ram_paging_out && p2mt != p2m_ram_paged )
{
/* gfn is already on its way back and vcpu is not paused */
@@ -3005,19 +3022,25 @@ int p2m_mem_paging_prep(struct p2m_domai
struct page_info *page;
p2m_type_t p2mt;
p2m_access_t a;
+ mfn_t mfn;
int ret = -ENOMEM;
p2m_lock(p2m);
- p2m->get_entry(p2m, gfn, &p2mt, &a, p2m_query);
+ mfn = p2m->get_entry(p2m, gfn, &p2mt, &a, p2m_query);
- /* Get a free page */
- page = alloc_domheap_page(p2m->domain, 0);
- if ( unlikely(page == NULL) )
- goto out;
+ /* Allocate a page if the gfn does not have one yet */
+ if ( !mfn_valid(mfn) )
+ {
+ /* Get a free page */
+ page = alloc_domheap_page(p2m->domain, 0);
+ if ( unlikely(page == NULL) )
+ goto out;
+ mfn = page_to_mfn(page);
+ }
/* Fix p2m mapping */
- set_p2m_entry(p2m, gfn, page_to_mfn(page), 0, p2m_ram_paging_in, a);
+ set_p2m_entry(p2m, gfn, mfn, 0, p2m_ram_paging_in, a);
audit_p2m(p2m, 1);
atomic_dec(&p2m->domain->paged_pages);
Index: xen-4.1.3-testing/xen/include/public/mem_event.h
===================================================================
--- xen-4.1.3-testing.orig/xen/include/public/mem_event.h
+++ xen-4.1.3-testing/xen/include/public/mem_event.h
@@ -38,6 +38,7 @@
/* Memory event flags */
#define MEM_EVENT_FLAG_VCPU_PAUSED (1 << 0)
#define MEM_EVENT_FLAG_DROP_PAGE (1 << 1)
+#define MEM_EVENT_FLAG_EVICT_FAIL (1 << 2)
/* Reasons for the memory event request */
#define MEM_EVENT_REASON_UNKNOWN 0 /* typical reason */

View File

@ -1,62 +0,0 @@
# HG changeset patch
# User Jan Beulich <jbeulich@suse.com>
# Date 1318580154 -7200
# Node ID de316831471a8e0f11f615e7bf336dee2ba811e7
# Parent a65693f9fb1250ff4819774a70284693705db9e7
cpufreq: error path fixes
This fixes an actual bug (failure to exit from a function after an
allocation failure), an inconsistency (not removing the cpufreq_dom
list member upon failure), and a latent bug (not clearing the current
governor upon governor initialization failure when there was no old
one; latent because the only current code path leading to this
situation frees the policy upon failure and hence the governor not
getting cleared is benign).
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
--- a/xen/drivers/cpufreq/cpufreq.c
+++ b/xen/drivers/cpufreq/cpufreq.c
@@ -195,8 +195,10 @@ int cpufreq_add_cpu(unsigned int cpu)
if (!domexist || hw_all) {
policy = xmalloc(struct cpufreq_policy);
- if (!policy)
+ if (!policy) {
ret = -ENOMEM;
+ goto err0;
+ }
memset(policy, 0, sizeof(struct cpufreq_policy));
policy->cpu = cpu;
@@ -206,7 +208,7 @@ int cpufreq_add_cpu(unsigned int cpu)
if (ret) {
xfree(policy);
per_cpu(cpufreq_cpu_policy, cpu) = NULL;
- return ret;
+ goto err0;
}
if (cpufreq_verbose)
printk("CPU %u initialization completed\n", cpu);
@@ -263,7 +265,7 @@ err1:
cpufreq_driver->exit(policy);
xfree(policy);
}
-
+err0:
if (cpus_empty(cpufreq_dom->map)) {
list_del(&cpufreq_dom->node);
xfree(cpufreq_dom);
--- a/xen/drivers/cpufreq/utility.c
+++ b/xen/drivers/cpufreq/utility.c
@@ -462,8 +462,8 @@ int __cpufreq_set_policy(struct cpufreq_
data->governor->name);
/* new governor failed, so re-start old one */
+ data->governor = old_gov;
if (old_gov) {
- data->governor = old_gov;
__cpufreq_governor(data, CPUFREQ_GOV_START);
printk(KERN_WARNING "Still stay at %s governor\n",
data->governor->name);

View File

@ -1,68 +0,0 @@
changeset: 23978:fd3fa0a85020
user: Olaf Hering <olaf@aepfle.de>
date: Thu Oct 20 11:25:55 2011 +0100
files: xen/arch/x86/mm/p2m.c
description:
xenpaging: check p2mt in p2m_mem_paging functions
Add checks to forward the p2m_ram_paging* state properly during page-in.
Resume can be called several times if several vcpus called populate for
the gfn. Finish resume only once.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Acked-by: Tim Deegan <tim@xen.org>
Committed-by: Tim Deegan <tim@xen.org>
---
xen/arch/x86/mm/p2m.c | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
Index: xen-4.1.3-testing/xen/arch/x86/mm/p2m.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/mm/p2m.c
+++ xen-4.1.3-testing/xen/arch/x86/mm/p2m.c
@@ -3023,16 +3023,22 @@ int p2m_mem_paging_prep(struct p2m_domai
p2m_type_t p2mt;
p2m_access_t a;
mfn_t mfn;
- int ret = -ENOMEM;
+ int ret;
p2m_lock(p2m);
mfn = p2m->get_entry(p2m, gfn, &p2mt, &a, p2m_query);
+ ret = -ENOENT;
+ /* Allow only missing pages */
+ if ( p2mt != p2m_ram_paging_in_start )
+ goto out;
+
/* Allocate a page if the gfn does not have one yet */
if ( !mfn_valid(mfn) )
{
/* Get a free page */
+ ret = -ENOMEM;
page = alloc_domheap_page(p2m->domain, 0);
if ( unlikely(page == NULL) )
goto out;
@@ -3067,9 +3073,15 @@ void p2m_mem_paging_resume(struct p2m_do
{
p2m_lock(p2m);
mfn = p2m->get_entry(p2m, rsp.gfn, &p2mt, &a, p2m_query);
- set_p2m_entry(p2m, rsp.gfn, mfn, 0, p2m_ram_rw, a);
- set_gpfn_from_mfn(mfn_x(mfn), rsp.gfn);
- audit_p2m(p2m, 1);
+ /* Allow only pages which were prepared properly, or pages which
+ * were nominated but not evicted */
+ if ( mfn_valid(mfn) &&
+ (p2mt == p2m_ram_paging_in || p2mt == p2m_ram_paging_in_start) )
+ {
+ set_p2m_entry(p2m, rsp.gfn, mfn, 0, p2m_ram_rw, a);
+ set_gpfn_from_mfn(mfn_x(mfn), rsp.gfn);
+ audit_p2m(p2m, 1);
+ }
p2m_unlock(p2m);
}

View File

@ -1,158 +0,0 @@
changeset: 23979:18306b054799
user: Olaf Hering <olaf@aepfle.de>
date: Thu Oct 20 11:25:58 2011 +0100
files: xen/arch/x86/mm/p2m.c
description:
xenpaging: document p2m_mem_paging functions
Add some documentation for each of the p2m_mem_paging functions to describe
what they ought to do.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Acked-by: Tim Deegan <tim@xen.org>
Committed-by: Tim Deegan <tim@xen.org>
---
xen/arch/x86/mm/p2m.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 93 insertions(+)
Index: xen-4.1.3-testing/xen/arch/x86/mm/p2m.c
===================================================================
--- xen-4.1.3-testing.orig/xen/arch/x86/mm/p2m.c
+++ xen-4.1.3-testing/xen/arch/x86/mm/p2m.c
@@ -2841,6 +2841,24 @@ set_shared_p2m_entry(struct p2m_domain *
}
#ifdef __x86_64__
+/**
+ * p2m_mem_paging_nominate - Mark a guest page as to-be-paged-out
+ * @d: guest domain
+ * @gfn: guest page to nominate
+ *
+ * Returns 0 for success or negative errno values if gfn is not pageable.
+ *
+ * p2m_mem_paging_nominate() is called by the pager and checks if a guest page
+ * can be paged out. If the following conditions are met the p2mt will be
+ * changed:
+ * - the gfn is backed by a mfn
+ * - the p2mt of the gfn is pageable
+ * - the mfn is not used for IO
+ * - the mfn has exactly one user and has no special meaning
+ *
+ * Once the p2mt is changed the page is readonly for the guest. On success the
+ * pager can write the page contents to disk and later evict the page.
+ */
int p2m_mem_paging_nominate(struct p2m_domain *p2m, unsigned long gfn)
{
struct page_info *page;
@@ -2886,6 +2904,25 @@ int p2m_mem_paging_nominate(struct p2m_d
return ret;
}
+/**
+ * p2m_mem_paging_evict - Mark a guest page as paged-out
+ * @d: guest domain
+ * @gfn: guest page to evict
+ *
+ * Returns 0 for success or negative errno values if eviction is not possible.
+ *
+ * p2m_mem_paging_evict() is called by the pager and will free a guest page and
+ * release it back to Xen. If the following conditions are met the page can be
+ * freed:
+ * - the gfn is backed by a mfn
+ * - the gfn was nominated
+ * - the mfn has still exactly one user and has no special meaning
+ *
+ * After successful nomination some other process could have mapped the page. In
+ * this case eviction can not be done. If the gfn was populated before the pager
+ * could evict it, eviction can not be done either. In this case the gfn is
+ * still backed by a mfn.
+ */
int p2m_mem_paging_evict(struct p2m_domain *p2m, unsigned long gfn)
{
struct page_info *page;
@@ -2945,6 +2982,15 @@ int p2m_mem_paging_evict(struct p2m_doma
return ret;
}
+/**
+ * p2m_mem_paging_drop_page - Tell pager to drop its reference to a paged page
+ * @d: guest domain
+ * @gfn: guest page to drop
+ *
+ * p2m_mem_paging_drop_page() will notify the pager that a paged-out gfn was
+ * released by the guest. The pager is supposed to drop its reference of the
+ * gfn.
+ */
void p2m_mem_paging_drop_page(struct p2m_domain *p2m, unsigned long gfn)
{
struct vcpu *v = current;
@@ -2964,6 +3010,27 @@ void p2m_mem_paging_drop_page(struct p2m
}
}
+/**
+ * p2m_mem_paging_populate - Tell pager to populete a paged page
+ * @d: guest domain
+ * @gfn: guest page in paging state
+ *
+ * p2m_mem_paging_populate() will notify the pager that a page in any of the
+ * paging states needs to be written back into the guest.
+ * This function needs to be called whenever gfn_to_mfn() returns any of the p2m
+ * paging types because the gfn may not be backed by a mfn.
+ *
+ * The gfn can be in any of the paging states, but the pager needs only be
+ * notified when the gfn is in the paging-out path (paging_out or paged). This
+ * function may be called more than once from several vcpus. If the vcpu belongs
+ * to the guest, the vcpu must be stopped and the pager notified that the vcpu
+ * was stopped. The pager needs to handle several requests for the same gfn.
+ *
+ * If the gfn is not in the paging-out path and the vcpu does not belong to the
+ * guest, nothing needs to be done and the function assumes that a request was
+ * already sent to the pager. In this case the caller has to try again until the
+ * gfn is fully paged in again.
+ */
void p2m_mem_paging_populate(struct p2m_domain *p2m, unsigned long gfn)
{
struct vcpu *v = current;
@@ -3017,6 +3084,17 @@ void p2m_mem_paging_populate(struct p2m_
mem_event_put_request(d, &d->mem_paging, &req);
}
+/**
+ * p2m_mem_paging_prep - Allocate a new page for the guest
+ * @d: guest domain
+ * @gfn: guest page in paging state
+ *
+ * p2m_mem_paging_prep() will allocate a new page for the guest if the gfn is
+ * not backed by a mfn. It is called by the pager.
+ * It is required that the gfn was already populated. The gfn may already have a
+ * mfn if populate was called for gfn which was nominated but not evicted. In
+ * this case only the p2mt needs to be forwarded.
+ */
int p2m_mem_paging_prep(struct p2m_domain *p2m, unsigned long gfn)
{
struct page_info *page;
@@ -3057,6 +3135,21 @@ int p2m_mem_paging_prep(struct p2m_domai
return ret;
}
+/**
+ * p2m_mem_paging_resume - Resume guest gfn and vcpus
+ * @d: guest domain
+ * @gfn: guest page in paging state
+ *
+ * p2m_mem_paging_resume() will forward the p2mt of a gfn to ram_rw and all
+ * waiting vcpus will be unpaused again. It is called by the pager.
+ *
+ * The gfn was previously either evicted and populated, or nominated and
+ * populated. If the page was evicted the p2mt will be p2m_ram_paging_in. If
+ * the page was just nominated the p2mt will be p2m_ram_paging_in_start because
+ * the pager did not call p2m_mem_paging_prep().
+ *
+ * If the gfn was dropped the vcpu needs to be unpaused.
+ */
void p2m_mem_paging_resume(struct p2m_domain *p2m)
{
struct domain *d = p2m->domain;

Some files were not shown because too many files have changed in this diff Show More