diff options
| author | Timur Tabi <timur@freescale.com> | 2011-06-09 16:52:06 -0400 |
|---|---|---|
| committer | Kumar Gala <galak@kernel.crashing.org> | 2011-07-08 01:21:27 -0400 |
| commit | 6db7199407ca56f55bc0832fb124e1ad216ea57b (patch) | |
| tree | 62321e519dd0f74e24de02492fdd79c51173e08a /drivers/virt | |
| parent | 8dbb6bc13617379a6534700e51634a3f88c9a513 (diff) | |
drivers/virt: introduce Freescale hypervisor management driver
Add the drivers/virt directory, which houses drivers that support
virtualization environments, and add the Freescale hypervisor management
driver.
The Freescale hypervisor management driver provides several services to
drivers and applications related to the Freescale hypervisor:
1. An ioctl interface for querying and managing partitions
2. A file interface to reading incoming doorbells
3. An interrupt handler for shutting down the partition upon receiving the
shutdown doorbell from a manager partition
4. A kernel interface for receiving callbacks when a managed partition
shuts down.
Signed-off-by: Timur Tabi <timur@freescale.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Diffstat (limited to 'drivers/virt')
| -rw-r--r-- | drivers/virt/Kconfig | 32 | ||||
| -rw-r--r-- | drivers/virt/Makefile | 5 | ||||
| -rw-r--r-- | drivers/virt/fsl_hypervisor.c | 937 |
3 files changed, 974 insertions, 0 deletions
diff --git a/drivers/virt/Kconfig b/drivers/virt/Kconfig new file mode 100644 index 000000000000..2dcdbc9364d8 --- /dev/null +++ b/drivers/virt/Kconfig | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | # | ||
| 2 | # Virtualization support drivers | ||
| 3 | # | ||
| 4 | |||
| 5 | menuconfig VIRT_DRIVERS | ||
| 6 | bool "Virtualization drivers" | ||
| 7 | ---help--- | ||
| 8 | Say Y here to get to see options for device drivers that support | ||
| 9 | virtualization environments. | ||
| 10 | |||
| 11 | If you say N, all options in this submenu will be skipped and disabled. | ||
| 12 | |||
| 13 | if VIRT_DRIVERS | ||
| 14 | |||
| 15 | config FSL_HV_MANAGER | ||
| 16 | tristate "Freescale hypervisor management driver" | ||
| 17 | depends on FSL_SOC | ||
| 18 | help | ||
| 19 | The Freescale hypervisor management driver provides several services | ||
| 20 | to drivers and applications related to the Freescale hypervisor: | ||
| 21 | |||
| 22 | 1) An ioctl interface for querying and managing partitions. | ||
| 23 | |||
| 24 | 2) A file interface to reading incoming doorbells. | ||
| 25 | |||
| 26 | 3) An interrupt handler for shutting down the partition upon | ||
| 27 | receiving the shutdown doorbell from a manager partition. | ||
| 28 | |||
| 29 | 4) A kernel interface for receiving callbacks when a managed | ||
| 30 | partition shuts down. | ||
| 31 | |||
| 32 | endif | ||
diff --git a/drivers/virt/Makefile b/drivers/virt/Makefile new file mode 100644 index 000000000000..c47f04dd343b --- /dev/null +++ b/drivers/virt/Makefile | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | # | ||
| 2 | # Makefile for drivers that support virtualization | ||
| 3 | # | ||
| 4 | |||
| 5 | obj-$(CONFIG_FSL_HV_MANAGER) += fsl_hypervisor.o | ||
diff --git a/drivers/virt/fsl_hypervisor.c b/drivers/virt/fsl_hypervisor.c new file mode 100644 index 000000000000..1d3b8ebb3141 --- /dev/null +++ b/drivers/virt/fsl_hypervisor.c | |||
| @@ -0,0 +1,937 @@ | |||
| 1 | /* | ||
| 2 | * Freescale Hypervisor Management Driver | ||
| 3 | |||
| 4 | * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. | ||
| 5 | * Author: Timur Tabi <timur@freescale.com> | ||
| 6 | * | ||
| 7 | * This file is licensed under the terms of the GNU General Public License | ||
| 8 | * version 2. This program is licensed "as is" without any warranty of any | ||
| 9 | * kind, whether express or implied. | ||
| 10 | * | ||
| 11 | * The Freescale hypervisor management driver provides several services to | ||
| 12 | * drivers and applications related to the Freescale hypervisor: | ||
| 13 | * | ||
| 14 | * 1. An ioctl interface for querying and managing partitions. | ||
| 15 | * | ||
| 16 | * 2. A file interface to reading incoming doorbells. | ||
| 17 | * | ||
| 18 | * 3. An interrupt handler for shutting down the partition upon receiving the | ||
| 19 | * shutdown doorbell from a manager partition. | ||
| 20 | * | ||
| 21 | * 4. A kernel interface for receiving callbacks when a managed partition | ||
| 22 | * shuts down. | ||
| 23 | */ | ||
| 24 | |||
| 25 | #include <linux/kernel.h> | ||
| 26 | #include <linux/module.h> | ||
| 27 | #include <linux/init.h> | ||
| 28 | #include <linux/types.h> | ||
| 29 | #include <linux/err.h> | ||
| 30 | #include <linux/fs.h> | ||
| 31 | #include <linux/miscdevice.h> | ||
| 32 | #include <linux/mm.h> | ||
| 33 | #include <linux/pagemap.h> | ||
| 34 | #include <linux/slab.h> | ||
| 35 | #include <linux/poll.h> | ||
| 36 | #include <linux/of.h> | ||
| 37 | #include <linux/reboot.h> | ||
| 38 | #include <linux/uaccess.h> | ||
| 39 | #include <linux/notifier.h> | ||
| 40 | |||
| 41 | #include <linux/io.h> | ||
| 42 | #include <asm/fsl_hcalls.h> | ||
| 43 | |||
| 44 | #include <linux/fsl_hypervisor.h> | ||
| 45 | |||
| 46 | static BLOCKING_NOTIFIER_HEAD(failover_subscribers); | ||
| 47 | |||
| 48 | /* | ||
| 49 | * Ioctl interface for FSL_HV_IOCTL_PARTITION_RESTART | ||
| 50 | * | ||
| 51 | * Restart a running partition | ||
| 52 | */ | ||
| 53 | static long ioctl_restart(struct fsl_hv_ioctl_restart __user *p) | ||
| 54 | { | ||
| 55 | struct fsl_hv_ioctl_restart param; | ||
| 56 | |||
| 57 | /* Get the parameters from the user */ | ||
| 58 | if (copy_from_user(¶m, p, sizeof(struct fsl_hv_ioctl_restart))) | ||
| 59 | return -EFAULT; | ||
| 60 | |||
| 61 | param.ret = fh_partition_restart(param.partition); | ||
| 62 | |||
| 63 | if (copy_to_user(&p->ret, ¶m.ret, sizeof(__u32))) | ||
| 64 | return -EFAULT; | ||
| 65 | |||
| 66 | return 0; | ||
| 67 | } | ||
| 68 | |||
| 69 | /* | ||
| 70 | * Ioctl interface for FSL_HV_IOCTL_PARTITION_STATUS | ||
| 71 | * | ||
| 72 | * Query the status of a partition | ||
| 73 | */ | ||
| 74 | static long ioctl_status(struct fsl_hv_ioctl_status __user *p) | ||
| 75 | { | ||
| 76 | struct fsl_hv_ioctl_status param; | ||
| 77 | u32 status; | ||
| 78 | |||
| 79 | /* Get the parameters from the user */ | ||
| 80 | if (copy_from_user(¶m, p, sizeof(struct fsl_hv_ioctl_status))) | ||
| 81 | return -EFAULT; | ||
| 82 | |||
| 83 | param.ret = fh_partition_get_status(param.partition, &status); | ||
| 84 | if (!param.ret) | ||
| 85 | param.status = status; | ||
| 86 | |||
| 87 | if (copy_to_user(p, ¶m, sizeof(struct fsl_hv_ioctl_status))) | ||
| 88 | return -EFAULT; | ||
| 89 | |||
| 90 | return 0; | ||
| 91 | } | ||
| 92 | |||
| 93 | /* | ||
| 94 | * Ioctl interface for FSL_HV_IOCTL_PARTITION_START | ||
| 95 | * | ||
| 96 | * Start a stopped partition. | ||
| 97 | */ | ||
| 98 | static long ioctl_start(struct fsl_hv_ioctl_start __user *p) | ||
| 99 | { | ||
| 100 | struct fsl_hv_ioctl_start param; | ||
| 101 | |||
| 102 | /* Get the parameters from the user */ | ||
| 103 | if (copy_from_user(¶m, p, sizeof(struct fsl_hv_ioctl_start))) | ||
| 104 | return -EFAULT; | ||
| 105 | |||
| 106 | param.ret = fh_partition_start(param.partition, param.entry_point, | ||
| 107 | param.load); | ||
| 108 | |||
| 109 | if (copy_to_user(&p->ret, ¶m.ret, sizeof(__u32))) | ||
| 110 | return -EFAULT; | ||
| 111 | |||
| 112 | return 0; | ||
| 113 | } | ||
| 114 | |||
| 115 | /* | ||
| 116 | * Ioctl interface for FSL_HV_IOCTL_PARTITION_STOP | ||
| 117 | * | ||
| 118 | * Stop a running partition | ||
| 119 | */ | ||
| 120 | static long ioctl_stop(struct fsl_hv_ioctl_stop __user *p) | ||
| 121 | { | ||
| 122 | struct fsl_hv_ioctl_stop param; | ||
| 123 | |||
| 124 | /* Get the parameters from the user */ | ||
| 125 | if (copy_from_user(¶m, p, sizeof(struct fsl_hv_ioctl_stop))) | ||
| 126 | return -EFAULT; | ||
| 127 | |||
| 128 | param.ret = fh_partition_stop(param.partition); | ||
| 129 | |||
| 130 | if (copy_to_user(&p->ret, ¶m.ret, sizeof(__u32))) | ||
| 131 | return -EFAULT; | ||
| 132 | |||
| 133 | return 0; | ||
| 134 | } | ||
| 135 | |||
| 136 | /* | ||
| 137 | * Ioctl interface for FSL_HV_IOCTL_MEMCPY | ||
| 138 | * | ||
| 139 | * The FH_MEMCPY hypercall takes an array of address/address/size structures | ||
| 140 | * to represent the data being copied. As a convenience to the user, this | ||
| 141 | * ioctl takes a user-create buffer and a pointer to a guest physically | ||
| 142 | * contiguous buffer in the remote partition, and creates the | ||
| 143 | * address/address/size array for the hypercall. | ||
| 144 | */ | ||
| 145 | static long ioctl_memcpy(struct fsl_hv_ioctl_memcpy __user *p) | ||
| 146 | { | ||
| 147 | struct fsl_hv_ioctl_memcpy param; | ||
| 148 | |||
| 149 | struct page **pages = NULL; | ||
| 150 | void *sg_list_unaligned = NULL; | ||
| 151 | struct fh_sg_list *sg_list = NULL; | ||
| 152 | |||
| 153 | unsigned int num_pages; | ||
