- 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 OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=201
This commit is contained in:
parent
ea0e55c00e
commit
17854f1c81
61
25833-32on64-bogus-pt_base-adjust.patch
Normal file
61
25833-32on64-bogus-pt_base-adjust.patch
Normal file
@ -0,0 +1,61 @@
|
||||
# HG changeset patch
|
||||
# User Jan Beulich <jbeulich@suse.com>
|
||||
# Date 1347022899 -7200
|
||||
# Node ID bb85bbccb1c9d802c92dd3fe00841368966ff623
|
||||
# Parent e3b51948114ec1e2b2eece415b32e26ff857acde
|
||||
x86/32-on-64: adjust Dom0 initial page table layout
|
||||
|
||||
Drop the unnecessary reservation of the L4 page for 32on64 Dom0, and
|
||||
allocate its L3 first (to match behavior when running identical bit-
|
||||
width hypervisor and Dom0 kernel).
|
||||
|
||||
Reported-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Keir Fraser <keir@xen.org>
|
||||
|
||||
--- a/xen/arch/x86/domain_build.c
|
||||
+++ b/xen/arch/x86/domain_build.c
|
||||
@@ -510,7 +510,7 @@ int __init construct_dom0(
|
||||
#define NR(_l,_h,_s) \
|
||||
(((((_h) + ((1UL<<(_s))-1)) & ~((1UL<<(_s))-1)) - \
|
||||
((_l) & ~((1UL<<(_s))-1))) >> (_s))
|
||||
- if ( (1 + /* # L4 */
|
||||
+ if ( (!is_pv_32on64_domain(d) + /* # L4 */
|
||||
NR(v_start, v_end, L4_PAGETABLE_SHIFT) + /* # L3 */
|
||||
(!is_pv_32on64_domain(d) ?
|
||||
NR(v_start, v_end, L3_PAGETABLE_SHIFT) : /* # L2 */
|
||||
@@ -756,6 +756,8 @@ int __init construct_dom0(
|
||||
panic("Not enough RAM for domain 0 PML4.\n");
|
||||
page->u.inuse.type_info = PGT_l4_page_table|PGT_validated|1;
|
||||
l4start = l4tab = page_to_virt(page);
|
||||
+ maddr_to_page(mpt_alloc)->u.inuse.type_info = PGT_l3_page_table;
|
||||
+ l3start = __va(mpt_alloc); mpt_alloc += PAGE_SIZE;
|
||||
}
|
||||
copy_page(l4tab, idle_pg_table);
|
||||
l4tab[0] = l4e_empty(); /* zap trampoline mapping */
|
||||
@@ -787,9 +789,13 @@ int __init construct_dom0(
|
||||
l2tab += l2_table_offset(v_start);
|
||||
if ( !((unsigned long)l3tab & (PAGE_SIZE-1)) )
|
||||
{
|
||||
- maddr_to_page(mpt_alloc)->u.inuse.type_info =
|
||||
- PGT_l3_page_table;
|
||||
- l3start = l3tab = __va(mpt_alloc); mpt_alloc += PAGE_SIZE;
|
||||
+ if ( count || !l3start )
|
||||
+ {
|
||||
+ maddr_to_page(mpt_alloc)->u.inuse.type_info =
|
||||
+ PGT_l3_page_table;
|
||||
+ l3start = __va(mpt_alloc); mpt_alloc += PAGE_SIZE;
|
||||
+ }
|
||||
+ l3tab = l3start;
|
||||
clear_page(l3tab);
|
||||
if ( count == 0 )
|
||||
l3tab += l3_table_offset(v_start);
|
||||
@@ -938,7 +944,7 @@ int __init construct_dom0(
|
||||
if ( !vinitrd_start && initrd_len )
|
||||
si->flags |= SIF_MOD_START_PFN;
|
||||
si->flags |= (xen_processor_pmbits << 8) & SIF_PM_MASK;
|
||||
- si->pt_base = vpt_start + 2 * PAGE_SIZE * !!is_pv_32on64_domain(d);
|
||||
+ si->pt_base = vpt_start;
|
||||
si->nr_pt_frames = nr_pt_pages;
|
||||
si->mfn_list = vphysmap_start;
|
||||
snprintf(si->magic, sizeof(si->magic), "xen-3.0-x86_%d%s",
|
274
25835-adjust-rcu-lock-domain.patch
Normal file
274
25835-adjust-rcu-lock-domain.patch
Normal file
@ -0,0 +1,274 @@
|
||||
# HG changeset patch
|
||||
# User Jan Beulich <jbeulich@suse.com>
|
||||
# Date 1347033492 -7200
|
||||
# Node ID c70d70d85306b3e4a0538353be131100c5ee38d5
|
||||
# Parent 0376c85caaf34fe3cc8c3327f7a1d9ecd6f070b4
|
||||
adjust a few RCU domain locking calls
|
||||
|
||||
x86's do_physdev_op() had a case where the locking was entirely
|
||||
superfluous. Its physdev_map_pirq() further had a case where the lock
|
||||
was being obtained too early, needlessly complicating early exit paths.
|
||||
|
||||
Grant table code had two open coded instances of
|
||||
rcu_lock_target_domain_by_id(), and a third code section could be
|
||||
consolidated by using the newly introduced helper function.
|
||||
|
||||
The memory hypercall code had two more instances of open coding
|
||||
rcu_lock_target_domain_by_id(), but note that here this is not just
|
||||
cleanup, but also fixes an error return path in memory_exchange() to
|
||||
actually return an error.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Keir Fraser <keir@xen.org>
|
||||
|
||||
--- a/xen/arch/x86/physdev.c
|
||||
+++ b/xen/arch/x86/physdev.c
|
||||
@@ -90,14 +90,10 @@ static int physdev_hvm_map_pirq(
|
||||
int physdev_map_pirq(domid_t domid, int type, int *index, int *pirq_p,
|
||||
struct msi_info *msi)
|
||||
{
|
||||
- struct domain *d;
|
||||
+ struct domain *d = current->domain;
|
||||
int pirq, irq, ret = 0;
|
||||
void *map_data = NULL;
|
||||
|
||||
- ret = rcu_lock_target_domain_by_id(domid, &d);
|
||||
- if ( ret )
|
||||
- return ret;
|
||||
-
|
||||
if ( domid == DOMID_SELF && is_hvm_domain(d) )
|
||||
{
|
||||
/*
|
||||
@@ -105,14 +101,15 @@ int physdev_map_pirq(domid_t domid, int
|
||||
* calls back into itself and deadlocks on hvm_domain.irq_lock.
|
||||
*/
|
||||
if ( !is_hvm_pv_evtchn_domain(d) )
|
||||
- {
|
||||
- ret = -EINVAL;
|
||||
- goto free_domain;
|
||||
- }
|
||||
- ret = physdev_hvm_map_pirq(d, type, index, pirq_p);
|
||||
- goto free_domain;
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ return physdev_hvm_map_pirq(d, type, index, pirq_p);
|
||||
}
|
||||
|
||||
+ ret = rcu_lock_target_domain_by_id(domid, &d);
|
||||
+ if ( ret )
|
||||
+ return ret;
|
||||
+
|
||||
if ( !IS_PRIV_FOR(current->domain, d) )
|
||||
{
|
||||
ret = -EPERM;
|
||||
@@ -696,13 +693,12 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
|
||||
}
|
||||
case PHYSDEVOP_get_free_pirq: {
|
||||
struct physdev_get_free_pirq out;
|
||||
- struct domain *d;
|
||||
+ struct domain *d = v->domain;
|
||||
|
||||
ret = -EFAULT;
|
||||
if ( copy_from_guest(&out, arg, 1) != 0 )
|
||||
break;
|
||||
|
||||
- d = rcu_lock_current_domain();
|
||||
spin_lock(&d->event_lock);
|
||||
|
||||
ret = get_free_pirq(d, out.type);
|
||||
@@ -717,7 +713,6 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
|
||||
}
|
||||
|
||||
spin_unlock(&d->event_lock);
|
||||
- rcu_unlock_domain(d);
|
||||
|
||||
if ( ret >= 0 )
|
||||
{
|
||||
--- a/xen/common/grant_table.c
|
||||
+++ b/xen/common/grant_table.c
|
||||
@@ -24,7 +24,7 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
-#include <xen/config.h>
|
||||
+#include <xen/err.h>
|
||||
#include <xen/iocap.h>
|
||||
#include <xen/lib.h>
|
||||
#include <xen/sched.h>
|
||||
@@ -195,6 +195,30 @@ double_gt_unlock(struct grant_table *lgt
|
||||
spin_unlock(&rgt->lock);
|
||||
}
|
||||
|
||||
+static struct domain *gt_lock_target_domain_by_id(domid_t dom)
|
||||
+{
|
||||
+ struct domain *d;
|
||||
+ int rc = GNTST_general_error;
|
||||
+
|
||||
+ switch ( rcu_lock_target_domain_by_id(dom, &d) )
|
||||
+ {
|
||||
+ case 0:
|
||||
+ return d;
|
||||
+
|
||||
+ case -ESRCH:
|
||||
+ gdprintk(XENLOG_INFO, "Bad domid %d.\n", dom);
|
||||
+ rc = GNTST_bad_domain;
|
||||
+ break;
|
||||
+
|
||||
+ case -EPERM:
|
||||
+ rc = GNTST_permission_denied;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ ASSERT(rc < 0 && -rc <= MAX_ERRNO);
|
||||
+ return ERR_PTR(rc);
|
||||
+}
|
||||
+
|
||||
static inline int
|
||||
__get_maptrack_handle(
|
||||
struct grant_table *t)
|
||||
@@ -1261,7 +1285,6 @@ gnttab_setup_table(
|
||||
struct grant_table *gt;
|
||||
int i;
|
||||
unsigned long gmfn;
|
||||
- domid_t dom;
|
||||
|
||||
if ( count != 1 )
|
||||
return -EINVAL;
|
||||
@@ -1281,25 +1304,11 @@ gnttab_setup_table(
|
||||
goto out1;
|
||||
}
|
||||
|
||||
- dom = op.dom;
|
||||
- if ( dom == DOMID_SELF )
|
||||
+ d = gt_lock_target_domain_by_id(op.dom);
|
||||
+ if ( IS_ERR(d) )
|
||||
{
|
||||
- d = rcu_lock_current_domain();
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- if ( unlikely((d = rcu_lock_domain_by_id(dom)) == NULL) )
|
||||
- {
|
||||
- gdprintk(XENLOG_INFO, "Bad domid %d.\n", dom);
|
||||
- op.status = GNTST_bad_domain;
|
||||
- goto out1;
|
||||
- }
|
||||
-
|
||||
- if ( unlikely(!IS_PRIV_FOR(current->domain, d)) )
|
||||
- {
|
||||
- op.status = GNTST_permission_denied;
|
||||
- goto out2;
|
||||
- }
|
||||
+ op.status = PTR_ERR(d);
|
||||
+ goto out1;
|
||||
}
|
||||
|
||||
if ( xsm_grant_setup(current->domain, d) )
|
||||
@@ -1352,7 +1361,6 @@ gnttab_query_size(
|
||||
{
|
||||
struct gnttab_query_size op;
|
||||
struct domain *d;
|
||||
- domid_t dom;
|
||||
int rc;
|
||||
|
||||
if ( count != 1 )
|
||||
@@ -1364,25 +1372,11 @@ gnttab_query_size(
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
- dom = op.dom;
|
||||
- if ( dom == DOMID_SELF )
|
||||
- {
|
||||
- d = rcu_lock_current_domain();
|
||||
- }
|
||||
- else
|
||||
+ d = gt_lock_target_domain_by_id(op.dom);
|
||||
+ if ( IS_ERR(d) )
|
||||
{
|
||||
- if ( unlikely((d = rcu_lock_domain_by_id(dom)) == NULL) )
|
||||
- {
|
||||
- gdprintk(XENLOG_INFO, "Bad domid %d.\n", dom);
|
||||
- op.status = GNTST_bad_domain;
|
||||
- goto query_out;
|
||||
- }
|
||||
-
|
||||
- if ( unlikely(!IS_PRIV_FOR(current->domain, d)) )
|
||||
- {
|
||||
- op.status = GNTST_permission_denied;
|
||||
- goto query_out_unlock;
|
||||
- }
|
||||
+ op.status = PTR_ERR(d);
|
||||
+ goto query_out;
|
||||
}
|
||||
|
||||
rc = xsm_grant_query_size(current->domain, d);
|
||||
@@ -2251,15 +2245,10 @@ gnttab_get_status_frames(XEN_GUEST_HANDL
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
- rc = rcu_lock_target_domain_by_id(op.dom, &d);
|
||||
- if ( rc < 0 )
|
||||
+ d = gt_lock_target_domain_by_id(op.dom);
|
||||
+ if ( IS_ERR(d) )
|
||||
{
|
||||
- if ( rc == -ESRCH )
|
||||
- op.status = GNTST_bad_domain;
|
||||
- else if ( rc == -EPERM )
|
||||
- op.status = GNTST_permission_denied;
|
||||
- else
|
||||
- op.status = GNTST_general_error;
|
||||
+ op.status = PTR_ERR(d);
|
||||
goto out1;
|
||||
}
|
||||
rc = xsm_grant_setup(current->domain, d);
|
||||
--- a/xen/common/memory.c
|
||||
+++ b/xen/common/memory.c
|
||||
@@ -329,22 +329,9 @@ static long memory_exchange(XEN_GUEST_HA
|
||||
out_chunk_order = exch.in.extent_order - exch.out.extent_order;
|
||||
}
|
||||
|
||||
- if ( likely(exch.in.domid == DOMID_SELF) )
|
||||
- {
|
||||
- d = rcu_lock_current_domain();
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- if ( (d = rcu_lock_domain_by_id(exch.in.domid)) == NULL )
|
||||
- goto fail_early;
|
||||
-
|
||||
- if ( !IS_PRIV_FOR(current->domain, d) )
|
||||
- {
|
||||
- rcu_unlock_domain(d);
|
||||
- rc = -EPERM;
|
||||
- goto fail_early;
|
||||
- }
|
||||
- }
|
||||
+ rc = rcu_lock_target_domain_by_id(exch.in.domid, &d);
|
||||
+ if ( rc )
|
||||
+ goto fail_early;
|
||||
|
||||
memflags |= MEMF_bits(domain_clamp_alloc_bitsize(
|
||||
d,
|
||||
@@ -583,20 +570,8 @@ long do_memory_op(unsigned long cmd, XEN
|
||||
&& (reservation.mem_flags & XENMEMF_populate_on_demand) )
|
||||
args.memflags |= MEMF_populate_on_demand;
|
||||
|
||||
- if ( likely(reservation.domid == DOMID_SELF) )
|
||||
- {
|
||||
- d = rcu_lock_current_domain();
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- if ( (d = rcu_lock_domain_by_id(reservation.domid)) == NULL )
|
||||
- return start_extent;
|
||||
- if ( !IS_PRIV_FOR(current->domain, d) )
|
||||
- {
|
||||
- rcu_unlock_domain(d);
|
||||
- return start_extent;
|
||||
- }
|
||||
- }
|
||||
+ if ( unlikely(rcu_lock_target_domain_by_id(reservation.domid, &d)) )
|
||||
+ return start_extent;
|
||||
args.domain = d;
|
||||
|
||||
rc = xsm_memory_adjust_reservation(current->domain, d);
|
52
25836-VT-d-S3-MSI-resume.patch
Normal file
52
25836-VT-d-S3-MSI-resume.patch
Normal file
@ -0,0 +1,52 @@
|
||||
# HG changeset patch
|
||||
# User Jan Beulich <jbeulich@suse.com>
|
||||
# Date 1347263130 -7200
|
||||
# Node ID 7d216f026f71022186196a75244e97cf3864f50b
|
||||
# Parent c70d70d85306b3e4a0538353be131100c5ee38d5
|
||||
VT-d: split .ack and .disable DMA-MSI actors
|
||||
|
||||
Calling irq_complete_move() from .disable is wrong, breaking S3 resume.
|
||||
|
||||
Comparing with all other .ack actors, it was also missing a call to
|
||||
move_{native,masked}_irq(). As the actor is masking its interrupt
|
||||
anyway (albeit it's not immediately obvious why), the latter is the
|
||||
better choice.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Keir Fraser <keir@xen.org>
|
||||
Acked-by Xiantao Zhang <xiantao.zhang@intel.com>
|
||||
|
||||
--- a/xen/drivers/passthrough/vtd/iommu.c
|
||||
+++ b/xen/drivers/passthrough/vtd/iommu.c
|
||||
@@ -1040,8 +1040,6 @@ static void dma_msi_mask(struct irq_desc
|
||||
unsigned long flags;
|
||||
struct iommu *iommu = desc->action->dev_id;
|
||||
|
||||
- irq_complete_move(desc);
|
||||
-
|
||||
/* mask it */
|
||||
spin_lock_irqsave(&iommu->register_lock, flags);
|
||||
dmar_writel(iommu->reg, DMAR_FECTL_REG, DMA_FECTL_IM);
|
||||
@@ -1054,6 +1052,13 @@ static unsigned int dma_msi_startup(stru
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void dma_msi_ack(struct irq_desc *desc)
|
||||
+{
|
||||
+ irq_complete_move(desc);
|
||||
+ dma_msi_mask(desc);
|
||||
+ move_masked_irq(desc);
|
||||
+}
|
||||
+
|
||||
static void dma_msi_end(struct irq_desc *desc, u8 vector)
|
||||
{
|
||||
dma_msi_unmask(desc);
|
||||
@@ -1115,7 +1120,7 @@ static hw_irq_controller dma_msi_type =
|
||||
.shutdown = dma_msi_mask,
|
||||
.enable = dma_msi_unmask,
|
||||
.disable = dma_msi_mask,
|
||||
- .ack = dma_msi_mask,
|
||||
+ .ack = dma_msi_ack,
|
||||
.end = dma_msi_end,
|
||||
.set_affinity = dma_msi_set_affinity,
|
||||
};
|
27
25850-tmem-xsa-15-1.patch
Normal file
27
25850-tmem-xsa-15-1.patch
Normal file
@ -0,0 +1,27 @@
|
||||
# HG changeset patch
|
||||
# User Ian Campbell <ian.campbell@citrix.com>
|
||||
# Date 1347365190 -7200
|
||||
# Node ID 0dba5a8886556f1b92e59eb19c570ad1704037f6
|
||||
# Parent 90533f3b6babfda56edbbefda47c46b391204132
|
||||
tmem: only allow tmem control operations from privileged domains
|
||||
|
||||
This is part of XSA-15 / CVE-2012-3497.
|
||||
|
||||
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
|
||||
Committed-by: Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
--- a/xen/common/tmem.c
|
||||
+++ b/xen/common/tmem.c
|
||||
@@ -2541,10 +2541,8 @@ static NOINLINE int do_tmem_control(stru
|
||||
OID *oidp = (OID *)(&op->u.ctrl.oid[0]);
|
||||
|
||||
if (!tmh_current_is_privileged())
|
||||
- {
|
||||
- /* don't fail... mystery: sometimes dom0 fails here */
|
||||
- /* return -EPERM; */
|
||||
- }
|
||||
+ return -EPERM;
|
||||
+
|
||||
switch(subop)
|
||||
{
|
||||
case TMEMC_THAW:
|
45
25851-tmem-xsa-15-2.patch
Normal file
45
25851-tmem-xsa-15-2.patch
Normal file
@ -0,0 +1,45 @@
|
||||
# HG changeset patch
|
||||
# User Ian Campbell <ian.campbell@citrix.com>
|
||||
# Date 1347365203 -7200
|
||||
# Node ID fcf567acc92ae57f4adfbe967b01a2ba0390c08f
|
||||
# Parent 0dba5a8886556f1b92e59eb19c570ad1704037f6
|
||||
tmem: consistently make pool_id a uint32_t
|
||||
|
||||
Treating it as an int could allow a malicious guest to provide a
|
||||
negative pool_Id, by passing the MAX_POOLS_PER_DOMAIN limit check and
|
||||
allowing access to the negative offsets of the pool array.
|
||||
|
||||
This is part of XSA-15 / CVE-2012-3497.
|
||||
|
||||
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
|
||||
Committed-by: Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
--- a/xen/common/tmem.c
|
||||
+++ b/xen/common/tmem.c
|
||||
@@ -2417,7 +2417,7 @@ static NOINLINE int tmemc_save_subop(int
|
||||
return rc;
|
||||
}
|
||||
|
||||
-static NOINLINE int tmemc_save_get_next_page(int cli_id, int pool_id,
|
||||
+static NOINLINE int tmemc_save_get_next_page(int cli_id, uint32_t pool_id,
|
||||
tmem_cli_va_t buf, uint32_t bufsize)
|
||||
{
|
||||
client_t *client = tmh_client_from_cli_id(cli_id);
|
||||
@@ -2509,7 +2509,7 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int tmemc_restore_put_page(int cli_id, int pool_id, OID *oidp,
|
||||
+static int tmemc_restore_put_page(int cli_id, uint32_t pool_id, OID *oidp,
|
||||
uint32_t index, tmem_cli_va_t buf, uint32_t bufsize)
|
||||
{
|
||||
client_t *client = tmh_client_from_cli_id(cli_id);
|
||||
@@ -2521,7 +2521,7 @@ static int tmemc_restore_put_page(int cl
|
||||
return do_tmem_put(pool,oidp,index,0,0,0,bufsize,buf.p);
|
||||
}
|
||||
|
||||
-static int tmemc_restore_flush_page(int cli_id, int pool_id, OID *oidp,
|
||||
+static int tmemc_restore_flush_page(int cli_id, uint32_t pool_id, OID *oidp,
|
||||
uint32_t index)
|
||||
{
|
||||
client_t *client = tmh_client_from_cli_id(cli_id);
|
23
25852-tmem-xsa-15-3.patch
Normal file
23
25852-tmem-xsa-15-3.patch
Normal file
@ -0,0 +1,23 @@
|
||||
# HG changeset patch
|
||||
# User Ian Campbell <ian.campbell@citrix.com>
|
||||
# Date 1347365214 -7200
|
||||
# Node ID d189d99ef00c1e197321593d13282e1b57eb4a38
|
||||
# Parent fcf567acc92ae57f4adfbe967b01a2ba0390c08f
|
||||
tmem: check the pool_id is valid when destroying a tmem pool
|
||||
|
||||
This is part of XSA-15 / CVE-2012-3497.
|
||||
|
||||
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
|
||||
Committed-by: Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
--- a/xen/common/tmem.c
|
||||
+++ b/xen/common/tmem.c
|
||||
@@ -1870,6 +1870,8 @@ static NOINLINE int do_tmem_destroy_pool
|
||||
|
||||
if ( client->pools == NULL )
|
||||
return 0;
|
||||
+ if ( pool_id >= MAX_POOLS_PER_DOMAIN )
|
||||
+ return 0;
|
||||
if ( (pool = client->pools[pool_id]) == NULL )
|
||||
return 0;
|
||||
client->pools[pool_id] = NULL;
|
44
25853-tmem-xsa-15-4.patch
Normal file
44
25853-tmem-xsa-15-4.patch
Normal file
@ -0,0 +1,44 @@
|
||||
# HG changeset patch
|
||||
# User Ian Campbell <ian.campbell@citrix.com>
|
||||
# Date 1347365847 -7200
|
||||
# Node ID f53c5aadbba9d389f4a7d83f308499e22d1d1eda
|
||||
# Parent d189d99ef00c1e197321593d13282e1b57eb4a38
|
||||
tmem: check for a valid client ("domain") in the save subops
|
||||
|
||||
This is part of XSA-15 / CVE-2012-3497.
|
||||
|
||||
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
|
||||
Acked-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Dan Magenheimer <dan.magenheimer@oracle.com>
|
||||
Committed-by: Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
--- a/xen/common/tmem.c
|
||||
+++ b/xen/common/tmem.c
|
||||
@@ -2379,12 +2379,18 @@ static NOINLINE int tmemc_save_subop(int
|
||||
rc = MAX_POOLS_PER_DOMAIN;
|
||||
break;
|
||||
case TMEMC_SAVE_GET_CLIENT_WEIGHT:
|
||||
+ if ( client == NULL )
|
||||
+ break;
|
||||
rc = client->weight == -1 ? -2 : client->weight;
|
||||
break;
|
||||
case TMEMC_SAVE_GET_CLIENT_CAP:
|
||||
+ if ( client == NULL )
|
||||
+ break;
|
||||
rc = client->cap == -1 ? -2 : client->cap;
|
||||
break;
|
||||
case TMEMC_SAVE_GET_CLIENT_FLAGS:
|
||||
+ if ( client == NULL )
|
||||
+ break;
|
||||
rc = (client->compress ? TMEM_CLIENT_COMPRESS : 0 ) |
|
||||
(client->was_frozen ? TMEM_CLIENT_FROZEN : 0 );
|
||||
break;
|
||||
@@ -2408,6 +2414,8 @@ static NOINLINE int tmemc_save_subop(int
|
||||
*uuid = pool->uuid[1];
|
||||
rc = 0;
|
||||
case TMEMC_SAVE_END:
|
||||
+ if ( client == NULL )
|
||||
+ break;
|
||||
client->live_migrating = 0;
|
||||
if ( !list_empty(&client->persistent_invalidated_list) )
|
||||
list_for_each_entry_safe(pgp,pgp2,
|
556
25854-tmem-xsa-15-5.patch
Normal file
556
25854-tmem-xsa-15-5.patch
Normal file
@ -0,0 +1,556 @@
|
||||
# HG changeset patch
|
||||
# User Jan Beulich <jbeulich@suse.com>
|
||||
# Date 1347365869 -7200
|
||||
# Node ID ccd60ed6c555e1816cac448fcb20a84533977b43
|
||||
# Parent f53c5aadbba9d389f4a7d83f308499e22d1d1eda
|
||||
tmem: don't access guest memory without using the accessors intended for this
|
||||
|
||||
This is not permitted, not even for buffers coming from Dom0 (and it
|
||||
would also break the moment Dom0 runs in HVM mode). An implication from
|
||||
the changes here is that tmh_copy_page() can't be used anymore for
|
||||
control operations calling tmh_copy_{from,to}_client() (as those pass
|
||||
the buffer by virtual address rather than MFN).
|
||||
|
||||
Note that tmemc_save_get_next_page() previously didn't set the returned
|
||||
handle's pool_id field, while the new code does. It need to be
|
||||
confirmed that this is not a problem (otherwise the copy-out operation
|
||||
will require further tmh_...() abstractions to be added).
|
||||
|
||||
Further note that the patch removes (rather than adjusts) an invalid
|
||||
call to unmap_domain_page() (no matching map_domain_page()) from
|
||||
tmh_compress_from_client() and adds a missing one to an error return
|
||||
path in tmh_copy_from_client().
|
||||
|
||||
Finally note that the patch adds a previously missing return statement
|
||||
to cli_get_page() (without which that function could de-reference a
|
||||
NULL pointer, triggerable from guest mode).
|
||||
|
||||
This is part of XSA-15 / CVE-2012-3497.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Dan Magenheimer <dan.magenheimer@oracle.com>
|
||||
|
||||
--- a/xen/common/tmem.c
|
||||
+++ b/xen/common/tmem.c
|
||||
@@ -388,11 +388,13 @@ static NOINLINE int pcd_copy_to_client(t
|
||||
pcd = pgp->pcd;
|
||||
if ( pgp->size < PAGE_SIZE && pgp->size != 0 &&
|
||||
pcd->size < PAGE_SIZE && pcd->size != 0 )
|
||||
- ret = tmh_decompress_to_client(cmfn, pcd->cdata, pcd->size, NULL);
|
||||
+ ret = tmh_decompress_to_client(cmfn, pcd->cdata, pcd->size,
|
||||
+ tmh_cli_buf_null);
|
||||
else if ( tmh_tze_enabled() && pcd->size < PAGE_SIZE )
|
||||
ret = tmh_copy_tze_to_client(cmfn, pcd->tze, pcd->size);
|
||||
else
|
||||
- ret = tmh_copy_to_client(cmfn, pcd->pfp, 0, 0, PAGE_SIZE, NULL);
|
||||
+ ret = tmh_copy_to_client(cmfn, pcd->pfp, 0, 0, PAGE_SIZE,
|
||||
+ tmh_cli_buf_null);
|
||||
tmem_read_unlock(&pcd_tree_rwlocks[firstbyte]);
|
||||
return ret;
|
||||
}
|
||||
@@ -1444,7 +1446,7 @@ static inline void tmem_ensure_avail_pag
|
||||
/************ TMEM CORE OPERATIONS ************************************/
|
||||
|
||||
static NOINLINE int do_tmem_put_compress(pgp_t *pgp, tmem_cli_mfn_t cmfn,
|
||||
- void *cva)
|
||||
+ tmem_cli_va_t clibuf)
|
||||
{
|
||||
void *dst, *p;
|
||||
size_t size;
|
||||
@@ -1463,7 +1465,7 @@ static NOINLINE int do_tmem_put_compress
|
||||
if ( pgp->pfp != NULL )
|
||||
pgp_free_data(pgp, pgp->us.obj->pool);
|
||||
START_CYC_COUNTER(compress);
|
||||
- ret = tmh_compress_from_client(cmfn, &dst, &size, cva);
|
||||
+ ret = tmh_compress_from_client(cmfn, &dst, &size, clibuf);
|
||||
if ( (ret == -EFAULT) || (ret == 0) )
|
||||
goto out;
|
||||
else if ( (size == 0) || (size >= tmem_subpage_maxsize()) ) {
|
||||
@@ -1490,7 +1492,8 @@ out:
|
||||
}
|
||||
|
||||
static NOINLINE int do_tmem_dup_put(pgp_t *pgp, tmem_cli_mfn_t cmfn,
|
||||
- pagesize_t tmem_offset, pagesize_t pfn_offset, pagesize_t len, void *cva)
|
||||
+ pagesize_t tmem_offset, pagesize_t pfn_offset, pagesize_t len,
|
||||
+ tmem_cli_va_t clibuf)
|
||||
{
|
||||
pool_t *pool;
|
||||
obj_t *obj;
|
||||
@@ -1512,7 +1515,7 @@ static NOINLINE int do_tmem_dup_put(pgp_
|
||||
/* can we successfully manipulate pgp to change out the data? */
|
||||
if ( len != 0 && client->compress && pgp->size != 0 )
|
||||
{
|
||||
- ret = do_tmem_put_compress(pgp,cmfn,cva);
|
||||
+ ret = do_tmem_put_compress(pgp, cmfn, clibuf);
|
||||
if ( ret == 1 )
|
||||
goto done;
|
||||
else if ( ret == 0 )
|
||||
@@ -1530,7 +1533,8 @@ copy_uncompressed:
|
||||
goto failed_dup;
|
||||
pgp->size = 0;
|
||||
/* tmh_copy_from_client properly handles len==0 and offsets != 0 */
|
||||
- ret = tmh_copy_from_client(pgp->pfp,cmfn,tmem_offset,pfn_offset,len,0);
|
||||
+ ret = tmh_copy_from_client(pgp->pfp, cmfn, tmem_offset, pfn_offset, len,
|
||||
+ tmh_cli_buf_null);
|
||||
if ( ret == -EFAULT )
|
||||
goto bad_copy;
|
||||
if ( tmh_dedup_enabled() && !is_persistent(pool) )
|
||||
@@ -1582,7 +1586,7 @@ cleanup:
|
||||
static NOINLINE int do_tmem_put(pool_t *pool,
|
||||
OID *oidp, uint32_t index,
|
||||
tmem_cli_mfn_t cmfn, pagesize_t tmem_offset,
|
||||
- pagesize_t pfn_offset, pagesize_t len, void *cva)
|
||||
+ pagesize_t pfn_offset, pagesize_t len, tmem_cli_va_t clibuf)
|
||||
{
|
||||
obj_t *obj = NULL, *objfound = NULL, *objnew = NULL;
|
||||
pgp_t *pgp = NULL, *pgpdel = NULL;
|
||||
@@ -1596,7 +1600,8 @@ static NOINLINE int do_tmem_put(pool_t *
|
||||
{
|
||||
ASSERT_SPINLOCK(&objfound->obj_spinlock);
|
||||
if ((pgp = pgp_lookup_in_obj(objfound, index)) != NULL)
|
||||
- return do_tmem_dup_put(pgp,cmfn,tmem_offset,pfn_offset,len,cva);
|
||||
+ return do_tmem_dup_put(pgp, cmfn, tmem_offset, pfn_offset, len,
|
||||
+ clibuf);
|
||||
}
|
||||
|
||||
/* no puts allowed into a frozen pool (except dup puts) */
|
||||
@@ -1631,7 +1636,7 @@ static NOINLINE int do_tmem_put(pool_t *
|
||||
if ( len != 0 && client->compress )
|
||||
{
|
||||
ASSERT(pgp->pfp == NULL);
|
||||
- ret = do_tmem_put_compress(pgp,cmfn,cva);
|
||||
+ ret = do_tmem_put_compress(pgp, cmfn, clibuf);
|
||||
if ( ret == 1 )
|
||||
goto insert_page;
|
||||
if ( ret == -ENOMEM )
|
||||
@@ -1655,7 +1660,8 @@ copy_uncompressed:
|
||||
goto delete_and_free;
|
||||
}
|
||||
/* tmh_copy_from_client properly handles len==0 (TMEM_NEW_PAGE) */
|
||||
- ret = tmh_copy_from_client(pgp->pfp,cmfn,tmem_offset,pfn_offset,len,cva);
|
||||
+ ret = tmh_copy_from_client(pgp->pfp, cmfn, tmem_offset, pfn_offset, len,
|
||||
+ clibuf);
|
||||
if ( ret == -EFAULT )
|
||||
goto bad_copy;
|
||||
if ( tmh_dedup_enabled() && !is_persistent(pool) )
|
||||
@@ -1725,12 +1731,13 @@ free:
|
||||
|
||||
static NOINLINE int do_tmem_get(pool_t *pool, OID *oidp, uint32_t index,
|
||||
tmem_cli_mfn_t cmfn, pagesize_t tmem_offset,
|
||||
- pagesize_t pfn_offset, pagesize_t len, void *cva)
|
||||
+ pagesize_t pfn_offset, pagesize_t len, tmem_cli_va_t clibuf)
|
||||
{
|
||||
obj_t *obj;
|
||||
pgp_t *pgp;
|
||||
client_t *client = pool->client;
|
||||
DECL_LOCAL_CYC_COUNTER(decompress);
|
||||
+ int rc = -EFAULT;
|
||||
|
||||
if ( !_atomic_read(pool->pgp_count) )
|
||||
return -EEMPTY;
|
||||
@@ -1755,16 +1762,18 @@ static NOINLINE int do_tmem_get(pool_t *
|
||||
if ( tmh_dedup_enabled() && !is_persistent(pool) &&
|
||||
pgp->firstbyte != NOT_SHAREABLE )
|
||||
{
|
||||
- if ( pcd_copy_to_client(cmfn, pgp) == -EFAULT )
|
||||
+ rc = pcd_copy_to_client(cmfn, pgp);
|
||||
+ if ( rc <= 0 )
|
||||
goto bad_copy;
|
||||
} else if ( pgp->size != 0 ) {
|
||||
START_CYC_COUNTER(decompress);
|
||||
- if ( tmh_decompress_to_client(cmfn, pgp->cdata,
|
||||
- pgp->size, cva) == -EFAULT )
|
||||
+ rc = tmh_decompress_to_client(cmfn, pgp->cdata,
|
||||
+ pgp->size, clibuf);
|
||||
+ if ( rc <= 0 )
|
||||
goto bad_copy;
|
||||
END_CYC_COUNTER(decompress);
|
||||
} else if ( tmh_copy_to_client(cmfn, pgp->pfp, tmem_offset,
|
||||
- pfn_offset, len, cva) == -EFAULT)
|
||||
+ pfn_offset, len, clibuf) == -EFAULT)
|
||||
goto bad_copy;
|
||||
if ( is_ephemeral(pool) )
|
||||
{
|
||||
@@ -1804,8 +1813,7 @@ static NOINLINE int do_tmem_get(pool_t *
|
||||
bad_copy:
|
||||
/* this should only happen if the client passed a bad mfn */
|
||||
failed_copies++;
|
||||
- return -EFAULT;
|
||||
-
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
static NOINLINE int do_tmem_flush_page(pool_t *pool, OID *oidp, uint32_t index)
|
||||
@@ -2345,7 +2353,6 @@ static NOINLINE int tmemc_save_subop(int
|
||||
pool_t *pool = (client == NULL || pool_id >= MAX_POOLS_PER_DOMAIN)
|
||||
? NULL : client->pools[pool_id];
|
||||
uint32_t p;
|
||||
- uint64_t *uuid;
|
||||
pgp_t *pgp, *pgp2;
|
||||
int rc = -1;
|
||||
|
||||
@@ -2409,9 +2416,7 @@ static NOINLINE int tmemc_save_subop(int
|
||||
case TMEMC_SAVE_GET_POOL_UUID:
|
||||
if ( pool == NULL )
|
||||
break;
|
||||
- uuid = (uint64_t *)buf.p;
|
||||
- *uuid++ = pool->uuid[0];
|
||||
- *uuid = pool->uuid[1];
|
||||
+ tmh_copy_to_client_buf(buf, pool->uuid, 2);
|
||||
rc = 0;
|
||||
case TMEMC_SAVE_END:
|
||||
if ( client == NULL )
|
||||
@@ -2436,7 +2441,7 @@ static NOINLINE int tmemc_save_get_next_
|
||||
pgp_t *pgp;
|
||||
OID oid;
|
||||
int ret = 0;
|
||||
- struct tmem_handle *h;
|
||||
+ struct tmem_handle h;
|
||||
unsigned int pagesize = 1 << (pool->pageshift+12);
|
||||
|
||||
if ( pool == NULL || is_ephemeral(pool) )
|
||||
@@ -2467,11 +2472,13 @@ static NOINLINE int tmemc_save_get_next_
|
||||
pgp_t,us.pool_pers_pages);
|
||||
pool->cur_pgp = pgp;
|
||||
oid = pgp->us.obj->oid;
|
||||
- h = (struct tmem_handle *)buf.p;
|
||||
- *(OID *)&h->oid[0] = oid;
|
||||
- h->index = pgp->index;
|
||||
- buf.p = (void *)(h+1);
|
||||
- ret = do_tmem_get(pool, &oid, h->index,0,0,0,pagesize,buf.p);
|
||||
+ h.pool_id = pool_id;
|
||||
+ BUILD_BUG_ON(sizeof(h.oid) != sizeof(oid));
|
||||
+ memcpy(h.oid, oid.oid, sizeof(h.oid));
|
||||
+ h.index = pgp->index;
|
||||
+ tmh_copy_to_client_buf(buf, &h, 1);
|
||||
+ tmh_client_buf_add(buf, sizeof(h));
|
||||
+ ret = do_tmem_get(pool, &oid, pgp->index, 0, 0, 0, pagesize, buf);
|
||||
|
||||
out:
|
||||
tmem_spin_unlock(&pers_lists_spinlock);
|
||||
@@ -2483,7 +2490,7 @@ static NOINLINE int tmemc_save_get_next_
|
||||
{
|
||||
client_t *client = tmh_client_from_cli_id(cli_id);
|
||||
pgp_t *pgp;
|
||||
- struct tmem_handle *h;
|
||||
+ struct tmem_handle h;
|
||||
int ret = 0;
|
||||
|
||||
if ( client == NULL )
|
||||
@@ -2509,10 +2516,11 @@ static NOINLINE int tmemc_save_get_next_
|
||||
pgp_t,client_inv_pages);
|
||||
client->cur_pgp = pgp;
|
||||
}
|
||||
- h = (struct tmem_handle *)buf.p;
|
||||
- h->pool_id = pgp->pool_id;
|
||||
- *(OID *)&h->oid = pgp->inv_oid;
|
||||
- h->index = pgp->index;
|
||||
+ h.pool_id = pgp->pool_id;
|
||||
+ BUILD_BUG_ON(sizeof(h.oid) != sizeof(pgp->inv_oid));
|
||||
+ memcpy(h.oid, pgp->inv_oid.oid, sizeof(h.oid));
|
||||
+ h.index = pgp->index;
|
||||
+ tmh_copy_to_client_buf(buf, &h, 1);
|
||||
ret = 1;
|
||||
out:
|
||||
tmem_spin_unlock(&pers_lists_spinlock);
|
||||
@@ -2528,7 +2536,7 @@ static int tmemc_restore_put_page(int cl
|
||||
|
||||
if ( pool == NULL )
|
||||
return -1;
|
||||
- return do_tmem_put(pool,oidp,index,0,0,0,bufsize,buf.p);
|
||||
+ return do_tmem_put(pool, oidp, index, 0, 0, 0, bufsize, buf);
|
||||
}
|
||||
|
||||
static int tmemc_restore_flush_page(int cli_id, uint32_t pool_id, OID *oidp,
|
||||
@@ -2732,19 +2740,19 @@ EXPORT long do_tmem_op(tmem_cli_op_t uop
|
||||
break;
|
||||
case TMEM_NEW_PAGE:
|
||||
tmem_ensure_avail_pages();
|
||||
- rc = do_tmem_put(pool, oidp,
|
||||
- op.u.gen.index, op.u.gen.cmfn, 0, 0, 0, NULL);
|
||||
+ rc = do_tmem_put(pool, oidp, op.u.gen.index, op.u.gen.cmfn, 0, 0, 0,
|
||||
+ tmh_cli_buf_null);
|
||||
break;
|
||||
case TMEM_PUT_PAGE:
|
||||
tmem_ensure_avail_pages();
|
||||
- rc = do_tmem_put(pool, oidp,
|
||||
- op.u.gen.index, op.u.gen.cmfn, 0, 0, PAGE_SIZE, NULL);
|
||||
+ rc = do_tmem_put(pool, oidp, op.u.gen.index, op.u.gen.cmfn, 0, 0,
|
||||
+ PAGE_SIZE, tmh_cli_buf_null);
|
||||
if (rc == 1) succ_put = 1;
|
||||
else non_succ_put = 1;
|
||||
break;
|
||||
case TMEM_GET_PAGE:
|
||||
rc = do_tmem_get(pool, oidp, op.u.gen.index, op.u.gen.cmfn,
|
||||
- 0, 0, PAGE_SIZE, 0);
|
||||
+ 0, 0, PAGE_SIZE, tmh_cli_buf_null);
|
||||
if (rc == 1) succ_get = 1;
|
||||
else non_succ_get = 1;
|
||||
break;
|
||||
@@ -2763,13 +2771,13 @@ EXPORT long do_tmem_op(tmem_cli_op_t uop
|
||||
case TMEM_READ:
|
||||
rc = do_tmem_get(pool, oidp, op.u.gen.index, op.u.gen.cmfn,
|
||||
op.u.gen.tmem_offset, op.u.gen.pfn_offset,
|
||||
- op.u.gen.len,0);
|
||||
+ op.u.gen.len, tmh_cli_buf_null);
|
||||
break;
|
||||
case TMEM_WRITE:
|
||||
rc = do_tmem_put(pool, oidp,
|
||||
op.u.gen.index, op.u.gen.cmfn,
|
||||
op.u.gen.tmem_offset, op.u.gen.pfn_offset,
|
||||
- op.u.gen.len, NULL);
|
||||
+ op.u.gen.len, tmh_cli_buf_null);
|
||||
break;
|
||||
case TMEM_XCHG:
|
||||
/* need to hold global lock to ensure xchg is atomic */
|
||||
--- a/xen/common/tmem_xen.c
|
||||
+++ b/xen/common/tmem_xen.c
|
||||
@@ -51,6 +51,7 @@ DECL_CYC_COUNTER(pg_copy);
|
||||
#define LZO_DSTMEM_PAGES 2
|
||||
static DEFINE_PER_CPU_READ_MOSTLY(unsigned char *, workmem);
|
||||
static DEFINE_PER_CPU_READ_MOSTLY(unsigned char *, dstmem);
|
||||
+static DEFINE_PER_CPU_READ_MOSTLY(void *, scratch_page);
|
||||
|
||||
#ifdef COMPARE_COPY_PAGE_SSE2
|
||||
#include <asm/flushtlb.h> /* REMOVE ME AFTER TEST */
|
||||
@@ -115,6 +116,7 @@ static inline void *cli_get_page(tmem_cl
|
||||
{
|
||||
if ( page )
|
||||
put_page(page);
|
||||
+ return NULL;
|
||||
}
|
||||
|
||||
if ( cli_write && !get_page_type(page, PGT_writable_page) )
|
||||
@@ -144,12 +146,12 @@ static inline void cli_put_page(tmem_cli
|
||||
|
||||
EXPORT int tmh_copy_from_client(pfp_t *pfp,
|
||||
tmem_cli_mfn_t cmfn, pagesize_t tmem_offset,
|
||||
- pagesize_t pfn_offset, pagesize_t len, void *cli_va)
|
||||
+ pagesize_t pfn_offset, pagesize_t len, tmem_cli_va_t clibuf)
|
||||
{
|
||||
unsigned long tmem_mfn, cli_mfn = 0;
|
||||
- void *tmem_va;
|
||||
+ char *tmem_va, *cli_va = NULL;
|
||||
pfp_t *cli_pfp = NULL;
|
||||
- bool_t tmemc = cli_va != NULL; /* if true, cli_va is control-op buffer */
|
||||
+ int rc = 1;
|
||||
|
||||
ASSERT(pfp != NULL);
|
||||
tmem_mfn = page_to_mfn(pfp);
|
||||
@@ -160,62 +162,76 @@ EXPORT int tmh_copy_from_client(pfp_t *p
|
||||
unmap_domain_page(tmem_va);
|
||||
return 1;
|
||||
}
|
||||
- if ( !tmemc )
|
||||
+ if ( guest_handle_is_null(clibuf) )
|
||||
{
|
||||
cli_va = cli_get_page(cmfn, &cli_mfn, &cli_pfp, 0);
|
||||
if ( cli_va == NULL )
|
||||
+ {
|
||||
+ unmap_domain_page(tmem_va);
|
||||
return -EFAULT;
|
||||
+ }
|
||||
}
|
||||
mb();
|
||||
- if (len == PAGE_SIZE && !tmem_offset && !pfn_offset)
|
||||
+ if ( len == PAGE_SIZE && !tmem_offset && !pfn_offset && cli_va )
|
||||
tmh_copy_page(tmem_va, cli_va);
|
||||
else if ( (tmem_offset+len <= PAGE_SIZE) &&
|
||||
(pfn_offset+len <= PAGE_SIZE) )
|
||||
- memcpy((char *)tmem_va+tmem_offset,(char *)cli_va+pfn_offset,len);
|
||||
- if ( !tmemc )
|
||||
+ {
|
||||
+ if ( cli_va )
|
||||
+ memcpy(tmem_va + tmem_offset, cli_va + pfn_offset, len);
|
||||
+ else if ( copy_from_guest_offset(tmem_va + tmem_offset, clibuf,
|
||||
+ pfn_offset, len) )
|
||||
+ rc = -EFAULT;
|
||||
+ }
|
||||
+ if ( cli_va )
|
||||
cli_put_page(cmfn, cli_va, cli_pfp, cli_mfn, 0);
|
||||
unmap_domain_page(tmem_va);
|
||||
- return 1;
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
EXPORT int tmh_compress_from_client(tmem_cli_mfn_t cmfn,
|
||||
- void **out_va, size_t *out_len, void *cli_va)
|
||||
+ void **out_va, size_t *out_len, tmem_cli_va_t clibuf)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char *dmem = this_cpu(dstmem);
|
||||
unsigned char *wmem = this_cpu(workmem);
|
||||
+ char *scratch = this_cpu(scratch_page);
|
||||
pfp_t *cli_pfp = NULL;
|
||||
unsigned long cli_mfn = 0;
|
||||
- bool_t tmemc = cli_va != NULL; /* if true, cli_va is control-op buffer */
|
||||
+ void *cli_va = NULL;
|
||||
|
||||
if ( dmem == NULL || wmem == NULL )
|
||||
return 0; /* no buffer, so can't compress */
|
||||
- if ( !tmemc )
|
||||
+ if ( guest_handle_is_null(clibuf) )
|
||||
{
|
||||
cli_va = cli_get_page(cmfn, &cli_mfn, &cli_pfp, 0);
|
||||
if ( cli_va == NULL )
|
||||
return -EFAULT;
|
||||
}
|
||||
+ else if ( !scratch )
|
||||
+ return 0;
|
||||
+ else if ( copy_from_guest(scratch, clibuf, PAGE_SIZE) )
|
||||
+ return -EFAULT;
|
||||
mb();
|
||||
- ret = lzo1x_1_compress(cli_va, PAGE_SIZE, dmem, out_len, wmem);
|
||||
+ ret = lzo1x_1_compress(cli_va ?: scratch, PAGE_SIZE, dmem, out_len, wmem);
|
||||
ASSERT(ret == LZO_E_OK);
|
||||
*out_va = dmem;
|
||||
- if ( !tmemc )
|
||||
+ if ( cli_va )
|
||||
cli_put_page(cmfn, cli_va, cli_pfp, cli_mfn, 0);
|
||||
- unmap_domain_page(cli_va);
|
||||
return 1;
|
||||
}
|
||||
|
||||
EXPORT int tmh_copy_to_client(tmem_cli_mfn_t cmfn, pfp_t *pfp,
|
||||
- pagesize_t tmem_offset, pagesize_t pfn_offset, pagesize_t len, void *cli_va)
|
||||
+ pagesize_t tmem_offset, pagesize_t pfn_offset, pagesize_t len,
|
||||
+ tmem_cli_va_t clibuf)
|
||||
{
|
||||
unsigned long tmem_mfn, cli_mfn = 0;
|
||||
- void *tmem_va;
|
||||
+ char *tmem_va, *cli_va = NULL;
|
||||
pfp_t *cli_pfp = NULL;
|
||||
- bool_t tmemc = cli_va != NULL; /* if true, cli_va is control-op buffer */
|
||||
+ int rc = 1;
|
||||
|
||||
ASSERT(pfp != NULL);
|
||||
- if ( !tmemc )
|
||||
+ if ( guest_handle_is_null(clibuf) )
|
||||
{
|
||||
cli_va = cli_get_page(cmfn, &cli_mfn, &cli_pfp, 1);
|
||||
if ( cli_va == NULL )
|
||||
@@ -223,37 +239,48 @@ EXPORT int tmh_copy_to_client(tmem_cli_m
|
||||
}
|
||||
tmem_mfn = page_to_mfn(pfp);
|
||||
tmem_va = map_domain_page(tmem_mfn);
|
||||
- if (len == PAGE_SIZE && !tmem_offset && !pfn_offset)
|
||||
+ if ( len == PAGE_SIZE && !tmem_offset && !pfn_offset && cli_va )
|
||||
tmh_copy_page(cli_va, tmem_va);
|
||||
else if ( (tmem_offset+len <= PAGE_SIZE) && (pfn_offset+len <= PAGE_SIZE) )
|
||||
- memcpy((char *)cli_va+pfn_offset,(char *)tmem_va+tmem_offset,len);
|
||||
+ {
|
||||
+ if ( cli_va )
|
||||
+ memcpy(cli_va + pfn_offset, tmem_va + tmem_offset, len);
|
||||
+ else if ( copy_to_guest_offset(clibuf, pfn_offset,
|
||||
+ tmem_va + tmem_offset, len) )
|
||||
+ rc = -EFAULT;
|
||||
+ }
|
||||
unmap_domain_page(tmem_va);
|
||||
- if ( !tmemc )
|
||||
+ if ( cli_va )
|
||||
cli_put_page(cmfn, cli_va, cli_pfp, cli_mfn, 1);
|
||||
mb();
|
||||
- return 1;
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
EXPORT int tmh_decompress_to_client(tmem_cli_mfn_t cmfn, void *tmem_va,
|
||||
- size_t size, void *cli_va)
|
||||
+ size_t size, tmem_cli_va_t clibuf)
|
||||
{
|
||||
unsigned long cli_mfn = 0;
|
||||
pfp_t *cli_pfp = NULL;
|
||||
+ void *cli_va = NULL;
|
||||
+ char *scratch = this_cpu(scratch_page);
|
||||
size_t out_len = PAGE_SIZE;
|
||||
- bool_t tmemc = cli_va != NULL; /* if true, cli_va is control-op buffer */
|
||||
int ret;
|
||||
|
||||
- if ( !tmemc )
|
||||
+ if ( guest_handle_is_null(clibuf) )
|
||||
{
|
||||
cli_va = cli_get_page(cmfn, &cli_mfn, &cli_pfp, 1);
|
||||
if ( cli_va == NULL )
|
||||
return -EFAULT;
|
||||
}
|
||||
- ret = lzo1x_decompress_safe(tmem_va, size, cli_va, &out_len);
|
||||
+ else if ( !scratch )
|
||||
+ return 0;
|
||||
+ ret = lzo1x_decompress_safe(tmem_va, size, cli_va ?: scratch, &out_len);
|
||||
ASSERT(ret == LZO_E_OK);
|
||||
ASSERT(out_len == PAGE_SIZE);
|
||||
- if ( !tmemc )
|
||||
+ if ( cli_va )
|
||||
cli_put_page(cmfn, cli_va, cli_pfp, cli_mfn, 1);
|
||||
+ else if ( copy_to_guest(clibuf, scratch, PAGE_SIZE) )
|
||||
+ return -EFAULT;
|
||||
mb();
|
||||
return 1;
|
||||
}
|
||||
@@ -423,6 +450,11 @@ static int cpu_callback(
|
||||
struct page_info *p = alloc_domheap_pages(0, workmem_order, 0);
|
||||
per_cpu(workmem, cpu) = p ? page_to_virt(p) : NULL;
|
||||
}
|
||||
+ if ( per_cpu(scratch_page, cpu) == NULL )
|
||||
+ {
|
||||
+ struct page_info *p = alloc_domheap_page(NULL, 0);
|
||||
+ per_cpu(scratch_page, cpu) = p ? page_to_virt(p) : NULL;
|
||||
+ }
|
||||
break;
|
||||
}
|
||||
case CPU_DEAD:
|
||||
@@ -439,6 +471,11 @@ static int cpu_callback(
|
||||
free_domheap_pages(p, workmem_order);
|
||||
per_cpu(workmem, cpu) = NULL;
|
||||
}
|
||||
+ if ( per_cpu(scratch_page, cpu) != NULL )
|
||||
+ {
|
||||
+ free_domheap_page(virt_to_page(per_cpu(scratch_page, cpu)));
|
||||
+ per_cpu(scratch_page, cpu) = NULL;
|
||||
+ }
|
||||
break;
|
||||
}
|
||||
default:
|
||||
--- a/xen/include/xen/tmem_xen.h
|
||||
+++ b/xen/include/xen/tmem_xen.h
|
||||
@@ -482,27 +482,33 @@ static inline int tmh_get_tmemop_from_cl
|
||||
return copy_from_guest(op, uops, 1);
|
||||
}
|
||||
|
||||
+#define tmh_cli_buf_null guest_handle_from_ptr(NULL, char)
|
||||
+
|
||||
static inline void tmh_copy_to_client_buf_offset(tmem_cli_va_t clibuf, int off,
|
||||
char *tmembuf, int len)
|
||||
{
|
||||
copy_to_guest_offset(clibuf,off,tmembuf,len);
|
||||
}
|
||||
|
||||
+#define tmh_copy_to_client_buf(clibuf, tmembuf, cnt) \
|
||||
+ copy_to_guest(guest_handle_cast(clibuf, void), tmembuf, cnt)
|
||||
+
|
||||
+#define tmh_client_buf_add guest_handle_add_offset
|
||||
+
|
||||
#define TMH_CLI_ID_NULL ((cli_id_t)((domid_t)-1L))
|
||||
|
||||
#define tmh_cli_id_str "domid"
|
||||
#define tmh_client_str "domain"
|
||||
|
||||
-extern int tmh_decompress_to_client(tmem_cli_mfn_t,void*,size_t,void*);
|
||||
+int tmh_decompress_to_client(tmem_cli_mfn_t, void *, size_t, tmem_cli_va_t);
|
||||
|
||||
-extern int tmh_compress_from_client(tmem_cli_mfn_t,void**,size_t *,void*);
|
||||
+int tmh_compress_from_client(tmem_cli_mfn_t, void **, size_t *, tmem_cli_va_t);
|
||||
|
||||
-extern int tmh_copy_from_client(pfp_t *pfp,
|
||||
- tmem_cli_mfn_t cmfn, pagesize_t tmem_offset,
|
||||
- pagesize_t pfn_offset, pagesize_t len, void *cva);
|
||||
+int tmh_copy_from_client(pfp_t *, tmem_cli_mfn_t, pagesize_t tmem_offset,
|
||||
+ pagesize_t pfn_offset, pagesize_t len, tmem_cli_va_t);
|
||||
|
||||
-extern int tmh_copy_to_client(tmem_cli_mfn_t cmfn, pfp_t *pfp,
|
||||
- pagesize_t tmem_offset, pagesize_t pfn_offset, pagesize_t len, void *cva);
|
||||
+int tmh_copy_to_client(tmem_cli_mfn_t, pfp_t *, pagesize_t tmem_offset,
|
||||
+ pagesize_t pfn_offset, pagesize_t len, tmem_cli_va_t);
|
||||
|
||||
extern int tmh_copy_tze_to_client(tmem_cli_mfn_t cmfn, void *tmem_va, pagesize_t len);
|
||||
|
137
25855-tmem-xsa-15-6.patch
Normal file
137
25855-tmem-xsa-15-6.patch
Normal file
@ -0,0 +1,137 @@
|
||||
# HG changeset patch
|
||||
# User Jan Beulich <jbeulich@suse.com>
|
||||
# Date 1347365879 -7200
|
||||
# Node ID 33b8c42a87ec2fa6e6533dd9ee7603f732b168f5
|
||||
# Parent ccd60ed6c555e1816cac448fcb20a84533977b43
|
||||
tmem: detect arithmetic overflow in tmh_copy_{from,to}_client()
|
||||
|
||||
This implies adjusting callers to deal with errors other than -EFAULT
|
||||
and removing some comments which would otherwise become stale.
|
||||
|
||||
Reported-by: Tim Deegan <tim@xen.org>
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Dan Magenheimer <dan.magenheimer@oracle.com>
|
||||
|
||||
--- a/xen/common/tmem.c
|
||||
+++ b/xen/common/tmem.c
|
||||
@@ -1535,7 +1535,7 @@ copy_uncompressed:
|
||||
/* tmh_copy_from_client properly handles len==0 and offsets != 0 */
|
||||
ret = tmh_copy_from_client(pgp->pfp, cmfn, tmem_offset, pfn_offset, len,
|
||||
tmh_cli_buf_null);
|
||||
- if ( ret == -EFAULT )
|
||||
+ if ( ret < 0 )
|
||||
goto bad_copy;
|
||||
if ( tmh_dedup_enabled() && !is_persistent(pool) )
|
||||
{
|
||||
@@ -1556,9 +1556,7 @@ done:
|
||||
return 1;
|
||||
|
||||
bad_copy:
|
||||
- /* this should only happen if the client passed a bad mfn */
|
||||
failed_copies++;
|
||||
- ret = -EFAULT;
|
||||
goto cleanup;
|
||||
|
||||
failed_dup:
|
||||
@@ -1662,7 +1660,7 @@ copy_uncompressed:
|
||||
/* tmh_copy_from_client properly handles len==0 (TMEM_NEW_PAGE) */
|
||||
ret = tmh_copy_from_client(pgp->pfp, cmfn, tmem_offset, pfn_offset, len,
|
||||
clibuf);
|
||||
- if ( ret == -EFAULT )
|
||||
+ if ( ret < 0 )
|
||||
goto bad_copy;
|
||||
if ( tmh_dedup_enabled() && !is_persistent(pool) )
|
||||
{
|
||||
@@ -1702,8 +1700,6 @@ insert_page:
|
||||
return 1;
|
||||
|
||||
bad_copy:
|
||||
- /* this should only happen if the client passed a bad mfn */
|
||||
- ret = -EFAULT;
|
||||
failed_copies++;
|
||||
|
||||
delete_and_free:
|
||||
@@ -1737,7 +1733,7 @@ static NOINLINE int do_tmem_get(pool_t *
|
||||
pgp_t *pgp;
|
||||
client_t *client = pool->client;
|
||||
DECL_LOCAL_CYC_COUNTER(decompress);
|
||||
- int rc = -EFAULT;
|
||||
+ int rc;
|
||||
|
||||
if ( !_atomic_read(pool->pgp_count) )
|
||||
return -EEMPTY;
|
||||
@@ -1761,20 +1757,20 @@ static NOINLINE int do_tmem_get(pool_t *
|
||||
ASSERT(pgp->size != -1);
|
||||
if ( tmh_dedup_enabled() && !is_persistent(pool) &&
|
||||
pgp->firstbyte != NOT_SHAREABLE )
|
||||
- {
|
||||
rc = pcd_copy_to_client(cmfn, pgp);
|
||||
- if ( rc <= 0 )
|
||||
- goto bad_copy;
|
||||
- } else if ( pgp->size != 0 ) {
|
||||
+ else if ( pgp->size != 0 )
|
||||
+ {
|
||||
START_CYC_COUNTER(decompress);
|
||||
rc = tmh_decompress_to_client(cmfn, pgp->cdata,
|
||||
pgp->size, clibuf);
|
||||
- if ( rc <= 0 )
|
||||
- goto bad_copy;
|
||||
END_CYC_COUNTER(decompress);
|
||||
- } else if ( tmh_copy_to_client(cmfn, pgp->pfp, tmem_offset,
|
||||
- pfn_offset, len, clibuf) == -EFAULT)
|
||||
+ }
|
||||
+ else
|
||||
+ rc = tmh_copy_to_client(cmfn, pgp->pfp, tmem_offset,
|
||||
+ pfn_offset, len, clibuf);
|
||||
+ if ( rc <= 0 )
|
||||
goto bad_copy;
|
||||
+
|
||||
if ( is_ephemeral(pool) )
|
||||
{
|
||||
if ( is_private(pool) )
|
||||
@@ -1811,7 +1807,6 @@ static NOINLINE int do_tmem_get(pool_t *
|
||||
return 1;
|
||||
|
||||
bad_copy:
|
||||
- /* this should only happen if the client passed a bad mfn */
|
||||
failed_copies++;
|
||||
return rc;
|
||||
}
|
||||
--- a/xen/common/tmem_xen.c
|
||||
+++ b/xen/common/tmem_xen.c
|
||||
@@ -153,6 +153,8 @@ EXPORT int tmh_copy_from_client(pfp_t *p
|
||||
pfp_t *cli_pfp = NULL;
|
||||
int rc = 1;
|
||||
|
||||
+ if ( tmem_offset > PAGE_SIZE || pfn_offset > PAGE_SIZE || len > PAGE_SIZE )
|
||||
+ return -EINVAL;
|
||||
ASSERT(pfp != NULL);
|
||||
tmem_mfn = page_to_mfn(pfp);
|
||||
tmem_va = map_domain_page(tmem_mfn);
|
||||
@@ -183,6 +185,8 @@ EXPORT int tmh_copy_from_client(pfp_t *p
|
||||
pfn_offset, len) )
|
||||
rc = -EFAULT;
|
||||
}
|
||||
+ else if ( len )
|
||||
+ rc = -EINVAL;
|
||||
if ( cli_va )
|
||||
cli_put_page(cmfn, cli_va, cli_pfp, cli_mfn, 0);
|
||||
unmap_domain_page(tmem_va);
|
||||
@@ -230,6 +234,8 @@ EXPORT int tmh_copy_to_client(tmem_cli_m
|
||||
pfp_t *cli_pfp = NULL;
|
||||
int rc = 1;
|
||||
|
||||
+ if ( tmem_offset > PAGE_SIZE || pfn_offset > PAGE_SIZE || len > PAGE_SIZE )
|
||||
+ return -EINVAL;
|
||||
ASSERT(pfp != NULL);
|
||||
if ( guest_handle_is_null(clibuf) )
|
||||
{
|
||||
@@ -249,6 +255,8 @@ EXPORT int tmh_copy_to_client(tmem_cli_m
|
||||
tmem_va + tmem_offset, len) )
|
||||
rc = -EFAULT;
|
||||
}
|
||||
+ else if ( len )
|
||||
+ rc = -EINVAL;
|
||||
unmap_domain_page(tmem_va);
|
||||
if ( cli_va )
|
||||
cli_put_page(cmfn, cli_va, cli_pfp, cli_mfn, 1);
|
32
25856-tmem-xsa-15-7.patch
Normal file
32
25856-tmem-xsa-15-7.patch
Normal file
@ -0,0 +1,32 @@
|
||||
# HG changeset patch
|
||||
# User Jan Beulich <jbeulich@suse.com>
|
||||
# Date 1347365888 -7200
|
||||
# Node ID 83b97a59888b6d2d0f984b8403bd5764dd55c10c
|
||||
# Parent 33b8c42a87ec2fa6e6533dd9ee7603f732b168f5
|
||||
tmem: properly drop lock on error path in do_tmem_get()
|
||||
|
||||
Also remove a bogus assertion.
|
||||
|
||||
Reported-by: Tim Deegan <tim@xen.org>
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Dan Magenheimer <dan.magenheimer@oracle.com>
|
||||
|
||||
--- a/xen/common/tmem.c
|
||||
+++ b/xen/common/tmem.c
|
||||
@@ -1790,7 +1790,6 @@ static NOINLINE int do_tmem_get(pool_t *
|
||||
list_del(&pgp->us.client_eph_pages);
|
||||
list_add_tail(&pgp->us.client_eph_pages,&client->ephemeral_page_list);
|
||||
tmem_spin_unlock(&eph_lists_spinlock);
|
||||
- ASSERT(obj != NULL);
|
||||
obj->last_client = tmh_get_cli_id_from_current();
|
||||
}
|
||||
}
|
||||
@@ -1807,6 +1806,8 @@ static NOINLINE int do_tmem_get(pool_t *
|
||||
return 1;
|
||||
|
||||
bad_copy:
|
||||
+ obj->no_evict = 0;
|
||||
+ tmem_spin_unlock(&obj->obj_spinlock);
|
||||
failed_copies++;
|
||||
return rc;
|
||||
}
|
34
25857-tmem-xsa-15-8.patch
Normal file
34
25857-tmem-xsa-15-8.patch
Normal file
@ -0,0 +1,34 @@
|
||||
# HG changeset patch
|
||||
# User Jan Beulich <jbeulich@suse.com>
|
||||
# Date 1347365906 -7200
|
||||
# Node ID 109ea6a0c23aa0c5df79e3f5658162aed959ffcf
|
||||
# Parent 83b97a59888b6d2d0f984b8403bd5764dd55c10c
|
||||
tmem: properly drop lock on error path in do_tmem_op()
|
||||
|
||||
Reported-by: Tim Deegan <tim@xen.org>
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Dan Magenheimer <dan.magenheimer@oracle.com>
|
||||
|
||||
--- a/xen/common/tmem.c
|
||||
+++ b/xen/common/tmem.c
|
||||
@@ -2659,13 +2659,19 @@ EXPORT long do_tmem_op(tmem_cli_op_t uop
|
||||
if ( client != NULL && tmh_client_is_dying(client) )
|
||||
{
|
||||
rc = -ENODEV;
|
||||
- goto out;
|
||||
+ if ( tmh_lock_all )
|
||||
+ goto out;
|
||||
+ simple_error:
|
||||
+ errored_tmem_ops++;
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
if ( unlikely(tmh_get_tmemop_from_client(&op, uops) != 0) )
|
||||
{
|
||||
printk("tmem: can't get tmem struct from %s\n",client_str);
|
||||
rc = -EFAULT;
|
||||
+ if ( !tmh_lock_all )
|
||||
+ goto simple_error;
|
||||
goto out;
|
||||
}
|
||||
|
305
25858-tmem-xsa-15-9.patch
Normal file
305
25858-tmem-xsa-15-9.patch
Normal file
@ -0,0 +1,305 @@
|
||||
# HG changeset patch
|
||||
# User Jan Beulich <jbeulich@suse.com>
|
||||
# Date 1347365916 -7200
|
||||
# Node ID 0520982a602a3ac06dd5bc573ddaff5edc9c6987
|
||||
# Parent 109ea6a0c23aa0c5df79e3f5658162aed959ffcf
|
||||
tmem: reduce severity of log messages
|
||||
|
||||
Otherwise they can be used by a guest to spam the hypervisor log with
|
||||
all settings at their defaults.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Zhenzhong Duan <zhenzhong.duan@oracle.com>
|
||||
|
||||
--- a/xen/common/tmem.c
|
||||
+++ b/xen/common/tmem.c
|
||||
@@ -1107,7 +1107,7 @@ static int shared_pool_join(pool_t *pool
|
||||
sl->client = new_client;
|
||||
list_add_tail(&sl->share_list, &pool->share_list);
|
||||
if ( new_client->cli_id != pool->client->cli_id )
|
||||
- printk("adding new %s %d to shared pool owned by %s %d\n",
|
||||
+ tmh_client_info("adding new %s %d to shared pool owned by %s %d\n",
|
||||
client_str, new_client->cli_id, client_str, pool->client->cli_id);
|
||||
return ++pool->shared_count;
|
||||
}
|
||||
@@ -1137,7 +1137,7 @@ static NOINLINE void shared_pool_reassig
|
||||
old_client->eph_count -= _atomic_read(pool->pgp_count);
|
||||
list_splice_init(&old_client->ephemeral_page_list,
|
||||
&new_client->ephemeral_page_list);
|
||||
- printk("reassigned shared pool from %s=%d to %s=%d pool_id=%d\n",
|
||||
+ tmh_client_info("reassigned shared pool from %s=%d to %s=%d pool_id=%d\n",
|
||||
cli_id_str, old_client->cli_id, cli_id_str, new_client->cli_id, poolid);
|
||||
pool->pool_id = poolid;
|
||||
}
|
||||
@@ -1173,7 +1173,7 @@ static NOINLINE int shared_pool_quit(poo
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
- printk("tmem: no match unsharing pool, %s=%d\n",
|
||||
+ tmh_client_warn("tmem: no match unsharing pool, %s=%d\n",
|
||||
cli_id_str,pool->client->cli_id);
|
||||
return -1;
|
||||
}
|
||||
@@ -1184,17 +1184,18 @@ static void pool_flush(pool_t *pool, cli
|
||||
ASSERT(pool != NULL);
|
||||
if ( (is_shared(pool)) && (shared_pool_quit(pool,cli_id) > 0) )
|
||||
{
|
||||
- printk("tmem: %s=%d no longer using shared pool %d owned by %s=%d\n",
|
||||
+ tmh_client_warn("tmem: %s=%d no longer using shared pool %d owned by %s=%d\n",
|
||||
cli_id_str, cli_id, pool->pool_id, cli_id_str,pool->client->cli_id);
|
||||
return;
|
||||
}
|
||||
- printk("%s %s-%s tmem pool ",destroy?"destroying":"flushing",
|
||||
- is_persistent(pool) ? "persistent" : "ephemeral" ,
|
||||
- is_shared(pool) ? "shared" : "private");
|
||||
- printk("%s=%d pool_id=%d\n", cli_id_str,pool->client->cli_id,pool->pool_id);
|
||||
+ tmh_client_info("%s %s-%s tmem pool %s=%d pool_id=%d\n",
|
||||
+ destroy ? "destroying" : "flushing",
|
||||
+ is_persistent(pool) ? "persistent" : "ephemeral" ,
|
||||
+ is_shared(pool) ? "shared" : "private",
|
||||
+ cli_id_str, pool->client->cli_id, pool->pool_id);
|
||||
if ( pool->client->live_migrating )
|
||||
{
|
||||
- printk("can't %s pool while %s is live-migrating\n",
|
||||
+ tmh_client_warn("can't %s pool while %s is live-migrating\n",
|
||||
destroy?"destroy":"flush", client_str);
|
||||
return;
|
||||
}
|
||||
@@ -1213,21 +1214,22 @@ static client_t *client_create(cli_id_t
|
||||
client_t *client = tmh_alloc_infra(sizeof(client_t),__alignof__(client_t));
|
||||
int i;
|
||||
|
||||
- printk("tmem: initializing tmem capability for %s=%d...",cli_id_str,cli_id);
|
||||
+ tmh_client_info("tmem: initializing tmem capability for %s=%d...",
|
||||
+ cli_id_str, cli_id);
|
||||
if ( client == NULL )
|
||||
{
|
||||
- printk("failed... out of memory\n");
|
||||
+ tmh_client_err("failed... out of memory\n");
|
||||
goto fail;
|
||||
}
|
||||
memset(client,0,sizeof(client_t));
|
||||
if ( (client->tmh = tmh_client_init(cli_id)) == NULL )
|
||||
{
|
||||
- printk("failed... can't allocate host-dependent part of client\n");
|
||||
+ tmh_client_err("failed... can't allocate host-dependent part of client\n");
|
||||
goto fail;
|
||||
}
|
||||
if ( !tmh_set_client_from_id(client, client->tmh, cli_id) )
|
||||
{
|
||||
- printk("failed... can't set client\n");
|
||||
+ tmh_client_err("failed... can't set client\n");
|
||||
goto fail;
|
||||
}
|
||||
client->cli_id = cli_id;
|
||||
@@ -1249,7 +1251,7 @@ static client_t *client_create(cli_id_t
|
||||
client->eph_count = client->eph_count_max = 0;
|
||||
client->total_cycles = 0; client->succ_pers_puts = 0;
|
||||
client->succ_eph_gets = 0; client->succ_pers_gets = 0;
|
||||
- printk("ok\n");
|
||||
+ tmh_client_info("ok\n");
|
||||
return client;
|
||||
|
||||
fail:
|
||||
@@ -1903,32 +1905,33 @@ static NOINLINE int do_tmem_new_pool(cli
|
||||
cli_id = tmh_get_cli_id_from_current();
|
||||
else
|
||||
cli_id = this_cli_id;
|
||||
- printk("tmem: allocating %s-%s tmem pool for %s=%d...",
|
||||
+ tmh_client_info("tmem: allocating %s-%s tmem pool for %s=%d...",
|
||||
persistent ? "persistent" : "ephemeral" ,
|
||||
shared ? "shared" : "private", cli_id_str, cli_id);
|
||||
if ( specversion != TMEM_SPEC_VERSION )
|
||||
{
|
||||
- printk("failed... unsupported spec version\n");
|
||||
+ tmh_client_err("failed... unsupported spec version\n");
|
||||
return -EPERM;
|
||||
}
|
||||
if ( pagebits != (PAGE_SHIFT - 12) )
|
||||
{
|
||||
- printk("failed... unsupported pagesize %d\n",1<<(pagebits+12));
|
||||
+ tmh_client_err("failed... unsupported pagesize %d\n",
|
||||
+ 1 << (pagebits + 12));
|
||||
return -EPERM;
|
||||
}
|
||||
if ( flags & TMEM_POOL_PRECOMPRESSED )
|
||||
{
|
||||
- printk("failed... precompression flag set but unsupported\n");
|
||||
+ tmh_client_err("failed... precompression flag set but unsupported\n");
|
||||
return -EPERM;
|
||||
}
|
||||
if ( flags & TMEM_POOL_RESERVED_BITS )
|
||||
{
|
||||
- printk("failed... reserved bits must be zero\n");
|
||||
+ tmh_client_err("failed... reserved bits must be zero\n");
|
||||
return -EPERM;
|
||||
}
|
||||
if ( (pool = pool_alloc()) == NULL )
|
||||
{
|
||||
- printk("failed... out of memory\n");
|
||||
+ tmh_client_err("failed... out of memory\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
if ( this_cli_id != CLI_ID_NULL )
|
||||
@@ -1947,7 +1950,7 @@ static NOINLINE int do_tmem_new_pool(cli
|
||||
break;
|
||||
if ( d_poolid >= MAX_POOLS_PER_DOMAIN )
|
||||
{
|
||||
- printk("failed... no more pool slots available for this %s\n",
|
||||
+ tmh_client_err("failed... no more pool slots available for this %s\n",
|
||||
client_str);
|
||||
goto fail;
|
||||
}
|
||||
@@ -1977,9 +1980,8 @@ static NOINLINE int do_tmem_new_pool(cli
|
||||
{
|
||||
if ( shpool->uuid[0] == uuid_lo && shpool->uuid[1] == uuid_hi )
|
||||
{
|
||||
- printk("(matches shared pool uuid=%"PRIx64".%"PRIx64") ",
|
||||
- uuid_hi, uuid_lo);
|
||||
- printk("pool_id=%d\n",d_poolid);
|
||||
+ tmh_client_info("(matches shared pool uuid=%"PRIx64".%"PRIx64") pool_id=%d\n",
|
||||
+ uuid_hi, uuid_lo, d_poolid);
|
||||
client->pools[d_poolid] = global_shared_pools[s_poolid];
|
||||
shared_pool_join(global_shared_pools[s_poolid], client);
|
||||
pool_free(pool);
|
||||
@@ -1991,7 +1993,7 @@ static NOINLINE int do_tmem_new_pool(cli
|
||||
}
|
||||
if ( first_unused_s_poolid == MAX_GLOBAL_SHARED_POOLS )
|
||||
{
|
||||
- printk("tmem: failed... no global shared pool slots available\n");
|
||||
+ tmh_client_warn("tmem: failed... no global shared pool slots available\n");
|
||||
goto fail;
|
||||
}
|
||||
else
|
||||
@@ -2007,7 +2009,7 @@ static NOINLINE int do_tmem_new_pool(cli
|
||||
pool->pool_id = d_poolid;
|
||||
pool->persistent = persistent;
|
||||
pool->uuid[0] = uuid_lo; pool->uuid[1] = uuid_hi;
|
||||
- printk("pool_id=%d\n",d_poolid);
|
||||
+ tmh_client_info("pool_id=%d\n", d_poolid);
|
||||
return d_poolid;
|
||||
|
||||
fail:
|
||||
@@ -2030,14 +2032,15 @@ static int tmemc_freeze_pools(cli_id_t c
|
||||
{
|
||||
list_for_each_entry(client,&global_client_list,client_list)
|
||||
client_freeze(client,freeze);
|
||||
- printk("tmem: all pools %s for all %ss\n",s,client_str);
|
||||
+ tmh_client_info("tmem: all pools %s for all %ss\n", s, client_str);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( (client = tmh_client_from_cli_id(cli_id)) == NULL)
|
||||
return -1;
|
||||
client_freeze(client,freeze);
|
||||
- printk("tmem: all pools %s for %s=%d\n",s,cli_id_str,cli_id);
|
||||
+ tmh_client_info("tmem: all pools %s for %s=%d\n",
|
||||
+ s, cli_id_str, cli_id);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -2048,7 +2051,7 @@ static int tmemc_flush_mem(cli_id_t cli_
|
||||
|
||||
if ( cli_id != CLI_ID_NULL )
|
||||
{
|
||||
- printk("tmem: %s-specific flush not supported yet, use --all\n",
|
||||
+ tmh_client_warn("tmem: %s-specific flush not supported yet, use --all\n",
|
||||
client_str);
|
||||
return -1;
|
||||
}
|
||||
@@ -2261,13 +2264,15 @@ static int tmemc_set_var_one(client_t *c
|
||||
case TMEMC_SET_WEIGHT:
|
||||
old_weight = client->weight;
|
||||
client->weight = arg1;
|
||||
- printk("tmem: weight set to %d for %s=%d\n",arg1,cli_id_str,cli_id);
|
||||
+ tmh_client_info("tmem: weight set to %d for %s=%d\n",
|
||||
+ arg1, cli_id_str, cli_id);
|
||||
atomic_sub(old_weight,&client_weight_total);
|
||||
atomic_add(client->weight,&client_weight_total);
|
||||
break;
|
||||
case TMEMC_SET_CAP:
|
||||
client->cap = arg1;
|
||||
- printk("tmem: cap set to %d for %s=%d\n",arg1,cli_id_str,cli_id);
|
||||
+ tmh_client_info("tmem: cap set to %d for %s=%d\n",
|
||||
+ arg1, cli_id_str, cli_id);
|
||||
break;
|
||||
case TMEMC_SET_COMPRESS:
|
||||
#ifdef __i386__
|
||||
@@ -2275,17 +2280,17 @@ static int tmemc_set_var_one(client_t *c
|
||||
#endif
|
||||
if ( tmh_dedup_enabled() )
|
||||
{
|
||||
- printk("tmem: compression %s for all %ss, cannot be changed "
|
||||
- "when tmem_dedup is enabled\n",
|
||||
- tmh_compression_enabled() ? "enabled" : "disabled",client_str);
|
||||
+ tmh_client_warn("tmem: compression %s for all %ss, cannot be changed when tmem_dedup is enabled\n",
|
||||
+ tmh_compression_enabled() ? "enabled" : "disabled",
|
||||
+ client_str);
|
||||
return -1;
|
||||
}
|
||||
client->compress = arg1 ? 1 : 0;
|
||||
- printk("tmem: compression %s for %s=%d\n",
|
||||
+ tmh_client_info("tmem: compression %s for %s=%d\n",
|
||||
arg1 ? "enabled" : "disabled",cli_id_str,cli_id);
|
||||
break;
|
||||
default:
|
||||
- printk("tmem: unknown subop %d for tmemc_set_var\n",subop);
|
||||
+ tmh_client_warn("tmem: unknown subop %d for tmemc_set_var\n", subop);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
@@ -2668,7 +2673,7 @@ EXPORT long do_tmem_op(tmem_cli_op_t uop
|
||||
|
||||
if ( unlikely(tmh_get_tmemop_from_client(&op, uops) != 0) )
|
||||
{
|
||||
- printk("tmem: can't get tmem struct from %s\n",client_str);
|
||||
+ tmh_client_err("tmem: can't get tmem struct from %s\n", client_str);
|
||||
rc = -EFAULT;
|
||||
if ( !tmh_lock_all )
|
||||
goto simple_error;
|
||||
@@ -2702,7 +2707,8 @@ EXPORT long do_tmem_op(tmem_cli_op_t uop
|
||||
tmem_write_lock_set = 1;
|
||||
if ( (client = client_create(tmh_get_cli_id_from_current())) == NULL )
|
||||
{
|
||||
- printk("tmem: can't create tmem structure for %s\n",client_str);
|
||||
+ tmh_client_err("tmem: can't create tmem structure for %s\n",
|
||||
+ client_str);
|
||||
rc = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
@@ -2726,8 +2732,8 @@ EXPORT long do_tmem_op(tmem_cli_op_t uop
|
||||
if ( ((uint32_t)op.pool_id >= MAX_POOLS_PER_DOMAIN) ||
|
||||
((pool = client->pools[op.pool_id]) == NULL) )
|
||||
{
|
||||
+ tmh_client_err("tmem: operation requested on uncreated pool\n");
|
||||
rc = -ENODEV;
|
||||
- printk("tmem: operation requested on uncreated pool\n");
|
||||
goto out;
|
||||
}
|
||||
ASSERT_SENTINEL(pool,POOL);
|
||||
@@ -2783,11 +2789,11 @@ EXPORT long do_tmem_op(tmem_cli_op_t uop
|
||||
break;
|
||||
case TMEM_XCHG:
|
||||
/* need to hold global lock to ensure xchg is atomic */
|
||||
- printk("tmem_xchg op not implemented yet\n");
|
||||
+ tmh_client_warn("tmem_xchg op not implemented yet\n");
|
||||
rc = 0;
|
||||
break;
|
||||
default:
|
||||
- printk("tmem: op %d not implemented\n", op.cmd);
|
||||
+ tmh_client_warn("tmem: op %d not implemented\n", op.cmd);
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
--- a/xen/include/xen/tmem_xen.h
|
||||
+++ b/xen/include/xen/tmem_xen.h
|
||||
@@ -512,6 +512,9 @@ int tmh_copy_to_client(tmem_cli_mfn_t, p
|
||||
|
||||
extern int tmh_copy_tze_to_client(tmem_cli_mfn_t cmfn, void *tmem_va, pagesize_t len);
|
||||
|
||||
+#define tmh_client_err(fmt, args...) printk(XENLOG_G_ERR fmt, ##args)
|
||||
+#define tmh_client_warn(fmt, args...) printk(XENLOG_G_WARNING fmt, ##args)
|
||||
+#define tmh_client_info(fmt, args...) printk(XENLOG_G_INFO fmt, ##args)
|
||||
|
||||
#define TMEM_PERF
|
||||
#ifdef TMEM_PERF
|
41
25859-tmem-missing-break.patch
Normal file
41
25859-tmem-missing-break.patch
Normal file
@ -0,0 +1,41 @@
|
||||
# HG changeset patch
|
||||
# User Dan Magenheimer <dan.magenheimer@oracle.com>
|
||||
# Date 1347365943 -7200
|
||||
# Node ID 16e0392c6594b1757bbaa82076630a73d843229b
|
||||
# Parent 0520982a602a3ac06dd5bc573ddaff5edc9c6987
|
||||
tmem: fixup 2010 cleanup patch that breaks tmem save/restore
|
||||
|
||||
20918:a3fa6d444b25 "Fix domain reference leaks" (in Feb 2010, by Jan)
|
||||
does some cleanup in addition to the leak fixes. Unfortunately, that
|
||||
cleanup inadvertently resulted in an incorrect fallthrough in a switch
|
||||
statement which breaks tmem save/restore.
|
||||
|
||||
That broken patch was apparently applied to 4.0-testing and 4.1-testing
|
||||
so those are broken as well.
|
||||
|
||||
What is the process now for requesting back-patches to 4.0 and 4.1?
|
||||
|
||||
(Side note: This does not by itself entirely fix save/restore in 4.2.)
|
||||
|
||||
Signed-off-by: Dan Magenheimer <dan.magenheimer@oracle.com>
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Committed-by: Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
--- a/xen/common/tmem.c
|
||||
+++ b/xen/common/tmem.c
|
||||
@@ -2419,6 +2419,7 @@ static NOINLINE int tmemc_save_subop(int
|
||||
break;
|
||||
tmh_copy_to_client_buf(buf, pool->uuid, 2);
|
||||
rc = 0;
|
||||
+ break;
|
||||
case TMEMC_SAVE_END:
|
||||
if ( client == NULL )
|
||||
break;
|
||||
@@ -2429,6 +2430,7 @@ static NOINLINE int tmemc_save_subop(int
|
||||
pgp_free_from_inv_list(client,pgp);
|
||||
client->frozen = client->was_frozen;
|
||||
rc = 0;
|
||||
+ break;
|
||||
}
|
||||
return rc;
|
||||
}
|
106
25860-tmem-cleanup.patch
Normal file
106
25860-tmem-cleanup.patch
Normal file
@ -0,0 +1,106 @@
|
||||
# HG changeset patch
|
||||
# User Jan Beulich <jbeulich@suse.com>
|
||||
# Date 1347365969 -7200
|
||||
# Node ID e4cb8411161043c726f699252cc761e77853e820
|
||||
# Parent 16e0392c6594b1757bbaa82076630a73d843229b
|
||||
tmem: cleanup
|
||||
|
||||
- one more case of checking for a specific rather than any error
|
||||
- drop no longer needed first parameter from cli_put_page()
|
||||
- drop a redundant cast
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Dan Magenheimer <dan.magenheimer@oracle.com>
|
||||
|
||||
--- a/xen/common/tmem.c
|
||||
+++ b/xen/common/tmem.c
|
||||
@@ -1468,7 +1468,7 @@ static NOINLINE int do_tmem_put_compress
|
||||
pgp_free_data(pgp, pgp->us.obj->pool);
|
||||
START_CYC_COUNTER(compress);
|
||||
ret = tmh_compress_from_client(cmfn, &dst, &size, clibuf);
|
||||
- if ( (ret == -EFAULT) || (ret == 0) )
|
||||
+ if ( ret <= 0 )
|
||||
goto out;
|
||||
else if ( (size == 0) || (size >= tmem_subpage_maxsize()) ) {
|
||||
ret = 0;
|
||||
--- a/xen/common/tmem_xen.c
|
||||
+++ b/xen/common/tmem_xen.c
|
||||
@@ -97,7 +97,7 @@ static inline void *cli_get_page(tmem_cl
|
||||
return NULL;
|
||||
}
|
||||
|
||||
-static inline void cli_put_page(tmem_cli_mfn_t cmfn, void *cli_va, pfp_t *cli_pfp,
|
||||
+static inline void cli_put_page(void *cli_va, pfp_t *cli_pfp,
|
||||
unsigned long cli_mfn, bool_t mark_dirty)
|
||||
{
|
||||
ASSERT(0);
|
||||
@@ -126,20 +126,20 @@ static inline void *cli_get_page(tmem_cl
|
||||
}
|
||||
|
||||
*pcli_mfn = page_to_mfn(page);
|
||||
- *pcli_pfp = (pfp_t *)page;
|
||||
+ *pcli_pfp = page;
|
||||
return map_domain_page(*pcli_mfn);
|
||||
}
|
||||
|
||||
-static inline void cli_put_page(tmem_cli_mfn_t cmfn, void *cli_va, pfp_t *cli_pfp,
|
||||
+static inline void cli_put_page(void *cli_va, pfp_t *cli_pfp,
|
||||
unsigned long cli_mfn, bool_t mark_dirty)
|
||||
{
|
||||
if ( mark_dirty )
|
||||
{
|
||||
- put_page_and_type((struct page_info *)cli_pfp);
|
||||
+ put_page_and_type(cli_pfp);
|
||||
paging_mark_dirty(current->domain,cli_mfn);
|
||||
}
|
||||
else
|
||||
- put_page((struct page_info *)cli_pfp);
|
||||
+ put_page(cli_pfp);
|
||||
unmap_domain_page(cli_va);
|
||||
}
|
||||
#endif
|
||||
@@ -188,7 +188,7 @@ EXPORT int tmh_copy_from_client(pfp_t *p
|
||||
else if ( len )
|
||||
rc = -EINVAL;
|
||||
if ( cli_va )
|
||||
- cli_put_page(cmfn, cli_va, cli_pfp, cli_mfn, 0);
|
||||
+ cli_put_page(cli_va, cli_pfp, cli_mfn, 0);
|
||||
unmap_domain_page(tmem_va);
|
||||
return rc;
|
||||
}
|
||||
@@ -221,7 +221,7 @@ EXPORT int tmh_compress_from_client(tmem
|
||||
ASSERT(ret == LZO_E_OK);
|
||||
*out_va = dmem;
|
||||
if ( cli_va )
|
||||
- cli_put_page(cmfn, cli_va, cli_pfp, cli_mfn, 0);
|
||||
+ cli_put_page(cli_va, cli_pfp, cli_mfn, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -259,7 +259,7 @@ EXPORT int tmh_copy_to_client(tmem_cli_m
|
||||
rc = -EINVAL;
|
||||
unmap_domain_page(tmem_va);
|
||||
if ( cli_va )
|
||||
- cli_put_page(cmfn, cli_va, cli_pfp, cli_mfn, 1);
|
||||
+ cli_put_page(cli_va, cli_pfp, cli_mfn, 1);
|
||||
mb();
|
||||
return rc;
|
||||
}
|
||||
@@ -286,7 +286,7 @@ EXPORT int tmh_decompress_to_client(tmem
|
||||
ASSERT(ret == LZO_E_OK);
|
||||
ASSERT(out_len == PAGE_SIZE);
|
||||
if ( cli_va )
|
||||
- cli_put_page(cmfn, cli_va, cli_pfp, cli_mfn, 1);
|
||||
+ cli_put_page(cli_va, cli_pfp, cli_mfn, 1);
|
||||
else if ( copy_to_guest(clibuf, scratch, PAGE_SIZE) )
|
||||
return -EFAULT;
|
||||
mb();
|
||||
@@ -310,7 +310,7 @@ EXPORT int tmh_copy_tze_to_client(tmem_c
|
||||
memcpy((char *)cli_va,(char *)tmem_va,len);
|
||||
if ( len < PAGE_SIZE )
|
||||
memset((char *)cli_va+len,0,PAGE_SIZE-len);
|
||||
- cli_put_page(cmfn, cli_va, cli_pfp, cli_mfn, 1);
|
||||
+ cli_put_page(cli_va, cli_pfp, cli_mfn, 1);
|
||||
mb();
|
||||
return 1;
|
||||
}
|
218
25861-x86-early-fixmap.patch
Normal file
218
25861-x86-early-fixmap.patch
Normal file
@ -0,0 +1,218 @@
|
||||
# HG changeset patch
|
||||
# User Jan Beulich <jbeulich@suse.com>
|
||||
# Date 1347371120 -7200
|
||||
# Node ID 51c2d7c83cbc2a0357ce112a463f91d354dcdba9
|
||||
# Parent e4cb8411161043c726f699252cc761e77853e820
|
||||
x86: allow early use of fixmaps
|
||||
|
||||
As a prerequisite for adding an EHCI debug port based console
|
||||
implementation, set up the page tables needed for (a sub-portion of)
|
||||
the fixmaps together with other boot time page table construction.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Keir Fraser <keir@xen.org>
|
||||
|
||||
--- a/xen/arch/x86/boot/head.S
|
||||
+++ b/xen/arch/x86/boot/head.S
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <public/xen.h>
|
||||
#include <asm/asm_defns.h>
|
||||
#include <asm/desc.h>
|
||||
+#include <asm/fixmap.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/msr.h>
|
||||
|
||||
@@ -136,6 +137,9 @@ __start:
|
||||
add $8,%edx
|
||||
add $(1<<L2_PAGETABLE_SHIFT),%eax
|
||||
loop 1b
|
||||
+ /* Initialise L2 fixmap page directory entry. */
|
||||
+ mov $(sym_phys(l1_fixmap)+7),%eax
|
||||
+ mov %eax,sym_phys(l2_fixmap) + l2_table_offset(FIXADDR_TOP-1)*8
|
||||
/* Initialise L3 identity-map page directory entries. */
|
||||
mov $sym_phys(l3_identmap),%edi
|
||||
mov $(sym_phys(l2_identmap)+7),%eax
|
||||
@@ -144,9 +148,11 @@ __start:
|
||||
add $8,%edi
|
||||
add $PAGE_SIZE,%eax
|
||||
loop 1b
|
||||
- /* Initialise L3 xen-map page directory entry. */
|
||||
+ /* Initialise L3 xen-map and fixmap page directory entries. */
|
||||
mov $(sym_phys(l2_xenmap)+7),%eax
|
||||
mov %eax,sym_phys(l3_xenmap) + l3_table_offset(XEN_VIRT_START)*8
|
||||
+ mov $(sym_phys(l2_fixmap)+7),%eax
|
||||
+ mov %eax,sym_phys(l3_xenmap) + l3_table_offset(FIXADDR_TOP-1)*8
|
||||
/* Initialise L3 boot-map page directory entry. */
|
||||
mov $(sym_phys(l2_bootmap)+7),%eax
|
||||
mov %eax,sym_phys(l3_bootmap) + 0*8
|
||||
@@ -172,6 +178,9 @@ __start:
|
||||
add $(1<<L2_PAGETABLE_SHIFT),%eax
|
||||
cmp $(16<<20)+0xe3,%eax
|
||||
jne 1b
|
||||
+ /* Initialise L2 fixmap page directory entry. */
|
||||
+ mov $(sym_phys(l1_fixmap)+7),%eax
|
||||
+ mov %eax,sym_phys(idle_pg_table_l2) + l2_table_offset(FIXADDR_TOP-1)*8
|
||||
#endif
|
||||
|
||||
/* Initialize 4kB mappings of first 2MB or 4MB of memory. */
|
||||
--- a/xen/arch/x86/efi/boot.c
|
||||
+++ b/xen/arch/x86/efi/boot.c
|
||||
@@ -17,6 +17,9 @@
|
||||
#include <xen/vga.h>
|
||||
#include <asm/e820.h>
|
||||
#include <asm/edd.h>
|
||||
+#define __ASSEMBLY__ /* avoid pulling in ACPI stuff (conflicts with EFI) */
|
||||
+#include <asm/fixmap.h>
|
||||
+#undef __ASSEMBLY__
|
||||
#include <asm/mm.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/processor.h>
|
||||
@@ -1123,14 +1126,19 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SY
|
||||
slot &= L2_PAGETABLE_ENTRIES - 1;
|
||||
l2_bootmap[slot] = l2e_from_paddr(addr, __PAGE_HYPERVISOR|_PAGE_PSE);
|
||||
}
|
||||
+ /* Initialise L2 fixmap page directory entry. */
|
||||
+ l2_fixmap[l2_table_offset(FIXADDR_TOP - 1)] =
|
||||
+ l2e_from_paddr((UINTN)l1_fixmap, __PAGE_HYPERVISOR);
|
||||
/* Initialise L3 identity-map page directory entries. */
|
||||
for ( i = 0; i < ARRAY_SIZE(l2_identmap) / L2_PAGETABLE_ENTRIES; ++i )
|
||||
l3_identmap[i] = l3e_from_paddr((UINTN)(l2_identmap +
|
||||
i * L2_PAGETABLE_ENTRIES),
|
||||
__PAGE_HYPERVISOR);
|
||||
- /* Initialise L3 xen-map page directory entry. */
|
||||
+ /* Initialise L3 xen-map and fixmap page directory entries. */
|
||||
l3_xenmap[l3_table_offset(XEN_VIRT_START)] =
|
||||
l3e_from_paddr((UINTN)l2_xenmap, __PAGE_HYPERVISOR);
|
||||
+ l3_xenmap[l3_table_offset(FIXADDR_TOP - 1)] =
|
||||
+ l3e_from_paddr((UINTN)l2_fixmap, __PAGE_HYPERVISOR);
|
||||
/* Initialise L3 boot-map page directory entries. */
|
||||
l3_bootmap[l3_table_offset(xen_phys_start)] =
|
||||
l3e_from_paddr((UINTN)l2_bootmap, __PAGE_HYPERVISOR);
|
||||
--- a/xen/arch/x86/mm.c
|
||||
+++ b/xen/arch/x86/mm.c
|
||||
@@ -130,6 +130,10 @@
|
||||
l1_pgentry_t __attribute__ ((__section__ (".bss.page_aligned")))
|
||||
l1_identmap[L1_PAGETABLE_ENTRIES];
|
||||
|
||||
+/* Mapping of the fixmap space needed early. */
|
||||
+l1_pgentry_t __attribute__ ((__section__ (".bss.page_aligned")))
|
||||
+ l1_fixmap[L1_PAGETABLE_ENTRIES];
|
||||
+
|
||||
#define MEM_LOG(_f, _a...) gdprintk(XENLOG_WARNING , _f "\n" , ## _a)
|
||||
|
||||
/*
|
||||
--- a/xen/arch/x86/x86_64/mm.c
|
||||
+++ b/xen/arch/x86/x86_64/mm.c
|
||||
@@ -65,6 +65,10 @@ l3_pgentry_t __attribute__ ((__section__
|
||||
l2_pgentry_t __attribute__ ((__section__ (".bss.page_aligned")))
|
||||
l2_xenmap[L2_PAGETABLE_ENTRIES];
|
||||
|
||||
+/* Enough page directories to map the early fixmap space. */
|
||||
+l2_pgentry_t __attribute__ ((__section__ (".bss.page_aligned")))
|
||||
+ l2_fixmap[L2_PAGETABLE_ENTRIES];
|
||||
+
|
||||
/* Enough page directories to map into the bottom 1GB. */
|
||||
l3_pgentry_t __attribute__ ((__section__ (".bss.page_aligned")))
|
||||
l3_bootmap[L3_PAGETABLE_ENTRIES];
|
||||
--- a/xen/include/asm-x86/config.h
|
||||
+++ b/xen/include/asm-x86/config.h
|
||||
@@ -315,7 +315,7 @@ extern unsigned char boot_edid_info[128]
|
||||
#define MACHPHYS_MBYTES 16 /* 1 MB needed per 1 GB memory */
|
||||
#define FRAMETABLE_MBYTES (MACHPHYS_MBYTES * 6)
|
||||
|
||||
-#define IOREMAP_VIRT_END 0UL
|
||||
+#define IOREMAP_VIRT_END _AC(0,UL)
|
||||
#define IOREMAP_VIRT_START (IOREMAP_VIRT_END - (IOREMAP_MBYTES<<20))
|
||||
#define DIRECTMAP_VIRT_END IOREMAP_VIRT_START
|
||||
#define DIRECTMAP_VIRT_START (DIRECTMAP_VIRT_END - (DIRECTMAP_MBYTES<<20))
|
||||
--- a/xen/include/asm-x86/fixmap.h
|
||||
+++ b/xen/include/asm-x86/fixmap.h
|
||||
@@ -13,12 +13,17 @@
|
||||
#define _ASM_FIXMAP_H
|
||||
|
||||
#include <xen/config.h>
|
||||
+#include <asm/page.h>
|
||||
+
|
||||
+#define FIXADDR_TOP (IOREMAP_VIRT_END - PAGE_SIZE)
|
||||
+
|
||||
+#ifndef __ASSEMBLY__
|
||||
+
|
||||
#include <xen/pfn.h>
|
||||
#include <xen/kexec.h>
|
||||
#include <xen/iommu.h>
|
||||
#include <asm/apicdef.h>
|
||||
#include <asm/acpi.h>
|
||||
-#include <asm/page.h>
|
||||
#include <asm/amd-iommu.h>
|
||||
#include <asm/msi.h>
|
||||
#include <acpi/apei.h>
|
||||
@@ -66,7 +71,6 @@ enum fixed_addresses {
|
||||
__end_of_fixed_addresses
|
||||
};
|
||||
|
||||
-#define FIXADDR_TOP (IOREMAP_VIRT_END - PAGE_SIZE)
|
||||
#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
|
||||
#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
|
||||
|
||||
@@ -90,4 +94,6 @@ static inline unsigned long virt_to_fix(
|
||||
return __virt_to_fix(vaddr);
|
||||
}
|
||||
|
||||
+#endif /* __ASSEMBLY__ */
|
||||
+
|
||||
#endif
|
||||
--- a/xen/include/asm-x86/page.h
|
||||
+++ b/xen/include/asm-x86/page.h
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef __X86_PAGE_H__
|
||||
#define __X86_PAGE_H__
|
||||
|
||||
+#include <xen/const.h>
|
||||
+
|
||||
/*
|
||||
* It is important that the masks are signed quantities. This ensures that
|
||||
* the compiler sign-extends a 32-bit mask to 64 bits if that is required.
|
||||
@@ -306,13 +308,15 @@ extern l2_pgentry_t idle_pg_table_l2[
|
||||
extern l2_pgentry_t *compat_idle_pg_table_l2;
|
||||
extern unsigned int m2p_compat_vstart;
|
||||
extern l2_pgentry_t l2_xenmap[L2_PAGETABLE_ENTRIES],
|
||||
+ l2_fixmap[L2_PAGETABLE_ENTRIES],
|
||||
l2_bootmap[L2_PAGETABLE_ENTRIES];
|
||||
extern l3_pgentry_t l3_xenmap[L3_PAGETABLE_ENTRIES],
|
||||
l3_identmap[L3_PAGETABLE_ENTRIES],
|
||||
l3_bootmap[L3_PAGETABLE_ENTRIES];
|
||||
#endif
|
||||
extern l2_pgentry_t l2_identmap[4*L2_PAGETABLE_ENTRIES];
|
||||
-extern l1_pgentry_t l1_identmap[L1_PAGETABLE_ENTRIES];
|
||||
+extern l1_pgentry_t l1_identmap[L1_PAGETABLE_ENTRIES],
|
||||
+ l1_fixmap[L1_PAGETABLE_ENTRIES];
|
||||
void paging_init(void);
|
||||
void setup_idle_pagetable(void);
|
||||
#endif /* !defined(__ASSEMBLY__) */
|
||||
--- /dev/null
|
||||
+++ b/xen/include/xen/const.h
|
||||
@@ -0,0 +1,24 @@
|
||||
+/* const.h: Macros for dealing with constants. */
|
||||
+
|
||||
+#ifndef __XEN_CONST_H__
|
||||
+#define __XEN_CONST_H__
|
||||
+
|
||||
+/* Some constant macros are used in both assembler and
|
||||
+ * C code. Therefore we cannot annotate them always with
|
||||
+ * 'UL' and other type specifiers unilaterally. We
|
||||
+ * use the following macros to deal with this.
|
||||
+ *
|
||||
+ * Similarly, _AT() will cast an expression with a type in C, but
|
||||
+ * leave it unchanged in asm.
|
||||
+ */
|
||||
+
|
||||
+#ifdef __ASSEMBLY__
|
||||
+#define _AC(X,Y) X
|
||||
+#define _AT(T,X) X
|
||||
+#else
|
||||
+#define __AC(X,Y) (X##Y)
|
||||
+#define _AC(X,Y) __AC(X,Y)
|
||||
+#define _AT(T,X) ((T)(X))
|
||||
+#endif
|
||||
+
|
||||
+#endif /* __XEN_CONST_H__ */
|
144
25862-sercon-non-com.patch
Normal file
144
25862-sercon-non-com.patch
Normal file
@ -0,0 +1,144 @@
|
||||
# HG changeset patch
|
||||
# User Jan Beulich <jbeulich@suse.com>
|
||||
# Date 1347371236 -7200
|
||||
# Node ID 776a23fa0e938e4cf3307fc2e3b3f1a9488a5927
|
||||
# Parent 51c2d7c83cbc2a0357ce112a463f91d354dcdba9
|
||||
console: prepare for non-COMn port support
|
||||
|
||||
Widen SERHND_IDX (and use it where needed), introduce a flush low level
|
||||
driver method, and remove unnecessary peeking of the common code at the
|
||||
(driver specific) serial port identification string in the "console="
|
||||
command line option value.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Keir Fraser <keir@xen.org>
|
||||
|
||||
--- a/xen/arch/x86/smpboot.c
|
||||
+++ b/xen/arch/x86/smpboot.c
|
||||
@@ -1017,7 +1017,7 @@ void __init smp_intr_init(void)
|
||||
* Also ensure serial interrupts are high priority. We do not
|
||||
* want them to be blocked by unacknowledged guest-bound interrupts.
|
||||
*/
|
||||
- for ( seridx = 0; seridx < 2; seridx++ )
|
||||
+ for ( seridx = 0; seridx <= SERHND_IDX; seridx++ )
|
||||
{
|
||||
if ( (irq = serial_irq(seridx)) < 0 )
|
||||
continue;
|
||||
--- a/xen/drivers/char/console.c
|
||||
+++ b/xen/drivers/char/console.c
|
||||
@@ -539,6 +539,7 @@ void printk(const char *fmt, ...)
|
||||
void __init console_init_preirq(void)
|
||||
{
|
||||
char *p;
|
||||
+ int sh;
|
||||
|
||||
serial_init_preirq();
|
||||
|
||||
@@ -551,8 +552,9 @@ void __init console_init_preirq(void)
|
||||
vga_init();
|
||||
else if ( !strncmp(p, "none", 4) )
|
||||
continue;
|
||||
- else if ( strncmp(p, "com", 3) ||
|
||||
- (sercon_handle = serial_parse_handle(p)) == -1 )
|
||||
+ else if ( (sh = serial_parse_handle(p)) >= 0 )
|
||||
+ sercon_handle = sh;
|
||||
+ else
|
||||
{
|
||||
char *q = strchr(p, ',');
|
||||
if ( q != NULL )
|
||||
--- a/xen/drivers/char/serial.c
|
||||
+++ b/xen/drivers/char/serial.c
|
||||
@@ -22,9 +22,11 @@ size_param("serial_tx_buffer", serial_tx
|
||||
#define mask_serial_rxbuf_idx(_i) ((_i)&(serial_rxbufsz-1))
|
||||
#define mask_serial_txbuf_idx(_i) ((_i)&(serial_txbufsz-1))
|
||||
|
||||
-static struct serial_port com[2] = {
|
||||
- { .rx_lock = SPIN_LOCK_UNLOCKED, .tx_lock = SPIN_LOCK_UNLOCKED },
|
||||
- { .rx_lock = SPIN_LOCK_UNLOCKED, .tx_lock = SPIN_LOCK_UNLOCKED }
|
||||
+static struct serial_port com[SERHND_IDX + 1] = {
|
||||
+ [0 ... SERHND_IDX] = {
|
||||
+ .rx_lock = SPIN_LOCK_UNLOCKED,
|
||||
+ .tx_lock = SPIN_LOCK_UNLOCKED
|
||||
+ }
|
||||
};
|
||||
|
||||
void serial_rx_interrupt(struct serial_port *port, struct cpu_user_regs *regs)
|
||||
@@ -81,6 +83,8 @@ void serial_tx_interrupt(struct serial_p
|
||||
port->driver->putc(
|
||||
port, port->txbuf[mask_serial_txbuf_idx(port->txbufc++)]);
|
||||
}
|
||||
+ if ( i && port->driver->flush )
|
||||
+ port->driver->flush(port);
|
||||
}
|
||||
|
||||
spin_unlock(&port->tx_lock);
|
||||
@@ -175,6 +179,9 @@ void serial_putc(int handle, char c)
|
||||
|
||||
__serial_putc(port, c);
|
||||
|
||||
+ if ( port->driver->flush )
|
||||
+ port->driver->flush(port);
|
||||
+
|
||||
spin_unlock_irqrestore(&port->tx_lock, flags);
|
||||
}
|
||||
|
||||
@@ -206,6 +213,9 @@ void serial_puts(int handle, const char
|
||||
__serial_putc(port, c);
|
||||
}
|
||||
|
||||
+ if ( port->driver->flush )
|
||||
+ port->driver->flush(port);
|
||||
+
|
||||
spin_unlock_irqrestore(&port->tx_lock, flags);
|
||||
}
|
||||
|
||||
@@ -261,10 +271,10 @@ int __init serial_parse_handle(char *con
|
||||
switch ( conf[3] )
|
||||
{
|
||||
case '1':
|
||||
- handle = 0;
|
||||
+ handle = SERHND_COM1;
|
||||
break;
|
||||
case '2':
|
||||
- handle = 1;
|
||||
+ handle = SERHND_COM2;
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
@@ -365,6 +375,8 @@ void serial_start_sync(int handle)
|
||||
port->driver->putc(
|
||||
port, port->txbuf[mask_serial_txbuf_idx(port->txbufc++)]);
|
||||
}
|
||||
+ if ( port->driver->flush )
|
||||
+ port->driver->flush(port);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&port->tx_lock, flags);
|
||||
--- a/xen/include/xen/serial.h
|
||||
+++ b/xen/include/xen/serial.h
|
||||
@@ -60,6 +60,8 @@ struct uart_driver {
|
||||
int (*tx_empty)(struct serial_port *);
|
||||
/* Put a character onto the serial line. */
|
||||
void (*putc)(struct serial_port *, char);
|
||||
+ /* Flush accumulated characters. */
|
||||
+ void (*flush)(struct serial_port *);
|
||||
/* Get a character from the serial line: returns 0 if none available. */
|
||||
int (*getc)(struct serial_port *, char *);
|
||||
/* Get IRQ number for this port's serial line: returns -1 if none. */
|
||||
@@ -67,10 +69,12 @@ struct uart_driver {
|
||||
};
|
||||
|
||||
/* 'Serial handles' are composed from the following fields. */
|
||||
-#define SERHND_IDX (1<<0) /* COM1 or COM2? */
|
||||
-#define SERHND_HI (1<<1) /* Mux/demux each transferred char by MSB. */
|
||||
-#define SERHND_LO (1<<2) /* Ditto, except that the MSB is cleared. */
|
||||
-#define SERHND_COOKED (1<<3) /* Newline/carriage-return translation? */
|
||||
+#define SERHND_IDX (3<<0) /* COM1 or COM2? */
|
||||
+# define SERHND_COM1 (0<<0)
|
||||
+# define SERHND_COM2 (1<<0)
|
||||
+#define SERHND_HI (1<<2) /* Mux/demux each transferred char by MSB. */
|
||||
+#define SERHND_LO (1<<3) /* Ditto, except that the MSB is cleared. */
|
||||
+#define SERHND_COOKED (1<<4) /* Newline/carriage-return translation? */
|
||||
|
||||
/* Two-stage initialisation (before/after IRQ-subsystem initialisation). */
|
||||
void serial_init_preirq(void);
|
1778
25863-sercon-ehci-dbgp.patch
Normal file
1778
25863-sercon-ehci-dbgp.patch
Normal file
File diff suppressed because it is too large
Load Diff
142
25864-sercon-unused.patch
Normal file
142
25864-sercon-unused.patch
Normal file
@ -0,0 +1,142 @@
|
||||
# HG changeset patch
|
||||
# User Jan Beulich <jbeulich@suse.com>
|
||||
# Date 1347371512 -7200
|
||||
# Node ID e1380b5311ccee14eb47d7badb75339933d42249
|
||||
# Parent 0d0c55a1975db9c6cac2e9259b5ebea7a7bdbaec
|
||||
serial: avoid fully initializing unused consoles
|
||||
|
||||
Defer calling the drivers' post-IRQ initialization functions (generally
|
||||
doing allocation of transmit buffers) until it is known that the
|
||||
respective console is actually going to be used.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Keir Fraser <keir@xen.org>
|
||||
|
||||
--- a/xen/drivers/char/ehci-dbgp.c
|
||||
+++ b/xen/drivers/char/ehci-dbgp.c
|
||||
@@ -1391,7 +1391,8 @@ static int ehci_dbgp_check_release(struc
|
||||
printk(XENLOG_INFO "Releasing EHCI debug port at %02x:%02x.%u\n",
|
||||
dbgp->bus, dbgp->slot, dbgp->func);
|
||||
|
||||
- kill_timer(&dbgp->timer);
|
||||
+ if ( dbgp->timer.function )
|
||||
+ kill_timer(&dbgp->timer);
|
||||
dbgp->ehci_debug = NULL;
|
||||
|
||||
ctrl = readl(&ehci_debug->control);
|
||||
--- a/xen/drivers/char/serial.c
|
||||
+++ b/xen/drivers/char/serial.c
|
||||
@@ -29,6 +29,8 @@ static struct serial_port com[SERHND_IDX
|
||||
}
|
||||
};
|
||||
|
||||
+static bool_t __read_mostly post_irq;
|
||||
+
|
||||
void serial_rx_interrupt(struct serial_port *port, struct cpu_user_regs *regs)
|
||||
{
|
||||
char c;
|
||||
@@ -263,14 +265,12 @@ char serial_getc(int handle)
|
||||
|
||||
int __init serial_parse_handle(char *conf)
|
||||
{
|
||||
- int handle;
|
||||
+ int handle, flags = 0;
|
||||
|
||||
if ( !strncmp(conf, "dbgp", 4) && (!conf[4] || conf[4] == ',') )
|
||||
{
|
||||
- if ( !com[SERHND_DBGP].driver )
|
||||
- goto fail;
|
||||
-
|
||||
- return SERHND_DBGP | SERHND_COOKED;
|
||||
+ handle = SERHND_DBGP;
|
||||
+ goto common;
|
||||
}
|
||||
|
||||
if ( strncmp(conf, "com", 3) )
|
||||
@@ -288,17 +288,25 @@ int __init serial_parse_handle(char *con
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- if ( !com[handle].driver )
|
||||
- goto fail;
|
||||
-
|
||||
if ( conf[4] == 'H' )
|
||||
- handle |= SERHND_HI;
|
||||
+ flags |= SERHND_HI;
|
||||
else if ( conf[4] == 'L' )
|
||||
- handle |= SERHND_LO;
|
||||
+ flags |= SERHND_LO;
|
||||
|
||||
- handle |= SERHND_COOKED;
|
||||
+ common:
|
||||
+ if ( !com[handle].driver )
|
||||
+ goto fail;
|
||||
+
|
||||
+ if ( !post_irq )
|
||||
+ com[handle].state = serial_parsed;
|
||||
+ else if ( com[handle].state != serial_initialized )
|
||||
+ {
|
||||
+ if ( com[handle].driver->init_postirq )
|
||||
+ com[handle].driver->init_postirq(&com[handle]);
|
||||
+ com[handle].state = serial_initialized;
|
||||
+ }
|
||||
|
||||
- return handle;
|
||||
+ return handle | flags | SERHND_COOKED;
|
||||
|
||||
fail:
|
||||
return -1;
|
||||
@@ -450,8 +458,13 @@ void __init serial_init_postirq(void)
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < ARRAY_SIZE(com); i++ )
|
||||
- if ( com[i].driver && com[i].driver->init_postirq )
|
||||
- com[i].driver->init_postirq(&com[i]);
|
||||
+ if ( com[i].state == serial_parsed )
|
||||
+ {
|
||||
+ if ( com[i].driver->init_postirq )
|
||||
+ com[i].driver->init_postirq(&com[i]);
|
||||
+ com[i].state = serial_initialized;
|
||||
+ }
|
||||
+ post_irq = 1;
|
||||
}
|
||||
|
||||
void __init serial_endboot(void)
|
||||
@@ -475,7 +488,7 @@ void serial_suspend(void)
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < ARRAY_SIZE(com); i++ )
|
||||
- if ( com[i].driver && com[i].driver->suspend )
|
||||
+ if ( com[i].state == serial_initialized && com[i].driver->suspend )
|
||||
com[i].driver->suspend(&com[i]);
|
||||
}
|
||||
|
||||
@@ -483,7 +496,7 @@ void serial_resume(void)
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < ARRAY_SIZE(com); i++ )
|
||||
- if ( com[i].driver && com[i].driver->resume )
|
||||
+ if ( com[i].state == serial_initialized && com[i].driver->resume )
|
||||
com[i].driver->resume(&com[i]);
|
||||
}
|
||||
|
||||
--- a/xen/include/xen/serial.h
|
||||
+++ b/xen/include/xen/serial.h
|
||||
@@ -25,10 +25,17 @@ extern unsigned int serial_txbufsz;
|
||||
|
||||
struct uart_driver;
|
||||
|
||||
+enum serial_port_state {
|
||||
+ serial_unused,
|
||||
+ serial_parsed,
|
||||
+ serial_initialized
|
||||
+};
|
||||
+
|
||||
struct serial_port {
|
||||
/* Uart-driver parameters. */
|
||||
struct uart_driver *driver;
|
||||
void *uart;
|
||||
+ enum serial_port_state state;
|
||||
/* Number of characters the port can hold for transmit. */
|
||||
int tx_fifo_size;
|
||||
/* Transmit data buffer (interrupt-driven uart). */
|
56
25866-sercon-ns16550-pci-irq.patch
Normal file
56
25866-sercon-ns16550-pci-irq.patch
Normal file
@ -0,0 +1,56 @@
|
||||
# HG changeset patch
|
||||
# User Jan Beulich <jbeulich@suse.com>
|
||||
# Date 1347371733 -7200
|
||||
# Node ID ee12dc357fbecbb0517798f395d14bf1764c6766
|
||||
# Parent 5fb5b3b70e34ef278d06aff27878b4b8e6d9145f
|
||||
ns16550: PCI initialization adjustments
|
||||
|
||||
Besides single-port serial cards, also accept multi-port ones and such
|
||||
providing mixed functionality (e.g. also having a parallel port).
|
||||
|
||||
Reading PCI_INTERRUPT_PIN before ACPI gets enabled generally produces
|
||||
an incorrect IRQ (below 16, whereas after enabling ACPI it frequently
|
||||
would end up at a higher one), so this is useful (almost) only when a
|
||||
system already boots in ACPI mode.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Keir Fraser <keir@xen.org>
|
||||
|
||||
--- a/xen/drivers/char/ns16550.c
|
||||
+++ b/xen/drivers/char/ns16550.c
|
||||
@@ -449,7 +449,6 @@ static int __init check_existence(struct
|
||||
static int
|
||||
pci_uart_config (struct ns16550 *uart, int skip_amt, int bar_idx)
|
||||
{
|
||||
- uint16_t class;
|
||||
uint32_t bar, len;
|
||||
int b, d, f;
|
||||
|
||||
@@ -460,9 +459,15 @@ pci_uart_config (struct ns16550 *uart, i
|
||||
{
|
||||
for ( f = 0; f < 0x8; f++ )
|
||||
{
|
||||
- class = pci_conf_read16(0, b, d, f, PCI_CLASS_DEVICE);
|
||||
- if ( class != 0x700 )
|
||||
+ switch ( pci_conf_read16(0, b, d, f, PCI_CLASS_DEVICE) )
|
||||
+ {
|
||||
+ case 0x0700: /* single port serial */
|
||||
+ case 0x0702: /* multi port serial */
|
||||
+ case 0x0780: /* other (e.g serial+parallel) */
|
||||
+ break;
|
||||
+ default:
|
||||
continue;
|
||||
+ }
|
||||
|
||||
bar = pci_conf_read32(0, b, d, f,
|
||||
PCI_BASE_ADDRESS_0 + bar_idx*4);
|
||||
@@ -485,7 +490,8 @@ pci_uart_config (struct ns16550 *uart, i
|
||||
uart->bar = bar;
|
||||
uart->bar_idx = bar_idx;
|
||||
uart->io_base = bar & 0xfffe;
|
||||
- uart->irq = 0;
|
||||
+ uart->irq = pci_conf_read8(0, b, d, f, PCI_INTERRUPT_PIN) ?
|
||||
+ pci_conf_read8(0, b, d, f, PCI_INTERRUPT_LINE) : 0;
|
||||
|
||||
return 0;
|
||||
}
|
100
25867-sercon-ns16550-parse.patch
Normal file
100
25867-sercon-ns16550-parse.patch
Normal file
@ -0,0 +1,100 @@
|
||||
# HG changeset patch
|
||||
# User Jan Beulich <jbeulich@suse.com>
|
||||
# Date 1347371805 -7200
|
||||
# Node ID b22f184e1a3cac03abeed92ec4b74235fd0881f4
|
||||
# Parent ee12dc357fbecbb0517798f395d14bf1764c6766
|
||||
ns16550: command line parsing adjustments
|
||||
|
||||
Allow intermediate parts of the command line options to be absent
|
||||
(expressed by two immediately succeeding commas).
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Keir Fraser <keir@xen.org>
|
||||
|
||||
--- a/docs/misc/xen-command-line.markdown
|
||||
+++ b/docs/misc/xen-command-line.markdown
|
||||
@@ -199,7 +199,7 @@ If set, override Xen's calculation of th
|
||||
If set, override Xen's default choice for the platform timer.
|
||||
|
||||
### com1,com2
|
||||
-> `= <baud>[/<clock_hz>][,DPS[,<io-base>[,<irq>[,<port-bdf>[,<bridge-bdf>]]]] | pci | amt ] `
|
||||
+> `= <baud>[/<clock_hz>][,[DPS][,[<io-base>|pci|amt][,[<irq>][,[<port-bdf>][,[<bridge-bdf>]]]]]]`
|
||||
|
||||
Both option `com1` and `com2` follow the same format.
|
||||
|
||||
--- a/xen/drivers/char/ns16550.c
|
||||
+++ b/xen/drivers/char/ns16550.c
|
||||
@@ -536,26 +536,23 @@ static void __init ns16550_parse_port_co
|
||||
else if ( (baud = simple_strtoul(conf, &conf, 10)) != 0 )
|
||||
uart->baud = baud;
|
||||
|
||||
- if ( *conf == '/')
|
||||
+ if ( *conf == '/' )
|
||||
{
|
||||
conf++;
|
||||
uart->clock_hz = simple_strtoul(conf, &conf, 0) << 4;
|
||||
}
|
||||
|
||||
- if ( *conf != ',' )
|
||||
- goto config_parsed;
|
||||
- conf++;
|
||||
-
|
||||
- uart->data_bits = simple_strtoul(conf, &conf, 10);
|
||||
+ if ( *conf == ',' && *++conf != ',' )
|
||||
+ {
|
||||
+ uart->data_bits = simple_strtoul(conf, &conf, 10);
|
||||
|
||||
- uart->parity = parse_parity_char(*conf);
|
||||
- conf++;
|
||||
+ uart->parity = parse_parity_char(*conf);
|
||||
|
||||
- uart->stop_bits = simple_strtoul(conf, &conf, 10);
|
||||
+ uart->stop_bits = simple_strtoul(conf + 1, &conf, 10);
|
||||
+ }
|
||||
|
||||
- if ( *conf == ',' )
|
||||
+ if ( *conf == ',' && *++conf != ',' )
|
||||
{
|
||||
- conf++;
|
||||
if ( strncmp(conf, "pci", 3) == 0 )
|
||||
{
|
||||
if ( pci_uart_config(uart, 1/* skip AMT */, uart - ns16550_com) )
|
||||
@@ -572,24 +569,21 @@ static void __init ns16550_parse_port_co
|
||||
{
|
||||
uart->io_base = simple_strtoul(conf, &conf, 0);
|
||||
}
|
||||
+ }
|
||||
|
||||
- if ( *conf == ',' )
|
||||
- {
|
||||
- conf++;
|
||||
- uart->irq = simple_strtoul(conf, &conf, 10);
|
||||
- if ( *conf == ',' )
|
||||
- {
|
||||
- conf++;
|
||||
- uart->ps_bdf_enable = 1;
|
||||
- parse_pci_bdf(&conf, &uart->ps_bdf[0]);
|
||||
- if ( *conf == ',' )
|
||||
- {
|
||||
- conf++;
|
||||
- uart->pb_bdf_enable = 1;
|
||||
- parse_pci_bdf(&conf, &uart->pb_bdf[0]);
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
+ if ( *conf == ',' && *++conf != ',' )
|
||||
+ uart->irq = simple_strtol(conf, &conf, 10);
|
||||
+
|
||||
+ if ( *conf == ',' && *++conf != ',' )
|
||||
+ {
|
||||
+ uart->ps_bdf_enable = 1;
|
||||
+ parse_pci_bdf(&conf, &uart->ps_bdf[0]);
|
||||
+ }
|
||||
+
|
||||
+ if ( *conf == ',' && *++conf != ',' )
|
||||
+ {
|
||||
+ uart->pb_bdf_enable = 1;
|
||||
+ parse_pci_bdf(&conf, &uart->pb_bdf[0]);
|
||||
}
|
||||
|
||||
config_parsed:
|
70
25874-x86-EFI-chain-cfg.patch
Normal file
70
25874-x86-EFI-chain-cfg.patch
Normal file
@ -0,0 +1,70 @@
|
||||
# HG changeset patch
|
||||
# User Jan Beulich <jbeulich@suse.com>
|
||||
# Date 1347437974 -7200
|
||||
# Node ID 8c0aa97d529a55de2ab96be1a5a6e9ed6a9c6bf0
|
||||
# Parent ac8f4afccd6c6786a3fd5691e8b0c9b38c47e994
|
||||
x86-64/EFI: allow chaining of config files
|
||||
|
||||
Namely when making use the CONFIG_XEN_COMPAT_* options in the legacy
|
||||
Linux kernels, newer kernels may not be compatible with older
|
||||
hypervisors, so trying to boot such a combination makes little sense.
|
||||
Booting older kernels on newer hypervisors, however, has to always
|
||||
work.
|
||||
|
||||
With the way xen.efi looks for its configuration file, allowing
|
||||
individual configuration files to refer only to compatible kernels,
|
||||
and referring from an older- to a newer-hypervisor one (the kernels
|
||||
of which will, as said, necessarily be compatible with the older
|
||||
hypervisor) allows to greatly reduce redundancy at least in
|
||||
development environments where one frequently wants multiple
|
||||
hypervisors and kernles to be installed in parallel.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Keir Fraser <keir@xen.org>
|
||||
|
||||
--- a/docs/misc/efi.markdown
|
||||
+++ b/docs/misc/efi.markdown
|
||||
@@ -75,6 +75,13 @@ Specifies an XSM module to load.
|
||||
|
||||
Specifies a CPU microcode blob to load.
|
||||
|
||||
+###`chain=<filename>`
|
||||
+
|
||||
+Specifies an alternate configuration file to use in case the specified section
|
||||
+(and in particular its `kernel=` setting) can't be found in the default (or
|
||||
+specified) configuration file. This is only meaningful in the [global] section
|
||||
+and really not meant to be used together with the `-cfg=` command line option.
|
||||
+
|
||||
Filenames must be specified relative to the location of the EFI binary.
|
||||
|
||||
Extra options to be passed to Xen can also be specified on the command line,
|
||||
--- a/xen/arch/x86/efi/boot.c
|
||||
+++ b/xen/arch/x86/efi/boot.c
|
||||
@@ -797,7 +797,26 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SY
|
||||
else
|
||||
section.s = get_value(&cfg, "global", "default");
|
||||
|
||||
- name.s = get_value(&cfg, section.s, "kernel");
|
||||
+ for ( ; ; )
|
||||
+ {
|
||||
+ name.s = get_value(&cfg, section.s, "kernel");
|
||||
+ if ( name.s )
|
||||
+ break;
|
||||
+ name.s = get_value(&cfg, "global", "chain");
|
||||
+ if ( !name.s )
|
||||
+ break;
|
||||
+ efi_bs->FreePages(cfg.addr, PFN_UP(cfg.size));
|
||||
+ cfg.addr = 0;
|
||||
+ if ( !read_file(dir_handle, s2w(&name), &cfg) )
|
||||
+ {
|
||||
+ PrintStr(L"Chained configuration file '");
|
||||
+ PrintStr(name.w);
|
||||
+ efi_bs->FreePool(name.w);
|
||||
+ blexit(L"'not found\r\n");
|
||||
+ }
|
||||
+ pre_parse(&cfg);
|
||||
+ efi_bs->FreePool(name.w);
|
||||
+ }
|
||||
if ( !name.s )
|
||||
blexit(L"No Dom0 kernel image specified\r\n");
|
||||
split_value(name.s);
|
630
25909-xenpm-consistent.patch
Normal file
630
25909-xenpm-consistent.patch
Normal file
@ -0,0 +1,630 @@
|
||||
References: bnc#780401
|
||||
|
||||
# HG changeset patch
|
||||
# User Jan Beulich <jbeulich@suse.com>
|
||||
# Date 1347869399 -7200
|
||||
# Node ID 51408c3528030309e8f064bf6a3c96b37de7dc96
|
||||
# Parent 12fa949b90603f057d458e370284471412afb0ba
|
||||
xenpm: make argument parsing and error handling more consistent
|
||||
|
||||
Specifically, what values are or aren't accepted as CPU identifier, and
|
||||
how the values get interpreted should be consistent across sub-commands
|
||||
(intended behavior now: non-negative values are okay, and along with
|
||||
omitting the argument, specifying "all" will also be accepted).
|
||||
|
||||
For error handling, error messages should get consistently issued to
|
||||
stderr, and the tool should now (hopefully) produce an exit code of
|
||||
zero only in the (partial) success case (there may still be a small
|
||||
number of questionable cases).
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Keir Fraser <keir@xen.org>
|
||||
|
||||
--- a/tools/misc/xenpm.c
|
||||
+++ b/tools/misc/xenpm.c
|
||||
@@ -36,7 +36,7 @@
|
||||
#define CPUFREQ_TURBO_ENABLED 1
|
||||
|
||||
static xc_interface *xc_handle;
|
||||
-static int max_cpu_nr;
|
||||
+static unsigned int max_cpu_nr;
|
||||
|
||||
/* help message */
|
||||
void show_help(void)
|
||||
@@ -77,6 +77,33 @@ void help_func(int argc, char *argv[])
|
||||
show_help();
|
||||
}
|
||||
|
||||
+static void parse_cpuid(const char *arg, int *cpuid)
|
||||
+{
|
||||
+ if ( sscanf(arg, "%d", cpuid) != 1 || *cpuid < 0 )
|
||||
+ {
|
||||
+ if ( strcasecmp(arg, "all") )
|
||||
+ {
|
||||
+ fprintf(stderr, "Invalid CPU identifier: '%s'\n", arg);
|
||||
+ exit(EINVAL);
|
||||
+ }
|
||||
+ *cpuid = -1;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void parse_cpuid_and_int(int argc, char *argv[],
|
||||
+ int *cpuid, int *val, const char *what)
|
||||
+{
|
||||
+ if ( argc > 1 )
|
||||
+ parse_cpuid(argv[0], cpuid);
|
||||
+
|
||||
+ if ( argc == 0 || sscanf(argv[argc > 1], "%d", val) != 1 )
|
||||
+ {
|
||||
+ fprintf(stderr, argc ? "Invalid %s '%s'\n" : "Missing %s\n",
|
||||
+ what, argv[argc > 1]);
|
||||
+ exit(EINVAL);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void print_cxstat(int cpuid, struct xc_cx_stat *cxstat)
|
||||
{
|
||||
int i;
|
||||
@@ -166,7 +193,8 @@ static int show_cxstat_by_cpuid(xc_inter
|
||||
if ( ret )
|
||||
{
|
||||
if ( ret == -ENODEV )
|
||||
- printf("Either xen cpuidle is disabled or no valid information is registered!\n");
|
||||
+ fprintf(stderr,
|
||||
+ "Either Xen cpuidle is disabled or no valid information is registered!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -181,11 +209,8 @@ void cxstat_func(int argc, char *argv[])
|
||||
{
|
||||
int cpuid = -1;
|
||||
|
||||
- if ( argc > 0 && sscanf(argv[0], "%d", &cpuid) != 1 )
|
||||
- cpuid = -1;
|
||||
-
|
||||
- if ( cpuid >= max_cpu_nr )
|
||||
- cpuid = -1;
|
||||
+ if ( argc > 0 )
|
||||
+ parse_cpuid(argv[0], &cpuid);
|
||||
|
||||
show_max_cstate(xc_handle);
|
||||
|
||||
@@ -294,11 +319,8 @@ void pxstat_func(int argc, char *argv[])
|
||||
{
|
||||
int cpuid = -1;
|
||||
|
||||
- if ( argc > 0 && sscanf(argv[0], "%d", &cpuid) != 1 )
|
||||
- cpuid = -1;
|
||||
-
|
||||
- if ( cpuid >= max_cpu_nr )
|
||||
- cpuid = -1;
|
||||
+ if ( argc > 0 )
|
||||
+ parse_cpuid(argv[0], &cpuid);
|
||||
|
||||
if ( cpuid < 0 )
|
||||
{
|
||||
@@ -338,10 +360,10 @@ static void signal_int_handler(int signo
|
||||
goto out;
|
||||
}
|
||||
|
||||
- if ( gettimeofday(&tv, NULL) == -1 )
|
||||
+ if ( gettimeofday(&tv, NULL) )
|
||||
{
|
||||
fprintf(stderr, "failed to get timeofday\n");
|
||||
- goto out ;
|
||||
+ goto out;
|
||||
}
|
||||
usec_end = tv.tv_sec * 1000000UL + tv.tv_usec;
|
||||
|
||||
@@ -541,7 +563,7 @@ void start_gather_func(int argc, char *a
|
||||
printf("Timeout set to %d seconds\n", timeout);
|
||||
}
|
||||
|
||||
- if ( gettimeofday(&tv, NULL) == -1 )
|
||||
+ if ( gettimeofday(&tv, NULL) )
|
||||
{
|
||||
fprintf(stderr, "failed to get timeofday\n");
|
||||
return ;
|
||||
@@ -766,11 +788,8 @@ void cpufreq_para_func(int argc, char *a
|
||||
{
|
||||
int cpuid = -1;
|
||||
|
||||
- if ( argc > 0 && sscanf(argv[0], "%d", &cpuid) != 1 )
|
||||
- cpuid = -1;
|
||||
-
|
||||
- if ( cpuid >= max_cpu_nr )
|
||||
- cpuid = -1;
|
||||
+ if ( argc > 0 )
|
||||
+ parse_cpuid(argv[0], &cpuid);
|
||||
|
||||
if ( cpuid < 0 )
|
||||
{
|
||||
@@ -788,26 +807,22 @@ void scaling_max_freq_func(int argc, cha
|
||||
{
|
||||
int cpuid = -1, freq = -1;
|
||||
|
||||
- if ( (argc >= 2 && (sscanf(argv[1], "%d", &freq) != 1 ||
|
||||
- sscanf(argv[0], "%d", &cpuid) != 1)) ||
|
||||
- (argc == 1 && sscanf(argv[0], "%d", &freq) != 1 ) ||
|
||||
- argc == 0 )
|
||||
- {
|
||||
- fprintf(stderr, "failed to set scaling max freq\n");
|
||||
- return ;
|
||||
- }
|
||||
+ parse_cpuid_and_int(argc, argv, &cpuid, &freq, "frequency");
|
||||
|
||||
if ( cpuid < 0 )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < max_cpu_nr; i++ )
|
||||
if ( xc_set_cpufreq_para(xc_handle, i, SCALING_MAX_FREQ, freq) )
|
||||
- fprintf(stderr, "[CPU%d] failed to set scaling max freq\n", i);
|
||||
+ fprintf(stderr,
|
||||
+ "[CPU%d] failed to set scaling max freq (%d - %s)\n",
|
||||
+ i, errno, strerror(errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( xc_set_cpufreq_para(xc_handle, cpuid, SCALING_MAX_FREQ, freq) )
|
||||
- fprintf(stderr, "failed to set scaling max freq\n");
|
||||
+ fprintf(stderr, "failed to set scaling max freq (%d - %s)\n",
|
||||
+ errno, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -815,26 +830,22 @@ void scaling_min_freq_func(int argc, cha
|
||||
{
|
||||
int cpuid = -1, freq = -1;
|
||||
|
||||
- if ( (argc >= 2 && (sscanf(argv[1], "%d", &freq) != 1 ||
|
||||
- sscanf(argv[0], "%d", &cpuid) != 1) ) ||
|
||||
- (argc == 1 && sscanf(argv[0], "%d", &freq) != 1 ) ||
|
||||
- argc == 0 )
|
||||
- {
|
||||
- fprintf(stderr, "failed to set scaling min freq\n");
|
||||
- return ;
|
||||
- }
|
||||
+ parse_cpuid_and_int(argc, argv, &cpuid, &freq, "frequency");
|
||||
|
||||
if ( cpuid < 0 )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < max_cpu_nr; i++ )
|
||||
if ( xc_set_cpufreq_para(xc_handle, i, SCALING_MIN_FREQ, freq) )
|
||||
- fprintf(stderr, "[CPU%d] failed to set scaling min freq\n", i);
|
||||
+ fprintf(stderr,
|
||||
+ "[CPU%d] failed to set scaling min freq (%d - %s)\n",
|
||||
+ i, errno, strerror(errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( xc_set_cpufreq_para(xc_handle, cpuid, SCALING_MIN_FREQ, freq) )
|
||||
- fprintf(stderr, "failed to set scaling min freq\n");
|
||||
+ fprintf(stderr, "failed to set scaling min freq (%d - %s)\n",
|
||||
+ errno, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -842,26 +853,22 @@ void scaling_speed_func(int argc, char *
|
||||
{
|
||||
int cpuid = -1, speed = -1;
|
||||
|
||||
- if ( (argc >= 2 && (sscanf(argv[1], "%d", &speed) != 1 ||
|
||||
- sscanf(argv[0], "%d", &cpuid) != 1) ) ||
|
||||
- (argc == 1 && sscanf(argv[0], "%d", &speed) != 1 ) ||
|
||||
- argc == 0 )
|
||||
- {
|
||||
- fprintf(stderr, "failed to set scaling speed\n");
|
||||
- return ;
|
||||
- }
|
||||
+ parse_cpuid_and_int(argc, argv, &cpuid, &speed, "speed");
|
||||
|
||||
if ( cpuid < 0 )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < max_cpu_nr; i++ )
|
||||
if ( xc_set_cpufreq_para(xc_handle, i, SCALING_SETSPEED, speed) )
|
||||
- fprintf(stderr, "[CPU%d] failed to set scaling speed\n", i);
|
||||
+ fprintf(stderr,
|
||||
+ "[CPU%d] failed to set scaling speed (%d - %s)\n",
|
||||
+ i, errno, strerror(errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( xc_set_cpufreq_para(xc_handle, cpuid, SCALING_SETSPEED, speed) )
|
||||
- fprintf(stderr, "failed to set scaling speed\n");
|
||||
+ fprintf(stderr, "failed to set scaling speed (%d - %s)\n",
|
||||
+ errno, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -869,14 +876,7 @@ void scaling_sampling_rate_func(int argc
|
||||
{
|
||||
int cpuid = -1, rate = -1;
|
||||
|
||||
- if ( (argc >= 2 && (sscanf(argv[1], "%d", &rate) != 1 ||
|
||||
- sscanf(argv[0], "%d", &cpuid) != 1) ) ||
|
||||
- (argc == 1 && sscanf(argv[0], "%d", &rate) != 1 ) ||
|
||||
- argc == 0 )
|
||||
- {
|
||||
- fprintf(stderr, "failed to set scaling sampling rate\n");
|
||||
- return ;
|
||||
- }
|
||||
+ parse_cpuid_and_int(argc, argv, &cpuid, &rate, "rate");
|
||||
|
||||
if ( cpuid < 0 )
|
||||
{
|
||||
@@ -884,12 +884,14 @@ void scaling_sampling_rate_func(int argc
|
||||
for ( i = 0; i < max_cpu_nr; i++ )
|
||||
if ( xc_set_cpufreq_para(xc_handle, i, SAMPLING_RATE, rate) )
|
||||
fprintf(stderr,
|
||||
- "[CPU%d] failed to set scaling sampling rate\n", i);
|
||||
+ "[CPU%d] failed to set scaling sampling rate (%d - %s)\n",
|
||||
+ i, errno, strerror(errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( xc_set_cpufreq_para(xc_handle, cpuid, SAMPLING_RATE, rate) )
|
||||
- fprintf(stderr, "failed to set scaling sampling rate\n");
|
||||
+ fprintf(stderr, "failed to set scaling sampling rate (%d - %s)\n",
|
||||
+ errno, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -897,14 +899,7 @@ void scaling_up_threshold_func(int argc,
|
||||
{
|
||||
int cpuid = -1, threshold = -1;
|
||||
|
||||
- if ( (argc >= 2 && (sscanf(argv[1], "%d", &threshold) != 1 ||
|
||||
- sscanf(argv[0], "%d", &cpuid) != 1) ) ||
|
||||
- (argc == 1 && sscanf(argv[0], "%d", &threshold) != 1 ) ||
|
||||
- argc == 0 )
|
||||
- {
|
||||
- fprintf(stderr, "failed to set up scaling threshold\n");
|
||||
- return ;
|
||||
- }
|
||||
+ parse_cpuid_and_int(argc, argv, &cpuid, &threshold, "threshold");
|
||||
|
||||
if ( cpuid < 0 )
|
||||
{
|
||||
@@ -912,57 +907,49 @@ void scaling_up_threshold_func(int argc,
|
||||
for ( i = 0; i < max_cpu_nr; i++ )
|
||||
if ( xc_set_cpufreq_para(xc_handle, i, UP_THRESHOLD, threshold) )
|
||||
fprintf(stderr,
|
||||
- "[CPU%d] failed to set up scaling threshold\n", i);
|
||||
+ "[CPU%d] failed to set up scaling threshold (%d - %s)\n",
|
||||
+ i, errno, strerror(errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( xc_set_cpufreq_para(xc_handle, cpuid, UP_THRESHOLD, threshold) )
|
||||
- fprintf(stderr, "failed to set up scaling threshold\n");
|
||||
+ fprintf(stderr, "failed to set up scaling threshold (%d - %s)\n",
|
||||
+ errno, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
void scaling_governor_func(int argc, char *argv[])
|
||||
{
|
||||
int cpuid = -1;
|
||||
- char *name = NULL;
|
||||
+ char *name;
|
||||
|
||||
if ( argc >= 2 )
|
||||
{
|
||||
- name = strdup(argv[1]);
|
||||
- if ( name == NULL )
|
||||
- goto out;
|
||||
- if ( sscanf(argv[0], "%d", &cpuid) != 1 )
|
||||
- {
|
||||
- free(name);
|
||||
- goto out;
|
||||
- }
|
||||
+ parse_cpuid(argv[0], &cpuid);
|
||||
+ name = argv[1];
|
||||
}
|
||||
else if ( argc > 0 )
|
||||
+ name = argv[0];
|
||||
+ else
|
||||
{
|
||||
- name = strdup(argv[0]);
|
||||
- if ( name == NULL )
|
||||
- goto out;
|
||||
+ fprintf(stderr, "Missing argument(s)\n");
|
||||
+ exit(EINVAL);
|
||||
}
|
||||
- else
|
||||
- goto out;
|
||||
|
||||
if ( cpuid < 0 )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < max_cpu_nr; i++ )
|
||||
if ( xc_set_cpufreq_gov(xc_handle, i, name) )
|
||||
- fprintf(stderr, "[CPU%d] failed to set governor name\n", i);
|
||||
+ fprintf(stderr, "[CPU%d] failed to set governor name (%d - %s)\n",
|
||||
+ i, errno, strerror(errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( xc_set_cpufreq_gov(xc_handle, cpuid, name) )
|
||||
- fprintf(stderr, "failed to set governor name\n");
|
||||
+ fprintf(stderr, "failed to set governor name (%d - %s)\n",
|
||||
+ errno, strerror(errno));
|
||||
}
|
||||
-
|
||||
- free(name);
|
||||
- return ;
|
||||
-out:
|
||||
- fprintf(stderr, "failed to set governor name\n");
|
||||
}
|
||||
|
||||
void cpu_topology_func(int argc, char *argv[])
|
||||
@@ -971,7 +958,7 @@ void cpu_topology_func(int argc, char *a
|
||||
DECLARE_HYPERCALL_BUFFER(uint32_t, cpu_to_socket);
|
||||
DECLARE_HYPERCALL_BUFFER(uint32_t, cpu_to_node);
|
||||
xc_topologyinfo_t info = { 0 };
|
||||
- int i;
|
||||
+ int i, rc = ENOMEM;
|
||||
|
||||
cpu_to_core = xc_hypercall_buffer_alloc(xc_handle, cpu_to_core, sizeof(*cpu_to_core) * MAX_NR_CPU);
|
||||
cpu_to_socket = xc_hypercall_buffer_alloc(xc_handle, cpu_to_socket, sizeof(*cpu_to_socket) * MAX_NR_CPU);
|
||||
@@ -990,7 +977,9 @@ void cpu_topology_func(int argc, char *a
|
||||
|
||||
if ( xc_topologyinfo(xc_handle, &info) )
|
||||
{
|
||||
- printf("Can not get Xen CPU topology: %d\n", errno);
|
||||
+ rc = errno;
|
||||
+ fprintf(stderr, "Cannot get Xen CPU topology (%d - %s)\n",
|
||||
+ errno, strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1005,116 +994,95 @@ void cpu_topology_func(int argc, char *a
|
||||
printf("CPU%d\t %d\t %d\t %d\n",
|
||||
i, cpu_to_core[i], cpu_to_socket[i], cpu_to_node[i]);
|
||||
}
|
||||
+ rc = 0;
|
||||
out:
|
||||
xc_hypercall_buffer_free(xc_handle, cpu_to_core);
|
||||
xc_hypercall_buffer_free(xc_handle, cpu_to_socket);
|
||||
xc_hypercall_buffer_free(xc_handle, cpu_to_node);
|
||||
+ if ( rc )
|
||||
+ exit(rc);
|
||||
}
|
||||
|
||||
void set_sched_smt_func(int argc, char *argv[])
|
||||
{
|
||||
- int value, rc;
|
||||
+ int value;
|
||||
|
||||
- if (argc != 1){
|
||||
- show_help();
|
||||
- exit(-1);
|
||||
+ if ( argc != 1 ) {
|
||||
+ fprintf(stderr, "Missing or invalid argument(s)\n");
|
||||
+ exit(EINVAL);
|
||||
}
|
||||
|
||||
- if ( !strncmp(argv[0], "disable", sizeof("disable")) )
|
||||
- {
|
||||
+ if ( !strcasecmp(argv[0], "disable") )
|
||||
value = 0;
|
||||
- }
|
||||
- else if ( !strncmp(argv[0], "enable", sizeof("enable")) )
|
||||
- {
|
||||
+ else if ( !strcasecmp(argv[0], "enable") )
|
||||
value = 1;
|
||||
- }
|
||||
else
|
||||
{
|
||||
- show_help();
|
||||
- exit(-1);
|
||||
+ fprintf(stderr, "Invalid argument: %s\n", argv[0]);
|
||||
+ exit(EINVAL);
|
||||
}
|
||||
|
||||
- rc = xc_set_sched_opt_smt(xc_handle, value);
|
||||
- printf("%s sched_smt_power_savings %s\n", argv[0],
|
||||
- rc? "failed":"succeeded" );
|
||||
-
|
||||
- return;
|
||||
+ if ( !xc_set_sched_opt_smt(xc_handle, value) )
|
||||
+ printf("%s sched_smt_power_savings succeeded\n", argv[0]);
|
||||
+ else
|
||||
+ fprintf(stderr, "%s sched_smt_power_savings failed (%d - %s)\n",
|
||||
+ argv[0], errno, strerror(errno));
|
||||
}
|
||||
|
||||
void set_vcpu_migration_delay_func(int argc, char *argv[])
|
||||
{
|
||||
int value;
|
||||
- int rc;
|
||||
-
|
||||
- if (argc != 1){
|
||||
- show_help();
|
||||
- exit(-1);
|
||||
- }
|
||||
-
|
||||
- value = atoi(argv[0]);
|
||||
|
||||
- if (value < 0)
|
||||
- {
|
||||
- printf("Please try non-negative vcpu migration delay\n");
|
||||
- exit(-1);
|
||||
+ if ( argc != 1 || (value = atoi(argv[0])) < 0 ) {
|
||||
+ fprintf(stderr, "Missing or invalid argument(s)\n");
|
||||
+ exit(EINVAL);
|
||||
}
|
||||
|
||||
- rc = xc_set_vcpu_migration_delay(xc_handle, value);
|
||||
- printf("%s to set vcpu migration delay to %d us\n",
|
||||
- rc? "Fail":"Succeed", value );
|
||||
-
|
||||
- return;
|
||||
+ if ( !xc_set_vcpu_migration_delay(xc_handle, value) )
|
||||
+ printf("set vcpu migration delay to %d us succeeded\n", value);
|
||||
+ else
|
||||
+ fprintf(stderr, "set vcpu migration delay failed (%d - %s)\n",
|
||||
+ errno, strerror(errno));
|
||||
}
|
||||
|
||||
void get_vcpu_migration_delay_func(int argc, char *argv[])
|
||||
{
|
||||
uint32_t value;
|
||||
- int rc;
|
||||
|
||||
- if (argc != 0){
|
||||
- show_help();
|
||||
- exit(-1);
|
||||
- }
|
||||
+ if ( argc )
|
||||
+ fprintf(stderr, "Ignoring argument(s)\n");
|
||||
|
||||
- rc = xc_get_vcpu_migration_delay(xc_handle, &value);
|
||||
- if (!rc)
|
||||
- {
|
||||
- printf("Schduler vcpu migration delay is %d us\n", value);
|
||||
- }
|
||||
+ if ( !xc_get_vcpu_migration_delay(xc_handle, &value) )
|
||||
+ printf("Scheduler vcpu migration delay is %d us\n", value);
|
||||
else
|
||||
- {
|
||||
- printf("Failed to get scheduler vcpu migration delay, errno=%d\n", errno);
|
||||
- }
|
||||
-
|
||||
- return;
|
||||
+ fprintf(stderr,
|
||||
+ "Failed to get scheduler vcpu migration delay (%d - %s)\n",
|
||||
+ errno, strerror(errno));
|
||||
}
|
||||
|
||||
void set_max_cstate_func(int argc, char *argv[])
|
||||
{
|
||||
- int value, rc;
|
||||
+ int value;
|
||||
|
||||
if ( argc != 1 || sscanf(argv[0], "%d", &value) != 1 || value < 0 )
|
||||
{
|
||||
- show_help();
|
||||
- exit(-1);
|
||||
+ fprintf(stderr, "Missing or invalid argument(s)\n");
|
||||
+ exit(EINVAL);
|
||||
}
|
||||
|
||||
- rc = xc_set_cpuidle_max_cstate(xc_handle, (uint32_t)value);
|
||||
- printf("set max_cstate to C%d %s\n", value,
|
||||
- rc? "failed":"succeeded" );
|
||||
-
|
||||
- return;
|
||||
+ if ( !xc_set_cpuidle_max_cstate(xc_handle, (uint32_t)value) )
|
||||
+ printf("set max_cstate to C%d succeeded\n", value);
|
||||
+ else
|
||||
+ fprintf(stderr, "set max_cstate to C%d failed (%d - %s)\n",
|
||||
+ value, errno, strerror(errno));
|
||||
}
|
||||
|
||||
void enable_turbo_mode(int argc, char *argv[])
|
||||
{
|
||||
int cpuid = -1;
|
||||
|
||||
- if ( argc > 0 && sscanf(argv[0], "%d", &cpuid) != 1 )
|
||||
- cpuid = -1;
|
||||
-
|
||||
- if ( cpuid >= max_cpu_nr )
|
||||
- cpuid = -1;
|
||||
+ if ( argc > 0 )
|
||||
+ parse_cpuid(argv[0], &cpuid);
|
||||
|
||||
if ( cpuid < 0 )
|
||||
{
|
||||
@@ -1122,21 +1090,22 @@ void enable_turbo_mode(int argc, char *a
|
||||
* only make effects on dbs governor */
|
||||
int i;
|
||||
for ( i = 0; i < max_cpu_nr; i++ )
|
||||
- xc_enable_turbo(xc_handle, i);
|
||||
+ if ( xc_enable_turbo(xc_handle, i) )
|
||||
+ fprintf(stderr,
|
||||
+ "[CPU%d] failed to enable turbo mode (%d - %s)\n",
|
||||
+ i, errno, strerror(errno));
|
||||
}
|
||||
- else
|
||||
- xc_enable_turbo(xc_handle, cpuid);
|
||||
+ else if ( xc_enable_turbo(xc_handle, cpuid) )
|
||||
+ fprintf(stderr, "failed to enable turbo mode (%d - %s)\n",
|
||||
+ errno, strerror(errno));
|
||||
}
|
||||
|
||||
void disable_turbo_mode(int argc, char *argv[])
|
||||
{
|
||||
int cpuid = -1;
|
||||
|
||||
- if ( argc > 0 && sscanf(argv[0], "%d", &cpuid) != 1 )
|
||||
- cpuid = -1;
|
||||
-
|
||||
- if ( cpuid >= max_cpu_nr )
|
||||
- cpuid = -1;
|
||||
+ if ( argc > 0 )
|
||||
+ parse_cpuid(argv[0], &cpuid);
|
||||
|
||||
if ( cpuid < 0 )
|
||||
{
|
||||
@@ -1144,10 +1113,14 @@ void disable_turbo_mode(int argc, char *
|
||||
* only make effects on dbs governor */
|
||||
int i;
|
||||
for ( i = 0; i < max_cpu_nr; i++ )
|
||||
- xc_disable_turbo(xc_handle, i);
|
||||
+ if ( xc_disable_turbo(xc_handle, i) )
|
||||
+ fprintf(stderr,
|
||||
+ "[CPU%d] failed to disable turbo mode (%d - %s)\n",
|
||||
+ i, errno, strerror(errno));
|
||||
}
|
||||
- else
|
||||
- xc_disable_turbo(xc_handle, cpuid);
|
||||
+ else if ( xc_disable_turbo(xc_handle, cpuid) )
|
||||
+ fprintf(stderr, "failed to disable turbo mode (%d - %s)\n",
|
||||
+ errno, strerror(errno));
|
||||
}
|
||||
|
||||
struct {
|
||||
@@ -1191,15 +1164,17 @@ int main(int argc, char *argv[])
|
||||
if ( !xc_handle )
|
||||
{
|
||||
fprintf(stderr, "failed to get the handler\n");
|
||||
- return 0;
|
||||
+ return EIO;
|
||||
}
|
||||
|
||||
ret = xc_physinfo(xc_handle, &physinfo);
|
||||
if ( ret )
|
||||
{
|
||||
- fprintf(stderr, "failed to get the processor information\n");
|
||||
+ ret = errno;
|
||||
+ fprintf(stderr, "failed to get processor information (%d - %s)\n",
|
||||
+ ret, strerror(ret));
|
||||
xc_interface_close(xc_handle);
|
||||
- return 0;
|
||||
+ return ret;
|
||||
}
|
||||
max_cpu_nr = physinfo.nr_cpus;
|
||||
|
||||
@@ -1214,14 +1189,18 @@ int main(int argc, char *argv[])
|
||||
for ( i = 0; i < nr_matches; i++ )
|
||||
fprintf(stderr, " %s", main_options[matches_main_options[i]].name);
|
||||
fprintf(stderr, "\n");
|
||||
+ ret = EINVAL;
|
||||
}
|
||||
else if ( nr_matches == 1 )
|
||||
/* dispatch to the corresponding function handler */
|
||||
main_options[matches_main_options[0]].function(argc - 2, argv + 2);
|
||||
else
|
||||
+ {
|
||||
show_help();
|
||||
+ ret = EINVAL;
|
||||
+ }
|
||||
|
||||
xc_interface_close(xc_handle);
|
||||
- return 0;
|
||||
+ return ret;
|
||||
}
|
||||
|
@ -677,7 +677,7 @@ Index: xen-4.2.0-testing/tools/blktap/drivers/Makefile
|
||||
-LDLIBS_img := $(AIOLIBS) $(CRYPT_LIB) $(PTHREAD_LIBS) -lz
|
||||
+LDLIBS_xen := $(LDLIBS_libxenctrl) $(LDLIBS_libxenstore)
|
||||
+LDLIBS_blktapctrl := $(MEMSHRLIBS) $(LDLIBS_xen) -L../lib -lblktap -lrt -lm $(PTHREAD_LIBS)
|
||||
+LDLIBS_img := $(LIBAIO_DIR)/libaio.a $(CRYPT_LIB) $(PTHREAD_LIBS) -lz $(LDLIBS_xen)
|
||||
+LDLIBS_img := $(AIOLIBS) $(CRYPT_LIB) $(PTHREAD_LIBS) -lz $(LDLIBS_xen)
|
||||
|
||||
BLK-OBJS-y := block-aio.o
|
||||
BLK-OBJS-y += block-sync.o
|
||||
|
@ -1,21 +0,0 @@
|
||||
Index: xen-4.1.2-testing/tools/qemu-xen-traditional-dir-remote/hw/e1000.c
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/e1000.c
|
||||
+++ xen-4.1.2-testing/tools/qemu-xen-traditional-dir-remote/hw/e1000.c
|
||||
@@ -444,6 +444,8 @@ process_tx_desc(E1000State *s, struct e1
|
||||
bytes = split_size;
|
||||
if (tp->size + bytes > msh)
|
||||
bytes = msh - tp->size;
|
||||
+
|
||||
+ bytes = MIN(sizeof(tp->data) - tp->size, bytes);
|
||||
cpu_physical_memory_read(addr, tp->data + tp->size, bytes);
|
||||
if ((sz = tp->size + bytes) >= hdr && tp->size < hdr)
|
||||
memmove(tp->header, tp->data, hdr);
|
||||
@@ -459,6 +461,7 @@ process_tx_desc(E1000State *s, struct e1
|
||||
// context descriptor TSE is not set, while data descriptor TSE is set
|
||||
DBGOUT(TXERR, "TCP segmentaion Error\n");
|
||||
} else {
|
||||
+ split_size = MIN(sizeof(tp->data) - tp->size, split_size);
|
||||
cpu_physical_memory_read(addr, tp->data + tp->size, split_size);
|
||||
tp->size += split_size;
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
Index: xen-4.2.0-testing/tools/firmware/etherboot/patches/ipxe-git-f7c5918b179b
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ xen-4.2.0-testing/tools/firmware/etherboot/patches/ipxe-git-f7c5918b179b
|
||||
@@ -0,0 +1,61 @@
|
||||
+
|
||||
+Subject: [drivers] Fix warnings identified by gcc 4.5
|
||||
+From: Bruce Rogers brogers@novell.com Fri Apr 2 18:16:38 2010 -0600
|
||||
+Date: Fri Apr 16 07:32:49 2010 -0400:
|
||||
+Git: f7c5918b179be57fc7f352cb33664eb43de02c30
|
||||
+
|
||||
+In building gpxe for openSUSE Factory (part of kvm package), there were
|
||||
+a few problems identified by the compiler. This patch addresses them.
|
||||
+
|
||||
+Signed-off-by: Bruce Rogers <brogers@novell.com>
|
||||
+Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>
|
||||
+Signed-off-by: Marty Connor <mdc@etherboot.org>
|
||||
+
|
||||
+diff --git a/src/drivers/net/ath5k/ath5k_qcu.c b/src/drivers/net/ath5k/ath5k_qcu.c
|
||||
+index a674b85..cb25029 100644
|
||||
+--- a/src/drivers/net/ath5k/ath5k_qcu.c
|
||||
++++ b/src/drivers/net/ath5k/ath5k_qcu.c
|
||||
+@@ -268,7 +268,7 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah)
|
||||
+ }
|
||||
+
|
||||
+ if (tq->tqi_ready_time &&
|
||||
+- (tq->tqi_type != AR5K_TX_QUEUE_ID_CAB))
|
||||
++ (tq->tqi_type != AR5K_TX_QUEUE_CAB))
|
||||
+ ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,
|
||||
+ AR5K_QCU_RDYTIMECFG_INTVAL) |
|
||||
+ AR5K_QCU_RDYTIMECFG_ENABLE,
|
||||
+diff --git a/src/drivers/net/ns83820.c b/src/drivers/net/ns83820.c
|
||||
+index 44d875f..c5f2153 100644
|
||||
+--- a/src/drivers/net/ns83820.c
|
||||
++++ b/src/drivers/net/ns83820.c
|
||||
+@@ -687,7 +687,7 @@ static int ns83820_poll(struct nic *nic, int retrieve)
|
||||
+ // rx_ring[entry].link = 0;
|
||||
+ rx_ring[entry].cmdsts = cpu_to_le32(CMDSTS_OWN);
|
||||
+
|
||||
+- ns->cur_rx = ++ns->cur_rx % NR_RX_DESC;
|
||||
++ ns->cur_rx = (ns->cur_rx + 1) % NR_RX_DESC;
|
||||
+
|
||||
+ if (ns->cur_rx == 0) /* We have wrapped the ring */
|
||||
+ kick_rx();
|
||||
+diff --git a/src/drivers/net/tulip.c b/src/drivers/net/tulip.c
|
||||
+index e08e0d8..af30ec6 100644
|
||||
+--- a/src/drivers/net/tulip.c
|
||||
++++ b/src/drivers/net/tulip.c
|
||||
+@@ -1171,7 +1171,7 @@ static int tulip_poll(struct nic *nic, int retrieve)
|
||||
+ if (rx_ring[tp->cur_rx].status & 0x00008000) {
|
||||
+ /* return the descriptor and buffer to receive ring */
|
||||
+ rx_ring[tp->cur_rx].status = 0x80000000;
|
||||
+- tp->cur_rx = (++tp->cur_rx) % RX_RING_SIZE;
|
||||
++ tp->cur_rx = (tp->cur_rx + 1) % RX_RING_SIZE;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+@@ -1180,7 +1180,7 @@ static int tulip_poll(struct nic *nic, int retrieve)
|
||||
+
|
||||
+ /* return the descriptor and buffer to receive ring */
|
||||
+ rx_ring[tp->cur_rx].status = 0x80000000;
|
||||
+- tp->cur_rx = (++tp->cur_rx) % RX_RING_SIZE;
|
||||
++ tp->cur_rx = (tp->cur_rx + 1) % RX_RING_SIZE;
|
||||
+
|
||||
+ return 1;
|
||||
+ }
|
||||
Index: xen-4.2.0-testing/tools/firmware/etherboot/patches/series
|
||||
===================================================================
|
||||
--- xen-4.2.0-testing.orig/tools/firmware/etherboot/patches/series
|
||||
+++ xen-4.2.0-testing/tools/firmware/etherboot/patches/series
|
||||
@@ -1 +1,2 @@
|
||||
boot_prompt_option.patch
|
||||
+ipxe-git-f7c5918b179b
|
@ -1,366 +0,0 @@
|
||||
Index: xen-4.2.0-testing/tools/firmware/etherboot/patches/ipxe-git-13186b64b6c3
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ xen-4.2.0-testing/tools/firmware/etherboot/patches/ipxe-git-13186b64b6c3
|
||||
@@ -0,0 +1,354 @@
|
||||
+commit 13186b64b6c3d5cbe9ed13bda1532e79b1afe81d
|
||||
+Author: Michael Brown <mcb30@ipxe.org>
|
||||
+Date: Sat Jul 16 01:15:53 2011 +0100
|
||||
+
|
||||
+ [ipv4] Fix fragment reassembly
|
||||
+
|
||||
+ Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
||||
+ Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
|
||||
+
|
||||
+diff -up a/src/include/gpxe/ip.h.orig-frag b/src/include/gpxe/ip.h
|
||||
+--- a/src/include/gpxe/ip.h.orig-frag 2010-02-02 17:12:44.000000000 +0100
|
||||
++++ b/src/include/gpxe/ip.h 2011-11-18 15:49:17.202660163 +0100
|
||||
+@@ -32,9 +32,6 @@ struct net_protocol;
|
||||
+ #define IP_TOS 0
|
||||
+ #define IP_TTL 64
|
||||
+
|
||||
+-#define IP_FRAG_IOB_SIZE 1500
|
||||
+-#define IP_FRAG_TIMEOUT 50
|
||||
+-
|
||||
+ /** An IPv4 packet header */
|
||||
+ struct iphdr {
|
||||
+ uint8_t verhdrlen;
|
||||
+@@ -74,20 +71,16 @@ struct ipv4_miniroute {
|
||||
+ struct in_addr gateway;
|
||||
+ };
|
||||
+
|
||||
+-/* Fragment reassembly buffer */
|
||||
+-struct frag_buffer {
|
||||
+- /* Identification number */
|
||||
+- uint16_t ident;
|
||||
+- /* Source network address */
|
||||
+- struct in_addr src;
|
||||
+- /* Destination network address */
|
||||
+- struct in_addr dest;
|
||||
+- /* Reassembled I/O buffer */
|
||||
+- struct io_buffer *frag_iob;
|
||||
+- /* Reassembly timer */
|
||||
+- struct retry_timer frag_timer;
|
||||
++/* IPv4 fragment reassembly buffer */
|
||||
++struct ipv4_fragment {
|
||||
+ /* List of fragment reassembly buffers */
|
||||
+ struct list_head list;
|
||||
++ /** Reassembled packet */
|
||||
++ struct io_buffer *iobuf;
|
||||
++ /** Current offset */
|
||||
++ size_t offset;
|
||||
++ /** Reassembly timer */
|
||||
++ struct retry_timer timer;
|
||||
+ };
|
||||
+
|
||||
+ extern struct list_head ipv4_miniroutes;
|
||||
+diff -up a/src/include/gpxe/retry.h.orig-frag b/src/include/gpxe/retry.h
|
||||
+--- a/src/include/gpxe/retry.h.orig-frag 2010-02-02 17:12:44.000000000 +0100
|
||||
++++ b/src/include/gpxe/retry.h 2011-11-18 15:59:25.258837891 +0100
|
||||
+@@ -51,6 +51,19 @@ struct retry_timer {
|
||||
+ void ( * expired ) ( struct retry_timer *timer, int over );
|
||||
+ };
|
||||
+
|
||||
++/**
|
||||
++ * Initialise a timer
|
||||
++ *
|
||||
++ * @v timer Retry timer
|
||||
++ * @v expired Timer expired callback
|
||||
++ */
|
||||
++static inline __attribute__ (( always_inline )) void
|
||||
++timer_init ( struct retry_timer *timer,
|
||||
++ void ( * expired ) ( struct retry_timer *timer, int over ) )
|
||||
++{
|
||||
++ timer->expired = expired;
|
||||
++}
|
||||
++
|
||||
+ extern void start_timer ( struct retry_timer *timer );
|
||||
+ extern void start_timer_fixed ( struct retry_timer *timer,
|
||||
+ unsigned long timeout );
|
||||
+diff -up a/src/net/ipv4.c.orig-frag b/src/net/ipv4.c
|
||||
+--- a/src/net/ipv4.c.orig-frag 2010-02-02 17:12:44.000000000 +0100
|
||||
++++ b/src/net/ipv4.c 2011-11-18 15:49:17.203660142 +0100
|
||||
+@@ -14,6 +14,7 @@
|
||||
+ #include <gpxe/tcpip.h>
|
||||
+ #include <gpxe/dhcp.h>
|
||||
+ #include <gpxe/settings.h>
|
||||
++#include <gpxe/timer.h>
|
||||
+
|
||||
+ /** @file
|
||||
+ *
|
||||
+@@ -32,7 +33,10 @@ struct net_protocol ipv4_protocol;
|
||||
+ struct list_head ipv4_miniroutes = LIST_HEAD_INIT ( ipv4_miniroutes );
|
||||
+
|
||||
+ /** List of fragment reassembly buffers */
|
||||
+-static LIST_HEAD ( frag_buffers );
|
||||
++static LIST_HEAD ( ipv4_fragments );
|
||||
++
|
||||
++/** Fragment reassembly timeout */
|
||||
++#define IP_FRAG_TIMEOUT ( TICKS_PER_SEC / 2 )
|
||||
+
|
||||
+ /**
|
||||
+ * Add IPv4 minirouting table entry
|
||||
+@@ -134,104 +138,126 @@ static struct ipv4_miniroute * ipv4_rout
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+- * Fragment reassembly counter timeout
|
||||
++ * Expire fragment reassembly buffer
|
||||
+ *
|
||||
+- * @v timer Retry timer
|
||||
+- * @v over If asserted, the timer is greater than @c MAX_TIMEOUT
|
||||
++ * @v timer Retry timer
|
||||
++ * @v fail Failure indicator
|
||||
+ */
|
||||
+-static void ipv4_frag_expired ( struct retry_timer *timer __unused,
|
||||
+- int over ) {
|
||||
+- if ( over ) {
|
||||
+- DBG ( "Fragment reassembly timeout" );
|
||||
+- /* Free the fragment buffer */
|
||||
+- }
|
||||
++static void ipv4_fragment_expired ( struct retry_timer *timer,
|
||||
++ int fail __unused ) {
|
||||
++ struct ipv4_fragment *frag =
|
||||
++ container_of ( timer, struct ipv4_fragment, timer );
|
||||
++ struct iphdr *iphdr = frag->iobuf->data;
|
||||
++
|
||||
++ DBG ( "IPv4 fragment %04x expired\n", ntohs ( iphdr->ident ) );
|
||||
++ free_iob ( frag->iobuf );
|
||||
++ list_del ( &frag->list );
|
||||
++ free ( frag );
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+- * Free fragment buffer
|
||||
++ * Find matching fragment reassembly buffer
|
||||
+ *
|
||||
+- * @v fragbug Fragment buffer
|
||||
++ * @v iphdr IPv4 header
|
||||
++ * @ret frag Fragment reassembly buffer, or NULL
|
||||
+ */
|
||||
+-static void free_fragbuf ( struct frag_buffer *fragbuf ) {
|
||||
+- free ( fragbuf );
|
||||
++static struct ipv4_fragment * ipv4_fragment ( struct iphdr *iphdr ) {
|
||||
++ struct ipv4_fragment *frag;
|
||||
++ struct iphdr *frag_iphdr;
|
||||
++
|
||||
++ list_for_each_entry ( frag, &ipv4_fragments, list ) {
|
||||
++ frag_iphdr = frag->iobuf->data;
|
||||
++
|
||||
++ if ( ( iphdr->src.s_addr == frag_iphdr->src.s_addr ) &&
|
||||
++ ( iphdr->ident == frag_iphdr->ident ) ) {
|
||||
++ return frag;
|
||||
++ }
|
||||
++ }
|
||||
++
|
||||
++ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Fragment reassembler
|
||||
+ *
|
||||
+- * @v iobuf I/O buffer, fragment of the datagram
|
||||
+- * @ret frag_iob Reassembled packet, or NULL
|
||||
++ * @v iobuf I/O buffer
|
||||
++ * @ret iobuf Reassembled packet, or NULL
|
||||
+ */
|
||||
+-static struct io_buffer * ipv4_reassemble ( struct io_buffer * iobuf ) {
|
||||
++static struct io_buffer * ipv4_reassemble ( struct io_buffer *iobuf ) {
|
||||
+ struct iphdr *iphdr = iobuf->data;
|
||||
+- struct frag_buffer *fragbuf;
|
||||
+-
|
||||
+- /**
|
||||
+- * Check if the fragment belongs to any fragment series
|
||||
+- */
|
||||
+- list_for_each_entry ( fragbuf, &frag_buffers, list ) {
|
||||
+- if ( fragbuf->ident == iphdr->ident &&
|
||||
+- fragbuf->src.s_addr == iphdr->src.s_addr ) {
|
||||
+- /**
|
||||
+- * Check if the packet is the expected fragment
|
||||
+- *
|
||||
+- * The offset of the new packet must be equal to the
|
||||
+- * length of the data accumulated so far (the length of
|
||||
+- * the reassembled I/O buffer
|
||||
+- */
|
||||
+- if ( iob_len ( fragbuf->frag_iob ) ==
|
||||
+- ( iphdr->frags & IP_MASK_OFFSET ) ) {
|
||||
+- /**
|
||||
+- * Append the contents of the fragment to the
|
||||
+- * reassembled I/O buffer
|
||||
+- */
|
||||
+- iob_pull ( iobuf, sizeof ( *iphdr ) );
|
||||
+- memcpy ( iob_put ( fragbuf->frag_iob,
|
||||
+- iob_len ( iobuf ) ),
|
||||
+- iobuf->data, iob_len ( iobuf ) );
|
||||
+- free_iob ( iobuf );
|
||||
+-
|
||||
+- /** Check if the fragment series is over */
|
||||
+- if ( ! ( iphdr->frags & IP_MASK_MOREFRAGS ) ) {
|
||||
+- iobuf = fragbuf->frag_iob;
|
||||
+- free_fragbuf ( fragbuf );
|
||||
+- return iobuf;
|
||||
+- }
|
||||
+-
|
||||
+- } else {
|
||||
+- /* Discard the fragment series */
|
||||
+- free_fragbuf ( fragbuf );
|
||||
+- free_iob ( iobuf );
|
||||
+- }
|
||||
+- return NULL;
|
||||
++ size_t offset = ( ( ntohs ( iphdr->frags ) & IP_MASK_OFFSET ) << 3 );
|
||||
++ unsigned int more_frags = ( iphdr->frags & htons ( IP_MASK_MOREFRAGS ));
|
||||
++ size_t hdrlen = ( ( iphdr->verhdrlen & IP_MASK_HLEN ) * 4 );
|
||||
++ struct ipv4_fragment *frag;
|
||||
++ size_t expected_offset;
|
||||
++ struct io_buffer *new_iobuf;
|
||||
++
|
||||
++ /* Find matching fragment reassembly buffer, if any */
|
||||
++ frag = ipv4_fragment ( iphdr );
|
||||
++
|
||||
++ /* Drop out-of-order fragments */
|
||||
++ expected_offset = ( frag ? frag->offset : 0 );
|
||||
++ if ( offset != expected_offset ) {
|
||||
++ DBG ( "IPv4 dropping out-of-sequence fragment %04x (%zd+%zd, "
|
||||
++ "expected %zd)\n", ntohs ( iphdr->ident ), offset,
|
||||
++ ( iob_len ( iobuf ) - hdrlen ), expected_offset );
|
||||
++ goto drop;
|
||||
++ }
|
||||
++
|
||||
++ /* Create or extend fragment reassembly buffer as applicable */
|
||||
++ if ( frag == NULL ) {
|
||||
++
|
||||
++ /* Create new fragment reassembly buffer */
|
||||
++ frag = zalloc ( sizeof ( *frag ) );
|
||||
++ if ( ! frag )
|
||||
++ goto drop;
|
||||
++ list_add ( &frag->list, &ipv4_fragments );
|
||||
++ frag->iobuf = iobuf;
|
||||
++ frag->offset = ( iob_len ( iobuf ) - hdrlen );
|
||||
++ timer_init ( &frag->timer, ipv4_fragment_expired );
|
||||
++
|
||||
++ } else {
|
||||
++
|
||||
++ /* Extend reassembly buffer */
|
||||
++ iob_pull ( iobuf, hdrlen );
|
||||
++ new_iobuf = alloc_iob ( iob_len ( frag->iobuf ) +
|
||||
++ iob_len ( iobuf ) );
|
||||
++ if ( ! new_iobuf ) {
|
||||
++ DBG ( "IPv4 could not extend reassembly buffer to "
|
||||
++ "%zd bytes\n",
|
||||
++ ( iob_len ( frag->iobuf ) + iob_len ( iobuf ) ) );
|
||||
++ goto drop;
|
||||
+ }
|
||||
+- }
|
||||
+-
|
||||
+- /** Check if the fragment is the first in the fragment series */
|
||||
+- if ( iphdr->frags & IP_MASK_MOREFRAGS &&
|
||||
+- ( ( iphdr->frags & IP_MASK_OFFSET ) == 0 ) ) {
|
||||
+-
|
||||
+- /** Create a new fragment buffer */
|
||||
+- fragbuf = ( struct frag_buffer* ) malloc ( sizeof( *fragbuf ) );
|
||||
+- fragbuf->ident = iphdr->ident;
|
||||
+- fragbuf->src = iphdr->src;
|
||||
+-
|
||||
+- /* Set up the reassembly I/O buffer */
|
||||
+- fragbuf->frag_iob = alloc_iob ( IP_FRAG_IOB_SIZE );
|
||||
+- iob_pull ( iobuf, sizeof ( *iphdr ) );
|
||||
+- memcpy ( iob_put ( fragbuf->frag_iob, iob_len ( iobuf ) ),
|
||||
++ memcpy ( iob_put ( new_iobuf, iob_len ( frag->iobuf ) ),
|
||||
++ frag->iobuf->data, iob_len ( frag->iobuf ) );
|
||||
++ memcpy ( iob_put ( new_iobuf, iob_len ( iobuf ) ),
|
||||
+ iobuf->data, iob_len ( iobuf ) );
|
||||
++ free_iob ( frag->iobuf );
|
||||
++ frag->iobuf = new_iobuf;
|
||||
++ frag->offset += iob_len ( iobuf );
|
||||
+ free_iob ( iobuf );
|
||||
++ iphdr = frag->iobuf->data;
|
||||
++ iphdr->len = ntohs ( iob_len ( frag->iobuf ) );
|
||||
+
|
||||
+- /* Set the reassembly timer */
|
||||
+- fragbuf->frag_timer.timeout = IP_FRAG_TIMEOUT;
|
||||
+- fragbuf->frag_timer.expired = ipv4_frag_expired;
|
||||
+- start_timer ( &fragbuf->frag_timer );
|
||||
++ /* Stop fragment reassembly timer */
|
||||
++ stop_timer ( &frag->timer );
|
||||
+
|
||||
+- /* Add the fragment buffer to the list of fragment buffers */
|
||||
+- list_add ( &fragbuf->list, &frag_buffers );
|
||||
++ /* If this is the final fragment, return it */
|
||||
++ if ( ! more_frags ) {
|
||||
++ iobuf = frag->iobuf;
|
||||
++ list_del ( &frag->list );
|
||||
++ free ( frag );
|
||||
++ return iobuf;
|
||||
++ }
|
||||
+ }
|
||||
+-
|
||||
++
|
||||
++ /* (Re)start fragment reassembly timer */
|
||||
++ start_timer_fixed ( &frag->timer, IP_FRAG_TIMEOUT );
|
||||
++
|
||||
++ return NULL;
|
||||
++
|
||||
++ drop:
|
||||
++ free_iob ( iobuf );
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+@@ -432,37 +458,38 @@ static int ipv4_rx ( struct io_buffer *i
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
++ /* Truncate packet to correct length */
|
||||
++ iob_unput ( iobuf, ( iob_len ( iobuf ) - len ) );
|
||||
++
|
||||
+ /* Print IPv4 header for debugging */
|
||||
+ DBG ( "IPv4 RX %s<-", inet_ntoa ( iphdr->dest ) );
|
||||
+ DBG ( "%s len %d proto %d id %04x csum %04x\n",
|
||||
+ inet_ntoa ( iphdr->src ), ntohs ( iphdr->len ), iphdr->protocol,
|
||||
+ ntohs ( iphdr->ident ), ntohs ( iphdr->chksum ) );
|
||||
+
|
||||
+- /* Truncate packet to correct length, calculate pseudo-header
|
||||
+- * checksum and then strip off the IPv4 header.
|
||||
+- */
|
||||
+- iob_unput ( iobuf, ( iob_len ( iobuf ) - len ) );
|
||||
+- pshdr_csum = ipv4_pshdr_chksum ( iobuf, TCPIP_EMPTY_CSUM );
|
||||
+- iob_pull ( iobuf, hdrlen );
|
||||
+-
|
||||
+- /* Fragment reassembly */
|
||||
+- if ( ( iphdr->frags & htons ( IP_MASK_MOREFRAGS ) ) ||
|
||||
+- ( ( iphdr->frags & htons ( IP_MASK_OFFSET ) ) != 0 ) ) {
|
||||
+- /* Pass the fragment to ipv4_reassemble() which either
|
||||
+- * returns a fully reassembled I/O buffer or NULL.
|
||||
++ /* Perform fragment reassembly if applicable */
|
||||
++ if ( iphdr->frags & htons ( IP_MASK_OFFSET | IP_MASK_MOREFRAGS ) ) {
|
||||
++ /* Pass the fragment to ipv4_reassemble() which returns
|
||||
++ * either a fully reassembled I/O buffer or NULL.
|
||||
+ */
|
||||
+ iobuf = ipv4_reassemble ( iobuf );
|
||||
+ if ( ! iobuf )
|
||||
+ return 0;
|
||||
++ iphdr = iobuf->data;
|
||||
++ hdrlen = ( ( iphdr->verhdrlen & IP_MASK_HLEN ) * 4 );
|
||||
+ }
|
||||
+
|
||||
+- /* Construct socket addresses and hand off to transport layer */
|
||||
++ /* Construct socket addresses, calculate pseudo-header
|
||||
++ * checksum, and hand off to transport layer
|
||||
++ */
|
||||
+ memset ( &src, 0, sizeof ( src ) );
|
||||
+ src.sin.sin_family = AF_INET;
|
||||
+ src.sin.sin_addr = iphdr->src;
|
||||
+ memset ( &dest, 0, sizeof ( dest ) );
|
||||
+ dest.sin.sin_family = AF_INET;
|
||||
+ dest.sin.sin_addr = iphdr->dest;
|
||||
++ pshdr_csum = ipv4_pshdr_chksum ( iobuf, TCPIP_EMPTY_CSUM );
|
||||
++ iob_pull ( iobuf, hdrlen );
|
||||
+ if ( ( rc = tcpip_rx ( iobuf, iphdr->protocol, &src.st,
|
||||
+ &dest.st, pshdr_csum ) ) != 0 ) {
|
||||
+ DBG ( "IPv4 received packet rejected by stack: %s\n",
|
||||
Index: xen-4.2.0-testing/tools/firmware/etherboot/patches/series
|
||||
===================================================================
|
||||
--- xen-4.2.0-testing.orig/tools/firmware/etherboot/patches/series
|
||||
+++ xen-4.2.0-testing/tools/firmware/etherboot/patches/series
|
||||
@@ -1 +1,2 @@
|
||||
boot_prompt_option.patch
|
||||
+ipxe-git-13186b64b6c3
|
@ -1,7 +1,5 @@
|
||||
Index: xen-4.2.0-testing/xen/arch/x86/platform_hypercall.c
|
||||
===================================================================
|
||||
--- xen-4.2.0-testing.orig/xen/arch/x86/platform_hypercall.c
|
||||
+++ xen-4.2.0-testing/xen/arch/x86/platform_hypercall.c
|
||||
--- a/xen/arch/x86/platform_hypercall.c
|
||||
+++ b/xen/arch/x86/platform_hypercall.c
|
||||
@@ -25,7 +25,7 @@
|
||||
#include <xen/irq.h>
|
||||
#include <asm/current.h>
|
||||
@ -53,10 +51,8 @@ Index: xen-4.2.0-testing/xen/arch/x86/platform_hypercall.c
|
||||
default:
|
||||
ret = -ENOSYS;
|
||||
break;
|
||||
Index: xen-4.2.0-testing/xen/include/public/platform.h
|
||||
===================================================================
|
||||
--- xen-4.2.0-testing.orig/xen/include/public/platform.h
|
||||
+++ xen-4.2.0-testing/xen/include/public/platform.h
|
||||
--- a/xen/include/public/platform.h
|
||||
+++ b/xen/include/public/platform.h
|
||||
@@ -504,6 +504,16 @@ struct xenpf_core_parking {
|
||||
typedef struct xenpf_core_parking xenpf_core_parking_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xenpf_core_parking_t);
|
||||
|
@ -1,7 +1,5 @@
|
||||
Index: xen-4.2.0-testing/xen/arch/x86/domain.c
|
||||
===================================================================
|
||||
--- xen-4.2.0-testing.orig/xen/arch/x86/domain.c
|
||||
+++ xen-4.2.0-testing/xen/arch/x86/domain.c
|
||||
--- a/xen/arch/x86/domain.c
|
||||
+++ b/xen/arch/x86/domain.c
|
||||
@@ -148,15 +148,30 @@ void dump_pageframe_info(struct domain *
|
||||
|
||||
printk("Memory pages belonging to domain %u:\n", d->domain_id);
|
@ -1,71 +1,5 @@
|
||||
Index: xen-4.2.0-testing/xen/arch/x86/x86_32/entry.S
|
||||
===================================================================
|
||||
--- xen-4.2.0-testing.orig/xen/arch/x86/x86_32/entry.S
|
||||
+++ xen-4.2.0-testing/xen/arch/x86/x86_32/entry.S
|
||||
@@ -389,29 +389,41 @@ UNLIKELY_END(bounce_vm86_3)
|
||||
movl %eax,UREGS_eip+4(%esp)
|
||||
ret
|
||||
_ASM_EXTABLE(.Lft6, domain_crash_synchronous)
|
||||
- _ASM_EXTABLE(.Lft7, domain_crash_synchronous)
|
||||
- _ASM_EXTABLE(.Lft8, domain_crash_synchronous)
|
||||
- _ASM_EXTABLE(.Lft9, domain_crash_synchronous)
|
||||
- _ASM_EXTABLE(.Lft10, domain_crash_synchronous)
|
||||
- _ASM_EXTABLE(.Lft11, domain_crash_synchronous)
|
||||
- _ASM_EXTABLE(.Lft12, domain_crash_synchronous)
|
||||
+ _ASM_EXTABLE(.Lft7, domain_crash_page_fault)
|
||||
+ _ASM_EXTABLE(.Lft8, domain_crash_page_fault_4)
|
||||
+ _ASM_EXTABLE(.Lft9, domain_crash_page_fault_8)
|
||||
+ _ASM_EXTABLE(.Lft10, domain_crash_page_fault_12)
|
||||
+ _ASM_EXTABLE(.Lft11, domain_crash_page_fault)
|
||||
+ _ASM_EXTABLE(.Lft12, domain_crash_page_fault_4)
|
||||
_ASM_EXTABLE(.Lft13, domain_crash_synchronous)
|
||||
- _ASM_EXTABLE(.Lft14, domain_crash_synchronous)
|
||||
- _ASM_EXTABLE(.Lft15, domain_crash_synchronous)
|
||||
- _ASM_EXTABLE(.Lft16, domain_crash_synchronous)
|
||||
- _ASM_EXTABLE(.Lft17, domain_crash_synchronous)
|
||||
- _ASM_EXTABLE(.Lft18, domain_crash_synchronous)
|
||||
- _ASM_EXTABLE(.Lft19, domain_crash_synchronous)
|
||||
- _ASM_EXTABLE(.Lft20, domain_crash_synchronous)
|
||||
- _ASM_EXTABLE(.Lft21, domain_crash_synchronous)
|
||||
- _ASM_EXTABLE(.Lft22, domain_crash_synchronous)
|
||||
- _ASM_EXTABLE(.Lft23, domain_crash_synchronous)
|
||||
- _ASM_EXTABLE(.Lft24, domain_crash_synchronous)
|
||||
- _ASM_EXTABLE(.Lft25, domain_crash_synchronous)
|
||||
+ _ASM_EXTABLE(.Lft14, domain_crash_page_fault)
|
||||
+ _ASM_EXTABLE(.Lft15, domain_crash_page_fault_4)
|
||||
+ _ASM_EXTABLE(.Lft16, domain_crash_page_fault_8)
|
||||
+ _ASM_EXTABLE(.Lft17, domain_crash_page_fault)
|
||||
+ _ASM_EXTABLE(.Lft18, domain_crash_page_fault)
|
||||
+ _ASM_EXTABLE(.Lft19, domain_crash_page_fault_4)
|
||||
+ _ASM_EXTABLE(.Lft20, domain_crash_page_fault_8)
|
||||
+ _ASM_EXTABLE(.Lft21, domain_crash_page_fault_12)
|
||||
+ _ASM_EXTABLE(.Lft22, domain_crash_page_fault)
|
||||
+ _ASM_EXTABLE(.Lft23, domain_crash_page_fault_4)
|
||||
+ _ASM_EXTABLE(.Lft24, domain_crash_page_fault_8)
|
||||
+ _ASM_EXTABLE(.Lft25, domain_crash_page_fault_12)
|
||||
|
||||
+.section .rodata,"a"
|
||||
domain_crash_synchronous_string:
|
||||
.asciz "domain_crash_sync called from entry.S (%lx)\n"
|
||||
+.previous
|
||||
|
||||
+domain_crash_page_fault_12:
|
||||
+ addl $4,%esi
|
||||
+domain_crash_page_fault_8:
|
||||
+ addl $4,%esi
|
||||
+domain_crash_page_fault_4:
|
||||
+ addl $4,%esi
|
||||
+domain_crash_page_fault:
|
||||
+ pushl %esi
|
||||
+ call show_page_walk
|
||||
+ addl $4,%esp
|
||||
domain_crash_synchronous:
|
||||
pushl $domain_crash_synchronous_string
|
||||
call printk
|
||||
Index: xen-4.2.0-testing/xen/arch/x86/x86_64/entry.S
|
||||
===================================================================
|
||||
--- xen-4.2.0-testing.orig/xen/arch/x86/x86_64/entry.S
|
||||
+++ xen-4.2.0-testing/xen/arch/x86/x86_64/entry.S
|
||||
--- a/xen/arch/x86/x86_64/entry.S
|
||||
+++ b/xen/arch/x86/x86_64/entry.S
|
||||
@@ -427,22 +427,35 @@ UNLIKELY_END(bounce_failsafe)
|
||||
jz domain_crash_synchronous
|
||||
movq %rax,UREGS_rip+8(%rsp)
|
||||
@ -95,7 +29,7 @@ Index: xen-4.2.0-testing/xen/arch/x86/x86_64/entry.S
|
||||
+ _ASM_EXTABLE(.Lft12, domain_crash_page_fault_8)
|
||||
+ _ASM_EXTABLE(.Lft13, domain_crash_page_fault)
|
||||
|
||||
+.section .rodata,"a"
|
||||
+.section .rodata, "a", @progbits
|
||||
domain_crash_synchronous_string:
|
||||
.asciz "domain_crash_sync called from entry.S\n"
|
||||
+.previous
|
||||
|
@ -1,24 +1,16 @@
|
||||
Change default IO-APIC ack mode for single IO-APIC systems to old-style.
|
||||
|
||||
Index: xen-4.2.0-testing/xen/arch/x86/io_apic.c
|
||||
===================================================================
|
||||
--- xen-4.2.0-testing.orig/xen/arch/x86/io_apic.c
|
||||
+++ xen-4.2.0-testing/xen/arch/x86/io_apic.c
|
||||
@@ -43,7 +43,7 @@ static struct { int pin, apic; } ioapic_
|
||||
static DEFINE_SPINLOCK(ioapic_lock);
|
||||
|
||||
bool_t __read_mostly skip_ioapic_setup;
|
||||
-bool_t __read_mostly ioapic_ack_new = 1;
|
||||
+bool_t __read_mostly ioapic_ack_new = -1;
|
||||
bool_t __read_mostly ioapic_ack_forced = 0;
|
||||
|
||||
#ifndef sis_apic_bug
|
||||
@@ -2012,6 +2012,8 @@ void __init setup_IO_APIC(void)
|
||||
else
|
||||
--- a/xen/arch/x86/io_apic.c
|
||||
+++ b/xen/arch/x86/io_apic.c
|
||||
@@ -2013,7 +2013,10 @@ void __init setup_IO_APIC(void)
|
||||
io_apic_irqs = ~PIC_IRQS;
|
||||
|
||||
+ if (ioapic_ack_new < 0)
|
||||
+ ioapic_ack_new = (nr_ioapics > 1);
|
||||
printk("ENABLING IO-APIC IRQs\n");
|
||||
printk(" -> Using %s ACK method\n", ioapic_ack_new ? "new" : "old");
|
||||
- printk(" -> Using %s ACK method\n", ioapic_ack_new ? "new" : "old");
|
||||
+ if (!directed_eoi_enabled && !ioapic_ack_forced) {
|
||||
+ ioapic_ack_new = (nr_ioapics > 1);
|
||||
+ printk(" -> Using %s ACK method\n", ioapic_ack_new ? "new" : "old");
|
||||
+ }
|
||||
|
||||
/*
|
||||
* Set up IO-APIC IRQ routing.
|
||||
|
@ -1,7 +1,5 @@
|
||||
Index: xen-4.2.0-testing/tools/misc/gtraceview.c
|
||||
===================================================================
|
||||
--- xen-4.2.0-testing.orig/tools/misc/gtraceview.c
|
||||
+++ xen-4.2.0-testing/tools/misc/gtraceview.c
|
||||
--- a/tools/misc/gtraceview.c
|
||||
+++ b/tools/misc/gtraceview.c
|
||||
@@ -621,7 +621,8 @@ void crt_init(void)
|
||||
void nr_addch(int nr, int ch)
|
||||
{
|
||||
@ -12,10 +10,8 @@ Index: xen-4.2.0-testing/tools/misc/gtraceview.c
|
||||
getyx(stdscr, y, x);
|
||||
for (i = 0; i < nr; i++) {
|
||||
if (x == COLS-1)
|
||||
Index: xen-4.2.0-testing/tools/xcutils/xc_restore.c
|
||||
===================================================================
|
||||
--- xen-4.2.0-testing.orig/tools/xcutils/xc_restore.c
|
||||
+++ xen-4.2.0-testing/tools/xcutils/xc_restore.c
|
||||
--- a/tools/xcutils/xc_restore.c
|
||||
+++ b/tools/xcutils/xc_restore.c
|
||||
@@ -19,7 +19,8 @@ int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
@ -26,10 +22,8 @@ Index: xen-4.2.0-testing/tools/xcutils/xc_restore.c
|
||||
xc_interface *xch;
|
||||
int io_fd, ret;
|
||||
int superpages;
|
||||
Index: xen-4.2.0-testing/tools/firmware/rombios/32bit/tcgbios/tcgbios.c
|
||||
===================================================================
|
||||
--- xen-4.2.0-testing.orig/tools/firmware/rombios/32bit/tcgbios/tcgbios.c
|
||||
+++ xen-4.2.0-testing/tools/firmware/rombios/32bit/tcgbios/tcgbios.c
|
||||
--- a/tools/firmware/rombios/32bit/tcgbios/tcgbios.c
|
||||
+++ b/tools/firmware/rombios/32bit/tcgbios/tcgbios.c
|
||||
@@ -1064,7 +1064,7 @@ uint32_t HashLogEvent32(struct hlei *hle
|
||||
uint32_t rc = 0;
|
||||
uint16_t size;
|
||||
@ -39,10 +33,8 @@ Index: xen-4.2.0-testing/tools/firmware/rombios/32bit/tcgbios/tcgbios.c
|
||||
uint32_t hashdataptr;
|
||||
uint32_t hashdatalen;
|
||||
|
||||
Index: xen-4.2.0-testing/tools/console/client/main.c
|
||||
===================================================================
|
||||
--- xen-4.2.0-testing.orig/tools/console/client/main.c
|
||||
+++ xen-4.2.0-testing/tools/console/client/main.c
|
||||
--- a/tools/console/client/main.c
|
||||
+++ b/tools/console/client/main.c
|
||||
@@ -277,7 +277,8 @@ int main(int argc, char **argv)
|
||||
|
||||
};
|
||||
@ -53,10 +45,8 @@ Index: xen-4.2.0-testing/tools/console/client/main.c
|
||||
struct xs_handle *xs;
|
||||
char *end;
|
||||
console_type type = CONSOLE_INVAL;
|
||||
Index: xen-4.2.0-testing/tools/xenstat/xentop/xentop.c
|
||||
===================================================================
|
||||
--- xen-4.2.0-testing.orig/tools/xenstat/xentop/xentop.c
|
||||
+++ xen-4.2.0-testing/tools/xenstat/xentop/xentop.c
|
||||
--- a/tools/xenstat/xentop/xentop.c
|
||||
+++ b/tools/xenstat/xentop/xentop.c
|
||||
@@ -278,7 +278,8 @@ static void fail(const char *str)
|
||||
/* Return the row containing the cursor. */
|
||||
static int current_row(void)
|
||||
@ -77,11 +67,9 @@ Index: xen-4.2.0-testing/tools/xenstat/xentop/xentop.c
|
||||
getmaxyx(stdscr, y, x);
|
||||
return y;
|
||||
}
|
||||
Index: xen-4.2.0-testing/tools/libxl/libxlu_cfg.c
|
||||
===================================================================
|
||||
--- xen-4.2.0-testing.orig/tools/libxl/libxlu_cfg.c
|
||||
+++ xen-4.2.0-testing/tools/libxl/libxlu_cfg.c
|
||||
@@ -406,7 +406,7 @@ char *xlu__cfgl_dequote(CfgParseContext
|
||||
--- a/tools/libxl/libxlu_cfg.c
|
||||
+++ b/tools/libxl/libxlu_cfg.c
|
||||
@@ -406,7 +406,7 @@ char *xlu__cfgl_dequote(CfgParseContext
|
||||
|
||||
#define NUMERIC_CHAR(minlen,maxlen,base,basetext) do{ \
|
||||
char numbuf[(maxlen)+1], *ep; \
|
||||
@ -90,11 +78,9 @@ Index: xen-4.2.0-testing/tools/libxl/libxlu_cfg.c
|
||||
\
|
||||
strncpy(numbuf,p,(maxlen)); \
|
||||
numbuf[(maxlen)]= 0; \
|
||||
Index: xen-4.2.0-testing/tools/libxl/libxl_pci.c
|
||||
===================================================================
|
||||
--- xen-4.2.0-testing.orig/tools/libxl/libxl_pci.c
|
||||
+++ xen-4.2.0-testing/tools/libxl/libxl_pci.c
|
||||
@@ -71,7 +71,7 @@ int libxl__create_pci_backend(libxl__gc
|
||||
--- a/tools/libxl/libxl_pci.c
|
||||
+++ b/tools/libxl/libxl_pci.c
|
||||
@@ -71,7 +71,7 @@ int libxl__create_pci_backend(libxl__gc
|
||||
flexarray_t *front = NULL;
|
||||
flexarray_t *back = NULL;
|
||||
libxl__device device;
|
||||
@ -103,7 +89,7 @@ Index: xen-4.2.0-testing/tools/libxl/libxl_pci.c
|
||||
|
||||
front = flexarray_make(16, 1);
|
||||
if (!front)
|
||||
@@ -80,8 +80,6 @@ int libxl__create_pci_backend(libxl__gc
|
||||
@@ -80,8 +80,6 @@ int libxl__create_pci_backend(libxl__gc
|
||||
if (!back)
|
||||
goto out;
|
||||
|
||||
@ -112,10 +98,8 @@ Index: xen-4.2.0-testing/tools/libxl/libxl_pci.c
|
||||
LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Creating pci backend");
|
||||
|
||||
/* add pci device */
|
||||
Index: xen-4.2.0-testing/tools/libxl/libxl_dom.c
|
||||
===================================================================
|
||||
--- xen-4.2.0-testing.orig/tools/libxl/libxl_dom.c
|
||||
+++ xen-4.2.0-testing/tools/libxl/libxl_dom.c
|
||||
--- a/tools/libxl/libxl_dom.c
|
||||
+++ b/tools/libxl/libxl_dom.c
|
||||
@@ -565,7 +565,6 @@ int libxl__build_hvm(libxl__gc *gc, uint
|
||||
LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, ret, "hvm build set params failed");
|
||||
goto out;
|
||||
@ -124,10 +108,8 @@ Index: xen-4.2.0-testing/tools/libxl/libxl_dom.c
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
Index: xen-4.2.0-testing/tools/debugger/gdbsx/gx/gx_comm.c
|
||||
===================================================================
|
||||
--- xen-4.2.0-testing.orig/tools/debugger/gdbsx/gx/gx_comm.c
|
||||
+++ xen-4.2.0-testing/tools/debugger/gdbsx/gx/gx_comm.c
|
||||
--- a/tools/debugger/gdbsx/gx/gx_comm.c
|
||||
+++ b/tools/debugger/gdbsx/gx/gx_comm.c
|
||||
@@ -163,7 +163,7 @@ readchar(void)
|
||||
static char buf[BUFSIZ];
|
||||
static int bufcnt = 0;
|
||||
@ -137,10 +119,8 @@ Index: xen-4.2.0-testing/tools/debugger/gdbsx/gx/gx_comm.c
|
||||
|
||||
if (bufcnt-- > 0)
|
||||
return *bufp++ & 0x7f;
|
||||
Index: xen-4.2.0-testing/tools/python/xen/lowlevel/checkpoint/libcheckpoint.c
|
||||
===================================================================
|
||||
--- xen-4.2.0-testing.orig/tools/python/xen/lowlevel/checkpoint/libcheckpoint.c
|
||||
+++ xen-4.2.0-testing/tools/python/xen/lowlevel/checkpoint/libcheckpoint.c
|
||||
--- a/tools/python/xen/lowlevel/checkpoint/libcheckpoint.c
|
||||
+++ b/tools/python/xen/lowlevel/checkpoint/libcheckpoint.c
|
||||
@@ -836,7 +836,7 @@ static int create_suspend_thread(checkpo
|
||||
|
||||
static void stop_suspend_thread(checkpoint_state* s)
|
||||
@ -150,10 +130,8 @@ Index: xen-4.2.0-testing/tools/python/xen/lowlevel/checkpoint/libcheckpoint.c
|
||||
|
||||
s->done = 1;
|
||||
|
||||
Index: xen-4.2.0-testing/tools/python/xen/lowlevel/netlink/libnetlink.c
|
||||
===================================================================
|
||||
--- xen-4.2.0-testing.orig/tools/python/xen/lowlevel/netlink/libnetlink.c
|
||||
+++ xen-4.2.0-testing/tools/python/xen/lowlevel/netlink/libnetlink.c
|
||||
--- a/tools/python/xen/lowlevel/netlink/libnetlink.c
|
||||
+++ b/tools/python/xen/lowlevel/netlink/libnetlink.c
|
||||
@@ -433,7 +433,8 @@ int rtnl_from_file(FILE *rtnl, rtnl_filt
|
||||
nladdr.nl_groups = 0;
|
||||
|
||||
@ -164,10 +142,8 @@ Index: xen-4.2.0-testing/tools/python/xen/lowlevel/netlink/libnetlink.c
|
||||
int l;
|
||||
|
||||
status = fread(&buf, 1, sizeof(*h), rtnl);
|
||||
Index: xen-4.2.0-testing/xen/common/cpupool.c
|
||||
===================================================================
|
||||
--- xen-4.2.0-testing.orig/xen/common/cpupool.c
|
||||
+++ xen-4.2.0-testing/xen/common/cpupool.c
|
||||
--- a/xen/common/cpupool.c
|
||||
+++ b/xen/common/cpupool.c
|
||||
@@ -371,7 +371,7 @@ int cpupool_add_domain(struct domain *d,
|
||||
{
|
||||
struct cpupool *c;
|
||||
@ -188,10 +164,8 @@ Index: xen-4.2.0-testing/xen/common/cpupool.c
|
||||
|
||||
if ( d->cpupool == NULL )
|
||||
return;
|
||||
Index: xen-4.2.0-testing/xen/common/kexec.c
|
||||
===================================================================
|
||||
--- xen-4.2.0-testing.orig/xen/common/kexec.c
|
||||
+++ xen-4.2.0-testing/xen/common/kexec.c
|
||||
--- a/xen/common/kexec.c
|
||||
+++ b/xen/common/kexec.c
|
||||
@@ -817,7 +817,8 @@ static int kexec_exec(XEN_GUEST_HANDLE(v
|
||||
{
|
||||
xen_kexec_exec_t exec;
|
||||
@ -202,10 +176,8 @@ Index: xen-4.2.0-testing/xen/common/kexec.c
|
||||
|
||||
if ( unlikely(copy_from_guest(&exec, uarg, 1)) )
|
||||
return -EFAULT;
|
||||
Index: xen-4.2.0-testing/xen/arch/x86/time.c
|
||||
===================================================================
|
||||
--- xen-4.2.0-testing.orig/xen/arch/x86/time.c
|
||||
+++ xen-4.2.0-testing/xen/arch/x86/time.c
|
||||
--- a/xen/arch/x86/time.c
|
||||
+++ b/xen/arch/x86/time.c
|
||||
@@ -1012,7 +1012,8 @@ static void local_time_calibration(void)
|
||||
* System timestamps, extrapolated from local and master oscillators,
|
||||
* taken during this calibration and the previous calibration.
|
||||
@ -216,11 +188,9 @@ Index: xen-4.2.0-testing/xen/arch/x86/time.c
|
||||
s_time_t prev_master_stime, curr_master_stime;
|
||||
|
||||
/* TSC timestamps taken during this calibration and prev calibration. */
|
||||
Index: xen-4.2.0-testing/xen/arch/x86/mm/p2m.c
|
||||
===================================================================
|
||||
--- xen-4.2.0-testing.orig/xen/arch/x86/mm/p2m.c
|
||||
+++ xen-4.2.0-testing/xen/arch/x86/mm/p2m.c
|
||||
@@ -483,7 +483,7 @@ p2m_remove_page(struct p2m_domain *p2m,
|
||||
--- a/xen/arch/x86/mm/p2m.c
|
||||
+++ b/xen/arch/x86/mm/p2m.c
|
||||
@@ -483,7 +483,7 @@ p2m_remove_page(struct p2m_domain *p2m,
|
||||
unsigned int page_order)
|
||||
{
|
||||
unsigned long i;
|
||||
@ -229,10 +199,8 @@ Index: xen-4.2.0-testing/xen/arch/x86/mm/p2m.c
|
||||
p2m_type_t t;
|
||||
p2m_access_t a;
|
||||
|
||||
Index: xen-4.2.0-testing/xen/arch/x86/cpu/intel_cacheinfo.c
|
||||
===================================================================
|
||||
--- xen-4.2.0-testing.orig/xen/arch/x86/cpu/intel_cacheinfo.c
|
||||
+++ xen-4.2.0-testing/xen/arch/x86/cpu/intel_cacheinfo.c
|
||||
--- a/xen/arch/x86/cpu/intel_cacheinfo.c
|
||||
+++ b/xen/arch/x86/cpu/intel_cacheinfo.c
|
||||
@@ -169,7 +169,8 @@ unsigned int __cpuinit init_intel_cachei
|
||||
unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
|
||||
unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
|
||||
@ -243,10 +211,8 @@ Index: xen-4.2.0-testing/xen/arch/x86/cpu/intel_cacheinfo.c
|
||||
|
||||
if (c->cpuid_level > 3) {
|
||||
static int is_initialized;
|
||||
Index: xen-4.2.0-testing/xen/arch/x86/hvm/viridian.c
|
||||
===================================================================
|
||||
--- xen-4.2.0-testing.orig/xen/arch/x86/hvm/viridian.c
|
||||
+++ xen-4.2.0-testing/xen/arch/x86/hvm/viridian.c
|
||||
--- a/xen/arch/x86/hvm/viridian.c
|
||||
+++ b/xen/arch/x86/hvm/viridian.c
|
||||
@@ -317,7 +317,7 @@ int rdmsr_viridian_regs(uint32_t idx, ui
|
||||
int viridian_hypercall(struct cpu_user_regs *regs)
|
||||
{
|
||||
@ -256,11 +222,9 @@ Index: xen-4.2.0-testing/xen/arch/x86/hvm/viridian.c
|
||||
uint16_t status = HV_STATUS_SUCCESS;
|
||||
|
||||
union hypercall_input {
|
||||
Index: xen-4.2.0-testing/xen/arch/x86/mm.c
|
||||
===================================================================
|
||||
--- xen-4.2.0-testing.orig/xen/arch/x86/mm.c
|
||||
+++ xen-4.2.0-testing/xen/arch/x86/mm.c
|
||||
@@ -4969,7 +4969,7 @@ static int ptwr_emulated_update(
|
||||
--- a/xen/arch/x86/mm.c
|
||||
+++ b/xen/arch/x86/mm.c
|
||||
@@ -4973,7 +4973,7 @@ static int ptwr_emulated_update(
|
||||
{
|
||||
unsigned long mfn;
|
||||
unsigned long unaligned_addr = addr;
|
||||
@ -269,11 +233,9 @@ Index: xen-4.2.0-testing/xen/arch/x86/mm.c
|
||||
l1_pgentry_t pte, ol1e, nl1e, *pl1e;
|
||||
struct vcpu *v = current;
|
||||
struct domain *d = v->domain;
|
||||
Index: xen-4.2.0-testing/xen/common/tmem.c
|
||||
===================================================================
|
||||
--- xen-4.2.0-testing.orig/xen/common/tmem.c
|
||||
+++ xen-4.2.0-testing/xen/common/tmem.c
|
||||
@@ -1348,7 +1348,8 @@ obj_unlock:
|
||||
--- a/xen/common/tmem.c
|
||||
+++ b/xen/common/tmem.c
|
||||
@@ -1352,7 +1352,8 @@ obj_unlock:
|
||||
static int tmem_evict(void)
|
||||
{
|
||||
client_t *client = tmh_client_from_current();
|
||||
@ -283,8 +245,8 @@ Index: xen-4.2.0-testing/xen/common/tmem.c
|
||||
obj_t *obj;
|
||||
pool_t *pool;
|
||||
int ret = 0;
|
||||
@@ -1585,7 +1586,8 @@ static NOINLINE int do_tmem_put(pool_t *
|
||||
pagesize_t pfn_offset, pagesize_t len, void *cva)
|
||||
@@ -1589,7 +1590,8 @@ static NOINLINE int do_tmem_put(pool_t *
|
||||
pagesize_t pfn_offset, pagesize_t len, tmem_cli_va_t clibuf)
|
||||
{
|
||||
obj_t *obj = NULL, *objfound = NULL, *objnew = NULL;
|
||||
- pgp_t *pgp = NULL, *pgpdel = NULL;
|
||||
@ -293,29 +255,27 @@ Index: xen-4.2.0-testing/xen/common/tmem.c
|
||||
client_t *client = pool->client;
|
||||
int ret = client->frozen ? -EFROZEN : -ENOMEM;
|
||||
|
||||
Index: xen-4.2.0-testing/xen/common/tmem_xen.c
|
||||
===================================================================
|
||||
--- xen-4.2.0-testing.orig/xen/common/tmem_xen.c
|
||||
+++ xen-4.2.0-testing/xen/common/tmem_xen.c
|
||||
@@ -181,7 +181,7 @@ EXPORT int tmh_copy_from_client(pfp_t *p
|
||||
--- a/xen/common/tmem_xen.c
|
||||
+++ b/xen/common/tmem_xen.c
|
||||
@@ -196,7 +196,7 @@ EXPORT int tmh_copy_from_client(pfp_t *p
|
||||
EXPORT int tmh_compress_from_client(tmem_cli_mfn_t cmfn,
|
||||
void **out_va, size_t *out_len, void *cli_va)
|
||||
void **out_va, size_t *out_len, tmem_cli_va_t clibuf)
|
||||
{
|
||||
- int ret = 0;
|
||||
+ int __attribute__((__unused__)) ret = 0;
|
||||
unsigned char *dmem = this_cpu(dstmem);
|
||||
unsigned char *wmem = this_cpu(workmem);
|
||||
pfp_t *cli_pfp = NULL;
|
||||
@@ -241,7 +241,7 @@ EXPORT int tmh_decompress_to_client(tmem
|
||||
pfp_t *cli_pfp = NULL;
|
||||
char *scratch = this_cpu(scratch_page);
|
||||
@@ -272,7 +272,7 @@ EXPORT int tmh_decompress_to_client(tmem
|
||||
void *cli_va = NULL;
|
||||
char *scratch = this_cpu(scratch_page);
|
||||
size_t out_len = PAGE_SIZE;
|
||||
bool_t tmemc = cli_va != NULL; /* if true, cli_va is control-op buffer */
|
||||
- int ret;
|
||||
+ int __attribute__((__unused__)) ret;
|
||||
|
||||
if ( !tmemc )
|
||||
if ( guest_handle_is_null(clibuf) )
|
||||
{
|
||||
@@ -370,15 +370,17 @@ static void tmh_persistent_pool_page_put
|
||||
@@ -405,15 +405,17 @@ static void tmh_persistent_pool_page_put
|
||||
EXPORT tmh_client_t *tmh_client_init(cli_id_t cli_id)
|
||||
{
|
||||
tmh_client_t *tmh;
|
||||
@ -334,11 +294,9 @@ Index: xen-4.2.0-testing/xen/common/tmem_xen.c
|
||||
tmh->persistent_pool = xmem_pool_create(name, tmh_persistent_pool_page_get,
|
||||
tmh_persistent_pool_page_put, PAGE_SIZE, 0, PAGE_SIZE);
|
||||
if ( tmh->persistent_pool == NULL )
|
||||
Index: xen-4.2.0-testing/xen/arch/x86/mm/shadow/multi.c
|
||||
===================================================================
|
||||
--- xen-4.2.0-testing.orig/xen/arch/x86/mm/shadow/multi.c
|
||||
+++ xen-4.2.0-testing/xen/arch/x86/mm/shadow/multi.c
|
||||
@@ -124,7 +124,7 @@ set_shadow_status(struct vcpu *v, mfn_t
|
||||
--- a/xen/arch/x86/mm/shadow/multi.c
|
||||
+++ b/xen/arch/x86/mm/shadow/multi.c
|
||||
@@ -124,7 +124,7 @@ set_shadow_status(struct vcpu *v, mfn_t
|
||||
/* Put a shadow into the hash table */
|
||||
{
|
||||
struct domain *d = v->domain;
|
||||
@ -356,10 +314,8 @@ Index: xen-4.2.0-testing/xen/arch/x86/mm/shadow/multi.c
|
||||
shadow_l1e_t *sl1p, sl1e;
|
||||
struct page_info *sp;
|
||||
|
||||
Index: xen-4.2.0-testing/xen/arch/x86/domain_build.c
|
||||
===================================================================
|
||||
--- xen-4.2.0-testing.orig/xen/arch/x86/domain_build.c
|
||||
+++ xen-4.2.0-testing/xen/arch/x86/domain_build.c
|
||||
--- a/xen/arch/x86/domain_build.c
|
||||
+++ b/xen/arch/x86/domain_build.c
|
||||
@@ -377,8 +377,7 @@ int __init construct_dom0(
|
||||
return rc;
|
||||
|
||||
@ -370,11 +326,9 @@ Index: xen-4.2.0-testing/xen/arch/x86/domain_build.c
|
||||
machine = elf_uval(&elf, elf.ehdr, e_machine);
|
||||
switch (CONFIG_PAGING_LEVELS) {
|
||||
case 3: /* x86_32p */
|
||||
Index: xen-4.2.0-testing/xen/arch/x86/traps.c
|
||||
===================================================================
|
||||
--- xen-4.2.0-testing.orig/xen/arch/x86/traps.c
|
||||
+++ xen-4.2.0-testing/xen/arch/x86/traps.c
|
||||
@@ -1910,7 +1910,11 @@ static int emulate_privileged_op(struct
|
||||
--- a/xen/arch/x86/traps.c
|
||||
+++ b/xen/arch/x86/traps.c
|
||||
@@ -1910,7 +1910,11 @@ static int emulate_privileged_op(struct
|
||||
struct vcpu *v = current;
|
||||
unsigned long *reg, eip = regs->eip;
|
||||
u8 opcode, modrm_reg = 0, modrm_rm = 0, rep_prefix = 0, lock = 0, rex = 0;
|
||||
|
27
xen.changes
27
xen.changes
@ -1,3 +1,30 @@
|
||||
-------------------------------------------------------------------
|
||||
Wed Sep 19 09:43:42 MDT 2012 - carnold@novell.com
|
||||
|
||||
- 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
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Sep 18 16:16:04 MDT 2012 - carnold@novell.com
|
||||
|
||||
|
59
xen.spec
59
xen.spec
@ -15,6 +15,7 @@
|
||||
# Please submit bugfixes or comments via http://bugs.opensuse.org/
|
||||
#
|
||||
|
||||
|
||||
Name: xen
|
||||
ExclusiveArch: %ix86 x86_64
|
||||
%define xvers 4.2
|
||||
@ -162,6 +163,28 @@ Source99: baselibs.conf
|
||||
# http://xenbits.xensource.com/ext/xenalyze
|
||||
Source20000: xenalyze.hg.tar.bz2
|
||||
# Upstream patches
|
||||
Patch25833: 25833-32on64-bogus-pt_base-adjust.patch
|
||||
Patch25835: 25835-adjust-rcu-lock-domain.patch
|
||||
Patch25836: 25836-VT-d-S3-MSI-resume.patch
|
||||
Patch25850: 25850-tmem-xsa-15-1.patch
|
||||
Patch25851: 25851-tmem-xsa-15-2.patch
|
||||
Patch25852: 25852-tmem-xsa-15-3.patch
|
||||
Patch25853: 25853-tmem-xsa-15-4.patch
|
||||
Patch25854: 25854-tmem-xsa-15-5.patch
|
||||
Patch25855: 25855-tmem-xsa-15-6.patch
|
||||
Patch25856: 25856-tmem-xsa-15-7.patch
|
||||
Patch25857: 25857-tmem-xsa-15-8.patch
|
||||
Patch25858: 25858-tmem-xsa-15-9.patch
|
||||
Patch25859: 25859-tmem-missing-break.patch
|
||||
Patch25860: 25860-tmem-cleanup.patch
|
||||
Patch25861: 25861-x86-early-fixmap.patch
|
||||
Patch25862: 25862-sercon-non-com.patch
|
||||
Patch25863: 25863-sercon-ehci-dbgp.patch
|
||||
Patch25864: 25864-sercon-unused.patch
|
||||
Patch25866: 25866-sercon-ns16550-pci-irq.patch
|
||||
Patch25867: 25867-sercon-ns16550-parse.patch
|
||||
Patch25874: 25874-x86-EFI-chain-cfg.patch
|
||||
Patch25909: 25909-xenpm-consistent.patch
|
||||
# Upstream qemu patches
|
||||
# Our patches
|
||||
Patch301: xend-config.diff
|
||||
@ -268,11 +291,11 @@ Patch481: xend-domain-lock-sfex.patch
|
||||
Patch500: 32on64-extra-mem.patch
|
||||
Patch501: x86-ioapic-ack-default.patch
|
||||
Patch502: x86-cpufreq-report.patch
|
||||
Patch504: dom-print.patch
|
||||
Patch505: pvdrv-import-shared-info.patch
|
||||
Patch507: x86-extra-trap-info.patch
|
||||
Patch508: pvdrv_emulation_control.patch
|
||||
Patch509: blktap-pv-cdrom.patch
|
||||
Patch503: x86-dom-print.patch
|
||||
Patch504: pvdrv-import-shared-info.patch
|
||||
Patch505: x86-extra-trap-info.patch
|
||||
Patch506: pvdrv_emulation_control.patch
|
||||
Patch507: blktap-pv-cdrom.patch
|
||||
Patch510: pv-driver-build.patch
|
||||
Patch511: supported_module.diff
|
||||
Patch512: magic_ioport_compat.patch
|
||||
@ -623,6 +646,28 @@ Authors:
|
||||
tar xfj %{SOURCE6} -C $RPM_BUILD_DIR/%{xen_build_dir}/tools
|
||||
%patch20000 -p1
|
||||
# Upstream patches
|
||||
%patch25833 -p1
|
||||
%patch25835 -p1
|
||||
%patch25836 -p1
|
||||
%patch25850 -p1
|
||||
%patch25851 -p1
|
||||
%patch25852 -p1
|
||||
%patch25853 -p1
|
||||
%patch25854 -p1
|
||||
%patch25855 -p1
|
||||
%patch25856 -p1
|
||||
%patch25857 -p1
|
||||
%patch25858 -p1
|
||||
%patch25859 -p1
|
||||
%patch25860 -p1
|
||||
%patch25861 -p1
|
||||
%patch25862 -p1
|
||||
%patch25863 -p1
|
||||
%patch25864 -p1
|
||||
%patch25866 -p1
|
||||
%patch25867 -p1
|
||||
%patch25874 -p1
|
||||
%patch25909 -p1
|
||||
# Qemu
|
||||
# Our patches
|
||||
%patch301 -p1
|
||||
@ -724,11 +769,11 @@ tar xfj %{SOURCE6} -C $RPM_BUILD_DIR/%{xen_build_dir}/tools
|
||||
%patch500 -p1
|
||||
%patch501 -p1
|
||||
%patch502 -p1
|
||||
%patch503 -p1
|
||||
%patch504 -p1
|
||||
%patch505 -p1
|
||||
%patch506 -p1
|
||||
%patch507 -p1
|
||||
%patch508 -p1
|
||||
%patch509 -p1
|
||||
%if %suse_version < 1220
|
||||
%patch510 -p1
|
||||
%endif
|
||||
|
Loading…
Reference in New Issue
Block a user