mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
[IA64] Add support for enforcing singleshot mmap() semantics at the
privcmd interface. From: Isaku Yamahata <yamahata@valinux.co.jp> Signed-off-by: Keir Fraser <keir@xensource.com>
This commit is contained in:
1 parent
b73d95b84d
commit
6329cf0815
3 files changed
+21
-6
No files matched your search
@@ -546,6 +546,7 @@ struct xen_ia64_privcmd_range {
|
||||
};
|
||||
|
||||
struct xen_ia64_privcmd_vma {
|
||||
int is_privcmd_mmapped;
|
||||
struct xen_ia64_privcmd_range* range;
|
||||
|
||||
unsigned long num_entries;
|
||||
@@ -684,12 +685,15 @@ __xen_ia64_privcmd_vma_open(struct vm_area_struct* vma,
|
||||
static void
|
||||
xen_ia64_privcmd_vma_open(struct vm_area_struct* vma)
|
||||
{
|
||||
struct xen_ia64_privcmd_vma* old_privcmd_vma = (struct xen_ia64_privcmd_vma*)vma->vm_private_data;
|
||||
struct xen_ia64_privcmd_vma* privcmd_vma = (struct xen_ia64_privcmd_vma*)vma->vm_private_data;
|
||||
struct xen_ia64_privcmd_range* privcmd_range = privcmd_vma->range;
|
||||
|
||||
atomic_inc(&privcmd_range->ref_count);
|
||||
// vm_op->open() can't fail.
|
||||
privcmd_vma = kmalloc(sizeof(*privcmd_vma), GFP_KERNEL | __GFP_NOFAIL);
|
||||
// copy original value if necessary
|
||||
privcmd_vma->is_privcmd_mmapped = old_privcmd_vma->is_privcmd_mmapped;
|
||||
|
||||
__xen_ia64_privcmd_vma_open(vma, privcmd_vma, privcmd_range);
|
||||
}
|
||||
@@ -724,6 +728,14 @@ xen_ia64_privcmd_vma_close(struct vm_area_struct* vma)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
privcmd_enforce_singleshot_mapping(struct vm_area_struct *vma)
|
||||
{
|
||||
struct xen_ia64_privcmd_vma* privcmd_vma =
|
||||
(struct xen_ia64_privcmd_vma *)vma->vm_private_data;
|
||||
return (xchg(&privcmd_vma->is_privcmd_mmapped, 1) == 0);
|
||||
}
|
||||
|
||||
int
|
||||
privcmd_mmap(struct file * file, struct vm_area_struct * vma)
|
||||
{
|
||||
@@ -749,6 +761,8 @@ privcmd_mmap(struct file * file, struct vm_area_struct * vma)
|
||||
if (privcmd_vma == NULL) {
|
||||
goto out_enomem1;
|
||||
}
|
||||
privcmd_vma->is_privcmd_mmapped = 0;
|
||||
|
||||
res = kzalloc(sizeof(*res), GFP_KERNEL);
|
||||
if (res == NULL) {
|
||||
goto out_enomem1;
|
||||
|
||||
@@ -35,14 +35,9 @@
|
||||
static struct proc_dir_entry *privcmd_intf;
|
||||
static struct proc_dir_entry *capabilities_intf;
|
||||
|
||||
static int privcmd_enforce_singleshot_mapping(struct vm_area_struct *vma)
|
||||
{
|
||||
#ifndef HAVE_ARCH_PRIVCMD_MMAP
|
||||
if (xchg(&vma->vm_private_data, (void *)1) != NULL)
|
||||
return 0;
|
||||
static int privcmd_enforce_singleshot_mapping(struct vm_area_struct *vma);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int privcmd_ioctl(struct inode *inode, struct file *file,
|
||||
unsigned int cmd, unsigned long data)
|
||||
@@ -255,6 +250,11 @@ static int privcmd_mmap(struct file * file, struct vm_area_struct * vma)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int privcmd_enforce_singleshot_mapping(struct vm_area_struct *vma)
|
||||
{
|
||||
return (xchg(&vma->vm_private_data, (void *)1) == NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct file_operations privcmd_file_ops = {
|
||||
|
||||
@@ -138,6 +138,7 @@ int direct_remap_pfn_range(struct vm_area_struct *vma,
|
||||
pgprot_t prot,
|
||||
domid_t domid);
|
||||
struct file;
|
||||
int privcmd_enforce_singleshot_mapping(struct vm_area_struct *vma);
|
||||
int privcmd_mmap(struct file * file, struct vm_area_struct * vma);
|
||||
#define HAVE_ARCH_PRIVCMD_MMAP
|
||||
|
||||
|
||||