Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://xenbits.xen.org/people/sstabellini/…
Browse files Browse the repository at this point in the history
…linux-pvhvm

* 'for-linus' of git://xenbits.xen.org/people/sstabellini/linux-pvhvm:
  xen: suspend: remove xen_hvm_suspend
  xen: suspend: pull pre/post suspend hooks out into suspend_info
  xen: suspend: move arch specific pre/post suspend hooks into generic hooks
  xen: suspend: refactor non-arch specific pre/post suspend hooks
  xen: suspend: add "arch" to pre/post suspend hooks
  xen: suspend: pass extra hypercall argument via suspend_info struct
  xen: suspend: refactor cancellation flag into a structure
  xen: suspend: use HYPERVISOR_suspend for PVHVM case instead of open coding
  xen: switch to new schedop hypercall by default.
  xen: use new schedop interface for suspend
  xen: do not respond to unknown xenstore control requests
  xen: fix compile issue if XEN is enabled but XEN_PVHVM is disabled
  xen: PV on HVM: support PV spinlocks and IPIs
  xen: make the ballon driver work for hvm domains
  xen-blkfront: handle Xen major numbers other than XENVBD
  xen: do not use xen_info on HVM, set pv_info name to "Xen HVM"
  xen: no need to delay xen_setup_shutdown_event for hvm guests anymore
  • Loading branch information
Linus Torvalds committed Mar 15, 2011
2 parents 27d2a8b + b056b6a commit 76ca078
Show file tree
Hide file tree
Showing 13 changed files with 257 additions and 101 deletions.
9 changes: 2 additions & 7 deletions arch/ia64/xen/suspend.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,14 @@ xen_mm_unpin_all(void)
/* nothing */
}

void xen_pre_device_suspend(void)
{
/* nothing */
}

void
xen_pre_suspend()
xen_arch_pre_suspend()
{
/* nothing */
}

void
xen_post_suspend(int suspend_cancelled)
xen_arch_post_suspend(int suspend_cancelled)
{
if (suspend_cancelled)
return;
Expand Down
15 changes: 11 additions & 4 deletions arch/x86/include/asm/xen/hypercall.h
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ HYPERVISOR_fpu_taskswitch(int set)
static inline int
HYPERVISOR_sched_op(int cmd, void *arg)
{
return _hypercall2(int, sched_op_new, cmd, arg);
return _hypercall2(int, sched_op, cmd, arg);
}

static inline long
Expand Down Expand Up @@ -422,10 +422,17 @@ HYPERVISOR_set_segment_base(int reg, unsigned long value)
#endif

static inline int
HYPERVISOR_suspend(unsigned long srec)
HYPERVISOR_suspend(unsigned long start_info_mfn)
{
return _hypercall3(int, sched_op, SCHEDOP_shutdown,
SHUTDOWN_suspend, srec);
struct sched_shutdown r = { .reason = SHUTDOWN_suspend };

/*
* For a PV guest the tools require that the start_info mfn be
* present in rdx/edx when the hypercall is made. Per the
* hypercall calling convention this is the third hypercall
* argument, which is start_info_mfn here.
*/
return _hypercall3(int, sched_op, SCHEDOP_shutdown, &r, start_info_mfn);
}

static inline int
Expand Down
6 changes: 4 additions & 2 deletions arch/x86/xen/enlighten.c
Original file line number Diff line number Diff line change
Expand Up @@ -1284,8 +1284,7 @@ static int init_hvm_pv_info(int *major, int *minor)

xen_setup_features();

pv_info = xen_info;
pv_info.kernel_rpl = 0;
pv_info.name = "Xen HVM";

xen_domain_type = XEN_HVM_DOMAIN;

Expand Down Expand Up @@ -1331,6 +1330,8 @@ static int __cpuinit xen_hvm_cpu_notify(struct notifier_block *self,
switch (action) {
case CPU_UP_PREPARE:
per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu];
if (xen_have_vector_callback)
xen_init_lock_cpu(cpu);
break;
default:
break;
Expand All @@ -1355,6 +1356,7 @@ static void __init xen_hvm_guest_init(void)

if (xen_feature(XENFEAT_hvm_callback_vector))
xen_have_vector_callback = 1;
xen_hvm_smp_init();
register_cpu_notifier(&xen_hvm_cpu_notifier);
xen_unplug_emulated_devices();
have_vcpu_info_placement = 0;
Expand Down
38 changes: 38 additions & 0 deletions arch/x86/xen/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -509,3 +509,41 @@ void __init xen_smp_init(void)
xen_fill_possible_map();
xen_init_spinlocks();
}

static void __init xen_hvm_smp_prepare_cpus(unsigned int max_cpus)
{
native_smp_prepare_cpus(max_cpus);
WARN_ON(xen_smp_intr_init(0));

if (!xen_have_vector_callback)
return;
xen_init_lock_cpu(0);
xen_init_spinlocks();
}

static int __cpuinit xen_hvm_cpu_up(unsigned int cpu)
{
int rc;
rc = native_cpu_up(cpu);
WARN_ON (xen_smp_intr_init(cpu));
return rc;
}

static void xen_hvm_cpu_die(unsigned int cpu)
{
unbind_from_irqhandler(per_cpu(xen_resched_irq, cpu), NULL);
unbind_from_irqhandler(per_cpu(xen_callfunc_irq, cpu), NULL);
unbind_from_irqhandler(per_cpu(xen_debug_irq, cpu), NULL);
unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu), NULL);
native_cpu_die(cpu);
}

void __init xen_hvm_smp_init(void)
{
smp_ops.smp_prepare_cpus = xen_hvm_smp_prepare_cpus;
smp_ops.smp_send_reschedule = xen_smp_send_reschedule;
smp_ops.cpu_up = xen_hvm_cpu_up;
smp_ops.cpu_die = xen_hvm_cpu_die;
smp_ops.send_call_func_ipi = xen_smp_send_call_function_ipi;
smp_ops.send_call_func_single_ipi = xen_smp_send_call_function_single_ipi;
}
8 changes: 5 additions & 3 deletions arch/x86/xen/suspend.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include "xen-ops.h"
#include "mmu.h"

void xen_pre_suspend(void)
void xen_arch_pre_suspend(void)
{
xen_start_info->store_mfn = mfn_to_pfn(xen_start_info->store_mfn);
xen_start_info->console.domU.mfn =
Expand All @@ -26,8 +26,9 @@ void xen_pre_suspend(void)
BUG();
}

void xen_hvm_post_suspend(int suspend_cancelled)
void xen_arch_hvm_post_suspend(int suspend_cancelled)
{
#ifdef CONFIG_XEN_PVHVM
int cpu;
xen_hvm_init_shared_info();
xen_callback_vector();
Expand All @@ -37,9 +38,10 @@ void xen_hvm_post_suspend(int suspend_cancelled)
xen_setup_runstate_info(cpu);
}
}
#endif
}

void xen_post_suspend(int suspend_cancelled)
void xen_arch_post_suspend(int suspend_cancelled)
{
xen_build_mfn_list_list();

Expand Down
2 changes: 2 additions & 0 deletions arch/x86/xen/xen-ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,12 @@ void xen_setup_vcpu_info_placement(void);

#ifdef CONFIG_SMP
void xen_smp_init(void);
void __init xen_hvm_smp_init(void);

extern cpumask_var_t xen_cpu_initialized_map;
#else
static inline void xen_smp_init(void) {}
static inline void xen_hvm_smp_init(void) {}
#endif

#ifdef CONFIG_PARAVIRT_SPINLOCKS
Expand Down
79 changes: 74 additions & 5 deletions drivers/block/xen-blkfront.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ static DEFINE_SPINLOCK(minor_lock);
#define EXTENDED (1<<EXT_SHIFT)
#define VDEV_IS_EXTENDED(dev) ((dev)&(EXTENDED))
#define BLKIF_MINOR_EXT(dev) ((dev)&(~EXTENDED))
#define EMULATED_HD_DISK_MINOR_OFFSET (0)
#define EMULATED_HD_DISK_NAME_OFFSET (EMULATED_HD_DISK_MINOR_OFFSET / 256)
#define EMULATED_SD_DISK_MINOR_OFFSET (EMULATED_HD_DISK_MINOR_OFFSET + (4 * 16))
#define EMULATED_SD_DISK_NAME_OFFSET (EMULATED_HD_DISK_NAME_OFFSET + 4)

#define DEV_NAME "xvd" /* name in /dev */

Expand Down Expand Up @@ -434,14 +438,73 @@ static void xlvbd_flush(struct blkfront_info *info)
info->feature_flush ? "enabled" : "disabled");
}

static int xen_translate_vdev(int vdevice, int *minor, unsigned int *offset)
{
int major;
major = BLKIF_MAJOR(vdevice);
*minor = BLKIF_MINOR(vdevice);
switch (major) {
case XEN_IDE0_MAJOR:
*offset = (*minor / 64) + EMULATED_HD_DISK_NAME_OFFSET;
*minor = ((*minor / 64) * PARTS_PER_DISK) +
EMULATED_HD_DISK_MINOR_OFFSET;
break;
case XEN_IDE1_MAJOR:
*offset = (*minor / 64) + 2 + EMULATED_HD_DISK_NAME_OFFSET;
*minor = (((*minor / 64) + 2) * PARTS_PER_DISK) +
EMULATED_HD_DISK_MINOR_OFFSET;
break;
case XEN_SCSI_DISK0_MAJOR:
*offset = (*minor / PARTS_PER_DISK) + EMULATED_SD_DISK_NAME_OFFSET;
*minor = *minor + EMULATED_SD_DISK_MINOR_OFFSET;
break;
case XEN_SCSI_DISK1_MAJOR:
case XEN_SCSI_DISK2_MAJOR:
case XEN_SCSI_DISK3_MAJOR:
case XEN_SCSI_DISK4_MAJOR:
case XEN_SCSI_DISK5_MAJOR:
case XEN_SCSI_DISK6_MAJOR:
case XEN_SCSI_DISK7_MAJOR:
*offset = (*minor / PARTS_PER_DISK) +
((major - XEN_SCSI_DISK1_MAJOR + 1) * 16) +
EMULATED_SD_DISK_NAME_OFFSET;
*minor = *minor +
((major - XEN_SCSI_DISK1_MAJOR + 1) * 16 * PARTS_PER_DISK) +
EMULATED_SD_DISK_MINOR_OFFSET;
break;
case XEN_SCSI_DISK8_MAJOR:
case XEN_SCSI_DISK9_MAJOR:
case XEN_SCSI_DISK10_MAJOR:
case XEN_SCSI_DISK11_MAJOR:
case XEN_SCSI_DISK12_MAJOR:
case XEN_SCSI_DISK13_MAJOR:
case XEN_SCSI_DISK14_MAJOR:
case XEN_SCSI_DISK15_MAJOR:
*offset = (*minor / PARTS_PER_DISK) +
((major - XEN_SCSI_DISK8_MAJOR + 8) * 16) +
EMULATED_SD_DISK_NAME_OFFSET;
*minor = *minor +
((major - XEN_SCSI_DISK8_MAJOR + 8) * 16 * PARTS_PER_DISK) +
EMULATED_SD_DISK_MINOR_OFFSET;
break;
case XENVBD_MAJOR:
*offset = *minor / PARTS_PER_DISK;
break;
default:
printk(KERN_WARNING "blkfront: your disk configuration is "
"incorrect, please use an xvd device instead\n");
return -ENODEV;
}
return 0;
}

static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
struct blkfront_info *info,
u16 vdisk_info, u16 sector_size)
{
struct gendisk *gd;
int nr_minors = 1;
int err = -ENODEV;
int err;
unsigned int offset;
int minor;
int nr_parts;
Expand All @@ -456,12 +519,20 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
}

if (!VDEV_IS_EXTENDED(info->vdevice)) {
minor = BLKIF_MINOR(info->vdevice);
nr_parts = PARTS_PER_DISK;
err = xen_translate_vdev(info->vdevice, &minor, &offset);
if (err)
return err;
nr_parts = PARTS_PER_DISK;
} else {
minor = BLKIF_MINOR_EXT(info->vdevice);
nr_parts = PARTS_PER_EXT_DISK;
offset = minor / nr_parts;
if (xen_hvm_domain() && offset <= EMULATED_HD_DISK_NAME_OFFSET + 4)
printk(KERN_WARNING "blkfront: vdevice 0x%x might conflict with "
"emulated IDE disks,\n\t choose an xvd device name"
"from xvde on\n", info->vdevice);
}
err = -ENODEV;

if ((minor % nr_parts) == 0)
nr_minors = nr_parts;
Expand All @@ -475,8 +546,6 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
if (gd == NULL)
goto release;

offset = minor / nr_parts;

if (nr_minors > 1) {
if (offset < 26)
sprintf(gd->disk_name, "%s%c", DEV_NAME, 'a' + offset);
Expand Down
14 changes: 9 additions & 5 deletions drivers/xen/balloon.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ static int increase_reservation(unsigned long nr_pages)
set_phys_to_machine(pfn, frame_list[i]);

/* Link back into the page tables if not highmem. */
if (pfn < max_low_pfn) {
if (!xen_hvm_domain() && pfn < max_low_pfn) {
int ret;
ret = HYPERVISOR_update_va_mapping(
(unsigned long)__va(pfn << PAGE_SHIFT),
Expand Down Expand Up @@ -280,7 +280,7 @@ static int decrease_reservation(unsigned long nr_pages)

scrub_page(page);

if (!PageHighMem(page)) {
if (!xen_hvm_domain() && !PageHighMem(page)) {
ret = HYPERVISOR_update_va_mapping(
(unsigned long)__va(pfn << PAGE_SHIFT),
__pte_ma(0), 0);
Expand Down Expand Up @@ -392,15 +392,19 @@ static struct notifier_block xenstore_notifier;

static int __init balloon_init(void)
{
unsigned long pfn, extra_pfn_end;
unsigned long pfn, nr_pages, extra_pfn_end;
struct page *page;

if (!xen_pv_domain())
if (!xen_domain())
return -ENODEV;

pr_info("xen_balloon: Initialising balloon driver.\n");

balloon_stats.current_pages = min(xen_start_info->nr_pages, max_pfn);
if (xen_pv_domain())
nr_pages = xen_start_info->nr_pages;
else
nr_pages = max_pfn;
balloon_stats.current_pages = min(nr_pages, max_pfn);
balloon_stats.target_pages = balloon_stats.current_pages;
balloon_stats.balloon_low = 0;
balloon_stats.balloon_high = 0;
Expand Down
Loading

0 comments on commit 76ca078

Please sign in to comment.