Skip to content

Commit

Permalink
Changes representative of linux-3.10.0-327.3.1.el7.tar.xz
Browse files Browse the repository at this point in the history
  • Loading branch information
da-x committed Dec 21, 2015
1 parent 5103c62 commit 37f764e
Showing 28 changed files with 425 additions and 200 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ EXTRAVERSION =
NAME = Unicycling Gorilla
RHEL_MAJOR = 7
RHEL_MINOR = 2
RHEL_RELEASE = 327
RHEL_RELEASE = 327.3.1
RHEL_DRM_VERSION = 4
RHEL_DRM_PATCHLEVEL = 1
RHEL_DRM_SUBLEVEL = 0
15 changes: 15 additions & 0 deletions arch/powerpc/include/asm/kvm_book3s_64.h
Original file line number Diff line number Diff line change
@@ -86,6 +86,20 @@ static inline long try_lock_hpte(__be64 *hpte, unsigned long bits)
return old == 0;
}

static inline void unlock_hpte(__be64 *hpte, unsigned long hpte_v)
{
hpte_v &= ~HPTE_V_HVLOCK;
asm volatile(PPC_RELEASE_BARRIER "" : : : "memory");
hpte[0] = cpu_to_be64(hpte_v);
}

/* Without barrier */
static inline void __unlock_hpte(__be64 *hpte, unsigned long hpte_v)
{
hpte_v &= ~HPTE_V_HVLOCK;
hpte[0] = cpu_to_be64(hpte_v);
}

static inline int __hpte_actual_psize(unsigned int lp, int psize)
{
int i, shift;
@@ -416,6 +430,7 @@ static inline struct kvm_memslots *kvm_memslots_raw(struct kvm *kvm)
}

extern void kvmhv_rm_send_ipi(int cpu);
extern void kvmppc_mmu_debugfs_init(struct kvm *kvm);

#endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */

2 changes: 2 additions & 0 deletions arch/powerpc/include/asm/kvm_host.h
Original file line number Diff line number Diff line change
@@ -257,6 +257,8 @@ struct kvm_arch {
spinlock_t slot_phys_lock;
cpumask_t need_tlb_flush;
int hpt_cma_alloc;
struct dentry *debugfs_dir;
struct dentry *htab_dentry;
#endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */
#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE
struct mutex hpt_mutex;
2 changes: 2 additions & 0 deletions arch/powerpc/kernel/pci-common.c
Original file line number Diff line number Diff line change
@@ -987,6 +987,8 @@ void pcibios_setup_bus_self(struct pci_bus *bus)

static void pcibios_setup_device(struct pci_dev *dev)
{
arch_dma_init(&dev->dev);

/* Fixup NUMA node as it may not be setup yet by the generic
* code and is needed by the DMA init
*/
161 changes: 146 additions & 15 deletions arch/powerpc/kvm/book3s_64_mmu_hv.c
Original file line number Diff line number Diff line change
@@ -27,6 +27,7 @@
#include <linux/srcu.h>
#include <linux/anon_inodes.h>
#include <linux/file.h>
#include <linux/debugfs.h>

#include <asm/tlbflush.h>
#include <asm/kvm_ppc.h>
@@ -478,9 +479,7 @@ static int kvmppc_mmu_book3s_64_hv_xlate(struct kvm_vcpu *vcpu, gva_t eaddr,
v = be64_to_cpu(hptep[0]) & ~HPTE_V_HVLOCK;
gr = kvm->arch.revmap[index].guest_rpte;

/* Unlock the HPTE */
asm volatile("lwsync" : : : "memory");
hptep[0] = cpu_to_be64(v);
unlock_hpte(hptep, v);
preempt_enable();

gpte->eaddr = eaddr;
@@ -609,8 +608,7 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,
hpte[0] = be64_to_cpu(hptep[0]) & ~HPTE_V_HVLOCK;
hpte[1] = be64_to_cpu(hptep[1]);
hpte[2] = r = rev->guest_rpte;
asm volatile("lwsync" : : : "memory");
hptep[0] = cpu_to_be64(hpte[0]);
unlock_hpte(hptep, hpte[0]);
preempt_enable();

if (hpte[0] != vcpu->arch.pgfault_hpte[0] ||
@@ -762,7 +760,7 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,

hptep[1] = cpu_to_be64(r);
eieio();
hptep[0] = cpu_to_be64(hpte[0]);
__unlock_hpte(hptep, hpte[0]);
asm volatile("ptesync" : : : "memory");
preempt_enable();
if (page && hpte_is_writable(r))
@@ -783,7 +781,7 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,
return ret;

out_unlock:
hptep[0] &= ~cpu_to_be64(HPTE_V_HVLOCK);
__unlock_hpte(hptep, be64_to_cpu(hptep[0]));
preempt_enable();
goto out_put;
}
@@ -913,7 +911,7 @@ static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp,
}
}
unlock_rmap(rmapp);
hptep[0] &= ~cpu_to_be64(HPTE_V_HVLOCK);
__unlock_hpte(hptep, be64_to_cpu(hptep[0]));
}
return 0;
}
@@ -1001,7 +999,7 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp,
}
ret = 1;
}
hptep[0] &= ~cpu_to_be64(HPTE_V_HVLOCK);
__unlock_hpte(hptep, be64_to_cpu(hptep[0]));
} while ((i = j) != head);

unlock_rmap(rmapp);
@@ -1124,8 +1122,7 @@ static int kvm_test_clear_dirty_npages(struct kvm *kvm, unsigned long *rmapp)

/* Now check and modify the HPTE */
if (!(hptep[0] & cpu_to_be64(HPTE_V_VALID))) {
/* unlock and continue */
hptep[0] &= ~cpu_to_be64(HPTE_V_HVLOCK);
__unlock_hpte(hptep, be64_to_cpu(hptep[0]));
continue;
}

@@ -1146,9 +1143,9 @@ static int kvm_test_clear_dirty_npages(struct kvm *kvm, unsigned long *rmapp)
npages_dirty = n;
eieio();
}
v &= ~(HPTE_V_ABSENT | HPTE_V_HVLOCK);
v &= ~HPTE_V_ABSENT;
v |= HPTE_V_VALID;
hptep[0] = cpu_to_be64(v);
__unlock_hpte(hptep, v);
} while ((i = j) != head);

unlock_rmap(rmapp);
@@ -1386,8 +1383,7 @@ static long record_hpte(unsigned long flags, __be64 *hptp,
r &= ~HPTE_GR_MODIFIED;
revp->guest_rpte = r;
}
asm volatile(PPC_RELEASE_BARRIER "" : : : "memory");
hptp[0] &= ~cpu_to_be64(HPTE_V_HVLOCK);
unlock_hpte(hptp, be64_to_cpu(hptp[0]));
preempt_enable();
if (!(valid == want_valid && (first_pass || dirty)))
ok = 0;
@@ -1663,6 +1659,141 @@ int kvm_vm_ioctl_get_htab_fd(struct kvm *kvm, struct kvm_get_htab_fd *ghf)
return ret;
}

struct debugfs_htab_state {
struct kvm *kvm;
struct mutex mutex;
unsigned long hpt_index;
int chars_left;
int buf_index;
char buf[64];
};

static int debugfs_htab_open(struct inode *inode, struct file *file)
{
struct kvm *kvm = inode->i_private;
struct debugfs_htab_state *p;

p = kzalloc(sizeof(*p), GFP_KERNEL);
if (!p)
return -ENOMEM;

kvm_get_kvm(kvm);
p->kvm = kvm;
mutex_init(&p->mutex);
file->private_data = p;

return nonseekable_open(inode, file);
}

static int debugfs_htab_release(struct inode *inode, struct file *file)
{
struct debugfs_htab_state *p = file->private_data;

kvm_put_kvm(p->kvm);
kfree(p);
return 0;
}

static ssize_t debugfs_htab_read(struct file *file, char __user *buf,
size_t len, loff_t *ppos)
{
struct debugfs_htab_state *p = file->private_data;
ssize_t ret, r;
unsigned long i, n;
unsigned long v, hr, gr;
struct kvm *kvm;
__be64 *hptp;

ret = mutex_lock_interruptible(&p->mutex);
if (ret)
return ret;

if (p->chars_left) {
n = p->chars_left;
if (n > len)
n = len;
r = copy_to_user(buf, p->buf + p->buf_index, n);
n -= r;
p->chars_left -= n;
p->buf_index += n;
buf += n;
len -= n;
ret = n;
if (r) {
if (!n)
ret = -EFAULT;
goto out;
}
}

kvm = p->kvm;
i = p->hpt_index;
hptp = (__be64 *)(kvm->arch.hpt_virt + (i * HPTE_SIZE));
for (; len != 0 && i < kvm->arch.hpt_npte; ++i, hptp += 2) {
if (!(be64_to_cpu(hptp[0]) & (HPTE_V_VALID | HPTE_V_ABSENT)))
continue;

/* lock the HPTE so it's stable and read it */
preempt_disable();
while (!try_lock_hpte(hptp, HPTE_V_HVLOCK))
cpu_relax();
v = be64_to_cpu(hptp[0]) & ~HPTE_V_HVLOCK;
hr = be64_to_cpu(hptp[1]);
gr = kvm->arch.revmap[i].guest_rpte;
unlock_hpte(hptp, v);
preempt_enable();

if (!(v & (HPTE_V_VALID | HPTE_V_ABSENT)))
continue;

n = scnprintf(p->buf, sizeof(p->buf),
"%6lx %.16lx %.16lx %.16lx\n",
i, v, hr, gr);
p->chars_left = n;
if (n > len)
n = len;
r = copy_to_user(buf, p->buf, n);
n -= r;
p->chars_left -= n;
p->buf_index = n;
buf += n;
len -= n;
ret += n;
if (r) {
if (!ret)
ret = -EFAULT;
goto out;
}
}
p->hpt_index = i;

out:
mutex_unlock(&p->mutex);
return ret;
}

ssize_t debugfs_htab_write(struct file *file, const char __user *buf,
size_t len, loff_t *ppos)
{
return -EACCES;
}

static const struct file_operations debugfs_htab_fops = {
.owner = THIS_MODULE,
.open = debugfs_htab_open,
.release = debugfs_htab_release,
.read = debugfs_htab_read,
.write = debugfs_htab_write,
.llseek = generic_file_llseek,
};

void kvmppc_mmu_debugfs_init(struct kvm *kvm)
{
kvm->arch.htab_dentry = debugfs_create_file("htab", 0400,
kvm->arch.debugfs_dir, kvm,
&debugfs_htab_fops);
}

void kvmppc_mmu_book3s_hv_init(struct kvm_vcpu *vcpu)
{
struct kvmppc_mmu *mmu = &vcpu->arch.mmu;
12 changes: 12 additions & 0 deletions arch/powerpc/kvm/book3s_hv.c
Original file line number Diff line number Diff line change
@@ -32,6 +32,7 @@
#include <linux/page-flags.h>
#include <linux/srcu.h>
#include <linux/miscdevice.h>
#include <linux/debugfs.h>

#include <asm/reg.h>
#include <asm/cputable.h>
@@ -3034,6 +3035,7 @@ static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu)
static int kvmppc_core_init_vm_hv(struct kvm *kvm)
{
unsigned long lpcr, lpid;
char buf[32];

/* Allocate the guest's logical partition ID */

@@ -3088,6 +3090,14 @@ static int kvmppc_core_init_vm_hv(struct kvm *kvm)
*/
kvm_hv_vm_activated();

/*
* Create a debugfs directory for the VM
*/
snprintf(buf, sizeof(buf), "vm%d", current->pid);
kvm->arch.debugfs_dir = debugfs_create_dir(buf, kvm_debugfs_dir);
if (!IS_ERR_OR_NULL(kvm->arch.debugfs_dir))
kvmppc_mmu_debugfs_init(kvm);

return 0;
}

@@ -3103,6 +3113,8 @@ static void kvmppc_free_vcores(struct kvm *kvm)

static void kvmppc_core_destroy_vm_hv(struct kvm *kvm)
{
debugfs_remove_recursive(kvm->arch.debugfs_dir);

kvm_hv_vm_deactivated();

kvmppc_free_vcores(kvm);
Loading

0 comments on commit 37f764e

Please sign in to comment.