Skip to content

Commit

Permalink
Merge tag 'stable/for-linus-3.5-rc0-tag' of git://git.kernel.org/pub/…
Browse files Browse the repository at this point in the history
…scm/linux/kernel/git/konrad/xen

Pull Xen updates from Konrad Rzeszutek Wilk:
 "Features:
   * Extend the APIC ops implementation and add IRQ_WORKER vector
     support so that 'perf' can work properly.
   * Fix self-ballooning code, and balloon logic when booting as initial
     domain.
   * Move array printing code to generic debugfs
   * Support XenBus domains.
   * Lazily free grants when a domain is dead/non-existent.
   * In M2P code use batching calls
  Bug-fixes:
   * Fix NULL dereference in allocation failure path (hvc_xen)
   * Fix unbinding of IRQ_WORKER vector during vCPU hot-unplug
   * Fix HVM guest resume - we would leak an PIRQ value instead of
     reusing the existing one."

Fix up add-add onflicts in arch/x86/xen/enlighten.c due to addition of
apic ipi interface next to the new apic_id functions.

* tag 'stable/for-linus-3.5-rc0-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen:
  xen: do not map the same GSI twice in PVHVM guests.
  hvc_xen: NULL dereference on allocation failure
  xen: Add selfballoning memory reservation tunable.
  xenbus: Add support for xenbus backend in stub domain
  xen/smp: unbind irqworkX when unplugging vCPUs.
  xen: enter/exit lazy_mmu_mode around m2p_override calls
  xen/acpi/sleep: Enable ACPI sleep via the __acpi_os_prepare_sleep
  xen: implement IRQ_WORK_VECTOR handler
  xen: implement apic ipi interface
  xen/setup: update VA mapping when releasing memory during setup
  xen/setup: Combine the two hypercall functions - since they are quite similar.
  xen/setup: Populate freed MFNs from non-RAM E820 entries and gaps to E820 RAM
  xen/setup: Only print "Freeing XXX-YYY pfn range: Z pages freed" if Z > 0
  xen/gnttab: add deferred freeing logic
  debugfs: Add support to print u32 array in debugfs
  xen/p2m: An early bootup variant of set_phys_to_machine
  xen/p2m: Collapse early_alloc_p2m_middle redundant checks.
  xen/p2m: Allow alloc_p2m_middle to call reserve_brk depending on argument
  xen/p2m: Move code around to allow for better re-usage.
  • Loading branch information
Linus Torvalds committed May 24, 2012
2 parents ce00417 + 68c2c39 commit b5f4035
Show file tree
Hide file tree
Showing 27 changed files with 827 additions and 226 deletions.
1 change: 1 addition & 0 deletions arch/x86/include/asm/xen/events.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ enum ipi_vector {
XEN_CALL_FUNCTION_VECTOR,
XEN_CALL_FUNCTION_SINGLE_VECTOR,
XEN_SPIN_UNLOCK_VECTOR,
XEN_IRQ_WORK_VECTOR,

XEN_NR_IPIS,
};
Expand Down
1 change: 1 addition & 0 deletions arch/x86/include/asm/xen/page.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ extern unsigned long machine_to_phys_nr;

extern unsigned long get_phys_to_machine(unsigned long pfn);
extern bool set_phys_to_machine(unsigned long pfn, unsigned long mfn);
extern bool __init early_set_phys_to_machine(unsigned long pfn, unsigned long mfn);
extern bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn);
extern unsigned long set_phys_range_identity(unsigned long pfn_s,
unsigned long pfn_e);
Expand Down
4 changes: 4 additions & 0 deletions arch/x86/pci/xen.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ static int xen_register_pirq(u32 gsi, int gsi_override, int triggering,
int shareable = 0;
char *name;

irq = xen_irq_from_gsi(gsi);
if (irq > 0)
return irq;

if (set_pirq)
pirq = gsi;

Expand Down
104 changes: 0 additions & 104 deletions arch/x86/xen/debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,107 +19,3 @@ struct dentry * __init xen_init_debugfs(void)
return d_xen_debug;
}

struct array_data
{
void *array;
unsigned elements;
};

static int u32_array_open(struct inode *inode, struct file *file)
{
file->private_data = NULL;
return nonseekable_open(inode, file);
}

static size_t format_array(char *buf, size_t bufsize, const char *fmt,
u32 *array, unsigned array_size)
{
size_t ret = 0;
unsigned i;

for(i = 0; i < array_size; i++) {
size_t len;

len = snprintf(buf, bufsize, fmt, array[i]);
len++; /* ' ' or '\n' */
ret += len;

if (buf) {
buf += len;
bufsize -= len;
buf[-1] = (i == array_size-1) ? '\n' : ' ';
}
}

ret++; /* \0 */
if (buf)
*buf = '\0';

return ret;
}

static char *format_array_alloc(const char *fmt, u32 *array, unsigned array_size)
{
size_t len = format_array(NULL, 0, fmt, array, array_size);
char *ret;

ret = kmalloc(len, GFP_KERNEL);
if (ret == NULL)
return NULL;

format_array(ret, len, fmt, array, array_size);
return ret;
}

static ssize_t u32_array_read(struct file *file, char __user *buf, size_t len,
loff_t *ppos)
{
struct inode *inode = file->f_path.dentry->d_inode;
struct array_data *data = inode->i_private;
size_t size;

if (*ppos == 0) {
if (file->private_data) {
kfree(file->private_data);
file->private_data = NULL;
}

file->private_data = format_array_alloc("%u", data->array, data->elements);
}

size = 0;
if (file->private_data)
size = strlen(file->private_data);

return simple_read_from_buffer(buf, len, ppos, file->private_data, size);
}

static int xen_array_release(struct inode *inode, struct file *file)
{
kfree(file->private_data);

return 0;
}

static const struct file_operations u32_array_fops = {
.owner = THIS_MODULE,
.open = u32_array_open,
.release= xen_array_release,
.read = u32_array_read,
.llseek = no_llseek,
};

struct dentry *xen_debugfs_create_u32_array(const char *name, umode_t mode,
struct dentry *parent,
u32 *array, unsigned elements)
{
struct array_data *data = kmalloc(sizeof(*data), GFP_KERNEL);

if (data == NULL)
return NULL;

data->array = array;
data->elements = elements;

return debugfs_create_file(name, mode, parent, data, &u32_array_fops);
}
4 changes: 0 additions & 4 deletions arch/x86/xen/debugfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,4 @@

struct dentry * __init xen_init_debugfs(void);

struct dentry *xen_debugfs_create_u32_array(const char *name, umode_t mode,
struct dentry *parent,
u32 *array, unsigned elements);

#endif /* _XEN_DEBUGFS_H */
13 changes: 12 additions & 1 deletion arch/x86/xen/enlighten.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include <xen/page.h>
#include <xen/hvm.h>
#include <xen/hvc-console.h>
#include <xen/acpi.h>

#include <asm/paravirt.h>
#include <asm/apic.h>
Expand Down Expand Up @@ -75,6 +76,7 @@

#include "xen-ops.h"
#include "mmu.h"
#include "smp.h"
#include "multicalls.h"

EXPORT_SYMBOL_GPL(hypercall_page);
Expand Down Expand Up @@ -883,6 +885,14 @@ static void set_xen_basic_apic_ops(void)
apic->safe_wait_icr_idle = xen_safe_apic_wait_icr_idle;
apic->set_apic_id = xen_set_apic_id;
apic->get_apic_id = xen_get_apic_id;

#ifdef CONFIG_SMP
apic->send_IPI_allbutself = xen_send_IPI_allbutself;
apic->send_IPI_mask_allbutself = xen_send_IPI_mask_allbutself;
apic->send_IPI_mask = xen_send_IPI_mask;
apic->send_IPI_all = xen_send_IPI_all;
apic->send_IPI_self = xen_send_IPI_self;
#endif
}

#endif
Expand Down Expand Up @@ -1340,7 +1350,6 @@ asmlinkage void __init xen_start_kernel(void)

xen_raw_console_write("mapping kernel into physical memory\n");
pgd = xen_setup_kernel_pagetable(pgd, xen_start_info->nr_pages);
xen_ident_map_ISA();

/* Allocate and initialize top and mid mfn levels for p2m structure */
xen_build_mfn_list_list();
Expand Down Expand Up @@ -1400,6 +1409,8 @@ asmlinkage void __init xen_start_kernel(void)

/* Make sure ACS will be enabled */
pci_request_acs();

xen_acpi_sleep_register();
}
#ifdef CONFIG_PCI
/* PCI BIOS service won't work from a PV guest. */
Expand Down
23 changes: 0 additions & 23 deletions arch/x86/xen/mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1933,29 +1933,6 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
#endif
}

void __init xen_ident_map_ISA(void)
{
unsigned long pa;

/*
* If we're dom0, then linear map the ISA machine addresses into
* the kernel's address space.
*/
if (!xen_initial_domain())
return;

xen_raw_printk("Xen: setup ISA identity maps\n");

for (pa = ISA_START_ADDRESS; pa < ISA_END_ADDRESS; pa += PAGE_SIZE) {
pte_t pte = mfn_pte(PFN_DOWN(pa), PAGE_KERNEL_IO);

if (HYPERVISOR_update_va_mapping(PAGE_OFFSET + pa, pte, 0))
BUG();
}

xen_flush_tlb();
}

static void __init xen_post_allocator_init(void)
{
pv_mmu_ops.set_pte = xen_set_pte;
Expand Down
104 changes: 62 additions & 42 deletions arch/x86/xen/p2m.c
Original file line number Diff line number Diff line change
Expand Up @@ -499,16 +499,18 @@ static bool alloc_p2m(unsigned long pfn)
return true;
}

static bool __init __early_alloc_p2m(unsigned long pfn)
static bool __init early_alloc_p2m_middle(unsigned long pfn, bool check_boundary)
{
unsigned topidx, mididx, idx;
unsigned long *p2m;
unsigned long *mid_mfn_p;

topidx = p2m_top_index(pfn);
mididx = p2m_mid_index(pfn);
idx = p2m_index(pfn);

/* Pfff.. No boundary cross-over, lets get out. */
if (!idx)
if (!idx && check_boundary)
return false;

WARN(p2m_top[topidx][mididx] == p2m_identity,
Expand All @@ -522,24 +524,66 @@ static bool __init __early_alloc_p2m(unsigned long pfn)
return false;

/* Boundary cross-over for the edges: */
if (idx) {
unsigned long *p2m = extend_brk(PAGE_SIZE, PAGE_SIZE);
unsigned long *mid_mfn_p;
p2m = extend_brk(PAGE_SIZE, PAGE_SIZE);

p2m_init(p2m);
p2m_init(p2m);

p2m_top[topidx][mididx] = p2m;
p2m_top[topidx][mididx] = p2m;

/* For save/restore we need to MFN of the P2M saved */

mid_mfn_p = p2m_top_mfn_p[topidx];
WARN(mid_mfn_p[mididx] != virt_to_mfn(p2m_missing),
"P2M_TOP_P[%d][%d] != MFN of p2m_missing!\n",
topidx, mididx);
mid_mfn_p[mididx] = virt_to_mfn(p2m);
/* For save/restore we need to MFN of the P2M saved */

mid_mfn_p = p2m_top_mfn_p[topidx];
WARN(mid_mfn_p[mididx] != virt_to_mfn(p2m_missing),
"P2M_TOP_P[%d][%d] != MFN of p2m_missing!\n",
topidx, mididx);
mid_mfn_p[mididx] = virt_to_mfn(p2m);

return true;
}

static bool __init early_alloc_p2m(unsigned long pfn)
{
unsigned topidx = p2m_top_index(pfn);
unsigned long *mid_mfn_p;
unsigned long **mid;

mid = p2m_top[topidx];
mid_mfn_p = p2m_top_mfn_p[topidx];
if (mid == p2m_mid_missing) {
mid = extend_brk(PAGE_SIZE, PAGE_SIZE);

p2m_mid_init(mid);

p2m_top[topidx] = mid;

BUG_ON(mid_mfn_p != p2m_mid_missing_mfn);
}
return idx != 0;
/* And the save/restore P2M tables.. */
if (mid_mfn_p == p2m_mid_missing_mfn) {
mid_mfn_p = extend_brk(PAGE_SIZE, PAGE_SIZE);
p2m_mid_mfn_init(mid_mfn_p);

p2m_top_mfn_p[topidx] = mid_mfn_p;
p2m_top_mfn[topidx] = virt_to_mfn(mid_mfn_p);
/* Note: we don't set mid_mfn_p[midix] here,
* look in early_alloc_p2m_middle */
}
return true;
}
bool __init early_set_phys_to_machine(unsigned long pfn, unsigned long mfn)
{
if (unlikely(!__set_phys_to_machine(pfn, mfn))) {
if (!early_alloc_p2m(pfn))
return false;

if (!early_alloc_p2m_middle(pfn, false /* boundary crossover OK!*/))
return false;

if (!__set_phys_to_machine(pfn, mfn))
return false;
}

return true;
}
unsigned long __init set_phys_range_identity(unsigned long pfn_s,
unsigned long pfn_e)
Expand All @@ -559,35 +603,11 @@ unsigned long __init set_phys_range_identity(unsigned long pfn_s,
pfn < ALIGN(pfn_e, (P2M_MID_PER_PAGE * P2M_PER_PAGE));
pfn += P2M_MID_PER_PAGE * P2M_PER_PAGE)
{
unsigned topidx = p2m_top_index(pfn);
unsigned long *mid_mfn_p;
unsigned long **mid;

mid = p2m_top[topidx];
mid_mfn_p = p2m_top_mfn_p[topidx];
if (mid == p2m_mid_missing) {
mid = extend_brk(PAGE_SIZE, PAGE_SIZE);

p2m_mid_init(mid);

p2m_top[topidx] = mid;

BUG_ON(mid_mfn_p != p2m_mid_missing_mfn);
}
/* And the save/restore P2M tables.. */
if (mid_mfn_p == p2m_mid_missing_mfn) {
mid_mfn_p = extend_brk(PAGE_SIZE, PAGE_SIZE);
p2m_mid_mfn_init(mid_mfn_p);

p2m_top_mfn_p[topidx] = mid_mfn_p;
p2m_top_mfn[topidx] = virt_to_mfn(mid_mfn_p);
/* Note: we don't set mid_mfn_p[midix] here,
* look in __early_alloc_p2m */
}
WARN_ON(!early_alloc_p2m(pfn));
}

__early_alloc_p2m(pfn_s);
__early_alloc_p2m(pfn_e);
early_alloc_p2m_middle(pfn_s, true);
early_alloc_p2m_middle(pfn_e, true);

for (pfn = pfn_s; pfn < pfn_e; pfn++)
if (!__set_phys_to_machine(pfn, IDENTITY_FRAME(pfn)))
Expand Down
Loading

0 comments on commit b5f4035

Please sign in to comment.